[m-rev.] for review: improvements to deep profiler
Julien Fischer
juliensf at cs.mu.OZ.AU
Tue Aug 23 23:29:17 AEST 2005
For review by anyone.
Estimated hours taken: 3
Branches: main, release
Improvements to the deep profiling tool.
Provide the facility to hide modules/procedures to which there
have been no calls. This reduces the amount of clutter
when exploring the program module by module and when listing
the procedures in a module (the clutter is primarily a result
of unused standard library modules). By default, we currently
do not hide any modules/procedures.
Add a toggle to sort lists of procedures by the number of redos
they perform. We have had control at the head of tables to do
this for a while now.
Delete the function int_list_from_to/2 since that functionality
is now available in the standard library.
deep_profiler/html_format.m:
Provide toggles that allow the user to show/hide inactive
modules and procedures.
Add a toggle to sort lists of procedures by the number
of redos.
Rename a numbered sequence of variables so that it
is easier to insert new ones in the middle of the
sequence.
deep_profiler/interface.m:
Add support for hiding/showing inactive modules.
deep_profiler/measurements.m:
Add a predicate, is_inactive/1, that test if an own_prof_info
for a given entity is inactive.
deep_profiler/query.m:
When generating the module and procedure summaries, respect
the new preference settings for hiding/showing inactive
modules/procedures.
deep_profiler/top_procs.m:
Delete int_list_from_to/2 and replace calls to it with
'..' from the standard library.
Julien.
Index: html_format.m
===================================================================
RCS file: /home/mercury1/repository/mercury/deep_profiler/html_format.m,v
retrieving revision 1.9
diff -u -r1.9 html_format.m
--- html_format.m 14 Jul 2005 08:51:34 -0000 1.9
+++ html_format.m 23 Aug 2005 13:24:14 -0000
@@ -300,6 +300,18 @@
;
BoxToggle = ""
),
+ ( list__member(toggle_inactive_modules, RelevantToggles) ->
+ InactiveModuleToggle =
+ footer_inactive_modules_toggle(Cmd, Pref, Deep)
+ ;
+ InactiveModuleToggle = ""
+ ),
+ ( list__member(toggle_inactive_procs, RelevantToggles) ->
+ InactiveProcsToggle =
+ footer_inactive_procs_toggle(Cmd, Pref, Deep)
+ ;
+ InactiveProcsToggle = ""
+ ),
AllToggles =
FieldToggle ++
AncestorToggle ++
@@ -308,7 +320,9 @@
ContourToggle ++
TimeFormatToggle ++
ColourToggle ++
- BoxToggle.
+ BoxToggle ++
+ InactiveModuleToggle ++
+ InactiveProcsToggle.
%-----------------------------------------------------------------------------%
@@ -320,7 +334,9 @@
; toggle_summarize
; toggle_order_criteria
; toggle_contour
- ; toggle_time_format.
+ ; toggle_time_format
+ ; toggle_inactive_modules
+ ; toggle_inactive_procs.
:- func command_relevant_toggles(cmd) = list(toggle_kind).
@@ -341,10 +357,10 @@
toggle_contour, toggle_time_format].
command_relevant_toggles(modules) =
[toggle_fields, toggle_box, toggle_colour, toggle_order_criteria,
- toggle_time_format].
+ toggle_time_format, toggle_inactive_modules].
command_relevant_toggles(module(_)) =
[toggle_fields, toggle_box, toggle_colour, toggle_order_criteria,
- toggle_time_format].
+ toggle_time_format, toggle_inactive_procs].
command_relevant_toggles(top_procs(_, _, _, _)) =
[toggle_fields, toggle_box, toggle_colour, toggle_time_format].
command_relevant_toggles(proc_static(_)) = [].
@@ -765,65 +781,112 @@
toggle_cost_criteria(CostKind, InclDesc, Scope, UpdateCriteria) = Toggles :-
( CostKind \= calls ->
- Msg1 = "Sort by calls",
- Toggle1 = string__format("<A HREF=""%s"">%s</A>\n",
+ MsgCalls = "Sort by calls",
+ ToggleCalls = string__format("<A HREF=""%s"">%s</A>\n",
[s(UpdateCriteria(calls, InclDesc, Scope)),
- s(Msg1)])
+ s(MsgCalls)])
;
- Toggle1 = ""
+ ToggleCalls = ""
+ ),
+ ( CostKind \= redos ->
+ MsgRedos = "Sort by redos",
+ ToggleRedos = string.format("<A HREF=""%s"">%s</A>\n",
+ [s(UpdateCriteria(redos, InclDesc, Scope)),
+ s(MsgRedos)])
+ ;
+ ToggleRedos = ""
),
( CostKind \= time ->
- Msg2 = "Sort by time",
- Toggle2 = string__format("<A HREF=""%s"">%s</A>\n",
+ MsgTime = "Sort by time",
+ ToggleTime = string__format("<A HREF=""%s"">%s</A>\n",
[s(UpdateCriteria(time, InclDesc, Scope)),
- s(Msg2)])
+ s(MsgTime)])
;
- Toggle2 = ""
+ ToggleTime = ""
),
( CostKind \= allocs ->
- Msg3 = "Sort by allocations",
- Toggle3 = string__format("<A HREF=""%s"">%s</A>\n",
+ MsgAllocs = "Sort by allocations",
+ ToggleAllocs = string__format("<A HREF=""%s"">%s</A>\n",
[s(UpdateCriteria(allocs, InclDesc, Scope)),
- s(Msg3)])
+ s(MsgAllocs)])
;
- Toggle3 = ""
+ ToggleAllocs = ""
),
( CostKind \= words ->
- Msg4 = "Sort by words",
- Toggle4 = string__format("<A HREF=""%s"">%s</A>\n",
+ MsgWords = "Sort by words",
+ ToggleWords = string__format("<A HREF=""%s"">%s</A>\n",
[s(UpdateCriteria(words, InclDesc, Scope)),
- s(Msg4)])
+ s(MsgWords)])
;
- Toggle4 = ""
+ ToggleWords = ""
),
(
InclDesc = self,
- Msg5 = "Include descendants",
- Toggle5 = string__format("<A HREF=""%s"">%s</A>\n",
+ MsgDesc = "Include descendants",
+ ToggleDesc = string__format("<A HREF=""%s"">%s</A>\n",
[s(UpdateCriteria(CostKind, self_and_desc, Scope)),
- s(Msg5)])
+ s(MsgDesc)])
;
InclDesc = self_and_desc,
- Msg5 = "Exclude descendants",
- Toggle5 = string__format("<A HREF=""%s"">%s</A>\n",
+ MsgDesc = "Exclude descendants",
+ ToggleDesc = string__format("<A HREF=""%s"">%s</A>\n",
[s(UpdateCriteria(CostKind, self, Scope)),
- s(Msg5)])
+ s(MsgDesc)])
),
(
Scope = per_call,
- Msg6 = "Count overall cost",
- Toggle6 = string__format("<A HREF=""%s"">%s</A>\n",
+ MsgScope = "Count overall cost",
+ ToggleScope = string__format("<A HREF=""%s"">%s</A>\n",
[s(UpdateCriteria(CostKind, InclDesc, overall)),
- s(Msg6)])
+ s(MsgScope)])
;
Scope = overall,
- Msg6 = "Count per-call cost",
- Toggle6 = string__format("<A HREF=""%s"">%s</A>\n",
+ MsgScope = "Count per-call cost",
+ ToggleScope = string__format("<A HREF=""%s"">%s</A>\n",
[s(UpdateCriteria(CostKind, InclDesc, per_call)),
- s(Msg6)])
+ s(MsgScope)])
+ ),
+ Toggles = ToggleCalls ++ ToggleRedos ++ ToggleTime ++ ToggleAllocs
+ ++ ToggleWords ++ ToggleDesc ++ ToggleScope.
+
+%-----------------------------------------------------------------------------%
+%
+% Toggles to control showing/hiding inactive modules/procedures
+%
+
+:- func footer_inactive_modules_toggle(cmd, preferences, deep) = string.
+
+footer_inactive_modules_toggle(Cmd, Pref0, Deep) = HTML :-
+ Pref0 ^ pref_inactive = inactive_items(Procs, Modules),
+ (
+ Modules = show,
+ Msg = "Hide inactive modules",
+ Pref = Pref0 ^ pref_inactive := inactive_items(Procs, hide)
+ ;
+ Modules = hide,
+ Msg = "Show inactive modules",
+ Pref = Pref0 ^ pref_inactive := inactive_items(Procs, show)
+ ),
+ HTML = string__format("<A HREF=""%s"">%s</A>\n",
+ [s(deep_cmd_pref_to_url(Pref, Deep, Cmd)),
+ s(Msg)]).
+
+:- func footer_inactive_procs_toggle(cmd, preferences, deep) = string.
+
+footer_inactive_procs_toggle(Cmd, Pref0, Deep) = HTML :-
+ Pref0 ^ pref_inactive = inactive_items(Procs, Modules),
+ (
+ Procs = show,
+ Msg = "Hide inactive procedures",
+ Pref = Pref0 ^ pref_inactive := inactive_items(hide, Modules)
+ ;
+ Procs = hide,
+ Msg = "Show inactive procedures",
+ Pref = Pref0 ^ pref_inactive := inactive_items(show, Modules)
),
- Toggles = Toggle1 ++ Toggle2 ++ Toggle3 ++ Toggle4
- ++ Toggle5 ++ Toggle6.
+ HTML = string__format("<A HREF=""%s"">%s</A>\n",
+ [s(deep_cmd_pref_to_url(Pref, Deep, Cmd)),
+ s(Msg)]).
%-----------------------------------------------------------------------------%
Index: interface.m
===================================================================
RCS file: /home/mercury1/repository/mercury/deep_profiler/interface.m,v
retrieving revision 1.9
diff -u -r1.9 interface.m
--- interface.m 14 Jul 2005 08:51:34 -0000 1.9
+++ interface.m 23 Aug 2005 13:24:17 -0000
@@ -176,7 +176,11 @@
pref_contour :: contour,
% whether contour exclusion should be
% applied
- pref_time :: time_format
+ pref_time :: time_format,
+
+ pref_inactive :: inactive_items
+ % Whether we should show modules/procs
+ % that haven't been called.
).
:- type port_fields
@@ -247,6 +251,14 @@
; scale_by_millions
; scale_by_thousands.
+:- type inactive_status ---> hide ; show.
+
+:- type inactive_items
+ ---> inactive_items(
+ inactive_procs :: inactive_status,
+ inactive_modules :: inactive_status
+ ).
+
:- func default_preferences = preferences.
:- func default_fields = fields.
@@ -261,6 +273,7 @@
:- func default_scope = measurement_scope.
:- func default_contour = contour.
:- func default_time_format = time_format.
+:- func default_inactive_items = inactive_items.
:- func query_separator_char = char.
:- func machine_datafile_cmd_pref_to_url(string, string, cmd, preferences)
@@ -291,7 +304,8 @@
default_summarize,
default_order_criteria,
default_contour,
- default_time_format
+ default_time_format,
+ default_inactive_items
).
default_fields = fields(port, ticks, no_alloc, memory(words)).
@@ -306,6 +320,7 @@
default_scope = overall.
default_contour = no_contour.
default_time_format = scale_by_thousands.
+default_inactive_items = inactive_items(show, show).
%-----------------------------------------------------------------------------%
@@ -577,7 +592,7 @@
preferences_to_string(Pref) = PrefStr :-
Pref = preferences(Fields, Box, Colour, MaybeAncestorLimit,
- Summarize, Order, Contour, Time),
+ Summarize, Order, Contour, Time, InactiveItems),
(
MaybeAncestorLimit = yes(AncestorLimit),
MaybeAncestorLimitStr =
@@ -586,7 +601,7 @@
MaybeAncestorLimit = no,
MaybeAncestorLimitStr = "no"
),
- PrefStr = string__format("%s%c%s%c%s%c%s%c%s%c%s%c%s%c%s",
+ PrefStr = string__format("%s%c%s%c%s%c%s%c%s%c%s%c%s%c%s%c%s",
[s(fields_to_string(Fields)),
c(pref_separator_char), s(box_to_string(Box)),
c(pref_separator_char), s(colour_scheme_to_string(Colour)),
@@ -594,7 +609,10 @@
c(pref_separator_char), s(summarize_to_string(Summarize)),
c(pref_separator_char), s(order_criteria_to_string(Order)),
c(pref_separator_char), s(contour_to_string(Contour)),
- c(pref_separator_char), s(time_format_to_string(Time))]).
+ c(pref_separator_char), s(time_format_to_string(Time)),
+ c(pref_separator_char),
+ s(inactive_items_to_string(InactiveItems))
+ ]).
url_component_to_cmd(QueryString, DefaultCmd) = Cmd :-
MaybeCmd = url_component_to_maybe_cmd(QueryString),
@@ -702,7 +720,8 @@
split(QueryString, pref_separator_char, Pieces),
(
Pieces = [FieldsStr, BoxStr, ColourStr, MaybeAncestorLimitStr,
- SummarizeStr, OrderStr, ContourStr, TimeStr],
+ SummarizeStr, OrderStr, ContourStr, TimeStr,
+ InactiveItemsStr],
string_to_fields(FieldsStr, Fields),
string_to_box(BoxStr, Box),
string_to_colour_scheme(ColourStr, Colour),
@@ -716,10 +735,12 @@
string_to_summarize(SummarizeStr, Summarize),
string_to_order_criteria(OrderStr, Order),
string_to_contour(ContourStr, Contour),
- string_to_time_format(TimeStr, Time)
+ string_to_time_format(TimeStr, Time),
+ string_to_inactive_items(InactiveItemsStr, InactiveItems)
->
Preferences = preferences(Fields, Box, Colour,
- MaybeAncestorLimit, Summarize, Order, Contour, Time),
+ MaybeAncestorLimit, Summarize, Order, Contour, Time,
+ InactiveItems),
MaybePreferences = yes(Preferences)
;
MaybePreferences = no
@@ -952,6 +973,20 @@
string_to_time_format("no", no_scale).
string_to_time_format("mi", scale_by_millions).
string_to_time_format("th", scale_by_thousands).
+
+:- func inactive_items_to_string(inactive_items) = string.
+
+inactive_items_to_string(inactive_items(hide, hide)) = "hh".
+inactive_items_to_string(inactive_items(show, hide)) = "sh".
+inactive_items_to_string(inactive_items(hide, show)) = "hs".
+inactive_items_to_string(inactive_items(show, show)) = "ss".
+
+:- pred string_to_inactive_items(string::in, inactive_items::out) is semidet.
+
+string_to_inactive_items("hh", inactive_items(hide, hide)).
+string_to_inactive_items("sh", inactive_items(show, hide)).
+string_to_inactive_items("hs", inactive_items(hide, show)).
+string_to_inactive_items("ss", inactive_items(show, show)).
:- pred string_to_colour_scheme(string::in, colour_scheme::out) is semidet.
Index: measurements.m
===================================================================
RCS file: /home/mercury1/repository/mercury/deep_profiler/measurements.m,v
retrieving revision 1.6
diff -u -r1.6 measurements.m
--- measurements.m 23 Jun 2005 08:21:29 -0000 1.6
+++ measurements.m 23 Aug 2005 13:24:17 -0000
@@ -59,6 +59,12 @@
:- func own_to_string(own_prof_info) = string.
+ % Tests if this profiling information represents an entity in the
+ % program that was inactive during the profiling run, e.g. a module
+ % or procedure that has had no calls made to it.
+ %
+:- pred is_inactive(own_prof_info::in) is semidet.
+
%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%
@@ -72,7 +78,7 @@
:- type own_prof_info
---> all(int, int, int, int, int, int, int)
% exits, fails, redos, excps, quanta, allocs, words
- % implicit calls = exits + fails - redos
+ % implicit calls = exits + fails + excps - redos
; det(int, int, int, int)
% exits, quanta, allocs, words;
% implicit fails == redos == excps == 0
@@ -318,6 +324,11 @@
string__int_to_string(Exits) ++ ", " ++
string__int_to_string(Fails) ++
")".
+
+is_inactive(all(0, 0, 0, 0, _, _, _)).
+is_inactive(det(0, _, _, _)).
+is_inactive(fast_det(0, _, _)).
+is_inactive(fast_nomem_semi(0, 0)).
%----------------------------------------------------------------------------%
:- end_module measurements.
Index: query.m
===================================================================
RCS file: /home/mercury1/repository/mercury/deep_profiler/query.m,v
retrieving revision 1.8
diff -u -r1.8 query.m
--- query.m 23 Jun 2005 08:21:29 -0000 1.8
+++ query.m 23 Aug 2005 13:24:20 -0000
@@ -598,7 +598,7 @@
ToggleCostHTML ++
page_footer(Cmd, Pref, Deep)
;
- TopProcs = list__map(
+ TopProcs = list.filter_map(
lookup_proc_total_to_html(Pref, Deep, no, ""),
list__map(wrap_proc_static_ptr, TopPSIs)),
RankedTopProcs = add_ranks(TopProcs),
@@ -630,7 +630,7 @@
modules_to_html(Pref, Deep) = HTML :-
map__to_assoc_list(Deep ^ module_data, ModulePairs0),
list__filter(not_mercury_runtime, ModulePairs0, ModulePairs),
- ModuleLines = list__map(module_summary_to_html(Pref, Deep),
+ ModuleLines = list.filter_map(module_summary_to_html(Pref, Deep),
ModulePairs),
SortedModuleLines = sort_line_groups(Pref ^ pref_criteria,
ModuleLines),
@@ -648,18 +648,21 @@
ModuleName \= "Mercury runtime".
:- func module_summary_to_html(preferences, deep, pair(string, module_data))
- = one_id_line.
+ = one_id_line is semidet.
module_summary_to_html(Pref, Deep, ModuleName - ModuleData) = LineGroup :-
- Own = ModuleData ^ module_own,
- Desc = ModuleData ^ module_desc,
- HTML =
- string__format("<TD><A HREF=""%s"">%s</A></TD>\n",
- [s(deep_cmd_pref_to_url(Pref, Deep,
- module(ModuleName))),
- s(ModuleName)]),
- LineGroup = line_group(ModuleName, 0, ModuleName, Own, Desc, HTML,
- unit).
+ ModuleData = module_data(Own, Desc, _),
+ ( Pref ^ pref_inactive = inactive_items(_, hide), is_inactive(Own) ->
+ fail
+ ;
+ HTML =
+ string__format("<TD><A HREF=""%s"">%s</A></TD>\n",
+ [s(deep_cmd_pref_to_url(Pref, Deep,
+ module(ModuleName))),
+ s(ModuleName)]),
+ LineGroup = line_group(ModuleName, 0, ModuleName, Own, Desc,
+ HTML, unit)
+ ).
%-----------------------------------------------------------------------------%
@@ -668,8 +671,8 @@
module_to_html(Pref, Deep, _ModuleName, ModuleData, IdHeaders, HTML) :-
ModuleData = module_data(_Own, _Desc, PSPtrs),
- ProcLines = list__map(lookup_proc_total_to_html(Pref, Deep, yes, ""),
- PSPtrs),
+ ProcLines = list.filter_map(
+ lookup_proc_total_to_html(Pref, Deep, yes, ""), PSPtrs),
Criteria = Pref ^ pref_criteria,
SortedProcLines = sort_line_groups(Criteria, ProcLines),
( Criteria = by_cost(_, _, _) ->
@@ -895,14 +898,24 @@
%-----------------------------------------------------------------------------%
+ % Fails if the procedure is inactive and the preferences say to
+ % hide inactive procedures.
+ %
:- func lookup_proc_total_to_html(preferences, deep, bool, string,
- proc_static_ptr) = one_id_line.
+ proc_static_ptr) = one_id_line is semidet.
lookup_proc_total_to_html(Pref, Deep, Bold, Prefix, PSPtr) = LineGroup :-
deep_lookup_ps_own(Deep, PSPtr, Own),
- deep_lookup_ps_desc(Deep, PSPtr, Desc),
- LineGroup = proc_total_to_html(Pref, Deep, Bold, Prefix,
- PSPtr, Own, Desc).
+ (
+ Pref ^ pref_inactive = inactive_items(hide, _),
+ is_inactive(Own)
+ ->
+ fail
+ ;
+ deep_lookup_ps_desc(Deep, PSPtr, Desc),
+ LineGroup = proc_total_to_html(Pref, Deep, Bold, Prefix,
+ PSPtr, Own, Desc)
+ ).
:- func lookup_proc_total_to_two_id_line(preferences, deep, bool, string,
proc_static_ptr) = two_id_line.
Index: top_procs.m
===================================================================
RCS file: /home/mercury1/repository/mercury/deep_profiler/top_procs.m,v
retrieving revision 1.4
diff -u -r1.4 top_procs.m
--- top_procs.m 14 Jul 2005 08:51:34 -0000 1.4
+++ top_procs.m 23 Aug 2005 13:24:21 -0000
@@ -74,7 +74,7 @@
SortCompatible = yes,
ProcStatics = Deep ^ proc_statics,
array__max(ProcStatics, MaxProcStatic),
- PSIs0 = int_list_from_to(1, MaxProcStatic),
+ PSIs0 = 1 .. MaxProcStatic,
deep_lookup_proc_dynamics(Deep, Deep ^ root, RootPD),
RootPD ^ pd_proc_static = proc_static_ptr(RootPSI),
list__filter(filter_top_procs(Deep, RootPSI, FilterPred),
@@ -115,15 +115,6 @@
MaybeTopPSIs = ok(TopPSIs)
)
)
- ).
-
-:- func int_list_from_to(int, int) = list(int).
-
-int_list_from_to(From, To) = List :-
- ( From > To ->
- List = []
- ;
- List = [From | int_list_from_to(From + 1, To)]
).
%-----------------------------------------------------------------------------%
--------------------------------------------------------------------------
mercury-reviews mailing list
post: mercury-reviews at cs.mu.oz.au
administrative address: owner-mercury-reviews at cs.mu.oz.au
unsubscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: unsubscribe
subscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------
More information about the reviews
mailing list