[m-rev.] for review: support call sequence numbers in the deep profiler
Zoltan Somogyi
zs at csse.unimelb.edu.au
Wed Oct 11 14:03:11 AEST 2006
For review by Julien.
Zoltan.
Include call sequence numbers in the pages generated by the deep profiler
(if the user's preferences ask for this).
deep_profiler/measurements.m:
Standardize on one spelling of call sequence numbers (callseqs).
Add some utility predicates for use in dump.m.
Fix a bug in the calculation of the number of calls: redos enter
procedure invocations, not leave them.
deep_profiler/profile.m:
Fix a bug: the num_callseqs field was in the wrong place.
deep_profiler/html_format.m:
When generating a line of the clique description, include call sequence
number information if requested.
Do likewise when generating other HTML fragments that have to match
the contents of those lines (e.g. the table headers).
Generate the links that allow the users to sort rows by call
sequence numbers.
Generate the links that allow the users to toggle the switches
controlling the display of call sequence number information.
Do not show the toggles relevant to the display of times if times are
not being displayed.
deep_profiler/interface.m:
Extend the preferences to allow requests for call sequence number
information.
Include the display of call sequence numbers in the default set of
preferences. However, include the display of time information in the
default only of the profiling run lasted long enough for this
information to have some hope of being useful.
Rename some function symbols to avoid ambiguities.
deep_profiler/query.m:
Extend the menu to include links for the most expensive
cliques/procedures as measured by call sequence numbers.
Include the links for the most expensive cliques/procedures as
measured by clock ticks in the menu only if the profiling run
lasted long enough for this to be useful.
Print out the total number of call sequence numbers with the other
statistics.
Use call sequence numbers instead of time to decide where the "action"
begins, since this works even for short profiling runs.
deep_profiler/top_procs.m:
Provide the capability of sorting on call sequence numbers.
deep_profiler/dump.m:
Provide the capability to dump out several more fields of the top level
structure (profile.deep), including the cliques, the reverse links and
the propagated measurement information.
deep_profiler/startup.m:
Dump out the cliques, the reverse links and the propagated measurement
information when computed.
deep_profiler/mdprof_cgi.m:
Add an option for setting the hostname in the generated links to
"localhost". This is useful on laptops temporarily disconnected
from the Domain Name System (e.g. my laptop).
Set this option automatically if the name of the file in the initial
query has a ".localhost" suffix added to it.
Add some tracing hooks.
deep_profiler/mdprof_test.m:
Add an option to specify what info to dump during startup.
deep_profiler/mdprof_dump.m:
Switch to using the compiler's method of specifying what to dump,
since this is more maintainable.
deep_profiler/exclude.m:
Rename some function symbols to avoid ambiguities.
deep_profiler/timeout.m:
Add conditionally compiled code to help debug lock management.
deep_profiler/callgraph.m:
deep_profiler/canonical.m:
deep_profiler/cliques.m:
deep_profiler/conf.m:
deep_profiler/read_profile.m:
Minor cleanups.
cvs diff: Diffing .
Index: callgraph.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/deep_profiler/callgraph.m,v
retrieving revision 1.9
diff -u -b -r1.9 callgraph.m
--- callgraph.m 29 Sep 2006 06:15:11 -0000 1.9
+++ callgraph.m 11 Oct 2006 03:49:04 -0000
@@ -46,19 +46,17 @@
% :- import_module io.
% :- import_module require.
% :- import_module string.
-% :- import_module unsafe.
%-----------------------------------------------------------------------------%
find_cliques(InitDeep, BottomUpPDPtrCliqueList) :-
make_graph(InitDeep, Graph),
topological_sort(Graph, TopDownPDICliqueList),
- %
+
% Turn each of the sets of PDIs into a list of PDPtrs. We use foldl here
% because the list may be very long and map runs out of stack space, and
% we want the final list in reverse order anyway because the propagation
% algorithm works bottom up.
- %
list.foldl(accumulate_pdptr_lists, TopDownPDICliqueList,
[], BottomUpPDPtrCliqueList).
@@ -133,10 +131,9 @@
make_clique_indexes(NPDs, CliqueList, Cliques, CliqueIndex) :-
Cliques = array(CliqueList),
array.init(NPDs, clique_ptr(-1), CliqueIndex0),
- %
+
% For each clique, add entries to the CliqueIndex array, which maps every
% proc_dynamic_ptr back to the clique to which it belongs.
- %
array_foldl_from_1(index_clique, Cliques, CliqueIndex0, CliqueIndex).
:- pred index_clique(int::in, list(proc_dynamic_ptr)::in,
@@ -149,8 +146,6 @@
:- pred index_clique_member(int::in, proc_dynamic_ptr::in,
array(clique_ptr)::array_di, array(clique_ptr)::array_uo) is det.
-% :- pragma promise_pure(index_clique_member/4).
-
index_clique_member(CliqueNum, PDPtr, !CliqueIndex) :-
PDPtr = proc_dynamic_ptr(PDI),
% impure unsafe_perform_io(write_pdi_cn(PDI, CliqueNum)),
Index: canonical.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/deep_profiler/canonical.m,v
retrieving revision 1.12
diff -u -b -r1.12 canonical.m
--- canonical.m 5 Oct 2006 04:37:50 -0000 1.12
+++ canonical.m 11 Oct 2006 03:49:04 -0000
@@ -44,8 +44,6 @@
%-----------------------------------------------------------------------------%
-% :- import_module unsafe.
-
:- type merge_info
---> merge_info(
merge_clique_members :: array(list(proc_dynamic_ptr)),
Index: cliques.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/deep_profiler/cliques.m,v
retrieving revision 1.7
diff -u -b -r1.7 cliques.m
--- cliques.m 9 Mar 2006 04:56:39 -0000 1.7
+++ cliques.m 11 Oct 2006 03:49:04 -0000
@@ -53,7 +53,6 @@
% :- import_module io.
% :- import_module string.
-% :- import_module unsafe.
%-----------------------------------------------------------------------------%
@@ -103,8 +102,6 @@
mklist(N - 1, Acc1, Acc)
).
-% :- pragma promise_pure(topological_sort/2).
-
topological_sort(Graph, TSort) :-
% impure unsafe_perform_io(io.nl),
% impure unsafe_perform_io(io.write_string("the graph:\n")),
@@ -202,8 +199,6 @@
:- pred dfs(list(int)::in, graph::in, visit::array_di, list(int)::in,
visit::array_uo, list(int)::out) is det.
-% :- pragma promise_pure(dfs/6).
-
dfs([], _Graph, Visit, Dfs, Visit, Dfs).
dfs([Node | Nodes], Graph, Visit0, Dfs0, Visit, Dfs) :-
( dense_bitset.member(Node, Visit0) ->
Index: conf.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/deep_profiler/conf.m,v
retrieving revision 1.8
diff -u -b -r1.8 conf.m
--- conf.m 9 Mar 2006 04:56:39 -0000 1.8
+++ conf.m 11 Oct 2006 03:49:04 -0000
@@ -62,10 +62,7 @@
io.read_file_as_string(TmpStream, TmpReadRes, !IO),
(
TmpReadRes = ok(ServerNameNl),
- (
- string.remove_suffix(ServerNameNl,
- "\n", ServerNamePrime)
- ->
+ ( string.remove_suffix(ServerNameNl, "\n", ServerNamePrime) ->
ServerName = ServerNamePrime
;
error("malformed server name")
Index: dump.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/deep_profiler/dump.m,v
retrieving revision 1.7
diff -u -b -r1.7 dump.m
--- dump.m 5 Oct 2006 04:37:50 -0000 1.7
+++ dump.m 11 Oct 2006 03:49:04 -0000
@@ -18,21 +18,31 @@
:- import_module profile.
:- import_module io.
-:- import_module bool.
+:- import_module list.
%-----------------------------------------------------------------------------%
- % dump_initial_deep(ProfStats, Restrict, DumpCSDs, DumpPDs,
- % DumpCSSs, DumpPSs, InitialDeep, !IO):
+ % dump_initial_deep(InitialDeep, DumpOptions, !IO):
+ %
% Dump selected parts of InitialDeep to standard output. The array of call
% site dynamics, proc dynamics, call site statics and proc statics is
- % dumped if the corresponding Dump bool is "yes". If Restrict is "yes",
- % then the only the elements of the static arrays that will be dumped are
- % the ones that are referred to from the dynamic arrays. The statistics
- % and the root node are dumped if ProfStats is "yes".
+ % dumped if DumpOptions contains "csd", "pd", "css" or "ps" respectively.
+ % If it contains "restrict", then the only the elements of the static
+ % arrays that will be dumped are the ones that are referred to from the
+ % dynamic arrays. The statistics and the root node are dumped if
+ % DumpOptions contains "stats".
+ %
+:- pred dump_initial_deep(initial_deep::in, list(string)::in, io::di, io::uo)
+ is det.
+
+ % dump_deep(Deep, DumpOptions, !IO):
+ %
+ % Dump selected parts of Deep to standard output. Information about cliques
+ % is output if DumpOptions contains "clique". The fields of Deep that
+ % contain reverse links are dumped if DumpOptions contains "rev".
+ % The propagated costs are dumped if DumpOptions contains "prop".
%
-:- pred dump_initial_deep(bool::in, bool::in, bool::in, bool::in, bool::in,
- bool::in, initial_deep::in, io::di, io::uo) is det.
+:- pred dump_deep(deep::in, list(string)::in, io::di, io::uo) is det.
%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%
@@ -43,7 +53,12 @@
:- import_module measurements.
:- import_module array.
-:- import_module list.
+:- import_module bool.
+:- import_module int.
+:- import_module map.
+:- import_module maybe.
+:- import_module pair.
+:- import_module require.
:- import_module set.
:- import_module std_util.
:- import_module string.
@@ -51,47 +66,39 @@
%----------------------------------------------------------------------------%
-dump_initial_deep(ProfStats, Restrict, DumpCSDs, DumpPDs, DumpCSSs, DumpPSs,
- InitialDeep, !IO) :-
+dump_initial_deep(InitialDeep, DumpOptions, !IO) :-
InitialDeep = initial_deep(Stats, InitRoot, CSDs, PDs, CSSs, PSs),
- (
- Restrict = yes,
+ ( should_dump(DumpOptions, "restrict") ->
get_static_ptrs_from_dynamic_procs(PDs, PSs, UsedPSs, UsedCSSs),
Restriction = these(UsedPSs, UsedCSSs)
;
- Restrict = no,
Restriction = none
),
- (
- ProfStats = yes,
+ ( should_dump(DumpOptions, "stat") ->
dump_init_profile_stats(Stats, !IO),
dump_init_root(InitRoot, !IO)
;
- ProfStats = no
+ true
),
- (
- DumpCSDs= yes,
+ ( should_dump(DumpOptions, "csd") ->
dump_init_call_site_dynamics(CSDs, !IO)
;
- DumpCSDs = no
+ true
),
- (
- DumpPDs = yes,
+ ( should_dump(DumpOptions, "pd") ->
dump_init_proc_dynamics(PDs, PSs, !IO)
;
- DumpPDs = no
+ true
),
- (
- DumpCSSs = yes,
+ ( should_dump(DumpOptions, "css") ->
dump_init_call_site_statics(Restriction, CSSs, !IO)
;
- DumpCSSs = no
+ true
),
- (
- DumpPSs = yes,
+ ( should_dump(DumpOptions, "ps") ->
dump_init_proc_statics(Restriction, PSs, !IO)
;
- DumpPSs = no
+ true
).
%----------------------------------------------------------------------------%
@@ -141,7 +148,7 @@
io.format("\tticks_per_sec = %d\n", [i(TicksPerSec)], !IO),
io.format("\tinstrument_quanta = %d\n", [i(InstrumentQuanta)], !IO),
io.format("\tuser_quanta = %d\n", [i(UserQuanta)], !IO),
- io.format("\tnum_call_seqs = %d\n", [i(NumCallSeqs)], !IO),
+ io.format("\tnum_callseqs = %d\n", [i(NumCallSeqs)], !IO),
io.format("\tword_size = %d\n", [i(WordSize)], !IO),
io.write_string("\tcanonical = ", !IO),
(
@@ -192,47 +199,75 @@
( Calls = 0 ->
true
;
- io.format("\tcalls:\t%d\n", [i(Calls)], !IO)
+ io.format("\tcalls:\t\t%d\n", [i(Calls)], !IO)
),
( Exits = 0 ->
true
;
- io.format("\texits:\t%d\n", [i(Exits)], !IO)
+ io.format("\texits:\t\t%d\n", [i(Exits)], !IO)
),
( Fails = 0 ->
true
;
- io.format("\tfails:\t%d\n", [i(Fails)], !IO)
+ io.format("\tfails:\t\t%d\n", [i(Fails)], !IO)
),
( Redos = 0 ->
true
;
- io.format("\tredos:\t%d\n", [i(Redos)], !IO)
+ io.format("\tredos:\t\t%d\n", [i(Redos)], !IO)
),
( Excps = 0 ->
true
;
- io.format("\texcps:\t%d\n", [i(Excps)], !IO)
+ io.format("\texcps:\t\t%d\n", [i(Excps)], !IO)
),
( Quanta = 0 ->
true
;
- io.format("\tquanta:\t%d\n", [i(Quanta)], !IO)
+ io.format("\tquanta:\t\t%d\n", [i(Quanta)], !IO)
),
( CallSeqs = 0 ->
true
;
- io.format("\tcall_seqs:\t%d\n", [i(CallSeqs)], !IO)
+ io.format("\tcallseqs:\t%d\n", [i(CallSeqs)], !IO)
),
( Allocs = 0 ->
true
;
- io.format("\tallocs:\t%d\n", [i(Allocs)], !IO)
+ io.format("\tallocs:\t\t%d\n", [i(Allocs)], !IO)
),
( Words = 0 ->
true
;
- io.format("\twords:\t%d\n", [i(Words)], !IO)
+ io.format("\twords:\t\t%d\n", [i(Words)], !IO)
+ ).
+
+:- pred dump_inherit_prof_info(inherit_prof_info::in, io::di, io::uo) is det.
+
+dump_inherit_prof_info(Inherit, !IO) :-
+ Quanta = inherit_quanta(Inherit),
+ CallSeqs = inherit_callseqs(Inherit),
+ Allocs = inherit_allocs(Inherit),
+ Words = inherit_words(Inherit),
+ ( Quanta = 0 ->
+ true
+ ;
+ io.format("\tquanta:\t\t%d\n", [i(Quanta)], !IO)
+ ),
+ ( CallSeqs = 0 ->
+ true
+ ;
+ io.format("\tcallseqs:\t%d\n", [i(CallSeqs)], !IO)
+ ),
+ ( Allocs = 0 ->
+ true
+ ;
+ io.format("\tallocs:\t\t%d\n", [i(Allocs)], !IO)
+ ),
+ ( Words = 0 ->
+ true
+ ;
+ io.format("\twords:\t\t%d\n", [i(Words)], !IO)
).
%----------------------------------------------------------------------------%
@@ -257,8 +292,7 @@
RefinedPSId = PS ^ ps_refined_id
),
io.format("pd%d:\n", [i(Index)], !IO),
- io.format("\tpd_proc_static = %d (%s)\n", [i(PSI), s(RefinedPSId)],
- !IO),
+ io.format("\tpd_proc_static = %d (%s)\n", [i(PSI), s(RefinedPSId)], !IO),
array_foldl_from_0(dump_call_site_array_slot, Sites, !IO),
io.nl(!IO).
@@ -282,8 +316,7 @@
dump_init_call_site_statics(Restriction, CallStatics, !IO) :-
io.write_string("SECTION CALL SITE STATICS:\n\n", !IO),
- array_foldl_from_1(dump_call_site_static(Restriction), CallStatics,
- !IO).
+ array_foldl_from_1(dump_call_site_static(Restriction), CallStatics, !IO).
:- pred dump_call_site_static(restriction::in, int::in, call_site_static::in,
io::di, io::uo) is det.
@@ -294,8 +327,7 @@
Restriction = none
;
Restriction = these(_, UsedCallSiteStatics),
- set.member(call_site_static_ptr(Index),
- UsedCallSiteStatics)
+ set.member(call_site_static_ptr(Index), UsedCallSiteStatics)
)
->
CallSiteStatic = call_site_static(ContainerPSPtr, SlotNum,
@@ -348,8 +380,7 @@
% redundant information.
true
;
- io.format("\tps_refined_id\t= %s\n",
- [s(RefinedId)], !IO)
+ io.format("\tps_refined_id\t= %s\n", [s(RefinedId)], !IO)
),
( RefinedId \= RawId ->
% The output is too big already; don't include
@@ -358,8 +389,7 @@
;
io.format("\tps_raw_id\t= %s\n", [s(RawId)], !IO)
),
- io.format("\tlocation\t= %s:%d\n",
- [s(FileName), i(LineNumber)], !IO),
+ io.format("\tlocation\t= %s:%d\n", [s(FileName), i(LineNumber)], !IO),
(
InInterface = yes,
io.write_string("\tin_interface\n", !IO)
@@ -419,5 +449,302 @@
io.write_string("callback", !IO).
%----------------------------------------------------------------------------%
+
+dump_deep(Deep, DumpOptions, !IO) :-
+ ( should_dump(DumpOptions, "clique") ->
+ dump_deep_cliques(Deep, !IO)
+ ;
+ true
+ ),
+ ( should_dump(DumpOptions, "rev") ->
+ dump_deep_rev_links(Deep, !IO)
+ ;
+ true
+ ),
+ ( should_dump(DumpOptions, "prop") ->
+ dump_deep_prop_measurements(Deep, !IO)
+ ;
+ true
+ ).
+
+%----------------------------------------------------------------------------%
+
+:- pred dump_deep_cliques(deep::in, io::di, io::uo) is det.
+
+dump_deep_cliques(Deep, !IO) :-
+ CliqueIndex = Deep ^ clique_index,
+ io.write_string("SECTION MAP FROM PROC DYNAMIC TO CLIQUE:\n\n", !IO),
+ array_foldl_from_1(dump_clique_index_entry, CliqueIndex, !IO),
+ io.nl(!IO),
+
+ CliqueMembers = Deep ^ clique_members,
+ io.write_string("SECTION MAP FROM CLIQUE TO PROC DYNAMICS:\n\n", !IO),
+ array_foldl_from_1(dump_clique_members, CliqueMembers, !IO),
+ io.nl(!IO),
+
+ CliqueParents = Deep ^ clique_parents,
+ io.write_string("SECTION MAP FROM CLIQUE TO PARENT CSD:\n\n", !IO),
+ array_foldl_from_1(dump_clique_parent, CliqueParents, !IO),
+ io.nl(!IO),
+
+ CliqueMaybeChild = Deep ^ clique_maybe_child,
+ io.write_string("SECTION MAP FROM CSD TO MAYBE CHILD CLIQUE:\n\n",
+ !IO),
+ array_foldl_from_1(dump_clique_maybe_child, CliqueMaybeChild, !IO),
+ io.nl(!IO).
+
+:- pred dump_clique_index_entry(int::in, clique_ptr::in,
+ io::di, io::uo) is det.
+
+dump_clique_index_entry(Index, CliquePtr, !IO) :-
+ CliquePtr = clique_ptr(CliqueNum),
+ io.format("pd%d is in clique%d\n", [i(Index), i(CliqueNum)], !IO).
+
+:- pred dump_clique_members(int::in, list(proc_dynamic_ptr)::in,
+ io::di, io::uo) is det.
+
+dump_clique_members(Index, CliqueMembers, !IO) :-
+ io.format("clique%d members:", [i(Index)], !IO),
+ list.foldl(dump_pd_in_clique, CliqueMembers, !IO),
+ io.nl(!IO).
+
+:- pred dump_pd_in_clique(proc_dynamic_ptr::in, io::di, io::uo) is det.
+
+dump_pd_in_clique(PDPtr, !IO) :-
+ PDPtr = proc_dynamic_ptr(PDNum),
+ io.write_string(" pd", !IO),
+ io.write_int(PDNum, !IO).
+
+:- pred dump_clique_parent(int::in, call_site_dynamic_ptr::in,
+ io::di, io::uo) is det.
+
+dump_clique_parent(Index, CSDPtr, !IO) :-
+ CSDPtr = call_site_dynamic_ptr(CSDNum),
+ io.format("clique%d parent: csd%d\n", [i(Index), i(CSDNum)], !IO).
+
+:- pred dump_clique_maybe_child(int::in, maybe(clique_ptr)::in,
+ io::di, io::uo) is det.
+
+dump_clique_maybe_child(Index, MaybeCliquePtr, !IO) :-
+ (
+ MaybeCliquePtr = no
+ ;
+ MaybeCliquePtr = yes(CliquePtr),
+ CliquePtr = clique_ptr(CliqueNum),
+ io.format("csd%d child: clique%d\n", [i(Index), i(CliqueNum)], !IO)
+ ).
+
+%----------------------------------------------------------------------------%
+
+:- pred dump_deep_rev_links(deep::in, io::di, io::uo) is det.
+
+dump_deep_rev_links(Deep, !IO) :-
+ ProcCallers = Deep ^ proc_callers,
+ io.write_string("SECTION MAP FROM PROC STATIC TO CALLER CSDs:\n\n", !IO),
+ array_foldl_from_1(dump_proc_static_caller_csds, ProcCallers, !IO),
+ io.nl(!IO),
+
+ CallSiteStaticMap = Deep ^ call_site_static_map,
+ io.write_string("SECTION MAP FROM CALL SITE DYNAMICS TO STATICS:\n\n", !IO),
+ array_foldl_from_1(dump_call_site_dynamic_to_static, CallSiteStaticMap,
+ !IO),
+ io.nl(!IO),
+
+ CallSiteCalls = Deep ^ call_site_calls,
+ io.write_string("SECTION MAP FROM CALL SITE STATICS TO CALLS:\n\n", !IO),
+ array_foldl_from_1(dump_call_site_calls, CallSiteCalls, !IO),
+ io.nl(!IO).
+
+:- pred dump_proc_static_caller_csds(int::in, list(call_site_dynamic_ptr)::in,
+ io::di, io::uo) is det.
+
+dump_proc_static_caller_csds(Index, CallerCSDs, !IO) :-
+ (
+ CallerCSDs = []
+ ;
+ CallerCSDs = [_ | _],
+ io.format("ps%d callers:", [i(Index)], !IO),
+ list.foldl(dump_space_csdptr, CallerCSDs, !IO),
+ io.nl(!IO)
+ ).
+
+:- pred dump_space_csdptr(call_site_dynamic_ptr::in, io::di, io::uo) is det.
+
+dump_space_csdptr(CSDPtr, !IO) :-
+ CSDPtr = call_site_dynamic_ptr(CSDNum),
+ io.write_string(" csd", !IO),
+ io.write_int(CSDNum, !IO).
+
+:- pred dump_call_site_dynamic_to_static(int::in, call_site_static_ptr::in,
+ io::di, io::uo) is det.
+
+dump_call_site_dynamic_to_static(Index, CSSPtr, !IO) :-
+ CSSPtr = call_site_static_ptr(CSSNum),
+ io.format("csd%d is at css%d\n", [i(Index), i(CSSNum)], !IO).
+
+:- pred dump_call_site_calls(int::in,
+ map(proc_static_ptr, list(call_site_dynamic_ptr))::in,
+ io::di, io::uo) is det.
+
+dump_call_site_calls(Index, CalleeMap, !IO) :-
+ CalleeList = map.to_assoc_list(CalleeMap),
+ (
+ CalleeList = []
+ ;
+ CalleeList = [OneCallee],
+ io.format("css%d calls one procedure: ", [i(Index)], !IO),
+ dump_call_site_calls_to_proc("", OneCallee, !IO)
+ ;
+ CalleeList = [_, _ | _],
+ io.format("css%d calls several procedures:\n", [i(Index)], !IO),
+ list.foldl(dump_call_site_calls_to_proc("\t"), CalleeList, !IO)
+ ).
+
+:- pred dump_call_site_calls_to_proc(string::in,
+ pair(proc_static_ptr, list(call_site_dynamic_ptr))::in,
+ io::di, io::uo) is det.
+
+dump_call_site_calls_to_proc(Prefix, PSPtr - CSDPtrs, !IO) :-
+ PSPtr = proc_static_ptr(PSNum),
+ io.format("%sps%d:", [s(Prefix), i(PSNum)], !IO),
+ list.foldl(dump_space_csdptr, CSDPtrs, !IO),
+ io.nl(!IO).
+
+%----------------------------------------------------------------------------%
+
+:- pred dump_deep_prop_measurements(deep::in, io::di, io::uo) is det.
+
+dump_deep_prop_measurements(Deep, !IO) :-
+ PDOwn = Deep ^ pd_own,
+ PDDesc = Deep ^ pd_desc,
+ PDOwnMax = array.max(PDOwn),
+ PDDescMax = array.max(PDDesc),
+ require(unify(PDOwnMax, PDDescMax),
+ "dump_deep: PDOwnMax != PDDescMax"),
+ io.write_string("SECTION PROC DYNAMIC MEASUREMENTS:\n\n", !IO),
+ dump_pd_measurements(1, PDOwnMax, PDOwn, PDDesc, !IO),
+
+ CSDs = Deep ^ call_site_dynamics,
+ CSDDesc = Deep ^ csd_desc,
+ CSDMax = array.max(CSDs),
+ CSDDescMax = array.max(CSDDesc),
+ require(unify(CSDMax, CSDDescMax),
+ "dump_deep: CSDMax != CSDDescMax"),
+ io.write_string("SECTION CALL SITE DYNAMIC MEASUREMENTS:\n\n", !IO),
+ dump_csd_measurements(1, CSDMax, CSDs, CSDDesc, !IO),
+
+ PSOwn = Deep ^ ps_own,
+ PSDesc = Deep ^ ps_desc,
+ PSOwnMax = array.max(PSOwn),
+ PSDescMax = array.max(PSDesc),
+ require(unify(PSOwnMax, PSDescMax),
+ "dump_deep: PSOwnMax != PSDescMax"),
+ io.write_string("SECTION PROC STATIC MEASUREMENTS:\n\n", !IO),
+ dump_ps_measurements(1, PSOwnMax, PSOwn, PSDesc, !IO),
+
+ CSSOwn = Deep ^ css_own,
+ CSSDesc = Deep ^ css_desc,
+ CSSOwnMax = array.max(CSSOwn),
+ CSSDescMax = array.max(CSSDesc),
+ require(unify(CSSOwnMax, CSSDescMax),
+ "dump_deep: CSSOwnMax != CSSDescMax"),
+ io.write_string("SECTION CALL SITE STATIC MEASUREMENTS:\n\n", !IO),
+ dump_css_measurements(1, CSSOwnMax, CSSOwn, CSSDesc, !IO).
+
+:- pred dump_pd_measurements(int::in, int::in,
+ array(own_prof_info)::in, array(inherit_prof_info)::in,
+ io::di, io::uo) is det.
+
+dump_pd_measurements(Cur, Max, PDOwn, PDDesc, !IO) :-
+ ( Cur =< Max ->
+ array.lookup(PDOwn, Cur, Own),
+ array.lookup(PDDesc, Cur, Desc),
+ dump_own_and_desc("pd", Cur, Own, Desc, !IO),
+ dump_pd_measurements(Cur + 1, Max, PDOwn, PDDesc, !IO)
+ ;
+ true
+ ).
+
+:- pred dump_csd_measurements(int::in, int::in,
+ array(call_site_dynamic)::in, array(inherit_prof_info)::in,
+ io::di, io::uo) is det.
+
+dump_csd_measurements(Cur, Max, CSDs, CSDDesc, !IO) :-
+ ( Cur =< Max ->
+ array.lookup(CSDs, Cur, CSD),
+ Own = CSD ^ csd_own_prof,
+ array.lookup(CSDDesc, Cur, Desc),
+ dump_own_and_desc("csd", Cur, Own, Desc, !IO),
+ dump_csd_measurements(Cur + 1, Max, CSDs, CSDDesc, !IO)
+ ;
+ true
+ ).
+
+:- pred dump_ps_measurements(int::in, int::in,
+ array(own_prof_info)::in, array(inherit_prof_info)::in,
+ io::di, io::uo) is det.
+
+dump_ps_measurements(Cur, Max, PSOwn, PSDesc, !IO) :-
+ ( Cur =< Max ->
+ array.lookup(PSOwn, Cur, Own),
+ array.lookup(PSDesc, Cur, Desc),
+ dump_own_and_desc("ps", Cur, Own, Desc, !IO),
+ dump_ps_measurements(Cur + 1, Max, PSOwn, PSDesc, !IO)
+ ;
+ true
+ ).
+
+:- pred dump_css_measurements(int::in, int::in,
+ array(own_prof_info)::in, array(inherit_prof_info)::in,
+ io::di, io::uo) is det.
+
+dump_css_measurements(Cur, Max, CSSOwn, CSSDesc, !IO) :-
+ ( Cur =< Max ->
+ array.lookup(CSSOwn, Cur, Own),
+ array.lookup(CSSDesc, Cur, Desc),
+ dump_own_and_desc("css", Cur, Own, Desc, !IO),
+ dump_css_measurements(Cur + 1, Max, CSSOwn, CSSDesc, !IO)
+ ;
+ true
+ ).
+
+:- pred dump_own_and_desc(string::in, int::in,
+ own_prof_info::in, inherit_prof_info::in, io::di, io::uo) is det.
+
+dump_own_and_desc(Prefix, Cur, Own, Desc, !IO) :-
+ ( is_zero_own_prof_info(Own) ->
+ PrintedOwn = no
+ ;
+ io.format("%s%d own:\n", [s(Prefix), i(Cur)], !IO),
+ dump_own_prof_info(Own, !IO),
+ PrintedOwn = yes
+ ),
+ ( is_zero_inherit_prof_info(Desc) ->
+ PrintedDesc = no
+ ;
+ io.format("%s%d inherit:\n", [s(Prefix), i(Cur)], !IO),
+ dump_inherit_prof_info(Desc, !IO),
+ PrintedDesc = yes
+ ),
+ (
+ ( PrintedOwn = yes
+ ; PrintedDesc = yes
+ )
+ ->
+ io.nl(!IO)
+ ;
+ true
+ ).
+
+%----------------------------------------------------------------------------%
+
+:- pred should_dump(list(string)::in, string::in) is semidet.
+
+should_dump(DumpOptions, What) :-
+ ( list.member(What, DumpOptions)
+ ; DumpOptions = []
+ ).
+
+%----------------------------------------------------------------------------%
:- end_module dump.
%----------------------------------------------------------------------------%
Index: exclude.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/deep_profiler/exclude.m,v
retrieving revision 1.9
diff -u -b -r1.9 exclude.m
--- exclude.m 20 Sep 2006 09:42:23 -0000 1.9
+++ exclude.m 11 Oct 2006 03:49:04 -0000
@@ -83,12 +83,11 @@
).
:- type exclusion_type
- ---> all_procedures % Exclude all procedures in the
- % named module.
- ; internal_procedures. % Exclude all procedures in the
- % named module, except those
- % which are exported from the
- % module.
+ ---> exclude_all_procedures
+ % Exclude all procedures in the named module.
+ ; exclude_internal_procedures.
+ % Exclude all procedures in the named module, except those
+ % which are exported from the module.
%-----------------------------------------------------------------------------%
@@ -129,18 +128,17 @@
Words = [Scope, ModuleName],
(
Scope = "all",
- ExclType = all_procedures
+ ExclType = exclude_all_procedures
;
Scope = "internal",
- ExclType = internal_procedures
+ ExclType = exclude_internal_procedures
)
->
Spec = exclude_spec(ModuleName, ExclType),
RevSpecs1 = [Spec | RevSpecs0],
read_exclude_lines(FileName, InputStream, RevSpecs1, Res, !IO)
;
- Msg = string.format(
- "file %s contains badly formatted line: %s",
+ Msg = string.format("file %s contains badly formatted line: %s",
[s(FileName), s(Line)]),
Res = error(Msg)
)
@@ -194,9 +192,9 @@
set.member(ExclSpec, ExcludedSpecs),
ExclSpec = exclude_spec(ModuleName, ExclType),
(
- ExclType = all_procedures
+ ExclType = exclude_all_procedures
;
- ExclType = internal_procedures,
+ ExclType = exclude_internal_procedures,
PS ^ ps_in_interface = no
)
->
Index: html_format.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/deep_profiler/html_format.m,v
retrieving revision 1.14
diff -u -b -r1.14 html_format.m
--- html_format.m 4 Oct 2006 07:03:54 -0000 1.14
+++ html_format.m 11 Oct 2006 03:49:04 -0000
@@ -56,8 +56,10 @@
:- func fields_header(preferences, id_fields, totals_disposition,
header_wrap_func) = string.
-:- func header_row(string, preferences, id_fields, totals_disposition) = string.
-:- func separator_row(preferences, id_fields, totals_disposition) = string.
+:- func header_row(string, preferences, id_fields, totals_disposition)
+ = string.
+:- func separator_row(preferences, id_fields, totals_disposition)
+ = string.
:- type sub_lines(T)
---> sub_lines(
@@ -165,45 +167,75 @@
banner_style(Pref) = HTML :-
Fields = Pref ^ pref_fields,
- GroupNum0 = 0,
+ some [!GroupNum] (
+ !:GroupNum = 0,
IdStyle = string.format(" TD.id { %s }\n",
- [s(select_colgroup_background(Pref, GroupNum0))]),
- GroupNum1 = GroupNum0 + 1,
- ( Fields ^ port_fields = no_port ->
- PortStyle = "",
- GroupNum2 = GroupNum1
+ [s(select_colgroup_background(Pref, !.GroupNum))]),
+ !:GroupNum = !.GroupNum + 1,
+ Fields = fields(PortFields, TimeFields, CallSeqsFields,
+ AllocFields, MemoryFields),
+ (
+ PortFields = no_port,
+ PortStyle = ""
;
+ PortFields = port,
PortStyle = string.format(" TD.port { %s }\n",
- [s(select_colgroup_background(Pref, GroupNum1))]),
- GroupNum2 = GroupNum1 + 1
+ [s(select_colgroup_background(Pref, !.GroupNum))]),
+ !:GroupNum = !.GroupNum + 1
),
- ( Fields ^ time_fields = no_time ->
- TimeStyle = "",
- GroupNum3 = GroupNum2
+ (
+ TimeFields = no_time,
+ TimeStyle = ""
;
+ ( TimeFields = ticks
+ ; TimeFields = time
+ ; TimeFields = ticks_and_time
+ ; TimeFields = time_and_percall
+ ; TimeFields = ticks_and_time_and_percall
+ ),
TimeStyle = string.format(" TD.time { %s }\n",
- [s(select_colgroup_background(Pref, GroupNum2))]),
- GroupNum3 = GroupNum2 + 1
+ [s(select_colgroup_background(Pref, !.GroupNum))]),
+ !:GroupNum = !.GroupNum + 1
),
- ( Fields ^ alloc_fields = no_alloc ->
- AllocStyle = "",
- GroupNum4 = GroupNum3
+ (
+ CallSeqsFields = no_callseqs,
+ CallSeqsStyle = ""
;
+ ( CallSeqsFields = callseqs
+ ; CallSeqsFields = callseqs_and_percall
+ ),
+ CallSeqsStyle = string.format(" TD.callseqs { %s }\n",
+ [s(select_colgroup_background(Pref, !.GroupNum))]),
+ !:GroupNum = !.GroupNum + 1
+ ),
+ (
+ AllocFields = no_alloc,
+ AllocStyle = ""
+ ;
+ ( AllocFields = alloc
+ ; AllocFields = alloc_and_percall
+ ),
AllocStyle = string.format(" TD.alloc { %s }\n",
- [s(select_colgroup_background(Pref, GroupNum3))]),
- GroupNum4 = GroupNum3 + 1
+ [s(select_colgroup_background(Pref, !.GroupNum))]),
+ !:GroupNum = !.GroupNum + 1
),
- ( Fields ^ memory_fields = no_memory ->
+ (
+ MemoryFields = no_memory,
MemoryStyle = ""
;
+ ( MemoryFields = memory(_)
+ ; MemoryFields = memory_and_percall(_)
+ ),
MemoryStyle = string.format(" TD.memory { %s }\n",
- [s(select_colgroup_background(Pref, GroupNum4))])
+ [s(select_colgroup_background(Pref, !.GroupNum))])
+ )
),
HTML =
"<STYLE TYPE=""text/css"">\n" ++
IdStyle ++
PortStyle ++
TimeStyle ++
+ CallSeqsStyle ++
AllocStyle ++
MemoryStyle ++
"</STYLE>\n".
@@ -212,7 +244,7 @@
select_colgroup_background(Pref, N) = HTML :-
(
- Pref ^ pref_colour = column_groups,
+ Pref ^ pref_colour = colour_column_groups,
( N /\ 1 = 0 ->
Background = even_background
;
@@ -220,7 +252,7 @@
),
string.format("background: %s", [s(Background)], HTML)
;
- Pref ^ pref_colour = none,
+ Pref ^ pref_colour = colour_none,
HTML = ""
).
@@ -252,11 +284,11 @@
footer_pref_toggles(Cmd, Pref, Deep) ++
"<br>\n" ++
string.format("<A HREF=""%s"">Menu</A>\n",
- [s(deep_cmd_pref_to_url(Pref, Deep, menu))]) ++
+ [s(deep_cmd_pref_to_url(Pref, Deep, deep_cmd_menu))]) ++
string.format("<A HREF=""%s"">Restart</A>\n",
- [s(deep_cmd_pref_to_url(Pref, Deep, restart))]) ++
+ [s(deep_cmd_pref_to_url(Pref, Deep, deep_cmd_restart))]) ++
string.format("<A HREF=""%s"">Quit</A>\n",
- [s(deep_cmd_pref_to_url(Pref, Deep, quit))]) ++
+ [s(deep_cmd_pref_to_url(Pref, Deep, deep_cmd_quit))]) ++
"</BODY>\n" ++
"</HTML>\n".
@@ -346,34 +378,35 @@
:- func command_relevant_toggles(cmd) = list(toggle_kind).
-command_relevant_toggles(quit) = [].
-command_relevant_toggles(restart) = [].
-command_relevant_toggles(timeout(_)) = [].
-command_relevant_toggles(menu) = [].
-command_relevant_toggles(root(_)) =
- command_relevant_toggles(clique(1)). % The clique num doesn't matter.
-command_relevant_toggles(clique(_)) =
+command_relevant_toggles(deep_cmd_quit) = [].
+command_relevant_toggles(deep_cmd_restart) = [].
+command_relevant_toggles(deep_cmd_timeout(_)) = [].
+command_relevant_toggles(deep_cmd_menu) = [].
+command_relevant_toggles(deep_cmd_root(_)) =
+ % The clique num doesn't matter.
+ command_relevant_toggles(deep_cmd_clique(1)).
+command_relevant_toggles(deep_cmd_clique(_)) =
[toggle_fields, toggle_box, toggle_colour, toggle_ancestor_limit,
toggle_summarize, toggle_order_criteria, toggle_time_format].
-command_relevant_toggles(proc(_)) =
+command_relevant_toggles(deep_cmd_proc(_)) =
[toggle_fields, toggle_box, toggle_colour, toggle_summarize,
toggle_order_criteria, toggle_time_format].
-command_relevant_toggles(proc_callers(_, _, _)) =
+command_relevant_toggles(deep_cmd_proc_callers(_, _, _)) =
[toggle_fields, toggle_box, toggle_colour, toggle_order_criteria,
toggle_contour, toggle_time_format].
-command_relevant_toggles(modules) =
+command_relevant_toggles(deep_cmd_modules) =
[toggle_fields, toggle_box, toggle_colour, toggle_order_criteria,
toggle_time_format, toggle_inactive_modules].
-command_relevant_toggles(module(_)) =
+command_relevant_toggles(deep_cmd_module(_)) =
[toggle_fields, toggle_box, toggle_colour, toggle_order_criteria,
toggle_time_format, toggle_inactive_procs].
-command_relevant_toggles(top_procs(_, _, _, _)) =
+command_relevant_toggles(deep_cmd_top_procs(_, _, _, _)) =
[toggle_fields, toggle_box, toggle_colour, toggle_time_format].
-command_relevant_toggles(proc_static(_)) = [].
-command_relevant_toggles(proc_dynamic(_)) = [].
-command_relevant_toggles(call_site_static(_)) = [].
-command_relevant_toggles(call_site_dynamic(_)) = [].
-command_relevant_toggles(raw_clique(_)) = [].
+command_relevant_toggles(deep_cmd_proc_static(_)) = [].
+command_relevant_toggles(deep_cmd_proc_dynamic(_)) = [].
+command_relevant_toggles(deep_cmd_call_site_static(_)) = [].
+command_relevant_toggles(deep_cmd_call_site_dynamic(_)) = [].
+command_relevant_toggles(deep_cmd_raw_clique(_)) = [].
:- func footer_field_toggle(cmd, preferences, deep) = string.
@@ -424,7 +457,7 @@
Time3Toggle = string.format("<A HREF=""%s"">%s</A>\n",
[s(deep_cmd_pref_to_url(Time3Pref, Deep, Cmd)), s(Time3Msg)])
),
- ( Fields ^ time_fields = ticks_and_time ->
+ ( Fields ^ time_fields = ticks_and_time->
Time4Toggle = ""
;
Time4Fields = Fields ^ time_fields := ticks_and_time,
@@ -445,13 +478,42 @@
( Fields ^ time_fields = ticks_and_time_and_percall ->
Time6Toggle = ""
;
- Time6Fields = Fields ^ time_fields :=
- ticks_and_time_and_percall,
+ Time6Fields = Fields ^ time_fields := ticks_and_time_and_percall,
Time6Pref = Pref ^ pref_fields := Time6Fields,
Time6Msg = "Ticks and times and per-call times",
Time6Toggle = string.format("<A HREF=""%s"">%s</A>\n",
[s(deep_cmd_pref_to_url(Time6Pref, Deep, Cmd)), s(Time6Msg)])
),
+ ( Fields ^ callseqs_fields = no_callseqs ->
+ CallSeqs1Toggle = ""
+ ;
+ CallSeqs1Fields = Fields ^ callseqs_fields := no_callseqs,
+ CallSeqs1Pref = Pref ^ pref_fields := CallSeqs1Fields,
+ CallSeqs1Msg = "No call sequence number info",
+ CallSeqs1Toggle = string.format("<A HREF=""%s"">%s</A>\n",
+ [s(deep_cmd_pref_to_url(CallSeqs1Pref, Deep, Cmd)),
+ s(CallSeqs1Msg)])
+ ),
+ ( Fields ^ callseqs_fields = callseqs ->
+ CallSeqs2Toggle = ""
+ ;
+ CallSeqs2Fields = Fields ^ callseqs_fields := callseqs,
+ CallSeqs2Pref = Pref ^ pref_fields := CallSeqs2Fields,
+ CallSeqs2Msg = "Call sequence numbers",
+ CallSeqs2Toggle = string.format("<A HREF=""%s"">%s</A>\n",
+ [s(deep_cmd_pref_to_url(CallSeqs2Pref, Deep, Cmd)),
+ s(CallSeqs2Msg)])
+ ),
+ ( Fields ^ callseqs_fields = callseqs_and_percall ->
+ CallSeqs3Toggle = ""
+ ;
+ CallSeqs3Fields = Fields ^ callseqs_fields := callseqs_and_percall,
+ CallSeqs3Pref = Pref ^ pref_fields := CallSeqs3Fields,
+ CallSeqs3Msg = "Call sequence numbers including per-call",
+ CallSeqs3Toggle = string.format("<A HREF=""%s"">%s</A>\n",
+ [s(deep_cmd_pref_to_url(CallSeqs3Pref, Deep, Cmd)),
+ s(CallSeqs3Msg)])
+ ),
( Fields ^ alloc_fields = no_alloc ->
Alloc1Toggle = ""
;
@@ -488,60 +550,64 @@
Memory1Toggle = string.format("<A HREF=""%s"">%s</A>\n",
[s(deep_cmd_pref_to_url(Memory1Pref, Deep, Cmd)), s(Memory1Msg)])
),
- ( Fields ^ memory_fields = memory(words) ->
+ ( Fields ^ memory_fields = memory(units_words) ->
Memory2Toggle = ""
;
- Memory2Fields = Fields ^ memory_fields := memory(words),
+ Memory2Fields = Fields ^ memory_fields := memory(units_words),
Memory2Pref = Pref ^ pref_fields := Memory2Fields,
Memory2Msg = "Words",
Memory2Toggle = string.format("<A HREF=""%s"">%s</A>\n",
[s(deep_cmd_pref_to_url(Memory2Pref, Deep, Cmd)), s(Memory2Msg)])
),
- ( Fields ^ memory_fields = memory(bytes) ->
+ ( Fields ^ memory_fields = memory(units_bytes) ->
Memory3Toggle = ""
;
- Memory3Fields = Fields ^ memory_fields := memory(bytes),
+ Memory3Fields = Fields ^ memory_fields := memory(units_bytes),
Memory3Pref = Pref ^ pref_fields := Memory3Fields,
Memory3Msg = "Bytes",
Memory3Toggle = string.format("<A HREF=""%s"">%s</A>\n",
[s(deep_cmd_pref_to_url(Memory3Pref, Deep, Cmd)), s(Memory3Msg)])
),
- ( Fields ^ memory_fields = memory_and_percall(words) ->
+ ( Fields ^ memory_fields = memory_and_percall(units_words) ->
Memory4Toggle = ""
;
Memory4Fields = Fields ^ memory_fields :=
- memory_and_percall(words),
+ memory_and_percall(units_words),
Memory4Pref = Pref ^ pref_fields := Memory4Fields,
Memory4Msg = "Words and per-call words",
Memory4Toggle = string.format("<A HREF=""%s"">%s</A>\n",
[s(deep_cmd_pref_to_url(Memory4Pref, Deep, Cmd)), s(Memory4Msg)])
),
- ( Fields ^ memory_fields = memory_and_percall(bytes) ->
+ ( Fields ^ memory_fields = memory_and_percall(units_bytes) ->
Memory5Toggle = ""
;
Memory5Fields = Fields ^ memory_fields :=
- memory_and_percall(bytes),
+ memory_and_percall(units_bytes),
Memory5Pref = Pref ^ pref_fields := Memory5Fields,
Memory5Msg = "Bytes and per-call bytes",
Memory5Toggle = string.format("<A HREF=""%s"">%s</A>\n",
[s(deep_cmd_pref_to_url(Memory5Pref, Deep, Cmd)), s(Memory5Msg)])
),
- ( Fields = default_fields ->
+ ( Fields = default_fields(Deep) ->
+ DefaultToggle = ""
+ ;
DefaultMsg = "Restore defaults",
- DefaultPref = Pref ^ pref_fields := default_fields,
+ DefaultPref = Pref ^ pref_fields := default_fields(Deep),
DefaultToggle = string.format("<A HREF=""%s"">%s</A>\n",
[s(deep_cmd_pref_to_url(DefaultPref, Deep, Cmd)), s(DefaultMsg)])
- ;
- DefaultToggle = ""
),
HTML =
"Toggle fields:\n" ++
DefaultToggle ++
Port1Toggle ++ Port2Toggle ++
+ "<br>\n" ++
Time1Toggle ++ Time2Toggle ++ Time3Toggle ++
Time4Toggle ++ Time5Toggle ++ Time6Toggle ++
"<br>\n" ++
+ CallSeqs1Toggle ++ CallSeqs2Toggle ++ CallSeqs3Toggle ++
+ "<br>\n" ++
Alloc1Toggle ++ Alloc2Toggle ++ Alloc3Toggle ++
+ "<br>\n" ++
Memory1Toggle ++ Memory2Toggle ++ Memory3Toggle ++
Memory4Toggle ++ Memory5Toggle ++
"<br>\n".
@@ -633,12 +699,12 @@
footer_colour_toggle(Cmd, Pref, Deep) = HTML :-
(
- Pref ^ pref_colour = none,
- Pref1 = Pref ^ pref_colour := column_groups,
+ Pref ^ pref_colour = colour_none,
+ Pref1 = Pref ^ pref_colour := colour_column_groups,
Msg1 = "Colour column groups"
;
- Pref ^ pref_colour = column_groups,
- Pref1 = Pref ^ pref_colour := none,
+ Pref ^ pref_colour = colour_column_groups,
+ Pref1 = Pref ^ pref_colour := colour_none,
Msg1 = "Fade column groups"
),
HTML = string.format("<A HREF=""%s"">%s</A>\n",
@@ -677,6 +743,25 @@
:- func footer_time_format_toggle(cmd, preferences, deep) = string.
footer_time_format_toggle(Cmd, Pref, Deep) = HTML :-
+ TimeFields = Pref ^ pref_fields ^ time_fields,
+ (
+ ( TimeFields = no_time
+ ; TimeFields = ticks
+ ),
+ ToggleTimeFormat = no
+ ;
+ ( TimeFields = time
+ ; TimeFields = ticks_and_time
+ ; TimeFields = time_and_percall
+ ; TimeFields = ticks_and_time_and_percall
+ ),
+ ToggleTimeFormat = yes
+ ),
+ (
+ ToggleTimeFormat = no,
+ HTML = ""
+ ;
+ ToggleTimeFormat = yes,
(
Pref ^ pref_time = no_scale,
Pref1 = Pref ^ pref_time := scale_by_millions,
@@ -700,7 +785,8 @@
string.format("<A HREF=""%s"">%s</A>\n",
[s(deep_cmd_pref_to_url(Pref1, Deep, Cmd)), s(Msg1)]) ++
string.format("<A HREF=""%s"">%s</A>\n",
- [s(deep_cmd_pref_to_url(Pref2, Deep, Cmd)), s(Msg2)]).
+ [s(deep_cmd_pref_to_url(Pref2, Deep, Cmd)), s(Msg2)])
+ ).
%-----------------------------------------------------------------------------%
@@ -752,10 +838,14 @@
[s(UpdateCriteria(Criteria1)), s(Msg1)]),
Toggle2 = string.format("<A HREF=""%s"">%s</A>\n",
[s(UpdateCriteria(Criteria2)), s(Msg2)]),
- ( Criteria = by_cost(CostKind, InclDesc, Scope) ->
+ (
+ Criteria = by_cost(CostKind, InclDesc, Scope),
ToggleRest = toggle_cost_criteria(CostKind, InclDesc, Scope,
UpdateCostCriteria)
;
+ ( Criteria = by_context
+ ; Criteria = by_name
+ ),
ToggleRest = ""
),
HTML = "Toggle ordering criteria:\n" ++ Toggle1 ++ Toggle2 ++ ToggleRest.
@@ -764,39 +854,89 @@
update_cost_criteria_func) = string.
toggle_cost_criteria(CostKind, InclDesc, Scope, UpdateCriteria) = Toggles :-
- ( CostKind \= calls ->
+ (
+ ( CostKind = cost_redos
+ ; CostKind = cost_time
+ ; CostKind = cost_callseqs
+ ; CostKind = cost_allocs
+ ; CostKind = cost_words
+ ),
MsgCalls = "Sort by calls",
ToggleCalls = string.format("<A HREF=""%s"">%s</A>\n",
- [s(UpdateCriteria(calls, InclDesc, Scope)), s(MsgCalls)])
+ [s(UpdateCriteria(cost_calls, InclDesc, Scope)), s(MsgCalls)])
;
+ CostKind = cost_calls,
ToggleCalls = ""
),
- ( CostKind \= redos ->
+ (
+ ( CostKind = cost_calls
+ ; CostKind = cost_time
+ ; CostKind = cost_callseqs
+ ; CostKind = cost_allocs
+ ; CostKind = cost_words
+ ),
MsgRedos = "Sort by redos",
ToggleRedos = string.format("<A HREF=""%s"">%s</A>\n",
- [s(UpdateCriteria(redos, InclDesc, Scope)), s(MsgRedos)])
+ [s(UpdateCriteria(cost_redos, InclDesc, Scope)), s(MsgRedos)])
;
+ CostKind = cost_redos,
ToggleRedos = ""
),
- ( CostKind \= time ->
+ (
+ ( CostKind = cost_calls
+ ; CostKind = cost_redos
+ ; CostKind = cost_callseqs
+ ; CostKind = cost_allocs
+ ; CostKind = cost_words
+ ),
MsgTime = "Sort by time",
ToggleTime = string.format("<A HREF=""%s"">%s</A>\n",
- [s(UpdateCriteria(time, InclDesc, Scope)), s(MsgTime)])
+ [s(UpdateCriteria(cost_time, InclDesc, Scope)), s(MsgTime)])
;
+ CostKind = cost_time,
ToggleTime = ""
),
- ( CostKind \= allocs ->
+ (
+ ( CostKind = cost_calls
+ ; CostKind = cost_redos
+ ; CostKind = cost_time
+ ; CostKind = cost_allocs
+ ; CostKind = cost_words
+ ),
+ MsgCallSeqs = "Sort by call sequence numbers",
+ ToggleCallSeqs = string.format("<A HREF=""%s"">%s</A>\n",
+ [s(UpdateCriteria(cost_callseqs, InclDesc, Scope)),
+ s(MsgCallSeqs)])
+ ;
+ CostKind = cost_callseqs,
+ ToggleCallSeqs = ""
+ ),
+ (
+ ( CostKind = cost_calls
+ ; CostKind = cost_redos
+ ; CostKind = cost_time
+ ; CostKind = cost_callseqs
+ ; CostKind = cost_words
+ ),
MsgAllocs = "Sort by allocations",
ToggleAllocs = string.format("<A HREF=""%s"">%s</A>\n",
- [s(UpdateCriteria(allocs, InclDesc, Scope)), s(MsgAllocs)])
+ [s(UpdateCriteria(cost_allocs, InclDesc, Scope)), s(MsgAllocs)])
;
+ CostKind = cost_allocs,
ToggleAllocs = ""
),
- ( CostKind \= words ->
+ (
+ ( CostKind = cost_calls
+ ; CostKind = cost_redos
+ ; CostKind = cost_time
+ ; CostKind = cost_callseqs
+ ; CostKind = cost_allocs
+ ),
MsgWords = "Sort by words",
ToggleWords = string.format("<A HREF=""%s"">%s</A>\n",
- [s(UpdateCriteria(words, InclDesc, Scope)), s(MsgWords)])
+ [s(UpdateCriteria(cost_words, InclDesc, Scope)), s(MsgWords)])
;
+ CostKind = cost_words,
ToggleWords = ""
),
(
@@ -821,8 +961,9 @@
ToggleScope = string.format("<A HREF=""%s"">%s</A>\n",
[s(UpdateCriteria(CostKind, InclDesc, per_call)), s(MsgScope)])
),
- Toggles = ToggleCalls ++ ToggleRedos ++ ToggleTime ++ ToggleAllocs
- ++ ToggleWords ++ ToggleDesc ++ ToggleScope.
+ Toggles = ToggleCalls ++ ToggleRedos ++ ToggleTime ++ ToggleCallSeqs ++
+ ToggleAllocs ++ ToggleWords ++
+ "\n<br>\n" ++ ToggleDesc ++ ToggleScope.
%-----------------------------------------------------------------------------%
%
@@ -834,13 +975,13 @@
footer_inactive_modules_toggle(Cmd, Pref0, Deep) = HTML :-
Pref0 ^ pref_inactive = inactive_items(Procs, Modules),
(
- Modules = show,
+ Modules = inactive_show,
Msg = "Hide inactive modules",
- Pref = Pref0 ^ pref_inactive := inactive_items(Procs, hide)
+ Pref = Pref0 ^ pref_inactive := inactive_items(Procs, inactive_hide)
;
- Modules = hide,
+ Modules = inactive_hide,
Msg = "Show inactive modules",
- Pref = Pref0 ^ pref_inactive := inactive_items(Procs, show)
+ Pref = Pref0 ^ pref_inactive := inactive_items(Procs, inactive_show)
),
HTML = string.format("<A HREF=""%s"">%s</A>\n",
[s(deep_cmd_pref_to_url(Pref, Deep, Cmd)), s(Msg)]).
@@ -850,13 +991,13 @@
footer_inactive_procs_toggle(Cmd, Pref0, Deep) = HTML :-
Pref0 ^ pref_inactive = inactive_items(Procs, Modules),
(
- Procs = show,
+ Procs = inactive_show,
Msg = "Hide inactive procedures",
- Pref = Pref0 ^ pref_inactive := inactive_items(hide, Modules)
+ Pref = Pref0 ^ pref_inactive := inactive_items(inactive_hide, Modules)
;
- Procs = hide,
+ Procs = inactive_hide,
Msg = "Show inactive procedures",
- Pref = Pref0 ^ pref_inactive := inactive_items(show, Modules)
+ Pref = Pref0 ^ pref_inactive := inactive_items(inactive_show, Modules)
),
HTML = string.format("<A HREF=""%s"">%s</A>\n",
[s(deep_cmd_pref_to_url(Pref, Deep, Cmd)), s(Msg)]).
@@ -883,7 +1024,7 @@
update_cost_criteria_in_top_procs_cmd(Pref, Deep, Limit,
CostKind, InclDesc, Scope) = HTML :-
- Cmd = top_procs(Limit, CostKind, InclDesc, Scope),
+ Cmd = deep_cmd_top_procs(Limit, CostKind, InclDesc, Scope),
HTML = deep_cmd_pref_to_url(Pref, Deep, Cmd).
%-----------------------------------------------------------------------------%
@@ -902,11 +1043,12 @@
:- func cost_kind_to_description(cost_kind) = string.
-cost_kind_to_description(calls) = "number of calls".
-cost_kind_to_description(redos) = "number of redos".
-cost_kind_to_description(time) = "time".
-cost_kind_to_description(allocs) = "memory allocations".
-cost_kind_to_description(words) = "words allocated".
+cost_kind_to_description(cost_calls) = "number of calls".
+cost_kind_to_description(cost_redos) = "number of redos".
+cost_kind_to_description(cost_time) = "time".
+cost_kind_to_description(cost_callseqs) = "call sequence numbers".
+cost_kind_to_description(cost_allocs) = "memory allocations".
+cost_kind_to_description(cost_words) = "words allocated".
:- func incl_desc_to_description(include_descendants) = string.
@@ -920,98 +1062,115 @@
%-----------------------------------------------------------------------------%
-% The predicates fields_header, table_width and own_and_desc_to_html all make
-% decisions about what columns each row in the table will have. They
-% therefore have similar control structures, and a change in one may require
-% changes in the others as well.
+% The predicates banner_style, fields_header, table_width and
+% own_and_desc_to_html all make decisions about what columns each row
+% in the table will have. They therefore have similar control structures,
+% and a change in one may require changes in the others as well.
fields_header(Pref, IdFields, TotalsDisp, WrapFunc) = HTML :-
Fields = Pref ^ pref_fields,
ProcName = WrapFunc("Procedure", by_name),
ModuleName = WrapFunc("Module", by_name),
+
+ some [!FirstRow, !SecondRow] (
(
IdFields = source_proc,
Source = WrapFunc("Source", by_context),
- FirstRow0 =
+ !:FirstRow =
"<TR>\n" ++
string.format("<TH ALIGN=LEFT ROWSPAN=2>%s\n", [s(Source)]) ++
string.format("<TH ALIGN=LEFT ROWSPAN=2>%s\n", [s(ProcName)])
;
IdFields = rank_proc,
- FirstRow0 =
+ !:FirstRow =
"<TR>\n" ++
"<TH ALIGN=LEFT ROWSPAN=2>Rank\n" ++
string.format("<TH ALIGN=LEFT ROWSPAN=2>%s\n", [s(ProcName)])
;
IdFields = rank_module,
- FirstRow0 =
+ !:FirstRow =
"<TR>\n" ++
"<TH ALIGN=LEFT ROWSPAN=2>Rank\n" ++
string.format("<TH ALIGN=LEFT ROWSPAN=2>%s\n", [s(ModuleName)])
;
IdFields = proc,
- FirstRow0 =
+ !:FirstRow =
"<TR>\n" ++
string.format("<TH ALIGN=LEFT ROWSPAN=2>%s\n", [s(ProcName)])
),
- SecondRow0 = "<TR>\n",
- ( show_port_counts(Fields) = yes ->
- Calls = WrapFunc("Calls", by_cost(calls, self, overall)),
- Redos = WrapFunc("Redos", by_cost(redos, self, overall)),
- FirstRow1 = FirstRow0 ++
+ !:SecondRow = "<TR>\n",
+
+ ShowPortCounts = show_port_counts(Fields),
+ (
+ ShowPortCounts = yes,
+ Calls = WrapFunc("Calls", by_cost(cost_calls, self, overall)),
+ Redos = WrapFunc("Redos", by_cost(cost_redos, self, overall)),
+ !:FirstRow = !.FirstRow ++
"<TH COLSPAN=5>Port counts\n",
- SecondRow1 = SecondRow0 ++
+ !:SecondRow = !.SecondRow ++
string.format("<TH ALIGN=RIGHT>%s\n", [s(Calls)]) ++
"<TH ALIGN=RIGHT>Exits\n" ++
"<TH ALIGN=RIGHT>Fails\n" ++
string.format("<TH ALIGN=RIGHT>%s\n", [s(Redos)]) ++
"<TH ALIGN=RIGHT>Excps\n"
;
- FirstRow1 = FirstRow0,
- SecondRow1 = SecondRow0
+ ShowPortCounts = no
),
- ( show_quanta(Fields) = yes ->
+
+ ShowQuanta = show_quanta(Fields),
+ (
+ ShowQuanta = yes,
TicksSelfOverall = WrapFunc("Self",
- by_cost(time, self, overall)),
+ by_cost(cost_time, self, overall)),
TicksSelfHeading =
string.format("<TH ALIGN=RIGHT>%s\n", [s(TicksSelfOverall)]),
TicksSelfFields = 1
;
+ ShowQuanta = no,
TicksSelfHeading = "",
TicksSelfFields = 0
),
- ( show_times(Fields) = yes ->
+ ShowTimes = show_times(Fields),
+ (
+ ShowTimes = yes,
( show_quanta(Fields) = yes ->
- TimeSelfOverall = WrapFunc("Time", by_cost(time, self, overall))
+ TimeSelfOverall = WrapFunc("Time",
+ by_cost(cost_time, self, overall))
;
- TimeSelfOverall = WrapFunc("Self", by_cost(time, self, overall))
+ TimeSelfOverall = WrapFunc("Self",
+ by_cost(cost_time, self, overall))
),
TimeSelfHeading =
string.format("<TH ALIGN=RIGHT>%s\n", [s(TimeSelfOverall)]),
TimeSelfFields = 1
;
+ ShowTimes = no,
TimeSelfHeading = "",
TimeSelfFields = 0
),
- ( ( show_quanta(Fields) = yes ; show_times(Fields) = yes ) ->
+ ( ( ShowQuanta = yes ; ShowTimes = yes ) ->
TimeSelfPercentHeading = "<TH ALIGN=RIGHT>%\n",
TimeSelfPercentFields = 1
;
TimeSelfPercentHeading = "",
TimeSelfPercentFields = 0
),
- ( show_per_times(Fields) = yes ->
- TimeSelfPerCall = WrapFunc("/call", by_cost(time, self, per_call)),
+ ShowTimesPerCall = show_times_per_call(Fields),
+ (
+ ShowTimesPerCall = yes,
+ TimeSelfPerCall = WrapFunc("/call",
+ by_cost(cost_time, self, per_call)),
TimeSelfPerCallHeading =
string.format("<TH ALIGN=RIGHT>%s\n", [s(TimeSelfPerCall)]),
TimeSelfPerCallFields = 1
;
+ ShowTimesPerCall = no,
TimeSelfPerCallHeading = "",
TimeSelfPerCallFields = 0
),
- ( TotalsDisp = totals_meaningful, show_quanta(Fields) = yes ->
+ ( TotalsDisp = totals_meaningful, ShowQuanta = yes ->
TicksTotalOverall = WrapFunc("Total",
- by_cost(time, self_and_desc, overall)),
+ by_cost(cost_time, self_and_desc, overall)),
TicksTotalHeading =
string.format("<TH ALIGN=RIGHT>%s\n", [s(TicksTotalOverall)]),
TicksTotalFields = 1
@@ -1019,13 +1178,13 @@
TicksTotalHeading = "",
TicksTotalFields = 0
),
- ( TotalsDisp = totals_meaningful, show_times(Fields) = yes ->
+ ( TotalsDisp = totals_meaningful, ShowTimes = yes ->
( show_quanta(Fields) = yes ->
TimeTotalOverall = WrapFunc("Time",
- by_cost(time, self_and_desc, overall))
+ by_cost(cost_time, self_and_desc, overall))
;
TimeTotalOverall = WrapFunc("Total",
- by_cost(time, self_and_desc, overall))
+ by_cost(cost_time, self_and_desc, overall))
),
TimeTotalHeading =
string.format("<TH ALIGN=RIGHT>%s\n", [s(TimeTotalOverall)]),
@@ -1036,7 +1195,7 @@
),
(
TotalsDisp = totals_meaningful,
- ( show_quanta(Fields) = yes ; show_times(Fields) = yes )
+ ( ShowQuanta = yes ; ShowTimes = yes )
->
TimeTotalPercentHeading = "<TH ALIGN=RIGHT>%\n",
TimeTotalPercentFields = 1
@@ -1044,9 +1203,9 @@
TimeTotalPercentHeading = "",
TimeTotalPercentFields = 0
),
- ( TotalsDisp = totals_meaningful, show_per_times(Fields) = yes ->
+ ( TotalsDisp = totals_meaningful, ShowTimesPerCall = yes ->
TimeTotalPerCall = WrapFunc("/call",
- by_cost(time, self_and_desc, per_call)),
+ by_cost(cost_time, self_and_desc, per_call)),
TimeTotalPerCallHeading =
string.format("<TH ALIGN=RIGHT>%s\n", [s(TimeTotalPerCall)]),
TimeTotalPerCallFields = 1
@@ -1059,59 +1218,141 @@
TimeSelfPercentFields + TimeSelfPerCallFields +
TicksTotalFields + TimeTotalFields +
TimeTotalPercentFields + TimeTotalPerCallFields,
- SecondRow2 = SecondRow1 ++
+ !:SecondRow = !.SecondRow ++
TicksSelfHeading ++ TimeSelfHeading ++
TimeSelfPercentHeading ++ TimeSelfPerCallHeading ++
TicksTotalHeading ++ TimeTotalHeading ++
TimeTotalPercentHeading ++ TimeTotalPerCallHeading,
- ( show_quanta(Fields) = yes, show_times(Fields) = yes ->
- FirstRow2 = FirstRow1 ++
+ (
+ ShowQuanta = yes,
+ ShowTimes = yes,
+ !:FirstRow = !.FirstRow ++
string.format("<TH COLSPAN=%d>Clock ticks and times\n",
[i(TimeFields)])
- ; show_quanta(Fields) = yes ->
- FirstRow2 = FirstRow1 ++
+ ;
+ ShowQuanta = yes,
+ ShowTimes = no,
+ !:FirstRow = !.FirstRow ++
string.format("<TH COLSPAN=%d>Clock ticks\n", [i(TimeFields)])
- ; show_times(Fields) = yes ->
- FirstRow2 = FirstRow1 ++
+ ;
+ ShowQuanta = no,
+ ShowTimes = yes,
+ !:FirstRow = !.FirstRow ++
string.format("<TH COLSPAN=%d>Time\n", [i(TimeFields)])
;
- FirstRow2 = FirstRow1
+ ShowQuanta = no,
+ ShowTimes = no
+ ),
+
+ ShowCallSeqs = show_callseqs(Fields),
+ (
+ ShowCallSeqs = yes,
+ CallSeqsSelfOverall = WrapFunc("Self",
+ by_cost(cost_callseqs, self, overall)),
+ CallSeqsSelfHeading =
+ string.format("<TH ALIGN=RIGHT>%s\n",
+ [s(CallSeqsSelfOverall)]) ++
+ "<TH ALIGN=RIGHT>%\n",
+ CallSeqsSelfFields = 2
+ ;
+ ShowCallSeqs = no,
+ CallSeqsSelfHeading = "",
+ CallSeqsSelfFields = 0
+ ),
+ ShowCallSeqsPerCall = show_callseqs_per_call(Fields),
+ (
+ ShowCallSeqsPerCall = yes,
+ CallSeqsSelfPerCall = WrapFunc("/call",
+ by_cost(cost_callseqs, self, per_call)),
+ CallSeqsSelfPerCallHeading =
+ string.format("<TH ALIGN=RIGHT>%s\n", [s(CallSeqsSelfPerCall)]),
+ CallSeqsSelfPerCallFields = 1
+ ;
+ ShowCallSeqsPerCall = no,
+ CallSeqsSelfPerCallHeading = "",
+ CallSeqsSelfPerCallFields = 0
+ ),
+ ( TotalsDisp = totals_meaningful, ShowCallSeqs = yes ->
+ CallSeqsTotalOverall = WrapFunc("Total",
+ by_cost(cost_callseqs, self_and_desc, overall)),
+ CallSeqsTotalHeading =
+ string.format("<TH ALIGN=RIGHT>%s\n",
+ [s(CallSeqsTotalOverall)]) ++
+ "<TH ALIGN=RIGHT>%\n",
+ CallSeqsTotalFields = 2
+ ;
+ CallSeqsTotalHeading = "",
+ CallSeqsTotalFields = 0
+ ),
+ ( TotalsDisp = totals_meaningful, ShowCallSeqsPerCall = yes ->
+ CallSeqsTotalPerCall = WrapFunc("/call",
+ by_cost(cost_callseqs, self_and_desc, per_call)),
+ CallSeqsTotalPerCallHeading =
+ string.format("<TH ALIGN=RIGHT>%s\n",
+ [s(CallSeqsTotalPerCall)]),
+ CallSeqsTotalPerCallFields = 1
+ ;
+ CallSeqsTotalPerCallHeading = "",
+ CallSeqsTotalPerCallFields = 0
+ ),
+ CallSeqsFields =
+ CallSeqsSelfFields + CallSeqsSelfPerCallFields +
+ CallSeqsTotalFields + CallSeqsTotalPerCallFields,
+ !:SecondRow = !.SecondRow ++
+ CallSeqsSelfHeading ++ CallSeqsSelfPerCallHeading ++
+ CallSeqsTotalHeading ++ CallSeqsTotalPerCallHeading,
+ (
+ ShowCallSeqs = yes,
+ !:FirstRow = !.FirstRow ++
+ string.format("<TH COLSPAN=%d>Call sequence numbers\n",
+ [i(CallSeqsFields)])
+ ;
+ ShowCallSeqs = no
),
- ( show_alloc(Fields) = yes ->
+
+ ShowAlloc = show_alloc(Fields),
+ (
+ ShowAlloc = yes,
AllocsSelfOverall = WrapFunc("Self",
- by_cost(allocs, self, overall)),
+ by_cost(cost_allocs, self, overall)),
AllocsSelfHeading =
- string.format("<TH ALIGN=RIGHT>%s\n", [s(AllocsSelfOverall)]) ++
+ string.format("<TH ALIGN=RIGHT>%s\n",
+ [s(AllocsSelfOverall)]) ++
"<TH ALIGN=RIGHT>%\n",
AllocsSelfFields = 2
;
+ ShowAlloc = no,
AllocsSelfHeading = "",
AllocsSelfFields = 0
),
- ( show_per_alloc(Fields) = yes ->
+ ShowAllocPerCall = show_alloc_per_call(Fields),
+ (
+ ShowAllocPerCall = yes,
AllocsSelfPerCall = WrapFunc("/call",
- by_cost(allocs, self, per_call)),
+ by_cost(cost_allocs, self, per_call)),
AllocsSelfPerCallHeading =
string.format("<TH ALIGN=RIGHT>%s\n", [s(AllocsSelfPerCall)]),
AllocsSelfPerCallFields = 1
;
+ ShowAllocPerCall = no,
AllocsSelfPerCallHeading = "",
AllocsSelfPerCallFields = 0
),
- ( TotalsDisp = totals_meaningful, show_alloc(Fields) = yes ->
+ ( TotalsDisp = totals_meaningful, ShowAlloc = yes ->
AllocsTotalOverall = WrapFunc("Total",
- by_cost(allocs, self_and_desc, overall)),
+ by_cost(cost_allocs, self_and_desc, overall)),
AllocsTotalHeading =
- string.format("<TH ALIGN=RIGHT>%s\n", [s(AllocsTotalOverall)]) ++
+ string.format("<TH ALIGN=RIGHT>%s\n",
+ [s(AllocsTotalOverall)]) ++
"<TH ALIGN=RIGHT>%\n",
AllocsTotalFields = 2
;
AllocsTotalHeading = "",
AllocsTotalFields = 0
),
- ( TotalsDisp = totals_meaningful, show_per_alloc(Fields) = yes ->
+ ( TotalsDisp = totals_meaningful, ShowAllocPerCall = yes ->
AllocsTotalPerCall = WrapFunc("/call",
- by_cost(allocs, self_and_desc, per_call)),
+ by_cost(cost_allocs, self_and_desc, per_call)),
AllocsTotalPerCallHeading =
string.format("<TH ALIGN=RIGHT>%s\n", [s(AllocsTotalPerCall)]),
AllocsTotalPerCallFields = 1
@@ -1122,51 +1363,61 @@
AllocsFields =
AllocsSelfFields + AllocsSelfPerCallFields +
AllocsTotalFields + AllocsTotalPerCallFields,
- SecondRow3 = SecondRow2 ++
+ !:SecondRow = !.SecondRow ++
AllocsSelfHeading ++ AllocsSelfPerCallHeading ++
AllocsTotalHeading ++ AllocsTotalPerCallHeading,
- ( show_alloc(Fields) = yes ->
- FirstRow3 = FirstRow2 ++
+ (
+ ShowAlloc = yes,
+ !:FirstRow = !.FirstRow ++
string.format("<TH COLSPAN=%d>Memory allocations\n",
[i(AllocsFields)])
;
- FirstRow3 = FirstRow2
+ ShowAlloc = no
),
- ( show_memory(Fields) = yes(_) ->
+
+ ShowMemory = show_memory(Fields),
+ (
+ ShowMemory = yes(_),
MemorySelfOverall = WrapFunc("Self",
- by_cost(words, self, overall)),
+ by_cost(cost_words, self, overall)),
MemorySelfHeading =
- string.format("<TH ALIGN=RIGHT>%s\n", [s(MemorySelfOverall)]) ++
+ string.format("<TH ALIGN=RIGHT>%s\n",
+ [s(MemorySelfOverall)]) ++
"<TH ALIGN=RIGHT>%\n",
MemorySelfFields = 2
;
+ ShowMemory = no,
MemorySelfHeading = "",
MemorySelfFields = 0
),
- ( show_per_memory(Fields) = yes(_) ->
+ ShowMemoryPerCall = show_memory_per_call(Fields),
+ (
+ ShowMemoryPerCall = yes(_),
MemorySelfPerCall = WrapFunc("/call",
- by_cost(words, self, per_call)),
+ by_cost(cost_words, self, per_call)),
MemorySelfPerCallHeading =
string.format("<TH ALIGN=RIGHT>%s\n", [s(MemorySelfPerCall)]),
MemorySelfPerCallFields = 1
;
+ ShowMemoryPerCall = no,
MemorySelfPerCallHeading = "",
MemorySelfPerCallFields = 0
),
- ( TotalsDisp = totals_meaningful, show_memory(Fields) = yes(_) ->
+ ( TotalsDisp = totals_meaningful, ShowMemory = yes(_) ->
MemoryTotalOverall = WrapFunc("Total",
- by_cost(words, self_and_desc, overall)),
+ by_cost(cost_words, self_and_desc, overall)),
MemoryTotalHeading =
- string.format("<TH ALIGN=RIGHT>%s\n", [s(MemoryTotalOverall)]) ++
+ string.format("<TH ALIGN=RIGHT>%s\n",
+ [s(MemoryTotalOverall)]) ++
"<TH ALIGN=RIGHT>%\n",
MemoryTotalFields = 2
;
MemoryTotalHeading = "",
MemoryTotalFields = 0
),
- ( TotalsDisp = totals_meaningful, show_per_memory(Fields) = yes(_) ->
+ ( TotalsDisp = totals_meaningful, ShowMemoryPerCall = yes(_) ->
MemoryTotalPerCall = WrapFunc("/call",
- by_cost(words, self_and_desc, per_call)),
+ by_cost(cost_words, self_and_desc, per_call)),
MemoryTotalPerCallHeading =
string.format("<TH ALIGN=RIGHT>%s\n", [s(MemoryTotalPerCall)]),
MemoryTotalPerCallFields = 1
@@ -1177,30 +1428,32 @@
MemoryFields =
MemorySelfFields + MemorySelfPerCallFields +
MemoryTotalFields + MemoryTotalPerCallFields,
- SecondRow4 = SecondRow3 ++
+ !:SecondRow = !.SecondRow ++
MemorySelfHeading ++ MemorySelfPerCallHeading ++
MemoryTotalHeading ++ MemoryTotalPerCallHeading,
- ( show_memory(Fields) = yes(Units) ->
(
- Units = words,
- FirstRow4 = FirstRow3 ++
+ ShowMemory = yes(Units),
+ (
+ Units = units_words,
+ !:FirstRow = !.FirstRow ++
string.format("<TH COLSPAN=%d>Memory words\n",
[i(MemoryFields)])
;
- Units = bytes,
- FirstRow4 = FirstRow3 ++
+ Units = units_bytes,
+ !:FirstRow = !.FirstRow ++
string.format("<TH COLSPAN=%d>Memory bytes\n",
[i(MemoryFields)])
)
;
- FirstRow4 = FirstRow3
+ ShowMemory = no
),
HTML =
"<THEAD>\n" ++
- FirstRow4 ++
- SecondRow4 ++
+ !.FirstRow ++
+ !.SecondRow ++
"<TBODY>\n" ++
- separator_row(Pref, IdFields, TotalsDisp).
+ separator_row(Pref, IdFields, TotalsDisp)
+ ).
%-----------------------------------------------------------------------------%
@@ -1241,46 +1494,56 @@
Time = 0
;
Fields ^ time_fields = ticks,
- Time = 4
+ Time = 2
;
Fields ^ time_fields = time,
- Time = 4
+ Time = 2
;
Fields ^ time_fields = ticks_and_time,
- Time = 6
+ Time = 3
;
Fields ^ time_fields = time_and_percall,
- Time = 6
+ Time = 3
;
Fields ^ time_fields = ticks_and_time_and_percall,
- Time = 8
+ Time = 4
+ ),
+ (
+ Fields ^ callseqs_fields = no_callseqs,
+ CallSeqs = 0
+ ;
+ Fields ^ callseqs_fields = callseqs,
+ CallSeqs = 2
+ ;
+ Fields ^ callseqs_fields = callseqs_and_percall,
+ CallSeqs = 3
),
(
Fields ^ alloc_fields = no_alloc,
Alloc = 0
;
Fields ^ alloc_fields = alloc,
- Alloc = 4
+ Alloc = 2
;
Fields ^ alloc_fields = alloc_and_percall,
- Alloc = 6
+ Alloc = 3
),
(
Fields ^ memory_fields = no_memory,
Memory = 0
;
Fields ^ memory_fields = memory(_),
- Memory = 4
+ Memory = 2
;
Fields ^ memory_fields = memory_and_percall(_),
- Memory = 6
+ Memory = 3
),
(
TotalsDisp = totals_meaningful,
- Width = Id + Port + Time + Alloc + Memory
+ Width = Id + Port + Time * 2 + CallSeqs * 2 + Alloc * 2 + Memory * 2
;
TotalsDisp = totals_not_meaningful,
- Width = Id + Port + Time // 2 + Alloc // 2 + Memory // 2
+ Width = Id + Port + Time + CallSeqs + Alloc + Memory
).
%-----------------------------------------------------------------------------%
@@ -1380,6 +1643,12 @@
OwnQuantaProp = percentage(OwnQuanta, RootQuanta),
TotalQuantaProp = percentage(TotalQuanta, RootQuanta),
+ OwnCallSeqs = callseqs(Own),
+ TotalCallSeqs = inherit_callseqs(OwnPlusDesc),
+ RootCallSeqs = inherit_callseqs(Root),
+ OwnCallSeqsProp = percentage(OwnCallSeqs, RootCallSeqs),
+ TotalCallSeqsProp = percentage(TotalCallSeqs, RootCallSeqs),
+
OwnAllocs = allocs(Own),
TotalAllocs = inherit_allocs(OwnPlusDesc),
RootAllocs = inherit_allocs(Root),
@@ -1392,25 +1661,11 @@
OwnMemoryProp = percentage(OwnWords, RootWords),
TotalMemoryProp = percentage(TotalWords, RootWords),
- ( show_memory(Fields) = yes(Unit) ->
- (
- Unit = words,
- OwnMemory = OwnWords,
- TotalMemory = TotalWords
- ;
- Unit = bytes,
- WordSize = Deep ^ profile_stats ^ word_size,
- OwnMemory = OwnWords * WordSize,
- TotalMemory = TotalWords * WordSize
- )
- ;
- % These values won't be used.
- OwnMemory = 0,
- TotalMemory = 0
- ),
-
Fields = Pref ^ pref_fields,
- ( show_port_counts(Fields) = yes ->
+
+ ShowPortCounts = show_port_counts(Fields),
+ (
+ ShowPortCounts = yes,
PortHTML =
string.format("<TD CLASS=port ALIGN=RIGHT>%s</TD>\n",
[s(commas(Calls))]) ++
@@ -1423,9 +1678,13 @@
string.format("<TD CLASS=port ALIGN=RIGHT>%s</TD>\n",
[s(commas(Excps))])
;
+ ShowPortCounts = no,
PortHTML = ""
),
- ( show_quanta(Fields) = yes ->
+
+ ShowQuanta = show_quanta(Fields),
+ (
+ ShowQuanta = yes,
QuantaSelfHTML =
string.format("<TD CLASS=time ALIGN=RIGHT>%s</TD>\n",
[s(commas(OwnQuanta))]),
@@ -1433,10 +1692,13 @@
string.format("<TD CLASS=time ALIGN=RIGHT>%s</TD>\n",
[s(commas(TotalQuanta))])
;
+ ShowQuanta = no,
QuantaSelfHTML = "",
QuantaTotalHTML = ""
),
- ( show_times(Fields) = yes ->
+ ShowTimes = show_times(Fields),
+ (
+ ShowTimes = yes,
TimeSelfHTML =
string.format("<TD CLASS=time ALIGN=RIGHT>%s</TD>\n",
[s(overall_time(Pref, Deep, OwnQuanta))]),
@@ -1444,10 +1706,13 @@
string.format("<TD CLASS=time ALIGN=RIGHT>%s</TD>\n",
[s(overall_time(Pref, Deep, TotalQuanta))])
;
+ ShowTimes = no,
TimeSelfHTML = "",
TimeTotalHTML = ""
),
- ( ( show_quanta(Fields) = yes ; show_times(Fields) = yes ) ->
+ ShowTimeFraction = bool.or(ShowQuanta, ShowTimes),
+ (
+ ShowTimeFraction = yes,
QuantaPropSelfHTML =
string.format("<TD CLASS=time ALIGN=RIGHT>%s</TD>\n",
[s(OwnQuantaProp)]),
@@ -1455,23 +1720,72 @@
string.format("<TD CLASS=time ALIGN=RIGHT>%s</TD>\n",
[s(TotalQuantaProp)])
;
+ ShowTimeFraction = no,
QuantaPropSelfHTML = "",
QuantaPropTotalHTML = ""
),
- ( show_per_times(Fields) = yes ->
+ ShowTimesPerCall = show_times_per_call(Fields),
+ (
+ ShowTimesPerCall = yes,
TimePerCallSelfHTML =
string.format("<TD CLASS=time ALIGN=RIGHT>%s</TD>\n",
- [s(per_call_time(Pref, Deep,
- OwnQuanta, Calls))]),
+ [s(per_call_time(Pref, Deep, OwnQuanta, Calls))]),
TimePerCallTotalHTML =
string.format("<TD CLASS=time ALIGN=RIGHT>%s</TD>\n",
- [s(per_call_time(Pref, Deep,
- TotalQuanta, Calls))])
+ [s(per_call_time(Pref, Deep, TotalQuanta, Calls))])
;
+ ShowTimesPerCall = no,
TimePerCallSelfHTML = "",
TimePerCallTotalHTML = ""
),
- ( show_alloc(Fields) = yes ->
+
+ ShowCallSeqs = show_callseqs(Fields),
+ (
+ ShowCallSeqs = yes,
+ CallSeqsSelfHTML =
+ string.format("<TD CLASS=callseqs ALIGN=RIGHT>%i</TD>\n",
+ [i(OwnCallSeqs)]),
+ CallSeqsTotalHTML =
+ string.format("<TD CLASS=callseqs ALIGN=RIGHT>%i</TD>\n",
+ [i(TotalCallSeqs)]),
+ CallSeqsPropSelfHTML =
+ string.format("<TD CLASS=callseqs ALIGN=RIGHT>%s</TD>\n",
+ [s(OwnCallSeqsProp)]),
+ CallSeqsPropTotalHTML =
+ string.format("<TD CLASS=callseqs ALIGN=RIGHT>%s</TD>\n",
+ [s(TotalCallSeqsProp)])
+ ;
+ ShowCallSeqs = no,
+ CallSeqsSelfHTML = "",
+ CallSeqsTotalHTML = "",
+ CallSeqsPropSelfHTML = "",
+ CallSeqsPropTotalHTML = ""
+ ),
+ ShowCallSeqsPerCall = show_callseqs_per_call(Fields),
+ (
+ ShowCallSeqsPerCall = yes,
+ ( Calls = 0 ->
+ OwnCallSeqsPerCall = 0.0,
+ TotalCallSeqsPerCall = 0.0
+ ;
+ OwnCallSeqsPerCall = float(OwnCallSeqs) / float(Calls),
+ TotalCallSeqsPerCall = float(TotalCallSeqs) / float(Calls)
+ ),
+ CallSeqsPerCallSelfHTML =
+ string.format("<TD CLASS=callseqs ALIGN=RIGHT>%.1f</TD>\n",
+ [f(OwnCallSeqsPerCall)]),
+ CallSeqsPerCallTotalHTML =
+ string.format("<TD CLASS=callseqs ALIGN=RIGHT>%.1f</TD>\n",
+ [f(TotalCallSeqsPerCall)])
+ ;
+ ShowCallSeqsPerCall = no,
+ CallSeqsPerCallSelfHTML = "",
+ CallSeqsPerCallTotalHTML = ""
+ ),
+
+ ShowAlloc = show_alloc(Fields),
+ (
+ ShowAlloc = yes,
AllocSelfHTML =
string.format("<TD CLASS=alloc ALIGN=RIGHT>%s</TD>\n",
[s(commas(OwnAllocs))]) ++
@@ -1483,10 +1797,13 @@
string.format("<TD CLASS=alloc ALIGN=RIGHT>%s</TD>\n",
[s(TotalAllocProp)])
;
+ ShowAlloc = no,
AllocSelfHTML = "",
AllocTotalHTML = ""
),
- ( show_per_alloc(Fields) = yes ->
+ ShowAllocPerCall = show_alloc_per_call(Fields),
+ (
+ ShowAllocPerCall = yes,
AllocPerCallSelfHTML =
string.format("<TD CLASS=alloc ALIGN=RIGHT>%s</TD>\n",
[s(count_per_call(OwnAllocs, Calls))]),
@@ -1494,10 +1811,32 @@
string.format("<TD CLASS=alloc ALIGN=RIGHT>%s</TD>\n",
[s(count_per_call(TotalAllocs, Calls))])
;
+ ShowAllocPerCall = no,
AllocPerCallSelfHTML = "",
AllocPerCallTotalHTML = ""
),
- ( show_memory(Fields) = yes(_) ->
+
+ ShowMemory = show_memory(Fields),
+ (
+ ShowMemory = yes(Unit),
+ (
+ Unit = units_words,
+ OwnMemory = OwnWords,
+ TotalMemory = TotalWords
+ ;
+ Unit = units_bytes,
+ WordSize = Deep ^ profile_stats ^ word_size,
+ OwnMemory = OwnWords * WordSize,
+ TotalMemory = TotalWords * WordSize
+ )
+ ;
+ ShowMemory = no,
+ % These values won't be used.
+ OwnMemory = 0,
+ TotalMemory = 0
+ ),
+ (
+ ShowMemory = yes(_),
MemorySelfHTML =
string.format("<TD CLASS=memory ALIGN=RIGHT>%s</TD>\n",
[s(commas(OwnMemory))]) ++
@@ -1509,10 +1848,13 @@
string.format("<TD CLASS=memory ALIGN=RIGHT>%s</TD>\n",
[s(TotalMemoryProp)])
;
+ ShowMemory = no,
MemorySelfHTML = "",
MemoryTotalHTML = ""
),
- ( show_per_memory(Fields) = yes(_) ->
+ ShowMemoryPerCall = show_memory_per_call(Fields),
+ (
+ ShowMemoryPerCall = yes(_),
MemoryPerCallSelfHTML =
string.format("<TD CLASS=memory ALIGN=RIGHT>%s</TD>\n",
[s(count_per_call(OwnMemory, Calls))]),
@@ -1520,9 +1862,11 @@
string.format("<TD CLASS=memory ALIGN=RIGHT>%s</TD>\n",
[s(count_per_call(TotalMemory, Calls))])
;
+ ShowMemoryPerCall = no,
MemoryPerCallSelfHTML = "",
MemoryPerCallTotalHTML = ""
),
+
(
TotalsDisp = totals_meaningful,
HTML =
@@ -1537,6 +1881,13 @@
QuantaPropTotalHTML ++
TimePerCallTotalHTML ++
+ CallSeqsSelfHTML ++
+ CallSeqsPropSelfHTML ++
+ CallSeqsPerCallSelfHTML ++
+ CallSeqsTotalHTML ++
+ CallSeqsPropTotalHTML ++
+ CallSeqsPerCallTotalHTML ++
+
AllocSelfHTML ++
AllocPerCallSelfHTML ++
AllocTotalHTML ++
@@ -1556,6 +1907,10 @@
QuantaPropSelfHTML ++
TimePerCallSelfHTML ++
+ CallSeqsSelfHTML ++
+ CallSeqsPropSelfHTML ++
+ CallSeqsPerCallSelfHTML ++
+
AllocSelfHTML ++
AllocPerCallSelfHTML ++
@@ -1756,16 +2111,34 @@
; TimeFields = ticks_and_time_and_percall, ShowTimes = yes
).
-:- func show_per_times(fields) = bool.
+:- func show_times_per_call(fields) = bool.
-show_per_times(Fields) = ShowPerTimes :-
+show_times_per_call(Fields) = ShowTimesPerCall :-
TimeFields = Fields ^ time_fields,
- ( TimeFields = no_time, ShowPerTimes = no
- ; TimeFields = ticks, ShowPerTimes = no
- ; TimeFields = time, ShowPerTimes = no
- ; TimeFields = ticks_and_time, ShowPerTimes = no
- ; TimeFields = time_and_percall, ShowPerTimes = yes
- ; TimeFields = ticks_and_time_and_percall, ShowPerTimes = yes
+ ( TimeFields = no_time, ShowTimesPerCall = no
+ ; TimeFields = ticks, ShowTimesPerCall = no
+ ; TimeFields = time, ShowTimesPerCall = no
+ ; TimeFields = ticks_and_time, ShowTimesPerCall = no
+ ; TimeFields = time_and_percall, ShowTimesPerCall = yes
+ ; TimeFields = ticks_and_time_and_percall, ShowTimesPerCall = yes
+ ).
+
+:- func show_callseqs(fields) = bool.
+
+show_callseqs(Fields) = ShowCallSeqs :-
+ CallSeqsField = Fields ^ callseqs_fields,
+ ( CallSeqsField = no_callseqs, ShowCallSeqs = no
+ ; CallSeqsField = callseqs, ShowCallSeqs = yes
+ ; CallSeqsField = callseqs_and_percall, ShowCallSeqs = yes
+ ).
+
+:- func show_callseqs_per_call(fields) = bool.
+
+show_callseqs_per_call(Fields) = ShowCallSeqsPerCall :-
+ CallSeqsField = Fields ^ callseqs_fields,
+ ( CallSeqsField = no_callseqs, ShowCallSeqsPerCall = no
+ ; CallSeqsField = callseqs, ShowCallSeqsPerCall = no
+ ; CallSeqsField = callseqs_and_percall, ShowCallSeqsPerCall = yes
).
:- func show_alloc(fields) = bool.
@@ -1777,9 +2150,9 @@
; AllocFields = alloc_and_percall, ShowAlloc = yes
).
-:- func show_per_alloc(fields) = bool.
+:- func show_alloc_per_call(fields) = bool.
-show_per_alloc(Fields) = ShowPerAlloc :-
+show_alloc_per_call(Fields) = ShowPerAlloc :-
AllocFields = Fields ^ alloc_fields,
( AllocFields = no_alloc, ShowPerAlloc = no
; AllocFields = alloc, ShowPerAlloc = no
@@ -1795,9 +2168,9 @@
; MemoryFields = memory_and_percall(Unit), ShowMemory = yes(Unit)
).
-:- func show_per_memory(fields) = maybe(memory_units).
+:- func show_memory_per_call(fields) = maybe(memory_units).
-show_per_memory(Fields) = ShowPerMemory :-
+show_memory_per_call(Fields) = ShowPerMemory :-
MemoryFields = Fields ^ memory_fields,
( MemoryFields = no_memory, ShowPerMemory = no
; MemoryFields = memory(_Unit), ShowPerMemory = no
@@ -1855,20 +2228,20 @@
proc_static_to_html_ref(Pref, Deep, PSPtr) = HTML :-
PSPtr = proc_static_ptr(PSI),
- URL = deep_cmd_pref_to_url(Pref, Deep, proc(PSI)),
+ URL = deep_cmd_pref_to_url(Pref, Deep, deep_cmd_proc(PSI)),
deep_lookup_proc_statics(Deep, PSPtr, PS),
ProcName = PS ^ ps_refined_id,
HTML = string.format("<A HREF=""%s"">%s</A>",
[s(URL), s(escape_html_string(ProcName))]).
module_name_to_html_ref(Pref, Deep, ModuleName) = HTML :-
- URL = deep_cmd_pref_to_url(Pref, Deep, module(ModuleName)),
+ URL = deep_cmd_pref_to_url(Pref, Deep, deep_cmd_module(ModuleName)),
HTML = string.format("<A HREF=""%s"">%s</A>",
[s(URL), s(escape_html_string(ModuleName))]).
clique_ptr_to_html_ref(Pref, Deep, ProcName, CliquePtr) = HTML :-
CliquePtr = clique_ptr(CliqueNum),
- URL = deep_cmd_pref_to_url(Pref, Deep, clique(CliqueNum)),
+ URL = deep_cmd_pref_to_url(Pref, Deep, deep_cmd_clique(CliqueNum)),
HTML = string.format("<A HREF=""%s"">%s</A>",
[s(URL), s(escape_html_string(ProcName))]).
Index: interface.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/deep_profiler/interface.m,v
retrieving revision 1.14
diff -u -b -r1.14 interface.m
--- interface.m 5 Oct 2006 04:49:29 -0000 1.14
+++ interface.m 11 Oct 2006 03:49:04 -0000
@@ -1,4 +1,4 @@
-%-----------------------------------------------------------------------------%
+%----------------------------------------------------------------------------%
% vim: ft=mercury ts=4 sw=4 et
%-----------------------------------------------------------------------------%
% Copyright (C) 2001-2002, 2004-2006 The University of Melbourne.
@@ -49,6 +49,8 @@
:- interface.
+:- import_module profile.
+
:- import_module bool.
:- import_module char.
:- import_module io.
@@ -56,9 +58,9 @@
%-----------------------------------------------------------------------------%
- % These functions derive the names of auxiliary files (or parts
- % thereof) from the name of the profiling data file being explored.
- % The auxiliary files are:
+ % These functions derive the names of auxiliary files (or parts thereof)
+ % from the name of the profiling data file being explored. The auxiliary
+ % files are:
%
% - the name of the named pipe for transmitting queries to the server;
% - the name of the named pipe for transmitting responses back to the
@@ -84,27 +86,29 @@
:- func contour_file_name(string) = string.
% send_term(ToFileName, Debug, Term):
+ %
% Write the term Term to ToFileName, making it is new contents.
- % If Debug is `yes', write it to the file `/tmp/.send_term'
- % as well.
+ % If Debug is `yes', write it to the file `/tmp/.send_term' as well.
%
:- pred send_term(string::in, bool::in, T::in, io::di, io::uo) is det.
% send_string(ToFileName, Debug, Str):
+ %
% Write the string Str to ToFileName, making it is new contents.
- % If Debug is `yes', write it to the file `/tmp/.send_string'
- % as well.
+ % If Debug is `yes', write it to the file `/tmp/.send_string' as well.
%
:- pred send_string(string::in, bool::in, string::in, io::di, io::uo) is det.
% recv_term(FromFileName, Debug, Term):
- % Read the contents of FromFileName, which should be a single
- % Mercury term. If Debug is `yes', write the result of the read
- % to the file `/tmp/.recv_term' as well.
+ %
+ % Read the contents of FromFileName, which should be a single Mercury term.
+ % If Debug is `yes', write the result of the read to the file
+ % `/tmp/.recv_term' as well.
%
:- pred recv_term(string::in, bool::in, T::out, io::di, io::uo) is det.
% recv_string(FromFileName, Debug, Str):
+ %
% Read the contents of FromFileName, and return it as Str.
% If Debug is `yes', write the result of the read to the file
% `/tmp/.recv_string' as well.
@@ -117,29 +121,29 @@
---> html(string).
:- type cmd_pref
- ---> cmd_pref(cmd, preferences).
+ ---> cmd_pref(cmd, preferences_indication).
:- type cmd
- ---> quit
- ; restart
- ; timeout(int)
- ; menu
- ; root(maybe(int))
- ; clique(int)
- ; proc(int)
- ; proc_callers(int, caller_groups, int)
- ; modules
- ; module(string)
- ; top_procs(display_limit, cost_kind, include_descendants,
+ ---> deep_cmd_quit
+ ; deep_cmd_restart
+ ; deep_cmd_timeout(int)
+ ; deep_cmd_menu
+ ; deep_cmd_root(maybe(int))
+ ; deep_cmd_clique(int)
+ ; deep_cmd_proc(int)
+ ; deep_cmd_proc_callers(int, caller_groups, int)
+ ; deep_cmd_modules
+ ; deep_cmd_module(string)
+ ; deep_cmd_top_procs(display_limit, cost_kind, include_descendants,
measurement_scope)
%
% The following commands are for debugging.
%
- ; proc_static(int)
- ; proc_dynamic(int)
- ; call_site_static(int)
- ; call_site_dynamic(int)
- ; raw_clique(int).
+ ; deep_cmd_proc_static(int)
+ ; deep_cmd_proc_dynamic(int)
+ ; deep_cmd_call_site_static(int)
+ ; deep_cmd_call_site_dynamic(int)
+ ; deep_cmd_raw_clique(int).
:- type caller_groups
---> group_by_call_site
@@ -148,11 +152,12 @@
; group_by_clique.
:- type cost_kind
- ---> calls
- ; redos
- ; time
- ; allocs
- ; words.
+ ---> cost_calls
+ ; cost_redos
+ ; cost_time
+ ; cost_callseqs
+ ; cost_allocs
+ ; cost_words.
:- type include_descendants
---> self
@@ -160,40 +165,46 @@
:- type display_limit
---> rank_range(int, int)
- % rank_range(M, N): display procedures
- % with rank M to N, both inclusive.
+ % rank_range(M, N): display procedures with rank M to N,
+ % both inclusive.
; threshold(float).
- % threshold(Percent): display
- % procedures whose cost is at least
- % Fraction of the whole program's
- % cost.
+ % threshold(Percent): display procedures whose cost is at least
+ % Percent% of the whole program's cost.
+
+:- type preferences_indication
+ ---> given_pref(preferences)
+ ; default_pref
+ ; all_pref.
:- type preferences
---> preferences(
+ % The set of fields to display.
pref_fields :: fields,
- % set of fields to display
+
+ % Whether displays should be boxed.
pref_box :: box,
- % whether displays should be boxed
+
+ % What principle governs colours.
pref_colour :: colour_scheme,
- % what principle governs colours
+
+ % The max number of ancestors to display.
pref_anc :: maybe(int),
- % max number of ancestors to display
+
+ % Whether pages should summarize at higher order call sites.
pref_summarize :: summarize,
- % whether pages should summarize
- % at higher order call sites
+
+ % The criteria for ordering lines in pages, if the command
+ % doesn't specify otherwise.
pref_criteria :: order_criteria,
- % the criteria for ordering lines in
- % pages, if the command doesn't specify
- % otherwise
+
+ % Whether contour exclusion should be applied.
pref_contour :: contour,
- % whether contour exclusion should be
- % applied
+
pref_time :: time_format,
+ % Whether we should show modules/procs that haven't been called.
pref_inactive :: inactive_items
- % Whether we should show modules/procs
- % that haven't been called.
).
:- type port_fields
@@ -208,6 +219,12 @@
; time_and_percall
; ticks_and_time_and_percall.
+
+:- type callseqs_fields
+ ---> no_callseqs
+ ; callseqs
+ ; callseqs_and_percall.
+
:- type alloc_fields
---> no_alloc
; alloc
@@ -219,13 +236,14 @@
; memory_and_percall(memory_units).
:- type memory_units
- ---> words
- ; bytes.
+ ---> units_words
+ ; units_bytes.
:- type fields
---> fields(
port_fields :: port_fields,
time_fields :: time_fields,
+ callseqs_fields :: callseqs_fields,
alloc_fields :: alloc_fields,
memory_fields :: memory_fields
).
@@ -235,8 +253,8 @@
; nobox.
:- type colour_scheme
- ---> column_groups
- ; none.
+ ---> colour_column_groups
+ ; colour_none.
:- type summarize
---> summarize
@@ -264,7 +282,9 @@
; scale_by_millions
; scale_by_thousands.
-:- type inactive_status ---> hide ; show.
+:- type inactive_status
+ ---> inactive_hide
+ ; inactive_show.
:- type inactive_items
---> inactive_items(
@@ -274,9 +294,15 @@
%-----------------------------------------------------------------------------%
-:- func default_preferences = preferences.
+ % Return "yes" if it is worth displaying times for this profile.
+ %
+:- func should_display_times(deep) = bool.
+
+:- func solidify_preference(deep, preferences_indication) = preferences.
-:- func default_fields = fields.
+:- func default_preferences(deep) = preferences.
+
+:- func default_fields(deep) = fields.
:- func all_fields = fields.
:- func default_box = box.
:- func default_colour_scheme = colour_scheme.
@@ -305,6 +331,7 @@
:- import_module conf.
:- import_module util.
+:- import_module int.
:- import_module list.
:- import_module require.
:- import_module set.
@@ -312,9 +339,34 @@
%-----------------------------------------------------------------------------%
-default_preferences =
+ % Display times only if the profile was derived from a run that ran for
+ % at least this many quanta.
+ %
+:- func minimum_meaningful_quanta = int.
+
+minimum_meaningful_quanta = 10.
+
+should_display_times(Deep) =
+ ( Deep ^ profile_stats ^ user_quanta > minimum_meaningful_quanta ->
+ yes
+ ;
+ no
+ ).
+
+solidify_preference(Deep, PrefInd) = Pref :-
+ (
+ PrefInd = given_pref(Pref)
+ ;
+ PrefInd = default_pref,
+ Pref = default_preferences(Deep)
+ ;
+ PrefInd = all_pref,
+ Pref = default_preferences(Deep) ^ pref_fields := all_fields
+ ).
+
+default_preferences(Deep) =
preferences(
- default_fields,
+ default_fields(Deep),
default_box,
default_colour_scheme,
default_ancestor_limit,
@@ -325,19 +377,29 @@
default_inactive_items
).
-default_fields = fields(port, ticks, no_alloc, memory(words)).
-all_fields = fields(port, ticks_and_time_and_percall, alloc, memory(words)).
+default_fields(Deep) = Fields :-
+ ShouldDisplayTimes = should_display_times(Deep),
+ (
+ ShouldDisplayTimes = yes,
+ Time = ticks
+ ;
+ ShouldDisplayTimes = no,
+ Time = no_time
+ ),
+ Fields = fields(port, Time, callseqs, no_alloc, memory(units_words)).
+all_fields = fields(port, ticks_and_time_and_percall, callseqs_and_percall,
+ alloc, memory(units_words)).
default_box = box.
-default_colour_scheme = column_groups.
+default_colour_scheme = colour_column_groups.
default_ancestor_limit = yes(5).
default_summarize = dont_summarize.
default_order_criteria = by_context.
-default_cost_kind = time.
+default_cost_kind = cost_callseqs.
default_incl_desc = self_and_desc.
default_scope = overall.
default_contour = no_contour.
default_time_format = scale_by_thousands.
-default_inactive_items = inactive_items(hide, hide).
+default_inactive_items = inactive_items(inactive_hide, inactive_hide).
%-----------------------------------------------------------------------------%
@@ -527,20 +589,20 @@
cmd_to_string(Cmd) = CmdStr :-
(
- Cmd = quit,
+ Cmd = deep_cmd_quit,
CmdStr = "quit"
;
- Cmd = restart,
+ Cmd = deep_cmd_restart,
CmdStr = "restart"
;
- Cmd = timeout(Minutes),
+ Cmd = deep_cmd_timeout(Minutes),
CmdStr = string.format("timeout%c%d",
[c(cmd_separator_char), i(Minutes)])
;
- Cmd = menu,
+ Cmd = deep_cmd_menu,
CmdStr = "menu"
;
- Cmd = root(MaybePercent),
+ Cmd = deep_cmd_root(MaybePercent),
(
MaybePercent = yes(Percent),
CmdStr = string.format("root%c%d",
@@ -551,29 +613,29 @@
[c(cmd_separator_char), s("no")])
)
;
- Cmd = clique(CliqueNum),
+ Cmd = deep_cmd_clique(CliqueNum),
CmdStr = string.format("clique%c%d",
[c(cmd_separator_char), i(CliqueNum)])
;
- Cmd = proc(ProcNum),
+ Cmd = deep_cmd_proc(ProcNum),
CmdStr = string.format("proc%c%d",
[c(cmd_separator_char), i(ProcNum)])
;
- Cmd = proc_callers(ProcNum, GroupCallers, BunchNum),
+ Cmd = deep_cmd_proc_callers(ProcNum, GroupCallers, BunchNum),
GroupCallersStr = caller_groups_to_string(GroupCallers),
CmdStr = string.format("proc_callers%c%d%c%s%c%d",
[c(cmd_separator_char), i(ProcNum),
c(cmd_separator_char), s(GroupCallersStr),
c(cmd_separator_char), i(BunchNum)])
;
- Cmd = modules,
+ Cmd = deep_cmd_modules,
CmdStr = "modules"
;
- Cmd = module(ModuleName),
+ Cmd = deep_cmd_module(ModuleName),
CmdStr = string.format("module%c%s",
[c(cmd_separator_char), s(ModuleName)])
;
- Cmd = top_procs(Limit, CostKind, InclDesc, Scope),
+ Cmd = deep_cmd_top_procs(Limit, CostKind, InclDesc, Scope),
LimitStr = limit_to_string(Limit),
CostKindStr = cost_kind_to_string(CostKind),
InclDescStr = incl_desc_to_string(InclDesc),
@@ -584,23 +646,23 @@
c(cmd_separator_char), s(InclDescStr),
c(cmd_separator_char), s(ScopeStr)])
;
- Cmd = proc_static(PSI),
+ Cmd = deep_cmd_proc_static(PSI),
CmdStr = string.format("proc_static%c%d",
[c(cmd_separator_char), i(PSI)])
;
- Cmd = proc_dynamic(PDI),
+ Cmd = deep_cmd_proc_dynamic(PDI),
CmdStr = string.format("proc_dynamic%c%d",
[c(cmd_separator_char), i(PDI)])
;
- Cmd = call_site_static(CSSI),
+ Cmd = deep_cmd_call_site_static(CSSI),
CmdStr = string.format("call_site_static%c%d",
[c(cmd_separator_char), i(CSSI)])
;
- Cmd = call_site_dynamic(CSDI),
+ Cmd = deep_cmd_call_site_dynamic(CSDI),
CmdStr = string.format("call_site_dynamic%c%d",
[c(cmd_separator_char), i(CSDI)])
;
- Cmd = raw_clique(CI),
+ Cmd = deep_cmd_raw_clique(CI),
CmdStr = string.format("raw_clique%c%d",
[c(cmd_separator_char), i(CI)])
).
@@ -652,83 +714,82 @@
fail
)
->
- MaybeCmd = yes(root(MaybePercent))
+ MaybeCmd = yes(deep_cmd_root(MaybePercent))
;
Pieces = ["clique", CliqueNumStr],
string.to_int(CliqueNumStr, CliqueNum)
->
- MaybeCmd = yes(clique(CliqueNum))
+ MaybeCmd = yes(deep_cmd_clique(CliqueNum))
;
Pieces = ["proc", PSIStr],
string.to_int(PSIStr, PSI)
->
- MaybeCmd = yes(proc(PSI))
+ MaybeCmd = yes(deep_cmd_proc(PSI))
;
Pieces = ["proc_callers", PSIStr, GroupCallersStr, BunchNumStr],
string.to_int(PSIStr, PSI),
string.to_int(BunchNumStr, BunchNum),
string_to_caller_groups(GroupCallersStr, GroupCallers)
->
- MaybeCmd = yes(proc_callers(PSI, GroupCallers, BunchNum))
+ MaybeCmd = yes(deep_cmd_proc_callers(PSI, GroupCallers, BunchNum))
;
Pieces = ["modules"]
->
- MaybeCmd = yes(modules)
+ MaybeCmd = yes(deep_cmd_modules)
;
Pieces = ["module", ModuleName]
->
- MaybeCmd = yes(module(ModuleName))
+ MaybeCmd = yes(deep_cmd_module(ModuleName))
;
- Pieces = ["top_procs", LimitStr,
- CostKindStr, InclDescStr, ScopeStr],
+ Pieces = ["top_procs", LimitStr, CostKindStr, InclDescStr, ScopeStr],
string_to_limit(LimitStr, Limit),
string_to_cost_kind(CostKindStr, CostKind),
string_to_incl_desc(InclDescStr, InclDesc),
string_to_scope(ScopeStr, Scope)
->
- MaybeCmd = yes(top_procs(Limit, CostKind, InclDesc, Scope))
+ MaybeCmd = yes(deep_cmd_top_procs(Limit, CostKind, InclDesc, Scope))
;
Pieces = ["menu"]
->
- MaybeCmd = yes(menu)
+ MaybeCmd = yes(deep_cmd_menu)
;
Pieces = ["proc_static", PSIStr],
string.to_int(PSIStr, PSI)
->
- MaybeCmd = yes(proc_static(PSI))
+ MaybeCmd = yes(deep_cmd_proc_static(PSI))
;
Pieces = ["proc_dynamic", PDIStr],
string.to_int(PDIStr, PDI)
->
- MaybeCmd = yes(proc_dynamic(PDI))
+ MaybeCmd = yes(deep_cmd_proc_dynamic(PDI))
;
Pieces = ["call_site_static", CSSIStr],
string.to_int(CSSIStr, CSSI)
->
- MaybeCmd = yes(call_site_static(CSSI))
+ MaybeCmd = yes(deep_cmd_call_site_static(CSSI))
;
Pieces = ["call_site_dynamic", CSDIStr],
string.to_int(CSDIStr, CSDI)
->
- MaybeCmd = yes(call_site_dynamic(CSDI))
+ MaybeCmd = yes(deep_cmd_call_site_dynamic(CSDI))
;
Pieces = ["raw_clique", CliqueNumStr],
string.to_int(CliqueNumStr, CliqueNum)
->
- MaybeCmd = yes(raw_clique(CliqueNum))
+ MaybeCmd = yes(deep_cmd_raw_clique(CliqueNum))
;
Pieces = ["timeout", TimeOutStr],
string.to_int(TimeOutStr, TimeOut)
->
- MaybeCmd = yes(timeout(TimeOut))
+ MaybeCmd = yes(deep_cmd_timeout(TimeOut))
;
Pieces = ["restart"]
->
- MaybeCmd = yes(restart)
+ MaybeCmd = yes(deep_cmd_restart)
;
Pieces = ["quit"]
->
- MaybeCmd = yes(quit)
+ MaybeCmd = yes(deep_cmd_quit)
;
MaybeCmd = no
).
@@ -755,9 +816,8 @@
string_to_time_format(TimeStr, Time),
string_to_inactive_items(InactiveItemsStr, InactiveItems)
->
- Preferences = preferences(Fields, Box, Colour,
- MaybeAncestorLimit, Summarize, Order, Contour, Time,
- InactiveItems),
+ Preferences = preferences(Fields, Box, Colour, MaybeAncestorLimit,
+ Summarize, Order, Contour, Time, InactiveItems),
MaybePreferences = yes(Preferences)
;
MaybePreferences = no
@@ -793,6 +853,19 @@
string_to_time_fields("tp", time_and_percall).
string_to_time_fields("qtp", ticks_and_time_and_percall).
+:- func callseqs_fields_to_string(callseqs_fields) = string.
+
+callseqs_fields_to_string(AllocFields) = String :-
+ string_to_callseqs_fields(String, AllocFields).
+
+:- pred string_to_callseqs_fields(string, callseqs_fields).
+:- mode string_to_callseqs_fields(in, out) is semidet.
+:- mode string_to_callseqs_fields(out, in) is det.
+
+string_to_callseqs_fields("_", no_callseqs).
+string_to_callseqs_fields("s", callseqs).
+string_to_callseqs_fields("S", callseqs_and_percall).
+
:- func alloc_fields_to_string(alloc_fields) = string.
alloc_fields_to_string(AllocFields) = String :-
@@ -804,7 +877,7 @@
string_to_alloc_fields("_", no_alloc).
string_to_alloc_fields("a", alloc).
-string_to_alloc_fields("ap", alloc_and_percall).
+string_to_alloc_fields("A", alloc_and_percall).
:- func memory_fields_to_string(memory_fields) = string.
@@ -816,18 +889,20 @@
:- mode string_to_memory_fields(out, in) is det.
string_to_memory_fields("_", no_memory).
-string_to_memory_fields("b", memory(bytes)).
-string_to_memory_fields("w", memory(words)).
-string_to_memory_fields("bp", memory_and_percall(bytes)).
-string_to_memory_fields("wp", memory_and_percall(words)).
+string_to_memory_fields("b", memory(units_bytes)).
+string_to_memory_fields("w", memory(units_words)).
+string_to_memory_fields("B", memory_and_percall(units_bytes)).
+string_to_memory_fields("W", memory_and_percall(units_words)).
:- func fields_to_string(fields) = string.
-fields_to_string(fields(Port, Time, Allocs, Memory)) =
+fields_to_string(fields(Port, Time, CallSeqs, Allocs, Memory)) =
port_fields_to_string(Port) ++
string.char_to_string(field_separator_char) ++
time_fields_to_string(Time) ++
string.char_to_string(field_separator_char) ++
+ callseqs_fields_to_string(CallSeqs) ++
+ string.char_to_string(field_separator_char) ++
alloc_fields_to_string(Allocs) ++
string.char_to_string(field_separator_char) ++
memory_fields_to_string(Memory).
@@ -837,13 +912,14 @@
string_to_fields(FieldsStr, Fields) :-
(
split(FieldsStr, field_separator_char, Pieces),
- Pieces = [PortStr, TimeStr, AllocStr, MemoryStr],
+ Pieces = [PortStr, TimeStr, CallSeqsStr, AllocStr, MemoryStr],
string_to_port_fields(PortStr, Port),
string_to_time_fields(TimeStr, Time),
+ string_to_callseqs_fields(CallSeqsStr, CallSeqs),
string_to_alloc_fields(AllocStr, Alloc),
string_to_memory_fields(MemoryStr, Memory)
->
- Fields = fields(Port, Time, Alloc, Memory)
+ Fields = fields(Port, Time, CallSeqs, Alloc, Memory)
;
fail
).
@@ -871,11 +947,12 @@
:- mode string_to_cost_kind(in, out) is semidet.
:- mode string_to_cost_kind(out, in) is det.
-string_to_cost_kind("calls", calls).
-string_to_cost_kind("redos", redos).
-string_to_cost_kind("time", time).
-string_to_cost_kind("allocs", allocs).
-string_to_cost_kind("words", words).
+string_to_cost_kind("calls", cost_calls).
+string_to_cost_kind("redos", cost_redos).
+string_to_cost_kind("time", cost_time).
+string_to_cost_kind("callseqs", cost_callseqs).
+string_to_cost_kind("allocs", cost_allocs).
+string_to_cost_kind("words", cost_words).
:- func incl_desc_to_string(include_descendants) = string.
@@ -894,7 +971,7 @@
limit_to_string(rank_range(Lo, Hi)) =
string.format("%d%c%d", [i(Lo), c(limit_separator_char), i(Hi)]).
limit_to_string(threshold(Threshold)) =
- string.format("%f", [f(Threshold)]).
+ string.format("%g", [f(Threshold)]).
:- pred string_to_limit(string::in, display_limit::out) is semidet.
@@ -1007,10 +1084,10 @@
:- mode string_to_inactive_items(in, out) is semidet.
:- mode string_to_inactive_items(out, in) is det.
-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)).
+string_to_inactive_items("hh", inactive_items(inactive_hide, inactive_hide)).
+string_to_inactive_items("sh", inactive_items(inactive_show, inactive_hide)).
+string_to_inactive_items("hs", inactive_items(inactive_hide, inactive_show)).
+string_to_inactive_items("ss", inactive_items(inactive_show, inactive_show)).
:- func colour_scheme_to_string(colour_scheme) = string.
@@ -1021,8 +1098,8 @@
:- mode string_to_colour_scheme(in, out) is semidet.
:- mode string_to_colour_scheme(out, in) is det.
-string_to_colour_scheme("cols", column_groups).
-string_to_colour_scheme("none", none).
+string_to_colour_scheme("cols", colour_column_groups).
+string_to_colour_scheme("none", colour_none).
:- func box_to_string(box) = string.
Index: mdprof_cgi.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/deep_profiler/mdprof_cgi.m,v
retrieving revision 1.15
diff -u -b -r1.15 mdprof_cgi.m
--- mdprof_cgi.m 8 Jun 2006 02:53:20 -0000 1.15
+++ mdprof_cgi.m 11 Oct 2006 03:53:40 -0000
@@ -74,13 +74,13 @@
),
split(QueryString0, query_separator_char, Pieces),
( Pieces = [CmdStr, PrefStr, FileName] ->
- Cmd = url_component_to_cmd(CmdStr, menu),
+ Cmd = url_component_to_cmd(CmdStr, deep_cmd_menu),
process_query(Cmd, yes(PrefStr), FileName, Options, !IO)
; Pieces = [CmdStr, FileName] ->
- Cmd = url_component_to_cmd(CmdStr, menu),
+ Cmd = url_component_to_cmd(CmdStr, deep_cmd_menu),
process_query(Cmd, no, FileName, Options, !IO)
; Pieces = [FileName] ->
- process_query(menu, no, FileName, Options, !IO)
+ process_query(deep_cmd_menu, no, FileName, Options, !IO)
;
io.set_exit_status(1, !IO),
% Give the simplest URL in the error message.
@@ -197,7 +197,7 @@
:- pred process_query(cmd::in, maybe(string)::in, string::in,
option_table::in, io::di, io::uo) is cc_multi.
-process_query(Cmd, MaybePrefStr, DataFileName, Options, !IO) :-
+process_query(Cmd, MaybePrefStr, DataFileName0, Options0, !IO) :-
(
MaybePrefStr = yes(PrefStr),
MaybePref = url_component_to_maybe_pref(PrefStr)
@@ -206,10 +206,18 @@
MaybePref = no
),
(
- MaybePref = yes(Pref)
+ MaybePref = yes(Pref),
+ PrefInd = given_pref(Pref)
;
MaybePref = no,
- Pref = default_preferences
+ PrefInd = default_pref
+ ),
+ ( string.remove_suffix(DataFileName0, ".localhost", DataFileNamePrime) ->
+ DataFileName = DataFileNamePrime,
+ map.det_update(Options0, localhost, bool(yes), Options)
+ ;
+ DataFileName = DataFileName0,
+ Options = Options0
),
ToServerPipe = to_server_pipe_name(DataFileName),
FromServerPipe = from_server_pipe_name(DataFileName),
@@ -229,13 +237,12 @@
),
check_for_existing_fifos(ToServerPipe, FromServerPipe, FifoCount, !IO),
( FifoCount = 0 ->
- handle_query_from_new_server(Cmd, Pref, DataFileName,
- ToServerPipe, FromServerPipe, StartupFile,
- MutexFile, WantFile, Options, !IO)
+ handle_query_from_new_server(Cmd, PrefInd, DataFileName,
+ ToServerPipe, FromServerPipe, StartupFile, MutexFile, WantFile,
+ Options, !IO)
; FifoCount = 2 ->
- handle_query_from_existing_server(Cmd, Pref,
- ToServerPipe, FromServerPipe,
- MutexFile, WantFile, Options, !IO)
+ handle_query_from_existing_server(Cmd, PrefInd,
+ ToServerPipe, FromServerPipe, MutexFile, WantFile, Options, !IO)
;
release_lock(Debug, MutexFile, !IO),
remove_want_file(WantFile, !IO),
@@ -246,19 +253,43 @@
% Handle the given query using the existing server. Delete the mutex and
% want files when we get out of the critical region.
%
-:- pred handle_query_from_existing_server(cmd::in, preferences::in,
+:- pred handle_query_from_existing_server(cmd::in, preferences_indication::in,
string::in, string::in, string::in, string::in, option_table::in,
io::di, io::uo) is det.
-handle_query_from_existing_server(Cmd, Pref, ToServerPipe, FromServerPipe,
+handle_query_from_existing_server(Cmd, PrefInd, ToServerPipe, FromServerPipe,
MutexFile, WantFile, Options, !IO) :-
lookup_bool_option(Options, debug, Debug),
- send_term(ToServerPipe, Debug, cmd_pref(Cmd, Pref), !IO),
+ trace [compiletime(flag("debug_client_server")), io(!S)] (
+ io.open_append("/tmp/deep_debug", Res1, !S),
+ ( Res1 = ok(DebugStream1) ->
+ io.write_string(DebugStream1,
+ "sending query to existing server.\n", !S),
+ io.write(DebugStream1, cmd_pref(Cmd, PrefInd), !S),
+ io.close_output(DebugStream1, !S)
+ ;
+ true
+ )
+ ),
+ send_term(ToServerPipe, Debug, cmd_pref(Cmd, PrefInd), !IO),
release_lock(Debug, MutexFile, !IO),
remove_want_file(WantFile, !IO),
recv_string(FromServerPipe, Debug, ResponseFileName, !IO),
CatCmd = string.format("cat %s", [s(ResponseFileName)]),
io.call_system(CatCmd, _, !IO),
+ trace [compiletime(flag("debug_client_server")), io(!T)] (
+ io.open_append("/tmp/deep_debug", Res2, !T),
+ ( Res2 = ok(DebugStream2) ->
+ io.write_string(DebugStream2,
+ "sending reply from existing server.\n", !T),
+ io.close_output(DebugStream2, !T),
+ DebugCatCmd = string.format("cat %s >> /tmp/deep_debug",
+ [s(ResponseFileName)]),
+ io.call_system(DebugCatCmd, _, !T)
+ ;
+ true
+ )
+ ),
(
Debug = yes
% Leave the response file to be examined.
@@ -270,13 +301,21 @@
% Handle the given query and then become the new server. Delete the mutex
% and want files when we get out of the critical region.
%
-:- pred handle_query_from_new_server(cmd::in, preferences::in, string::in,
- string::in, string::in, string::in, string::in, string::in,
+:- pred handle_query_from_new_server(cmd::in, preferences_indication::in,
+ string::in, string::in, string::in, string::in, string::in, string::in,
option_table::in, io::di, io::uo) is cc_multi.
-handle_query_from_new_server(Cmd, Pref, FileName, ToServerPipe, FromServerPipe,
- StartupFile, MutexFile, WantFile, Options, !IO) :-
- server_name(Machine, !IO),
+handle_query_from_new_server(Cmd, PrefInd, FileName,
+ ToServerPipe, FromServerPipe, StartupFile, MutexFile, WantFile,
+ Options, !IO) :-
+ lookup_bool_option(Options, localhost, LocalHost),
+ (
+ LocalHost = no,
+ server_name(Machine, !IO)
+ ;
+ LocalHost = yes,
+ Machine = "localhost"
+ ),
lookup_bool_option(Options, canonical_clique, Canonical),
lookup_bool_option(Options, server_process, ServerProcess),
lookup_bool_option(Options, debug, Debug),
@@ -297,16 +336,16 @@
MaybeStartupStream = no
),
read_and_startup(Machine, [FileName], Canonical, MaybeStartupStream,
- [], Res, !IO),
+ [], [], Res, !IO),
(
Res = ok(Deep),
+ Pref = solidify_preference(Deep, PrefInd),
try_exec(Cmd, Pref, Deep, HTML, !IO),
(
MaybeStartupStream = yes(StartupStream1),
io.format(StartupStream1, "query 0 output:\n%s\n", [s(HTML)], !IO),
- % If we don't flush the output before the fork, it will
- % be flushed twice, once by the parent process and
- % once by the child process.
+ % If we don't flush the output before the fork, it will be flushed
+ % twice, once by the parent process and once by the child process.
io.flush_output(StartupStream1, !IO)
;
MaybeStartupStream = no
@@ -363,7 +402,8 @@
DetachProcess = yes,
detach_process(DetachRes, !IO)
),
- ( DetachRes = in_child(ChildHasParent) ->
+ (
+ DetachRes = in_child(ChildHasParent),
% We are in the child; start serving queries.
(
ChildHasParent = child_has_parent,
@@ -407,7 +447,8 @@
lookup_bool_option(Options, canonical_clique, Canonical),
server_loop(ToServerPipe, FromServerPipe, TimeOut,
MaybeDebugStream, Debug, Canonical, 0, Deep, !IO)
- ; DetachRes = in_parent ->
+ ;
+ DetachRes = in_parent,
% We are in the parent after we spawned the child. We cause the process
% to exit simply by not calling server_loop.
%
@@ -416,6 +457,7 @@
release_lock(Debug, MutexFile, !IO),
remove_want_file(WantFile, !IO)
;
+ DetachRes = fork_failed,
% We are in the parent because the fork failed. Again we cause
% the process to exit simply by not calling server_loop, but we also
% report the failure through the exit status. We don't report it
@@ -447,19 +489,21 @@
;
MaybeStartupStream = no
),
- CmdPref0 = cmd_pref(Cmd0, Pref0),
- ( Cmd0 = restart ->
+ CmdPref0 = cmd_pref(Cmd0, PrefInd0),
+ Pref0 = solidify_preference(Deep, PrefInd0),
+
+ ( Cmd0 = deep_cmd_restart ->
read_and_startup(Deep0 ^ server_name, [Deep0 ^ data_file_name],
- Canonical, MaybeStartupStream, [], MaybeDeep, !IO),
+ Canonical, MaybeStartupStream, [], [], MaybeDeep, !IO),
(
MaybeDeep = ok(Deep),
MaybeMsg = no,
- Cmd = menu
+ Cmd = deep_cmd_menu
;
MaybeDeep = error(ErrorMsg),
MaybeMsg = yes(ErrorMsg),
Deep = Deep0,
- Cmd = quit
+ Cmd = deep_cmd_quit
)
;
Deep = Deep0,
@@ -495,13 +539,13 @@
MaybeStartupStream = no
),
- ( Cmd = quit ->
+ ( Cmd = deep_cmd_quit ->
% The lack of a recursive call here shuts down the server.
%
% This deletes all the files created by the process, including
% WantFile and MutexFile, with MutexFile being deleted last.
delete_cleanup_files(!IO)
- ; Cmd = timeout(TimeOut) ->
+ ; Cmd = deep_cmd_timeout(TimeOut) ->
server_loop(ToServerPipe, FromServerPipe, TimeOut, MaybeStartupStream,
Debug, Canonical, QueryNum, Deep, !IO)
;
@@ -654,6 +698,7 @@
; debug
; detach_process
; help
+ ; localhost
; modules
; proc
; quit
@@ -665,7 +710,6 @@
; version
; write_query_string.
-:- type options ---> options.
:- type option_table == (option_table(option)).
:- pred short(char::in, option::out) is semidet.
@@ -688,6 +732,7 @@
long("debug", debug).
long("detach-process", detach_process).
long("help", help).
+long("localhost", localhost).
long("modules", modules).
long("proc", proc).
long("quit", quit).
@@ -706,6 +751,7 @@
defaults(debug, bool(no)).
defaults(detach_process, bool(yes)).
defaults(help, bool(no)).
+defaults(localhost, bool(no)).
defaults(modules, bool(no)).
defaults(proc, int(0)).
defaults(quit, bool(no)).
@@ -726,17 +772,17 @@
lookup_int_option(Options, clique, CliqueNum),
lookup_int_option(Options, proc, ProcNum),
( Root = yes ->
- Cmd = root(no)
+ Cmd = deep_cmd_root(no)
; Modules = yes ->
- Cmd = modules
+ Cmd = deep_cmd_modules
; CliqueNum > 0 ->
- Cmd = clique(CliqueNum)
+ Cmd = deep_cmd_clique(CliqueNum)
; ProcNum > 0 ->
- Cmd = proc(ProcNum)
+ Cmd = deep_cmd_proc(ProcNum)
; Quit = yes ->
- Cmd = quit
+ Cmd = deep_cmd_quit
;
- Cmd = menu
+ Cmd = deep_cmd_menu
).
%-----------------------------------------------------------------------------%
Index: mdprof_dump.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/deep_profiler/mdprof_dump.m,v
retrieving revision 1.5
diff -u -b -r1.5 mdprof_dump.m
--- mdprof_dump.m 9 Oct 2006 08:09:04 -0000 1.5
+++ mdprof_dump.m 11 Oct 2006 03:49:04 -0000
@@ -79,37 +79,11 @@
:- pred main_2(option_table(option)::in, string::in, io::di, io::uo) is det.
main_2(Options, FileName, !IO) :-
- getopt.lookup_bool_option(Options, restrict_statics, Restrict),
- getopt.lookup_bool_option(Options, dump_prof_stats, ProfStats0),
- getopt.lookup_bool_option(Options, dump_call_site_dynamics, DumpCSDs0),
- getopt.lookup_bool_option(Options, dump_proc_dynamics, DumpPDs0),
- getopt.lookup_bool_option(Options, dump_call_site_statics, DumpCSSs0),
- getopt.lookup_bool_option(Options, dump_proc_statics, DumpPSs0),
- % If the user doesn't say what he/she wants, they dump everything.
- (
- ProfStats0 = no,
- DumpCSDs0 = no,
- DumpPDs0 = no,
- DumpCSSs0 = no,
- DumpPSs0 = no
- ->
- ProfStats = yes,
- DumpCSDs = yes,
- DumpPDs = yes,
- DumpCSSs = yes,
- DumpPSs = yes
- ;
- ProfStats = ProfStats0,
- DumpCSDs = DumpCSDs0,
- DumpPDs = DumpPDs0,
- DumpCSSs = DumpCSSs0,
- DumpPSs = DumpPSs0
- ),
+ getopt.lookup_accumulating_option(Options, dump_options, DumpOptions),
read_call_graph(FileName, MaybeInitialDeep, !IO),
(
MaybeInitialDeep = ok(InitialDeep),
- dump_initial_deep(ProfStats, Restrict, DumpCSDs, DumpPDs,
- DumpCSSs, DumpPSs, InitialDeep, !IO)
+ dump_initial_deep(InitialDeep, DumpOptions, !IO)
;
MaybeInitialDeep = error(Msg),
io.format("Cannot read %s: %s\n", [s(Msg), s(FileName)], !IO)
@@ -122,42 +96,24 @@
:- type option
---> help
- ; dump_prof_stats
- ; dump_call_site_dynamics
- ; dump_proc_dynamics
- ; dump_call_site_statics
- ; dump_proc_statics
- ; restrict_statics.
+ ; dump_options.
:- type option_table == (option_table(option)).
:- pred short_option(char::in, option::out) is semidet.
short_option('h', help).
+short_option('D', dump_options).
:- pred long_option(string::in, option::out) is semidet.
long_option("help", help).
-long_option("prof-stats", dump_prof_stats).
-long_option("call-site-dynamics", dump_call_site_dynamics).
-long_option("csd", dump_call_site_dynamics).
-long_option("proc-dynamics", dump_proc_dynamics).
-long_option("pd", dump_proc_dynamics).
-long_option("call-site-statics", dump_call_site_statics).
-long_option("css", dump_call_site_statics).
-long_option("proc-statics", dump_proc_statics).
-long_option("ps", dump_proc_statics).
-long_option("restrict-statics", restrict_statics).
+long_option("dump-options", dump_options).
:- pred defaults(option::out, option_data::out) is multi.
defaults(help, bool(no)).
-defaults(dump_prof_stats, bool(no)).
-defaults(dump_call_site_dynamics, bool(no)).
-defaults(dump_proc_dynamics, bool(no)).
-defaults(dump_call_site_statics, bool(no)).
-defaults(dump_proc_statics, bool(no)).
-defaults(restrict_statics, bool(no)).
+defaults(dump_options, accumulating([])).
%----------------------------------------------------------------------------%
@@ -165,23 +121,33 @@
usage(ProgName, !IO) :-
io.stderr_stream(StdErr, !IO),
- io.format(StdErr, "Usage: %s [<options>] [filename]\n", [s(ProgName)],
+ io.format(StdErr, "Usage: %s [-h] [-D what] [filename]\n", [s(ProgName)],
!IO),
- io.write_string(StdErr, "Options:\n", !IO),
- io.write_string(StdErr, "\t-h, --help\n", !IO),
- io.write_string(StdErr, "\t\tDisplay this message.\n", !IO),
- io.write_string(StdErr, "\t--csd, --call-site-dynamics\n", !IO),
- io.write_string(StdErr, "\t\tDump call-site dynamics.\n", !IO),
- io.write_string(StdErr, "\t--pd, --proc-dynamics\n", !IO),
- io.write_string(StdErr, "\t\tDump proc dynamics.\n", !IO),
- io.write_string(StdErr, "\t--css, --call-site-statics\n", !IO),
- io.write_string(StdErr, "\t\tDump call-site statics.\n", !IO),
- io.write_string(StdErr, "\t--ps, --proc-statics\n", !IO),
- io.write_string(StdErr, "\t\tDump proc statics.\n", !IO),
- io.write_string(StdErr, "\t--restrict-statics\n", !IO),
- io.write_string(StdErr, "\t\tOnly dump those proc and ", !IO),
- io.write_string(StdErr, "call-site statics that are referenced ", !IO),
- io.write_string(StdErr, "from the proc dynamics\n", !IO).
+ io.write_string(StdErr, options_description, !IO).
+
+:- func options_description = string.
+
+options_description =
+ "Options:\n" ++
+ "\t-h, --help\n" ++
+ "\t\tDisplay this message.\n" ++
+ "\t--D csd\n" ++
+ "\t\tDump call-site dynamics.\n" ++
+ "\t--D pd\n" ++
+ "\t\tDump proc dynamics.\n" ++
+ "\t--D css\n" ++
+ "\t\tDump call-site statics.\n" ++
+ "\t--D ps\n" ++
+ "\t\tDump proc statics.\n" ++
+ "\t--D restrict\n" ++
+ "\t\tDo not dump proc and call-site statics that are\n" ++
+ "\t\tnot referenced from the proc dynamics\n" ++
+ "\t--D clique\n" ++
+ "\t\tDump information about cliques.\n" ++
+ "\t--D rev\n" ++
+ "\t\tDump reverse links.\n" ++
+ "\t--D prop\n" ++
+ "\t\tDump propagated measurement information.\n".
%----------------------------------------------------------------------------%
:- end_module mdprof_dump.
Index: mdprof_test.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/deep_profiler/mdprof_test.m,v
retrieving revision 1.11
diff -u -b -r1.11 mdprof_test.m
--- mdprof_test.m 29 Mar 2006 08:07:40 -0000 1.11
+++ mdprof_test.m 11 Oct 2006 03:49:04 -0000
@@ -102,6 +102,7 @@
lookup_bool_option(Options, canonical_clique, Canonical),
lookup_bool_option(Options, verbose, Verbose),
lookup_accumulating_option(Options, dump, DumpStages),
+ lookup_accumulating_option(Options, dump_options, DumpOptions),
server_name(Machine, !IO),
(
Verbose = no,
@@ -112,7 +113,7 @@
MaybeOutput = yes(Stdout)
),
read_and_startup(Machine, [FileName], Canonical, MaybeOutput,
- DumpStages, Res, !IO),
+ DumpStages, DumpOptions, Res, !IO),
(
Res = ok(Deep),
lookup_bool_option(Options, test, Test),
@@ -121,7 +122,7 @@
;
Test = yes,
lookup_string_option(Options, test_dir, TestDir),
- test_server(TestDir, default_preferences, Deep, !IO)
+ test_server(TestDir, default_preferences(Deep), Deep, !IO)
)
;
Res = error(Error),
@@ -164,7 +165,7 @@
verify_profile_2(ProgName, Options, FileName, !IO) :-
lookup_bool_option(Options, canonical_clique, Canonical),
Machine = "dummy_server", % For verification this doesn't matter.
- read_and_startup(Machine, [FileName], Canonical, no, [], Res, !IO),
+ read_and_startup(Machine, [FileName], Canonical, no, [], [], Res, !IO),
(
Res = ok(_Deep)
;
@@ -226,7 +227,7 @@
test_cliques(Cur, Max, DirName, Pref, Deep, !IO) :-
( Cur =< Max ->
- try_exec(clique(Cur), Pref, Deep, HTML, !IO),
+ try_exec(deep_cmd_clique(Cur), Pref, Deep, HTML, !IO),
write_test_html(DirName, "clique", Cur, HTML, !IO),
test_cliques(Cur + 1, Max, DirName, Pref, Deep, !IO)
;
@@ -238,7 +239,7 @@
test_procs(Cur, Max, DirName, Pref, Deep, !IO) :-
( Cur =< Max ->
- try_exec(proc(Cur), Pref, Deep, HTML, !IO),
+ try_exec(deep_cmd_proc(Cur), Pref, Deep, HTML, !IO),
write_test_html(DirName, "proc", Cur, HTML, !IO),
test_procs(Cur + 1, Max, DirName, Pref, Deep, !IO)
;
@@ -285,6 +286,7 @@
:- type option
---> canonical_clique
; dump
+ ; dump_options
; flat
; help
; test
@@ -300,14 +302,15 @@
short('c', canonical_clique).
short('d', dump).
-short('v', verbose).
-short('D', test_dir).
+short('D', dump_options).
short('T', test).
+short('v', verbose).
:- pred long(string::in, option::out) is semidet.
long("canonical-clique", canonical_clique).
long("dump", dump).
+long("dump-options", dump_options).
long("help", help).
long("test", test).
long("test-dir", test_dir).
@@ -319,6 +322,7 @@
defaults(canonical_clique, bool(no)).
defaults(dump, accumulating([])).
+defaults(dump_options, accumulating([])).
defaults(help, bool(no)).
defaults(test, bool(no)).
defaults(test_dir, string("deep_test")).
Index: measurements.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/deep_profiler/measurements.m,v
retrieving revision 1.11
diff -u -b -r1.11 measurements.m
--- measurements.m 4 Oct 2006 06:59:17 -0000 1.11
+++ measurements.m 11 Oct 2006 03:49:04 -0000
@@ -30,19 +30,23 @@
:- func redos(own_prof_info) = int.
:- func excps(own_prof_info) = int.
:- func quanta(own_prof_info) = int.
-:- func call_seqs(own_prof_info) = int.
+:- func callseqs(own_prof_info) = int.
:- func allocs(own_prof_info) = int.
:- func words(own_prof_info) = int.
:- func zero_own_prof_info = own_prof_info.
+:- pred is_zero_own_prof_info(own_prof_info::in) is semidet.
+
:- func inherit_quanta(inherit_prof_info) = int.
-:- func inherit_call_seqs(inherit_prof_info) = int.
+:- func inherit_callseqs(inherit_prof_info) = int.
:- func inherit_allocs(inherit_prof_info) = int.
:- func inherit_words(inherit_prof_info) = int.
:- func zero_inherit_prof_info = inherit_prof_info.
+:- pred is_zero_inherit_prof_info(inherit_prof_info::in) is semidet.
+
:- func add_inherit_to_inherit(inherit_prof_info, inherit_prof_info)
= inherit_prof_info.
:- func add_own_to_inherit(own_prof_info, inherit_prof_info)
@@ -89,7 +93,7 @@
opa_redos :: int,
opa_excps :: int,
opa_quanta :: int,
- opa_call_seqs :: int,
+ opa_callseqs :: int,
opa_allocs :: int,
opa_words :: int
)
@@ -98,7 +102,7 @@
; own_prof_det(
opd_exits :: int,
opd_quanta :: int,
- opd_call_seqs :: int,
+ opd_callseqs :: int,
opd_allocs :: int,
opd_words :: int
)
@@ -107,7 +111,7 @@
; own_prof_fast_det(
opfd_exits :: int,
- opfd_call_seqs :: int,
+ opfd_callseqs :: int,
opfd_allocs :: int,
opfd_words :: int
)
@@ -118,7 +122,7 @@
; own_prof_fast_nomem_semi(
opfns_exits :: int,
opfns_fails :: int,
- opfns_call_seqs :: int
+ opfns_callseqs :: int
).
% implicit redos == excps == 0
% implicit calls == exits + fails
@@ -128,7 +132,7 @@
:- type inherit_prof_info
---> inherit_prof_info(
ipo_quanta :: int,
- ipo_call_seqs :: int,
+ ipo_callseqs :: int,
ipo_allocs :: int,
ipo_words :: int
).
@@ -138,7 +142,7 @@
fails(own_prof_fast_nomem_semi(_, Fails, _)) = Fails.
redos(own_prof_fast_nomem_semi(_, _, _)) = 0.
excps(own_prof_fast_nomem_semi(_, _, _)) = 0.
-call_seqs(own_prof_fast_nomem_semi(_, _, CallSeqs)) = CallSeqs.
+callseqs(own_prof_fast_nomem_semi(_, _, CallSeqs)) = CallSeqs.
quanta(own_prof_fast_nomem_semi(_, _, _)) = 0.
allocs(own_prof_fast_nomem_semi(_, _, _)) = 0.
words(own_prof_fast_nomem_semi(_, _, _)) = 0.
@@ -149,7 +153,7 @@
redos(own_prof_fast_det(_, _, _, _)) = 0.
excps(own_prof_fast_det(_, _, _, _)) = 0.
quanta(own_prof_fast_det(_, _, _, _)) = 0.
-call_seqs(own_prof_fast_det(_, CallSeqs, _, _)) = CallSeqs.
+callseqs(own_prof_fast_det(_, CallSeqs, _, _)) = CallSeqs.
allocs(own_prof_fast_det(_, _, Allocs, _)) = Allocs.
words(own_prof_fast_det(_, _, _, Words)) = Words.
@@ -159,7 +163,7 @@
redos(own_prof_det(_, _, _, _, _)) = 0.
excps(own_prof_det(_, _, _, _, _)) = 0.
quanta(own_prof_det(_, Quanta, _, _, _)) = Quanta.
-call_seqs(own_prof_det(_, _, CallSeqs, _, _)) = CallSeqs.
+callseqs(own_prof_det(_, _, CallSeqs, _, _)) = CallSeqs.
allocs(own_prof_det(_, _, _, Allocs, _)) = Allocs.
words(own_prof_det(_, _, _, _, Words)) = Words.
@@ -170,43 +174,50 @@
redos(own_prof_all(_, _, Redos, _, _, _, _, _)) = Redos.
excps(own_prof_all(_, _, _, Excps, _, _, _, _)) = Excps.
quanta(own_prof_all(_, _, _, _, Quanta, _, _, _)) = Quanta.
-call_seqs(own_prof_all(_, _, _, _, CallSeqs, _, _, _)) = CallSeqs.
+callseqs(own_prof_all(_, _, _, _, _, CallSeqs, _, _)) = CallSeqs.
allocs(own_prof_all(_, _, _, _, _, _, Allocs, _)) = Allocs.
words(own_prof_all(_, _, _, _, _, _, _, Words)) = Words.
zero_own_prof_info = own_prof_fast_nomem_semi(0, 0, 0).
+is_zero_own_prof_info(own_prof_all(0, 0, 0, 0, 0, 0, 0, 0)).
+is_zero_own_prof_info(own_prof_det(0, 0, 0, 0, 0)).
+is_zero_own_prof_info(own_prof_fast_det(0, 0, 0, 0)).
+is_zero_own_prof_info(own_prof_fast_nomem_semi(0, 0, 0)).
+
inherit_quanta(inherit_prof_info(Quanta, _, _, _)) = Quanta.
-inherit_call_seqs(inherit_prof_info(_, CallSeqs, _, _)) = CallSeqs.
+inherit_callseqs(inherit_prof_info(_, CallSeqs, _, _)) = CallSeqs.
inherit_allocs(inherit_prof_info(_, _, Allocs, _)) = Allocs.
inherit_words(inherit_prof_info(_, _, _, Words)) = Words.
zero_inherit_prof_info = inherit_prof_info(0, 0, 0, 0).
+is_zero_inherit_prof_info(inherit_prof_info(0, 0, 0, 0)).
+
add_inherit_to_inherit(PI1, PI2) = SumPI :-
Quanta = inherit_quanta(PI1) + inherit_quanta(PI2),
- CallSeqs = inherit_call_seqs(PI1) + inherit_call_seqs(PI2),
+ CallSeqs = inherit_callseqs(PI1) + inherit_callseqs(PI2),
Allocs = inherit_allocs(PI1) + inherit_allocs(PI2),
Words = inherit_words(PI1) + inherit_words(PI2),
SumPI = inherit_prof_info(Quanta, CallSeqs, Allocs, Words).
add_own_to_inherit(PI1, PI2) = SumPI :-
Quanta = quanta(PI1) + inherit_quanta(PI2),
- CallSeqs = call_seqs(PI1) + inherit_call_seqs(PI2),
+ CallSeqs = callseqs(PI1) + inherit_callseqs(PI2),
Allocs = allocs(PI1) + inherit_allocs(PI2),
Words = words(PI1) + inherit_words(PI2),
SumPI = inherit_prof_info(Quanta, CallSeqs, Allocs, Words).
subtract_own_from_inherit(PI1, PI2) = SumPI :-
Quanta = inherit_quanta(PI2) - quanta(PI1),
- CallSeqs = inherit_call_seqs(PI2) - call_seqs(PI1),
+ CallSeqs = inherit_callseqs(PI2) - callseqs(PI1),
Allocs = inherit_allocs(PI2) - allocs(PI1),
Words = inherit_words(PI2) - words(PI1),
SumPI = inherit_prof_info(Quanta, CallSeqs, Allocs, Words).
subtract_inherit_from_inherit(PI1, PI2) = SumPI :-
Quanta = inherit_quanta(PI2) - inherit_quanta(PI1),
- CallSeqs = inherit_call_seqs(PI2) - inherit_call_seqs(PI1),
+ CallSeqs = inherit_callseqs(PI2) - inherit_callseqs(PI1),
Allocs = inherit_allocs(PI2) - inherit_allocs(PI1),
Words = inherit_words(PI2) - inherit_words(PI1),
SumPI = inherit_prof_info(Quanta, CallSeqs, Allocs, Words).
@@ -217,11 +228,11 @@
Redos = redos(PI2),
Excps = excps(PI2),
Quanta = inherit_quanta(PI1) + quanta(PI2),
- CallSeqs = inherit_call_seqs(PI1) + call_seqs(PI2),
+ CallSeqs = inherit_callseqs(PI1) + callseqs(PI2),
Allocs = inherit_allocs(PI1) + allocs(PI2),
Words = inherit_words(PI1) + words(PI2),
- SumPI = compress_profile(Exits, Fails, Redos, Excps, Quanta, CallSeqs,
- Allocs, Words).
+ SumPI = compress_profile(Exits, Fails, Redos, Excps,
+ Quanta, CallSeqs, Allocs, Words).
add_own_to_own(PI1, PI2) = SumPI :-
Exits = exits(PI1) + exits(PI2),
@@ -229,11 +240,11 @@
Redos = redos(PI1) + redos(PI2),
Excps = excps(PI1) + excps(PI2),
Quanta = quanta(PI1) + quanta(PI2),
- CallSeqs = call_seqs(PI1) + call_seqs(PI2),
+ CallSeqs = callseqs(PI1) + callseqs(PI2),
Allocs = allocs(PI1) + allocs(PI2),
Words = words(PI1) + words(PI2),
- SumPI = compress_profile(Exits, Fails, Redos, Excps, Quanta, CallSeqs,
- Allocs, Words).
+ SumPI = compress_profile(Exits, Fails, Redos, Excps,
+ Quanta, CallSeqs, Allocs, Words).
sum_own_infos(Owns) =
list.foldl(add_own_to_own, Owns, zero_own_prof_info).
@@ -319,7 +330,7 @@
(
Own = own_prof_all(Exits, Fails, Redos, Excps, Quanta, CallSeqs,
Allocs, Words),
- Calls = Exits + Fails + Redos
+ Calls = Exits + Fails - Redos
;
Own = own_prof_det(Exits, Quanta, CallSeqs, Allocs, Words),
Calls = Exits,
Index: profile.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/deep_profiler/profile.m,v
retrieving revision 1.14
diff -u -b -r1.14 profile.m
--- profile.m 5 Oct 2006 04:37:51 -0000 1.14
+++ profile.m 11 Oct 2006 03:49:04 -0000
@@ -38,10 +38,10 @@
max_css :: int,
max_pd :: int,
max_ps :: int,
- num_callseqs :: int,
ticks_per_sec :: int,
instrument_quanta :: int,
user_quanta :: int,
+ num_callseqs :: int,
word_size :: int,
canonical :: bool
).
@@ -85,8 +85,7 @@
% index: call_site_dynamic_ptr int
% Reverse links.
- proc_callers :: array(
- list(call_site_dynamic_ptr)),
+ proc_callers :: array(list(call_site_dynamic_ptr)),
% index: proc_static_ptr int
call_site_static_map :: call_site_static_map,
% index: call_site_dynamic_ptr int
@@ -94,7 +93,7 @@
list(call_site_dynamic_ptr))),
% index: call_site_static_ptr int
- % Propagated timing info.
+ % Propagated measurements.
pd_own :: array(own_prof_info),
pd_desc :: array(inherit_prof_info),
csd_desc :: array(inherit_prof_info),
Index: query.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/deep_profiler/query.m,v
retrieving revision 1.13
diff -u -b -r1.13 query.m
--- query.m 29 Sep 2006 06:15:11 -0000 1.13
+++ query.m 11 Oct 2006 03:49:04 -0000
@@ -68,29 +68,27 @@
;
Msg = "unknown exception"
),
- HTML = string.format(
- "<H3>AN EXCEPTION HAS OCCURRED: %s</H3>\n",
+ HTML = string.format("<H3>AN EXCEPTION HAS OCCURRED: %s</H3>\n",
[s(Msg)])
).
:- pred exec(cmd::in, preferences::in, deep::in, string::out,
io::di, io::uo) is det.
-exec(restart, _Pref, _Deep, _HTML, !IO) :-
+exec(deep_cmd_restart, _Pref, _Deep, _HTML, !IO) :-
% Our caller is supposed to filter out restart commands.
error("exec: found restart command").
-exec(quit, _Pref, Deep, HTML, !IO) :-
+exec(deep_cmd_quit, _Pref, Deep, HTML, !IO) :-
HTML = string.format(
"<H3>Shutting down deep profile server for %s.</H3>\n",
[s(Deep ^ data_file_name)]).
-exec(timeout(TimeOut), _Pref, _Deep, HTML, !IO) :-
- HTML = string.format("<H3>Timeout set to %d minutes</H3>\n",
- [i(TimeOut)]).
+exec(deep_cmd_timeout(TimeOut), _Pref, _Deep, HTML, !IO) :-
+ HTML = string.format("<H3>Timeout set to %d minutes</H3>\n", [i(TimeOut)]).
exec(Cmd, Pref, Deep, HTML, !IO) :-
- Cmd = menu,
+ Cmd = deep_cmd_menu,
HTML = generate_menu_page(Cmd, Pref, Deep).
exec(Cmd, Pref, Deep, HTML, !IO) :-
- Cmd = root(MaybePercent),
+ Cmd = deep_cmd_root(MaybePercent),
deep_lookup_clique_index(Deep, Deep ^ root, RootCliquePtr),
RootCliquePtr = clique_ptr(RootCliqueNum),
(
@@ -101,7 +99,7 @@
generate_clique_page(Cmd, RootCliqueNum, Pref, Deep, HTML, 100, _)
).
exec(Cmd, Pref, Deep, HTML, !IO) :-
- Cmd = clique(CliqueNum),
+ Cmd = deep_cmd_clique(CliqueNum),
CliquePtr = clique_ptr(CliqueNum),
( valid_clique_ptr(Deep, CliquePtr) ->
generate_clique_page(Cmd, CliqueNum, Pref, Deep, HTML, 100, _)
@@ -112,7 +110,7 @@
page_footer(Cmd, Pref, Deep)
).
exec(Cmd, Pref, Deep, HTML, !IO) :-
- Cmd = proc(PSI),
+ Cmd = deep_cmd_proc(PSI),
PSPtr = proc_static_ptr(PSI),
( valid_proc_static_ptr(Deep, PSPtr) ->
HTML = generate_proc_page(Cmd, PSPtr, Pref, Deep)
@@ -123,7 +121,7 @@
page_footer(Cmd, Pref, Deep)
).
exec(Cmd, Pref, Deep, HTML, !IO) :-
- Cmd = proc_callers(PSI, CallerGroups, BunchNum),
+ Cmd = deep_cmd_proc_callers(PSI, CallerGroups, BunchNum),
PSPtr = proc_static_ptr(PSI),
( valid_proc_static_ptr(Deep, PSPtr) ->
generate_proc_callers_page(Cmd, PSPtr, CallerGroups, BunchNum,
@@ -135,10 +133,10 @@
page_footer(Cmd, Pref, Deep)
).
exec(Cmd, Pref, Deep, HTML, !IO) :-
- Cmd = modules,
+ Cmd = deep_cmd_modules,
HTML = generate_modules_page(Cmd, Pref, Deep).
exec(Cmd, Pref, Deep, HTML, !IO) :-
- Cmd = module(ModuleName),
+ Cmd = deep_cmd_module(ModuleName),
( map.search(Deep ^ module_data, ModuleName, ModuleData) ->
HTML = generate_module_page(Cmd, ModuleName, ModuleData, Pref, Deep)
;
@@ -148,18 +146,18 @@
page_footer(Cmd, Pref, Deep)
).
exec(Cmd, Pref, Deep, HTML, !IO) :-
- Cmd = top_procs(Limit, CostKind, InclDesc, Scope),
+ Cmd = deep_cmd_top_procs(Limit, CostKind, InclDesc, Scope),
HTML = generate_top_procs_page(Cmd, Limit, CostKind, InclDesc, Scope,
Pref, Deep).
-exec(proc_static(PSI), _Pref, Deep, HTML, !IO) :-
+exec(deep_cmd_proc_static(PSI), _Pref, Deep, HTML, !IO) :-
HTML = generate_proc_static_debug_page(PSI, Deep).
-exec(proc_dynamic(PDI), _Pref, Deep, HTML, !IO) :-
+exec(deep_cmd_proc_dynamic(PDI), _Pref, Deep, HTML, !IO) :-
HTML = generate_proc_dynamic_debug_page(PDI, Deep).
-exec(call_site_static(CSSI), _Pref, Deep, HTML, !IO) :-
+exec(deep_cmd_call_site_static(CSSI), _Pref, Deep, HTML, !IO) :-
HTML = generate_call_site_static_debug_page(CSSI, Deep).
-exec(call_site_dynamic(CSDI), _Pref, Deep, HTML, !IO) :-
+exec(deep_cmd_call_site_dynamic(CSDI), _Pref, Deep, HTML, !IO) :-
HTML = generate_call_site_dynamic_debug_page(CSDI, Deep).
-exec(raw_clique(CI), _Pref, Deep, HTML, !IO) :-
+exec(deep_cmd_raw_clique(CI), _Pref, Deep, HTML, !IO) :-
HTML = generate_clique_debug_page(CI, Deep).
%-----------------------------------------------------------------------------%
@@ -337,62 +335,86 @@
:- func generate_menu_page(cmd, preferences, deep) = string.
generate_menu_page(Cmd, Pref, Deep) = HTML :-
+ ShouldDisplayTimes = should_display_times(Deep),
HTML =
page_banner(Cmd, Pref) ++
"<p>\n" ++
menu_text ++
"<ul>\n" ++
"<li>\n" ++
- menu_item(Deep, Pref, root(no),
+ menu_item(Deep, Pref, deep_cmd_root(no),
"Exploring the call graph, starting at the root.") ++
"<li>\n" ++
- menu_item(Deep, Pref, root(yes(90)),
+ menu_item(Deep, Pref, deep_cmd_root(yes(90)),
"Exploring the call graph, starting at the action.") ++
"<li>\n" ++
- menu_item(Deep, Pref, modules,
+ menu_item(Deep, Pref, deep_cmd_modules,
"Exploring the program module by module.") ++
+ ( ShouldDisplayTimes = yes ->
"<li>\n" ++
menu_item(Deep, Pref,
- top_procs(rank_range(1, 100), time,
+ deep_cmd_top_procs(rank_range(1, 100), cost_time,
self, overall),
"Top 100 most expensive procedures: time, self.") ++
"<li>\n" ++
menu_item(Deep, Pref,
- top_procs(rank_range(1, 100), time,
+ deep_cmd_top_procs(rank_range(1, 100), cost_time,
self_and_desc, overall),
"Top 100 most expensive procedures: time, self+desc.")
- ++
+ ;
+ ""
+ ) ++
"<li>\n" ++
menu_item(Deep, Pref,
- top_procs(rank_range(1, 100), words,
+ deep_cmd_top_procs(rank_range(1, 100), cost_callseqs,
self, overall),
- "Top 100 most expensive procedures: words, self.") ++
+ "Top 100 most expensive procedures: callseqs, self.") ++
"<li>\n" ++
menu_item(Deep, Pref,
- top_procs(rank_range(1, 100), words,
+ deep_cmd_top_procs(rank_range(1, 100), cost_callseqs,
self_and_desc, overall),
+ "Top 100 most expensive procedures: callseqs, self+desc.") ++
+ "<li>\n" ++
+ menu_item(Deep, Pref,
+ deep_cmd_top_procs(rank_range(1, 100), cost_words, self, overall),
+ "Top 100 most expensive procedures: words, self.") ++
+ "<li>\n" ++
+ menu_item(Deep, Pref,
+ deep_cmd_top_procs(rank_range(1, 100), cost_words, self_and_desc,
+ overall),
"Top 100 most expensive procedures: words, self+desc.")
++
+ ( ShouldDisplayTimes = yes ->
"<li>\n" ++
menu_item(Deep, Pref,
- top_procs(threshold(0.1), time,
- self, overall),
+ deep_cmd_top_procs(threshold(0.1), cost_time, self, overall),
"Procedures above 0.1% threshold: time, self.") ++
"<li>\n" ++
menu_item(Deep, Pref,
- top_procs(threshold(0.1), time,
- self_and_desc, overall),
+ deep_cmd_top_procs(threshold(1.0), cost_time, self_and_desc,
+ overall),
"Procedures above 1% threshold: time, self+desc.")
+ ;
+ ""
+ ) ++
+ "<li>\n" ++
+ menu_item(Deep, Pref,
+ deep_cmd_top_procs(threshold(0.1), cost_callseqs, self, overall),
+ "Procedures above 0.1% threshold: callseqs, self.") ++
+ "<li>\n" ++
+ menu_item(Deep, Pref,
+ deep_cmd_top_procs(threshold(1.0), cost_callseqs, self_and_desc,
+ overall),
+ "Procedures above 1% threshold: callseqs, self+desc.")
++
"<li>\n" ++
menu_item(Deep, Pref,
- top_procs(threshold(0.1), words,
- self, overall),
+ deep_cmd_top_procs(threshold(0.1), cost_words, self, overall),
"Procedures above 0.1% threshold: words, self.") ++
"<li>\n" ++
menu_item(Deep, Pref,
- top_procs(threshold(0.1), words,
- self_and_desc, overall),
+ deep_cmd_top_procs(threshold(1.0), cost_words, self_and_desc,
+ overall),
"Procedures above 1% threshold: words, self+desc.")
++
"</ul>\n" ++
@@ -434,6 +456,9 @@
"<TR><TD ALIGN=left>Quanta in instrumentation:</TD>\n" ++
string.format("<TD ALIGN=right>%d</TD></TR>\n",
[i(Stats ^ instrument_quanta)]) ++
+ "<TR><TD ALIGN=left>Call sequence numbers:</TD>\n" ++
+ string.format("<TD ALIGN=right>%d</TD></TR>\n",
+ [i(Stats ^ num_callseqs)]) ++
"<TR><TD ALIGN=left>CallSiteDynamic structures:</TD>\n" ++
string.format("<TD ALIGN=right>%d</TD></TR>\n",
[i(Stats ^ max_csd)]) ++
@@ -459,8 +484,7 @@
generate_clique_page(Cmd, CliqueNum, Pref, Deep, HTML0,
Percent, ActionPtrs),
( ActionPtrs = [clique_ptr(ActionCliqueNum)] ->
- HTML = chase_the_action(Cmd, ActionCliqueNum,
- Pref, Deep, Percent)
+ HTML = chase_the_action(Cmd, ActionCliqueNum, Pref, Deep, Percent)
;
HTML = HTML0
).
@@ -470,18 +494,15 @@
:- pred generate_clique_page(cmd::in, int::in, preferences::in, deep::in,
string::out, int::in, list(clique_ptr)::out) is det.
-generate_clique_page(Cmd, CliqueNum, Pref, Deep, HTML,
- Percent, ActionPtrs) :-
- clique_to_html(Pref, Deep, clique_ptr(CliqueNum),
- CliqueHTML, Percent, ActionPtrs),
+generate_clique_page(Cmd, CliqueNum, Pref, Deep, HTML, Percent, ActionPtrs) :-
+ clique_to_html(Pref, Deep, clique_ptr(CliqueNum), CliqueHTML, Percent,
+ ActionPtrs),
HTML =
page_banner(Cmd, Pref) ++
- string.format("<H3>Clique %d:</H3>\n",
- [i(CliqueNum)]) ++
+ string.format("<H3>Clique %d:</H3>\n", [i(CliqueNum)]) ++
table_start(Pref) ++
fields_header(Pref, source_proc, totals_meaningful,
- wrap_clique_links(clique_ptr(CliqueNum),
- Pref, Deep)) ++
+ wrap_clique_links(clique_ptr(CliqueNum), Pref, Deep)) ++
CliqueHTML ++
table_end(Pref) ++
page_footer(Cmd, Pref, Deep).
@@ -519,10 +540,8 @@
""
;
table_start(Pref) ++
- fields_header(Pref, IdFields,
- totals_meaningful,
- wrap_proc_callers_links(PSPtr,
- CallerGroups, 1,
+ fields_header(Pref, IdFields, totals_meaningful,
+ wrap_proc_callers_links(PSPtr, CallerGroups, 1,
Pref, Deep)) ++
CallersHTML ++
table_end(Pref) ++
@@ -571,8 +590,8 @@
generate_top_procs_page(Cmd, Limit, CostKind, InclDesc0, Scope0, Pref, Deep)
= HTML :-
- ( CostKind = calls ->
- % counting calls is incompatible both with self_and_desc
+ ( CostKind = cost_calls ->
+ % Counting calls is incompatible both with self_and_desc
% and per_call.
InclDesc = self,
Scope = overall
@@ -595,7 +614,8 @@
Desc = cost_criteria_to_description(CostKind, InclDesc, Scope),
Heading = string.format("<H3>Top procedures %s</H3>\n",
[s(Desc)]),
- ( TopPSIs = [] ->
+ (
+ TopPSIs = [],
HTML =
page_banner(Cmd, Pref) ++
Heading ++ "<p>\n" ++
@@ -605,22 +625,20 @@
ToggleCostHTML ++
page_footer(Cmd, Pref, Deep)
;
+ TopPSIs = [_ | _],
TopProcs = list.filter_map(
lookup_proc_total_to_html(Pref, Deep, no, ""),
list.map(wrap_proc_static_ptr, TopPSIs)),
RankedTopProcs = add_ranks(TopProcs),
SummaryHTMLs = list.map(
- two_id_line_to_html(Pref, Deep,
- totals_meaningful),
+ two_id_line_to_html(Pref, Deep, totals_meaningful),
RankedTopProcs),
HTML =
page_banner(Cmd, Pref) ++
Heading ++ "<p>\n" ++
table_start(Pref) ++
- fields_header(Pref, rank_proc,
- totals_meaningful,
- wrap_top_procs_links(Limit, Pref,
- Deep)) ++
+ fields_header(Pref, rank_proc, totals_meaningful,
+ wrap_top_procs_links(Limit, Pref, Deep)) ++
string.append_list(SummaryHTMLs) ++
table_end(Pref) ++
"<p>\n" ++
@@ -660,11 +678,11 @@
module_summary_to_html(Pref, Deep, ModuleName - ModuleData) = LineGroup :-
ModuleData = module_data(Own, Desc, _),
not (
- Pref ^ pref_inactive ^ inactive_modules = hide,
+ Pref ^ pref_inactive ^ inactive_modules = inactive_hide,
is_inactive(Own)
),
HTML = string.format("<TD><A HREF=""%s"">%s</A></TD>\n",
- [s(deep_cmd_pref_to_url(Pref, Deep, module(ModuleName))),
+ [s(deep_cmd_pref_to_url(Pref, Deep, deep_cmd_module(ModuleName))),
s(ModuleName)]),
LineGroup = line_group(ModuleName, 0, ModuleName, Own, Desc, HTML, unit).
@@ -675,8 +693,8 @@
module_to_html(Pref, Deep, _ModuleName, ModuleData, IdHeaders, HTML) :-
ModuleData = module_data(_Own, _Desc, PSPtrs),
- ProcLines = list.filter_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(_, _, _) ->
@@ -686,8 +704,7 @@
IdHeaders = source_proc,
RankedProcLines = list.map(add_self_context, SortedProcLines)
),
- ProcHTMLs = list.map(
- two_id_line_to_html(Pref, Deep, totals_meaningful),
+ ProcHTMLs = list.map(two_id_line_to_html(Pref, Deep, totals_meaningful),
RankedProcLines),
HTML =
separator_row(Pref, IdHeaders, totals_meaningful) ++
@@ -742,8 +759,8 @@
separator_row(Pref, source_proc, totals_meaningful) ++
Ancestors ++
separator_row(Pref, source_proc, totals_meaningful) ++
- header_row("Procedures of the clique:",
- Pref, source_proc, totals_meaningful) ++
+ header_row("Procedures of the clique:", Pref, source_proc,
+ totals_meaningful) ++
separator_row(Pref, source_proc, totals_meaningful) ++
ProcGroups.
@@ -763,7 +780,7 @@
deep_lookup_call_site_dynamics(Deep, EntryCSDPtr, EntryCSD),
EntryPDPtr = EntryCSD ^ csd_caller,
( EntryPDPtr = Deep ^ root ->
- % we have reached the root
+ % We have reached the root.
HTML = "",
Cutoff = no
; RespectLimit = yes, AncestorLimit =< 0 ->
@@ -776,12 +793,11 @@
ThisHTML = two_id_line_to_html(Pref, Deep, totals_meaningful,
ThisLine),
clique_ancestors_to_html(Pref, Deep, AncestorLimit - 1,
- RespectLimit, EntryCliquePtr,
- AncestorHTML, Cutoff),
+ RespectLimit, EntryCliquePtr, AncestorHTML, Cutoff),
HTML = AncestorHTML ++ ThisHTML
)
;
- % we have reached the parent of root
+ % We have reached the parent of root.
HTML = "",
Cutoff = no
).
@@ -819,24 +835,21 @@
list.map(deep_lookup_pd_desc(Deep), PDPtrs, ProcDescs),
ProcOwn = sum_own_infos(ProcOwns),
ProcDesc = sum_inherit_infos(ProcDescs),
- ProcTotal = proc_total_to_two_id_line(Pref, Deep,
- yes, "summary ", PSPtr, ProcOwn, ProcDesc),
- list.map2(
- proc_in_clique_to_html(Pref, Deep, CliquePtr, Percent),
+ ProcTotal = proc_total_to_two_id_line(Pref, Deep, yes, "summary ",
+ PSPtr, ProcOwn, ProcDesc),
+ list.map2(proc_in_clique_to_html(Pref, Deep, CliquePtr, Percent),
PDPtrs, ComponentHTMLs, ActionPtrLists),
list.condense(ActionPtrLists, ActionPtrs),
string.append_list(ComponentHTMLs, ComponentHTML),
HTML =
separator_row(Pref, source_proc, totals_meaningful) ++
- two_id_line_to_html(Pref, Deep, totals_meaningful,
- ProcTotal) ++
+ two_id_line_to_html(Pref, Deep, totals_meaningful, ProcTotal) ++
separator_row(Pref, source_proc, totals_meaningful) ++
ComponentHTML
).
:- pred proc_in_clique_to_html(preferences::in, deep::in, clique_ptr::in,
- int::in, proc_dynamic_ptr::in, string::out, list(clique_ptr)::out)
- is det.
+ int::in, proc_dynamic_ptr::in, string::out, list(clique_ptr)::out) is det.
proc_in_clique_to_html(Pref, Deep, CliquePtr, Percent, PDPtr,
HTML, ActionPtrs) :-
@@ -845,36 +858,30 @@
deep_lookup_pd_desc(Deep, PDPtr, ProcDesc),
deep_lookup_proc_dynamics(Deep, PDPtr, PD),
PSPtr = PD ^ pd_proc_static,
- ProcTotal = proc_total_to_two_id_line(Pref, Deep,
- yes, "", PSPtr, ProcOwn, ProcDesc),
+ ProcTotal = proc_total_to_two_id_line(Pref, Deep, yes, "",
+ PSPtr, ProcOwn, ProcDesc),
child_call_sites(Deep ^ proc_dynamics, Deep ^ proc_statics,
PDPtr, GroupPairs),
- ( GroupPairs = [] ->
- HTML =
- separator_row(Pref, source_proc,
- totals_meaningful) ++
- two_id_line_to_html(Pref, Deep,
- totals_meaningful,ProcTotal),
+ ProcHTML =
+ separator_row(Pref, source_proc, totals_meaningful) ++
+ two_id_line_to_html(Pref, Deep, totals_meaningful, ProcTotal),
+ (
+ GroupPairs = [],
+ HTML = ProcHTML,
ActionPtrs = []
;
- list.map2(call_site_clique_to_html(Pref, Deep,
- CliquePtr, Percent),
+ GroupPairs = [_ | _],
+ list.map2(call_site_clique_to_html(Pref, Deep, CliquePtr, Percent),
GroupPairs, CallSiteLists, ActionPtrLists),
list.condense(CallSiteLists, CallSites),
list.condense(ActionPtrLists, ActionPtrs),
- SortedCallSites = sort_line_groups(
- Pref ^ pref_criteria, CallSites),
+ SortedCallSites = sort_line_groups(Pref ^ pref_criteria,
+ CallSites),
BodyHTMLs = list.map(
- two_id_line_group_to_html(Pref, Deep,
- totals_meaningful),
+ two_id_line_group_to_html(Pref, Deep, totals_meaningful),
SortedCallSites),
- HTML =
- separator_row(Pref, source_proc,
- totals_meaningful) ++
- two_id_line_to_html(Pref, Deep,
- totals_meaningful,ProcTotal) ++
- separator_row(Pref, source_proc,
- totals_meaningful) ++
+ HTML = ProcHTML ++
+ separator_row(Pref, source_proc, totals_meaningful) ++
string.append_list(BodyHTMLs)
)
;
@@ -907,7 +914,7 @@
lookup_proc_total_to_html(Pref, Deep, Bold, Prefix, PSPtr) = LineGroup :-
deep_lookup_ps_own(Deep, PSPtr, Own),
not (
- Pref ^ pref_inactive ^ inactive_procs = hide,
+ Pref ^ pref_inactive ^ inactive_procs = inactive_hide,
is_inactive(Own)
),
deep_lookup_ps_desc(Deep, PSPtr, Desc),
@@ -961,8 +968,7 @@
BoldEnd = "</B>"
),
HTML = string.format("<TD CLASS=id COLSPAN=%d>%s%s%s%s</TD>\n",
- [i(Span), s(BoldStart), s(Prefix),
- s(WrappedProcName), s(BoldEnd)]).
+ [i(Span), s(BoldStart), s(Prefix), s(WrappedProcName), s(BoldEnd)]).
%-----------------------------------------------------------------------------%
@@ -991,9 +997,8 @@
error("call_site_clique_to_html: non-normal_call error")
),
call_site_context(Deep, CSSPtr, FileName, LineNumber),
- multi_call_site_clique_to_html(Pref, Deep,
- FileName, LineNumber, Kind, CallerCliquePtr, CSDPtrs,
- LineGroups, Percent, ActionPtrs)
+ multi_call_site_clique_to_html(Pref, Deep, FileName, LineNumber,
+ Kind, CallerCliquePtr, CSDPtrs, LineGroups, Percent, ActionPtrs)
).
:- func maybe_extract_action_clique(deep, clique_ptr, int,
@@ -1013,9 +1018,9 @@
CSDOwn = CSD ^ csd_own_prof,
CSDTotal = add_own_to_inherit(CSDOwn, CSDDesc),
RootTotal = root_total_info(Deep),
- CSDQuanta = inherit_quanta(CSDTotal),
- RootQuanta = inherit_quanta(RootTotal),
- ( CSDQuanta * 100 > RootQuanta * Percent ->
+ CSDCallSeqs = inherit_callseqs(CSDTotal),
+ RootCallSeqs = inherit_callseqs(RootTotal),
+ ( CSDCallSeqs * 100 > RootCallSeqs * Percent ->
ActionPtrs = [CalleeCliquePtr]
;
ActionPtrs = []
@@ -1062,22 +1067,18 @@
SummaryHTML =
string.format("<TD CLASS=id>%s:%d</TD>\n",
[s(escape_html_string(FileName)), i(LineNumber)]) ++
- %
+
% NOTE: we don't escape HTML special characters for
% 'CallSiteName' because it has already been done.
- %
- string.format("<TD CLASS=id>%s</TD>\n",
- [s(CallSiteName)]),
+ string.format("<TD CLASS=id>%s</TD>\n", [s(CallSiteName)]),
(
Pref ^ pref_summarize = summarize,
- LineGroup = line_group(FileName, LineNumber,
- RawCallSiteName, Own, Desc, SummaryHTML,
- sub_lines(two_id, []))
+ LineGroup = line_group(FileName, LineNumber, RawCallSiteName,
+ Own, Desc, SummaryHTML, sub_lines(two_id, []))
;
Pref ^ pref_summarize = dont_summarize,
- LineGroup = line_group(FileName, LineNumber,
- RawCallSiteName, Own, Desc, SummaryHTML,
- sub_lines(two_id, SubLines))
+ LineGroup = line_group(FileName, LineNumber, RawCallSiteName,
+ Own, Desc, SummaryHTML, sub_lines(two_id, SubLines))
),
LineGroups = [LineGroup].
@@ -1095,12 +1096,10 @@
call_site_context(Deep, CSSPtr, FileName, LineNumber),
( Kind = normal_call_and_callee(CalleePSPtr, _) ->
LineGroup0 = normal_call_site_summary_to_html(Pref, Deep,
- FileName, LineNumber, CallerPSPtr, CalleePSPtr,
- CallSiteCallList)
+ FileName, LineNumber, CallerPSPtr, CalleePSPtr, CallSiteCallList)
;
LineGroup0 = multi_call_site_summary_to_html(Pref, Deep,
- FileName, LineNumber, Kind,
- CallerPSPtr, CallSiteCallList)
+ FileName, LineNumber, Kind, CallerPSPtr, CallSiteCallList)
),
CSSContext = string.format("%s:%d",
[s(escape_html_string(FileName)), i(LineNumber)]),
@@ -1120,8 +1119,7 @@
Desc = zero_inherit_prof_info,
SummaryHTML =
string.format("<TD CLASS=id>%s</TD>\n",
- [s(proc_static_to_html_ref(Pref,
- Deep, CalleePSPtr))]),
+ [s(proc_static_to_html_ref(Pref, Deep, CalleePSPtr))]),
LineGroup = line_group(FileName, LineNumber,
ProcName, Own, Desc, SummaryHTML,
sub_lines(two_id, []))
@@ -1130,8 +1128,7 @@
require(unify(CalleePSPtr, CalleePSPtrFromCall),
"call_site_summary_to_html: callee mismatch"),
LineGroup0 = call_site_summary_group_to_html(Pref, Deep,
- FileName, LineNumber, ProcName,
- CallerPSPtr, CallSiteCall),
+ FileName, LineNumber, ProcName, CallerPSPtr, CallSiteCall),
LineGroup = line_to_two_id_subline_group(LineGroup0)
;
error("normal_call_site_summary_to_html: too many procedures")
@@ -1151,24 +1148,20 @@
FileName, LineNumber, RawCallSiteName, CallerPSPtr),
CallSiteCallList),
sum_line_group_measurements(SubLines, Own, Desc),
- %
+
% NOTE: we don't escape HTML special characters for
% 'CallSiteName' because it has already been done.
- %
SummaryHTML =
- string.format("<TD CLASS=id>%s</TD>\n",
- [s(CallSiteName)]),
+ string.format("<TD CLASS=id>%s</TD>\n", [s(CallSiteName)]),
(
Pref ^ pref_summarize = summarize,
- LineGroup = line_group(FileName, LineNumber,
- RawCallSiteName, Own, Desc, SummaryHTML,
- sub_lines(two_id, []))
+ LineGroup = line_group(FileName, LineNumber, RawCallSiteName,
+ Own, Desc, SummaryHTML, sub_lines(two_id, []))
;
Pref ^ pref_summarize = dont_summarize,
ContextSubLines = list.map(add_context(""), SubLines),
- LineGroup = line_group(FileName, LineNumber,
- RawCallSiteName, Own, Desc, SummaryHTML,
- sub_lines(two_id, ContextSubLines))
+ LineGroup = line_group(FileName, LineNumber, RawCallSiteName,
+ Own, Desc, SummaryHTML, sub_lines(two_id, ContextSubLines))
).
:- func call_site_summary_group_to_html(preferences, deep,
@@ -1207,11 +1200,9 @@
inherit_prof_info::in, inherit_prof_info::out) is det.
process_call_site_dynamics_group([], _, _,
- MaybeCalleeCliquePtr, MaybeCalleeCliquePtr,
- Own, Own, Desc, Desc).
+ MaybeCalleeCliquePtr, MaybeCalleeCliquePtr, Own, Own, Desc, Desc).
process_call_site_dynamics_group([CSDPtr | CSDPtrs], Deep, CalleePSPtr,
- MaybeCalleeCliquePtr0, MaybeCalleeCliquePtr,
- Own0, Own, Desc0, Desc) :-
+ MaybeCalleeCliquePtr0, MaybeCalleeCliquePtr, Own0, Own, Desc0, Desc) :-
deep_lookup_call_site_dynamics(Deep, CSDPtr, CSD),
PDPtr = CSD ^ csd_callee,
deep_lookup_proc_dynamics(Deep, PDPtr, PD),
@@ -1233,8 +1224,7 @@
Own1 = add_own_to_own(Own0, CSDOwn),
Desc1 = add_inherit_to_inherit(Desc0, CSDDesc),
process_call_site_dynamics_group(CSDPtrs, Deep, CalleePSPtr,
- MaybeCalleeCliquePtr1, MaybeCalleeCliquePtr,
- Own1, Own, Desc1, Desc).
+ MaybeCalleeCliquePtr1, MaybeCalleeCliquePtr, Own1, Own, Desc1, Desc).
:- pred accumulate_csd_prof_info(deep::in, proc_static_ptr::in,
call_site_dynamic_ptr::in,
@@ -1280,8 +1270,7 @@
Context = string.format("%s:%d", [s(escape_html_string(FileName)),
i(LineNumber)]),
HTML = call_to_html(Pref, Deep, CallSiteDisplay, Context,
- CallerPDPtr, CalleePDPtr,
- MaybeCallerCliquePtr, CalleeCliquePtr),
+ CallerPDPtr, CalleePDPtr, MaybeCallerCliquePtr, CalleeCliquePtr),
ProcName = escape_html_string(proc_dynamic_name(Deep, CalleePDPtr)),
LineGroup = line_group(FileName, LineNumber, ProcName,
CallSiteOwn, CallSiteDesc, HTML, unit).
@@ -1375,7 +1364,7 @@
),
ChosenCliquePtr = clique_ptr(ChosenCliqueNum),
WrappedProcName = string.format("<A HREF=""%s"">%s</A>",
- [s(deep_cmd_pref_to_url(Pref, Deep, clique(ChosenCliqueNum))),
+ [s(deep_cmd_pref_to_url(Pref, Deep, deep_cmd_clique(ChosenCliqueNum))),
s(escape_html_string(ProcName))]),
(
CallSiteDisplay ^ display_wrap = wrap_url_always,
@@ -1448,8 +1437,7 @@
Deep, Result, !IO),
(
Result = ok(ExcludeSpec),
- CallerCSDPtrPairs = list.map(
- pair_contour(Deep, ExcludeSpec),
+ CallerCSDPtrPairs = list.map(pair_contour(Deep, ExcludeSpec),
CallerCSDPtrs),
MaybeErrorMsg = no
;
@@ -1460,10 +1448,10 @@
),
ProcName = proc_static_name(Deep, PSPtr),
PSPtr = proc_static_ptr(PSI),
- CmdSite = proc_callers(PSI, group_by_call_site, 1),
- CmdProc = proc_callers(PSI, group_by_proc, 1),
- CmdModule = proc_callers(PSI, group_by_module, 1),
- CmdClique = proc_callers(PSI, group_by_clique, 1),
+ CmdSite = deep_cmd_proc_callers(PSI, group_by_call_site, 1),
+ CmdProc = deep_cmd_proc_callers(PSI, group_by_proc, 1),
+ CmdModule = deep_cmd_proc_callers(PSI, group_by_module, 1),
+ CmdClique = deep_cmd_proc_callers(PSI, group_by_clique, 1),
LinkSite = "Group callers by call site",
LinkProc = "Group callers by procedure",
LinkModule = "Group callers by module",
@@ -1476,8 +1464,7 @@
GroupMap = list.foldl(accumulate_csds_by_call_site(Deep),
CallerCSDPtrPairs, map.init),
map.to_assoc_list(GroupMap, GroupList),
- Lines = list.map(
- proc_callers_call_site_to_html(Pref, Deep, PSPtr),
+ Lines = list.map(proc_callers_call_site_to_html(Pref, Deep, PSPtr),
GroupList),
SortedLines = sort_line_groups(Pref ^ pref_criteria, Lines),
IdFields = source_proc,
@@ -1497,8 +1484,7 @@
GroupMap = list.foldl(accumulate_csds_by_procedure(Deep),
CallerCSDPtrPairs, map.init),
map.to_assoc_list(GroupMap, GroupList),
- Lines = list.map(
- proc_callers_proc_to_html(Pref, Deep, PSPtr),
+ Lines = list.map(proc_callers_proc_to_html(Pref, Deep, PSPtr),
GroupList),
SortedLines = sort_line_groups(Pref ^ pref_criteria, Lines),
IdFields = source_proc,
@@ -1518,11 +1504,9 @@
GroupMap = list.foldl(accumulate_csds_by_module(Deep),
CallerCSDPtrPairs, map.init),
map.to_assoc_list(GroupMap, GroupList),
- RawLines = list.map(
- proc_callers_module_to_html(Pref, Deep, PSPtr),
+ RawLines = list.map(proc_callers_module_to_html(Pref, Deep, PSPtr),
GroupList),
- SortedRawLines = sort_line_groups(Pref ^ pref_criteria,
- RawLines),
+ SortedRawLines = sort_line_groups(Pref ^ pref_criteria, RawLines),
SortedLines = add_ranks(SortedRawLines),
IdFields = rank_module,
Entity = "module",
@@ -1541,11 +1525,9 @@
GroupMap = list.foldl(accumulate_csds_by_clique(Deep),
CallerCSDPtrPairs, map.init),
map.to_assoc_list(GroupMap, GroupList),
- RawLines = list.map(
- proc_callers_clique_to_html(Pref, Deep, PSPtr),
+ RawLines = list.map(proc_callers_clique_to_html(Pref, Deep, PSPtr),
GroupList),
- SortedRawLines = sort_line_groups(Pref ^ pref_criteria,
- RawLines),
+ SortedRawLines = sort_line_groups(Pref ^ pref_criteria, RawLines),
SortedLines = add_ranks(SortedRawLines),
IdFields = source_proc,
Entity = "clique",
@@ -1574,32 +1556,29 @@
DisplayedLines),
HTML = string.append_list(DisplayedHTMLs),
( BunchNum > 1 ->
- FirstCmd = proc_callers(PSI, CallerGroups, 1),
+ FirstCmd = deep_cmd_proc_callers(PSI, CallerGroups, 1),
FirstLink = "First group",
FirstToggle =
string.format("<A HREF=""%s"">%s</A>\n",
- [s(deep_cmd_pref_to_url(Pref, Deep, FirstCmd)),
- s(FirstLink)])
+ [s(deep_cmd_pref_to_url(Pref, Deep, FirstCmd)), s(FirstLink)])
;
FirstToggle = ""
),
( BunchNum > 2 ->
- PrevCmd = proc_callers(PSI, CallerGroups, BunchNum - 1),
+ PrevCmd = deep_cmd_proc_callers(PSI, CallerGroups, BunchNum - 1),
PrevLink = "Previous group",
PrevToggle =
string.format("<A HREF=""%s"">%s</A>\n",
- [s(deep_cmd_pref_to_url(Pref, Deep, PrevCmd)),
- s(PrevLink)])
+ [s(deep_cmd_pref_to_url(Pref, Deep, PrevCmd)), s(PrevLink)])
;
PrevToggle = ""
),
( NumLines > BunchNum * BunchSize ->
- NextCmd = proc_callers(PSI, CallerGroups, BunchNum + 1),
+ NextCmd = deep_cmd_proc_callers(PSI, CallerGroups, BunchNum + 1),
NextLink = "Next group",
NextToggle =
string.format("<A HREF=""%s"">%s</A>\n",
- [s(deep_cmd_pref_to_url(Pref, Deep, NextCmd)),
- s(NextLink)])
+ [s(deep_cmd_pref_to_url(Pref, Deep, NextCmd)), s(NextLink)])
;
NextToggle = ""
),
@@ -1641,7 +1620,7 @@
proc_callers_banner(PSI, ProcName, Pref, Deep, NumLines, BunchSize, BunchNum,
Parent) = HTML :-
- Cmd = proc(PSI),
+ Cmd = deep_cmd_proc(PSI),
WrappedProcName = string.format("<A HREF=""%s"">%s</A>",
[s(deep_cmd_pref_to_url(Pref, Deep, Cmd)),
s(escape_html_string(ProcName))]),
@@ -1657,8 +1636,7 @@
; BunchNum = 1 ->
HTML = string.format(
"<H3>There are %d %ss calling %s, showing first %d:</H3>",
- [i(NumLines), s(Parent), s(WrappedProcName),
- i(BunchSize)])
+ [i(NumLines), s(Parent), s(WrappedProcName), i(BunchSize)])
;
First = (BunchNum - 1) * BunchSize + 1,
Last0 = (BunchNum) * BunchSize,
@@ -1669,8 +1647,7 @@
),
HTML = string.format(
"<H3>There are %d %ss calling %s, showing %d to %d:</H3>",
- [i(NumLines), s(Parent), s(WrappedProcName),
- i(First), i(Last)])
+ [i(NumLines), s(Parent), s(WrappedProcName), i(First), i(Last)])
).
:- func proc_callers_call_site_to_html(preferences, deep, proc_static_ptr,
@@ -1683,15 +1660,13 @@
CallerPSPtr = CSS ^ css_container,
deep_lookup_proc_statics(Deep, CallerPSPtr, CallerPS),
CallerProcName = CallerPS ^ ps_refined_id,
- list.foldl2(accumulate_parent_csd_prof_info(Deep, CalleePSPtr),
- CSDPtrs,
+ list.foldl2(accumulate_parent_csd_prof_info(Deep, CalleePSPtr), CSDPtrs,
zero_own_prof_info, Own, zero_inherit_prof_info, Desc),
HTML =
string.format("<TD CLASS=id>%s:%d</TD>\n",
[s(FileName), i(LineNumber)]) ++
string.format("<TD CLASS=id>%s</TD>\n",
- [s(proc_static_to_html_ref(Pref, Deep,
- CallerPSPtr))]),
+ [s(proc_static_to_html_ref(Pref, Deep, CallerPSPtr))]),
LineGroup = line_group(FileName, LineNumber, CallerProcName,
Own, Desc, HTML, unit).
@@ -1703,15 +1678,13 @@
proc_static_context(Deep, CallerPSPtr, FileName, LineNumber),
deep_lookup_proc_statics(Deep, CallerPSPtr, CallerPS),
CallerProcName = CallerPS ^ ps_refined_id,
- list.foldl2(accumulate_parent_csd_prof_info(Deep, CalleePSPtr),
- CSDPtrs,
+ list.foldl2(accumulate_parent_csd_prof_info(Deep, CalleePSPtr), CSDPtrs,
zero_own_prof_info, Own, zero_inherit_prof_info, Desc),
HTML =
string.format("<TD CLASS=id>%s:%d</TD>\n",
[s(FileName), i(LineNumber)]) ++
string.format("<TD CLASS=id>%s</TD>\n",
- [s(proc_static_to_html_ref(Pref, Deep,
- CallerPSPtr))]),
+ [s(proc_static_to_html_ref(Pref, Deep, CallerPSPtr))]),
LineGroup = line_group(FileName, LineNumber, CallerProcName,
Own, Desc, HTML, unit).
@@ -1720,8 +1693,7 @@
proc_callers_module_to_html(Pref, Deep, CalleePSPtr, ModuleName - CSDPtrs)
= LineGroup :-
- list.foldl2(accumulate_parent_csd_prof_info(Deep, CalleePSPtr),
- CSDPtrs,
+ list.foldl2(accumulate_parent_csd_prof_info(Deep, CalleePSPtr), CSDPtrs,
zero_own_prof_info, Own, zero_inherit_prof_info, Desc),
HTML = string.format("<TD CLASS=id>%s</TD>\n",
[s(module_name_to_html_ref(Pref, Deep, ModuleName))]),
@@ -1735,8 +1707,7 @@
proc_callers_clique_to_html(Pref, Deep, CalleePSPtr, CliquePtr - CSDPtrs)
= LineGroup :-
- list.foldl2(accumulate_parent_csd_prof_info(Deep, CalleePSPtr),
- CSDPtrs,
+ list.foldl2(accumulate_parent_csd_prof_info(Deep, CalleePSPtr), CSDPtrs,
zero_own_prof_info, Own, zero_inherit_prof_info, Desc),
deep_lookup_clique_parents(Deep, CliquePtr, EntryCSDPtr),
deep_lookup_call_site_dynamics(Deep, EntryCSDPtr, EntryCSD),
@@ -1785,8 +1756,7 @@
deep_lookup_proc_statics(Deep, GroupPSPtr, GroupPS),
GroupModuleName = GroupPS ^ ps_decl_module,
( map.search(Map0, GroupModuleName, CostCSDPtrs0) ->
- map.det_update(Map0, GroupModuleName, [CostCSDPtr | CostCSDPtrs0],
- Map)
+ map.det_update(Map0, GroupModuleName, [CostCSDPtr | CostCSDPtrs0], Map)
;
map.det_insert(Map0, GroupModuleName, [CostCSDPtr], Map)
).
@@ -1823,10 +1793,8 @@
add_own_to_own(Own0, CSDOwn) = Own,
add_inherit_to_inherit(Desc0, CSDDesc) = Desc1,
- deep_lookup_clique_index(Deep, CSD ^ csd_callee,
- CalleeCliquePtr),
- deep_lookup_clique_members(Deep, CalleeCliquePtr,
- CalleeCliquePDPtrs),
+ deep_lookup_clique_index(Deep, CSD ^ csd_callee, CalleeCliquePtr),
+ deep_lookup_clique_members(Deep, CalleeCliquePtr, CalleeCliquePDPtrs),
list.foldl(compensate_using_comp_table(Deep, CallerPSPtr),
CalleeCliquePDPtrs, Desc1, Desc)
).
@@ -1888,13 +1856,13 @@
proc_summary_toggles_to_html(Pref, Deep, PSPtr) = HTML :-
PSPtr = proc_static_ptr(PSI),
Msg1 = "Parent call sites",
- Cmd1 = proc_callers(PSI, group_by_call_site, 1),
+ Cmd1 = deep_cmd_proc_callers(PSI, group_by_call_site, 1),
Msg2 = "Parent procedures",
- Cmd2 = proc_callers(PSI, group_by_proc, 1),
+ Cmd2 = deep_cmd_proc_callers(PSI, group_by_proc, 1),
Msg3 = "Parent modules",
- Cmd3 = proc_callers(PSI, group_by_module, 1),
+ Cmd3 = deep_cmd_proc_callers(PSI, group_by_module, 1),
Msg4 = "Parent cliques",
- Cmd4 = proc_callers(PSI, group_by_clique, 1),
+ Cmd4 = deep_cmd_proc_callers(PSI, group_by_clique, 1),
Link1 = string.format("<A HREF=""%s"">%s</A>\n",
[s(deep_cmd_pref_to_url(Pref, Deep, Cmd1)), s(Msg1)]),
Link2 = string.format("<A HREF=""%s"">%s</A>\n",
@@ -1916,7 +1884,7 @@
wrap_clique_links(CliquePtr, Pref0, Deep, Str0, Criteria) = Str :-
CliquePtr = clique_ptr(CI),
- Cmd = clique(CI),
+ Cmd = deep_cmd_clique(CI),
Pref = Pref0 ^ pref_criteria := Criteria,
URL = deep_cmd_pref_to_url(Pref, Deep, Cmd),
Str = string.format("<A HREF=%s>%s</A>",
@@ -1927,7 +1895,7 @@
wrap_proc_links(PSPtr, Pref0, Deep, Str0, Criteria) = Str :-
PSPtr = proc_static_ptr(PSI),
- Cmd = proc(PSI),
+ Cmd = deep_cmd_proc(PSI),
Pref = Pref0 ^ pref_criteria := Criteria,
URL = deep_cmd_pref_to_url(Pref, Deep, Cmd),
Str = string.format("<A HREF=%s>%s</A>",
@@ -1939,7 +1907,7 @@
wrap_proc_callers_links(PSPtr, CallerGroups, BunchNum, Pref0, Deep,
Str0, Criteria) = Str :-
PSPtr = proc_static_ptr(PSI),
- Cmd = proc_callers(PSI, CallerGroups, BunchNum),
+ Cmd = deep_cmd_proc_callers(PSI, CallerGroups, BunchNum),
Pref = Pref0 ^ pref_criteria := Criteria,
URL = deep_cmd_pref_to_url(Pref, Deep, Cmd),
Str = string.format("<A HREF=%s>%s</A>",
@@ -1949,7 +1917,7 @@
order_criteria) = string.
wrap_module_links(ModuleName, Pref0, Deep, Str0, Criteria) = Str :-
- Cmd = module(ModuleName),
+ Cmd = deep_cmd_module(ModuleName),
Pref = Pref0 ^ pref_criteria := Criteria,
URL = deep_cmd_pref_to_url(Pref, Deep, Cmd),
Str = string.format("<A HREF=%s>%s</A>",
@@ -1958,7 +1926,7 @@
:- func wrap_modules_links(preferences, deep, string, order_criteria) = string.
wrap_modules_links(Pref0, Deep, Str0, Criteria) = Str :-
- Cmd = modules,
+ Cmd = deep_cmd_modules,
Pref = Pref0 ^ pref_criteria := Criteria,
URL = deep_cmd_pref_to_url(Pref, Deep, Cmd),
Str = string.format("<A HREF=%s>%s</A>",
@@ -1976,7 +1944,7 @@
Str = Str0
;
Criteria = by_cost(CostKind, InclDesc, Scope),
- Cmd = top_procs(Limit, CostKind, InclDesc, Scope),
+ Cmd = deep_cmd_top_procs(Limit, CostKind, InclDesc, Scope),
URL = deep_cmd_pref_to_url(Pref, Deep, Cmd),
Str = string.format("<A HREF=%s>%s</A>",
[s(URL), s(escape_html_string(Str0))])
Index: read_profile.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/deep_profiler/read_profile.m,v
retrieving revision 1.18
diff -u -b -r1.18 read_profile.m
--- read_profile.m 9 Oct 2006 08:09:04 -0000 1.18
+++ read_profile.m 11 Oct 2006 03:49:04 -0000
@@ -132,7 +132,7 @@
% This must the same string as the one written by MR_write_out_id_string
% in runtime/mercury_deep_profiling.c.
-id_string = "Mercury deep profiler data version 2\n".
+id_string = "Mercury deep profiler data version 3\n".
:- func init_deep(int, int, int, int, int, int, int, int, int, int, int)
= initial_deep.
@@ -239,7 +239,7 @@
io::di, io::uo) is det.
read_call_site_static(Res, !IO) :-
- trace [ compile_time(flag("debug_read_profdeep")), io(!IO) ] (
+ trace [compile_time(flag("debug_read_profdeep")), io(!IO)] (
io.write_string("reading call_site_static.\n", !IO)
),
io_combinator.maybe_error_sequence_4(
@@ -259,7 +259,7 @@
(
Res1 = ok({CallSiteStatic, CSSI}),
Res = ok2(CallSiteStatic, CSSI),
- trace [ compile_time(flag("debug_read_profdeep")), io(!IO) ] (
+ trace [compile_time(flag("debug_read_profdeep")), io(!IO)] (
io.write_string("read call_site_static ", !IO),
io.write_int(CSSI, !IO),
io.write_string(": ", !IO),
@@ -276,7 +276,7 @@
io::di, io::uo) is det.
read_proc_static(Res, !IO) :-
- trace [ compile_time(flag("debug_read_profdeep")), io(!IO) ] (
+ trace [compile_time(flag("debug_read_profdeep")), io(!IO)] (
io.write_string("reading proc_static.\n", !IO)
),
io_combinator.maybe_error_sequence_6(
@@ -313,7 +313,7 @@
RefinedStr, RawStr, FileName, LineNumber,
IsInInterface, array(CSSPtrs), not_zeroed),
Res = ok2(ProcStatic, PSI),
- trace [ compile_time(flag("debug_read_profdeep")), io(!IO) ] (
+ trace [compile_time(flag("debug_read_profdeep")), io(!IO)] (
io.write_string("read proc_static ", !IO),
io.write_int(PSI, !IO),
io.write_string(": ", !IO),
@@ -536,7 +536,7 @@
io::di, io::uo) is det.
read_proc_dynamic(Res, !IO) :-
- trace [ compile_time(flag("debug_read_profdeep")), io(!IO) ] (
+ trace [compile_time(flag("debug_read_profdeep")), io(!IO)] (
io.write_string("reading proc_dynamic.\n", !IO)
),
io_combinator.maybe_error_sequence_3(
@@ -555,7 +555,7 @@
PSPtr = make_psptr(PSI),
ProcDynamic = proc_dynamic(PSPtr, array(Refs)),
Res = ok2(ProcDynamic, PDI),
- trace [ compile_time(flag("debug_read_profdeep")), io(!IO) ] (
+ trace [compile_time(flag("debug_read_profdeep")), io(!IO)] (
io.write_string("read proc_dynamic ", !IO),
io.write_int(PDI, !IO),
io.write_string(": ", !IO),
@@ -575,7 +575,7 @@
io::di, io::uo) is det.
read_call_site_dynamic(Res, !IO) :-
- trace [ compile_time(flag("debug_read_profdeep")), io(!IO) ] (
+ trace [compile_time(flag("debug_read_profdeep")), io(!IO)] (
io.write_string("reading call_site_dynamic.\n", !IO)
),
read_ptr(csd, Res1, !IO),
@@ -592,7 +592,7 @@
CallSiteDynamic = call_site_dynamic(
CallerPDPtr, PDPtr, Profile),
Res = ok2(CallSiteDynamic, CSDI),
- trace [ compile_time(flag("debug_read_profdeep")), io(!IO) ] (
+ trace [compile_time(flag("debug_read_profdeep")), io(!IO)] (
io.write_string("read call_site_dynamic ", !IO),
io.write_int(CSDI, !IO),
io.write_string(": ", !IO),
@@ -684,7 +684,7 @@
io::di, io::uo) is det.
read_call_site_slot(Res, !IO) :-
- trace [ compile_time(flag("debug_read_profdeep")), io(!IO) ] (
+ trace [compile_time(flag("debug_read_profdeep")), io(!IO)] (
io.write_string("reading call_site_slot.\n", !IO)
),
read_call_site_kind(Res1, !IO),
@@ -696,7 +696,7 @@
Res2 = ok(CSDI),
CSDPtr = make_csdptr(CSDI),
Res = ok(slot_normal(CSDPtr)),
- trace [ compile_time(flag("debug_read_profdeep")), io(!IO) ] (
+ trace [compile_time(flag("debug_read_profdeep")), io(!IO)] (
io.write_string("normal call_site slot ", !IO),
io.write_int(CSDI, !IO),
io.write_string("\n", !IO)
@@ -720,7 +720,7 @@
Res2 = ok(CSDIs),
CSDPtrs = list.map(make_csdptr, CSDIs),
Res = ok(slot_multi(Zeroed, array(CSDPtrs))),
- trace [ compile_time(flag("debug_read_profdeep")), io(!IO) ] (
+ trace [compile_time(flag("debug_read_profdeep")), io(!IO)] (
io.write_string("multi call_site slots ", !IO),
io.write(CSDIs, !IO),
io.write_string("\n", !IO)
@@ -755,7 +755,7 @@
maybe_error(list(int))::out, io::di, io::uo) is det.
read_multi_call_site_csdis_2(CSDIs0, Res, !IO) :-
- trace [ compile_time(flag("debug_read_profdeep")), io(!IO) ] (
+ trace [compile_time(flag("debug_read_profdeep")), io(!IO)] (
io.format("reading multi_call_site_csdi.\n", [], !IO)
),
read_deep_byte(Res0, !IO),
@@ -801,7 +801,7 @@
[i(Byte)], Msg),
Res = error(Msg)
),
- trace [ compile_time(flag("debug_read_profdeep")), io(!IO) ] (
+ trace [compile_time(flag("debug_read_profdeep")), io(!IO)] (
io.write_string("call_site_kind ", !IO),
io.write(Res, !IO),
io.write_string("\n", !IO)
@@ -848,7 +848,7 @@
format("unexpected call_site_kind %d", [i(Byte)], Msg),
Res = error(Msg)
),
- trace [ compile_time(flag("debug_read_profdeep")), io(!IO) ] (
+ trace [compile_time(flag("debug_read_profdeep")), io(!IO)] (
io.write_string("call_site_kind_and_callee ", !IO),
io.write(Res, !IO),
io.write_string("\n", !IO)
@@ -932,7 +932,7 @@
Res1 = error(Err),
Res = error(Err)
),
- trace [ compile_time(flag("debug_read_profdeep")), io(!IO) ] (
+ trace [compile_time(flag("debug_read_profdeep")), io(!IO)] (
io.write_string("string ", !IO),
io.write(Res, !IO),
io.write_string("\n", !IO)
@@ -942,7 +942,7 @@
read_ptr(_Kind, Res, !IO) :-
read_num1(0, Res, !IO),
- trace [ compile_time(flag("debug_read_profdeep")), io(!IO) ] (
+ trace [compile_time(flag("debug_read_profdeep")), io(!IO)] (
io.write_string("ptr ", !IO),
io.write(Res, !IO),
io.write_string("\n", !IO)
@@ -952,7 +952,7 @@
read_num(Res, !IO) :-
read_num1(0, Res, !IO),
- trace [ compile_time(flag("debug_read_profdeep")), io(!IO) ] (
+ trace [compile_time(flag("debug_read_profdeep")), io(!IO)] (
io.write_string("num ", !IO),
io.write(Res, !IO),
io.write_string("\n", !IO)
@@ -1047,7 +1047,7 @@
read_deep_byte(Res, !IO) :-
read_byte(Res0, !IO),
- trace [ compile_time(flag("debug_read_profdeep")), io(!IO) ] (
+ trace [compile_time(flag("debug_read_profdeep")), io(!IO)] (
io.write_string("byte ", !IO),
io.write(Res, !IO),
io.write_string("\n", !IO)
Index: startup.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/deep_profiler/startup.m,v
retrieving revision 1.13
diff -u -b -r1.13 startup.m
--- startup.m 29 Sep 2006 06:15:11 -0000 1.13
+++ startup.m 11 Oct 2006 03:49:04 -0000
@@ -12,6 +12,7 @@
% read_profile.m into the data structure that mdprof_cgi.m needs to service
% requests for web pages. The algorithm it implements is documented in the
% deep profiling paper.
+%
%-----------------------------------------------------------------------------%
:- module startup.
@@ -28,8 +29,8 @@
%-----------------------------------------------------------------------------%
:- pred read_and_startup(string::in, list(string)::in, bool::in,
- maybe(io.output_stream)::in, list(string)::in, maybe_error(deep)::out,
- io::di, io::uo) is det.
+ maybe(io.output_stream)::in, list(string)::in, list(string)::in,
+ maybe_error(deep)::out, io::di, io::uo) is det.
%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%
@@ -54,12 +55,10 @@
:- import_module svarray.
:- import_module svmap.
-% :- import_module unsafe.
-
%-----------------------------------------------------------------------------%
read_and_startup(Machine, DataFileNames, Canonical, MaybeOutputStream,
- DumpStages, Res, !IO) :-
+ DumpStages, DumpOptions, Res, !IO) :-
(
DataFileNames = [],
% This should have been caught and reported by main.
@@ -76,7 +75,7 @@
(
Res0 = ok(InitDeep),
startup(Machine, DataFileName, Canonical, MaybeOutputStream,
- DumpStages, InitDeep, Deep, !IO),
+ DumpStages, DumpOptions, InitDeep, Deep, !IO),
Res = ok(Deep)
;
Res0 = error(Error),
@@ -84,19 +83,19 @@
)
;
DataFileNames = [_, _ | _],
- error("mdprof_server: merging of data files " ++
- "is not yet implemented")
+ error("mdprof_server: merging of data files is not yet implemented")
).
:- pred startup(string::in, string::in, bool::in, maybe(io.output_stream)::in,
- list(string)::in, initial_deep::in, deep::out, io::di, io::uo) is det.
+ list(string)::in, list(string)::in, initial_deep::in, deep::out,
+ io::di, io::uo) is det.
-startup(Machine, DataFileName, Canonical, MaybeOutputStream, DumpStages,
- InitDeep0, Deep, !IO) :-
+startup(Machine, DataFileName, Canonical, MaybeOutputStream,
+ DumpStages, DumpOptions, InitDeep0, Deep, !IO) :-
InitDeep0 = initial_deep(InitStats, Root,
CallSiteDynamics0, ProcDynamics, CallSiteStatics0, ProcStatics0),
maybe_dump(DataFileName, DumpStages, 0,
- dump_initial_deep(yes, no, yes, yes, yes, yes, InitDeep0), !IO),
+ dump_initial_deep(InitDeep0, DumpOptions), !IO),
maybe_report_msg(MaybeOutputStream,
"% Mapping static call sites to containing procedures...\n", !IO),
@@ -117,7 +116,7 @@
InitDeep1 = initial_deep(InitStats, Root,
CallSiteDynamics, ProcDynamics, CallSiteStatics, ProcStatics),
maybe_dump(DataFileName, DumpStages, 10,
- dump_initial_deep(yes, no, yes, yes, yes, yes, InitDeep1), !IO),
+ dump_initial_deep(InitDeep1, DumpOptions), !IO),
(
Canonical = no,
InitDeep = InitDeep1
@@ -131,7 +130,7 @@
maybe_report_stats(MaybeOutputStream, !IO)
),
maybe_dump(DataFileName, DumpStages, 20,
- dump_initial_deep(yes, no, yes, yes, yes, yes, InitDeep), !IO),
+ dump_initial_deep(InitDeep, DumpOptions), !IO),
array.max(InitDeep ^ init_proc_dynamics, PDMax),
NPDs = PDMax + 1,
@@ -159,13 +158,12 @@
maybe_report_msg(MaybeOutputStream,
"% Constructing clique parent map...\n", !IO),
- % For each CallSiteDynamic pointer, if it points to
- % a ProcDynamic which is in a different clique to
- % the one from which the CallSiteDynamic's parent
- % came, then this CallSiteDynamic is the entry to
- % the [lower] clique. We need to compute this information
- % so that we can print clique-based timing summaries in
- % the browser.
+ % For each CallSiteDynamic pointer, if it points to a ProcDynamic
+ % which is in a different clique to the one from which the
+ % CallSiteDynamic's parent came, then this CallSiteDynamic is the entry to
+ % the [lower] clique. We need to compute this information so that
+ % we can print clique-based timing summaries in the browser.
+
array.max(Cliques, CliqueMax),
NCliques = CliqueMax + 1,
array.init(NCliques, call_site_dynamic_ptr(-1), CliqueParents0),
@@ -207,7 +205,7 @@
maybe_report_stats(MaybeOutputStream, !IO),
maybe_report_msg(MaybeOutputStream,
- "% Propagating time up call graph...\n", !IO),
+ "% Propagating measurements up call graph...\n", !IO),
array.init(NCSDs, zero_inherit_prof_info, CSDDesc0),
array.init(NPDs, zero_own_prof_info, PDOwn0),
@@ -230,11 +228,17 @@
PSOwn0, PSDesc0, CSSOwn0, CSSDesc0,
PDCompTable0, CSDCompTable0, ModuleData),
+ maybe_dump(DataFileName, DumpStages, 30,
+ dump_deep(Deep0, DumpOptions), !IO),
+
array_foldl_from_1(propagate_to_clique, Cliques, Deep0, Deep1),
maybe_report_msg(MaybeOutputStream,
"% Done.\n", !IO),
maybe_report_stats(MaybeOutputStream, !IO),
+ maybe_dump(DataFileName, DumpStages, 40,
+ dump_deep(Deep1, DumpOptions), !IO),
+
maybe_report_msg(MaybeOutputStream,
"% Summarizing information...\n", !IO),
summarize_proc_dynamics(Deep1, Deep2),
@@ -242,7 +246,10 @@
summarize_modules(Deep3, Deep),
maybe_report_msg(MaybeOutputStream,
"% Done.\n", !IO),
- maybe_report_stats(MaybeOutputStream, !IO).
+ maybe_report_stats(MaybeOutputStream, !IO),
+
+ maybe_dump(DataFileName, DumpStages, 50,
+ dump_deep(Deep, DumpOptions), !IO).
:- pred count_quanta(int::in, call_site_dynamic::in, int::in, int::out) is det.
@@ -259,13 +266,20 @@
maybe_dump(BaseName, DumpStages, ThisStageNum, Action, !IO) :-
string.int_to_string(ThisStageNum, ThisStage),
- ( list.member(ThisStage, DumpStages) ->
+ (
+ (
+ list.member("all", DumpStages)
+ ;
+ list.member(ThisStage, DumpStages)
+ )
+ ->
string.append_list([BaseName, ".deepdump.", ThisStage], FileName),
io.open_output(FileName, OpenRes, !IO),
(
OpenRes = ok(FileStream),
io.set_output_stream(FileStream, CurStream, !IO),
Action(!IO),
+ io.close_output(FileStream, !IO),
io.set_output_stream(CurStream, _, !IO)
;
OpenRes = error(Error),
@@ -707,8 +721,8 @@
propagate_to_clique(CliqueNumber, Members, !Deep) :-
array.lookup(!.Deep ^ clique_parents, CliqueNumber, ParentCSDPtr),
- list.foldl3(propagate_to_proc_dynamic(CliqueNumber, ParentCSDPtr),
- Members, !Deep, map.init, SumTable, map.init, OverrideMap),
+ list.foldl3(propagate_to_proc_dynamic(CliqueNumber, ParentCSDPtr), Members,
+ !Deep, map.init, SumTable, map.init, OverrideMap),
( valid_call_site_dynamic_ptr(!.Deep, ParentCSDPtr) ->
deep_lookup_call_site_dynamics(!.Deep, ParentCSDPtr, ParentCSD),
ParentOwn = ParentCSD ^ csd_own_prof,
@@ -765,7 +779,10 @@
CalleePDPtr = CSD ^ csd_callee,
deep_lookup_clique_index(!.Deep, CalleePDPtr, ChildCliquePtr),
ChildCliquePtr = clique_ptr(ChildCliqueNumber),
- ( ChildCliqueNumber \= CliqueNumber ->
+ ( ChildCliqueNumber = CliqueNumber ->
+ % We don't propagate profiling measurements along intra-clique calls.
+ true
+ ;
deep_lookup_pd_desc(!.Deep, PDPtr, ProcDesc0),
deep_lookup_csd_desc(!.Deep, CSDPtr, CalleeDesc),
CalleeTotal = add_own_to_inherit(CalleeOwn, CalleeDesc),
@@ -773,10 +790,6 @@
deep_update_pd_desc(PDPtr, ProcDesc, !Deep),
deep_lookup_csd_comp_table(!.Deep, CSDPtr, CSDCompTable),
!:PDCompTable = add_comp_tables(!.PDCompTable, CSDCompTable)
- ;
- % We don't propagate profiling measurements
- % along intra-clique calls.
- true
).
%-----------------------------------------------------------------------------%
Index: timeout.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/deep_profiler/timeout.m,v
retrieving revision 1.15
diff -u -b -r1.15 timeout.m
--- timeout.m 9 Mar 2006 04:56:41 -0000 1.15
+++ timeout.m 11 Oct 2006 03:49:04 -0000
@@ -387,8 +387,9 @@
(void) closedir(dir);
/*
- ** This call will delete the mutex file last, releasing the mutex
+ ** This call will delete the mutex file last, releasing the mutex.
*/
+
MP_delete_cleanup_files();
exit(EXIT_SUCCESS);
}
@@ -461,10 +462,32 @@
res = open(mutex_file, O_CREAT | O_EXCL, 0);
if (res >= 0) {
+#ifdef MP_DEBUG_LOCKS
+ FILE *debug_fp;
+
+ debug_fp = fopen(""/tmp/deep_locks"", ""a"");
+ if (debug_fp != NULL) {
+ fprintf(debug_fp, ""pid %d try: lock %s\\n"",
+ getpid(), mutex_file);
+ fclose(debug_fp);
+ }
+#endif
+
(void) close(res);
MP_register_cleanup_file(mutex_file);
success = MR_TRUE;
} else if (res < 0 && errno == EEXIST) {
+#ifdef MP_DEBUG_LOCKS
+ FILE *debug_fp;
+
+ debug_fp = fopen(""/tmp/deep_locks"", ""a"");
+ if (debug_fp != NULL) {
+ fprintf(debug_fp, ""pid %d try: no lock %s\\n"",
+ getpid(), mutex_file);
+ fclose(debug_fp);
+ }
+#endif
+
success = MR_FALSE;
} else {
MR_fatal_error(""MP_do_try_get_lock failed"");
@@ -481,10 +504,32 @@
for (;;) {
res = open(mutex_file, O_CREAT | O_EXCL, 0);
if (res >= 0) {
+#ifdef MP_DEBUG_LOCKS
+ FILE *debug_fp;
+
+ debug_fp = fopen(""/tmp/deep_locks"", ""a"");
+ if (debug_fp != NULL) {
+ fprintf(debug_fp, ""pid %d got lock %s\\n"",
+ getpid(), mutex_file);
+ fclose(debug_fp);
+ }
+#endif
+
(void) close(res);
MP_register_cleanup_file(mutex_file);
return;
} else if (res < 0 && errno == EEXIST) {
+#ifdef MP_DEBUG_LOCKS
+ FILE *debug_fp;
+
+ debug_fp = fopen(""/tmp/deep_locks"", ""a"");
+ if (debug_fp != NULL) {
+ fprintf(debug_fp, ""pid %d trying to lock %s ...\\n"",
+ getpid(), mutex_file);
+ fclose(debug_fp);
+ }
+#endif
+
sleep(5);
continue;
} else {
@@ -496,6 +541,17 @@
void
MP_do_release_lock(const char *mutex_file)
{
+#ifdef MP_DEBUG_LOCKS
+ FILE *debug_fp;
+
+ debug_fp = fopen(""/tmp/deep_locks"", ""a"");
+ if (debug_fp != NULL) {
+ fprintf(debug_fp, ""pid %d releasing lock %s\\n"",
+ getpid(), mutex_file);
+ fclose(debug_fp);
+ }
+#endif
+
MP_unregister_cleanup_file(mutex_file);
(void) unlink(mutex_file);
}
@@ -552,8 +608,7 @@
").
:- pragma foreign_proc("C",
- setup_signals(MutexFile::in, WantDir::in, WantPrefix::in,
- S0::di, S::uo),
+ setup_signals(MutexFile::in, WantDir::in, WantPrefix::in, S0::di, S::uo),
[will_not_call_mercury, promise_pure],
"
#ifdef MR_DEEP_PROFILER_ENABLED
@@ -630,8 +685,7 @@
#endif
").
-:- pred do_release_lock(string::in, io::di, io::uo)
- is det.
+:- pred do_release_lock(string::in, io::di, io::uo) is det.
:- pragma foreign_proc("C",
do_release_lock(MutexFile::in, S0::di, S::uo),
Index: top_procs.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/deep_profiler/top_procs.m,v
retrieving revision 1.8
diff -u -b -r1.8 top_procs.m
--- top_procs.m 29 Mar 2006 08:07:41 -0000 1.8
+++ top_procs.m 11 Oct 2006 03:49:04 -0000
@@ -127,8 +127,7 @@
( Result1 \= (=) ->
Result = Result1
;
- Result = compare_ps_words_both_overall(Deep,
- PSI1, PSI2)
+ Result = compare_ps_words_both_overall(Deep, PSI1, PSI2)
)
).
@@ -146,61 +145,93 @@
compare_proc_statics::out(func(in, in, in) = out is det),
pred(deep, int)::out(pred(in, in) is semidet)) is det.
-find_top_sort_predicate(calls, self, overall, yes,
+find_top_sort_predicate(cost_calls, self, overall, yes,
compare_ps_calls_self_overall, filter_ps_calls_self).
-find_top_sort_predicate(calls, self, per_call, no,
+find_top_sort_predicate(cost_calls, self, per_call, no,
compare_ps_calls_self_overall, filter_ps_calls_self).
-find_top_sort_predicate(calls, self_and_desc, overall, no,
+find_top_sort_predicate(cost_calls, self_and_desc, overall, no,
compare_ps_calls_self_overall, filter_ps_calls_self).
-find_top_sort_predicate(calls, self_and_desc, per_call, no,
+find_top_sort_predicate(cost_calls, self_and_desc, per_call, no,
compare_ps_calls_self_overall, filter_ps_calls_self).
-find_top_sort_predicate(redos, self, overall, yes,
+
+find_top_sort_predicate(cost_redos, self, overall, yes,
compare_ps_redos_self_overall, filter_ps_redos_self).
-find_top_sort_predicate(redos, self, per_call, no,
+find_top_sort_predicate(cost_redos, self, per_call, no,
compare_ps_redos_self_overall, filter_ps_redos_self).
-find_top_sort_predicate(redos, self_and_desc, overall, no,
+find_top_sort_predicate(cost_redos, self_and_desc, overall, no,
compare_ps_redos_self_overall, filter_ps_redos_self).
-find_top_sort_predicate(redos, self_and_desc, per_call, no,
+find_top_sort_predicate(cost_redos, self_and_desc, per_call, no,
compare_ps_redos_self_overall, filter_ps_redos_self).
-find_top_sort_predicate(time, self, overall, yes,
+
+find_top_sort_predicate(cost_time, self, overall, yes,
compare_ps_time_self_overall, filter_ps_time_self).
-find_top_sort_predicate(time, self, per_call, yes,
+find_top_sort_predicate(cost_time, self, per_call, yes,
compare_ps_time_self_percall, filter_ps_time_self).
-find_top_sort_predicate(time, self_and_desc, overall, yes,
+find_top_sort_predicate(cost_time, self_and_desc, overall, yes,
compare_ps_time_both_overall, filter_ps_time_both).
-find_top_sort_predicate(time, self_and_desc, per_call, yes,
+find_top_sort_predicate(cost_time, self_and_desc, per_call, yes,
compare_ps_time_both_percall, filter_ps_time_both).
-find_top_sort_predicate(allocs, self, overall, yes,
+
+find_top_sort_predicate(cost_callseqs, self, overall, yes,
+ compare_ps_callseqs_self_overall, filter_ps_callseqs_self).
+find_top_sort_predicate(cost_callseqs, self, per_call, yes,
+ compare_ps_callseqs_self_percall, filter_ps_callseqs_self).
+find_top_sort_predicate(cost_callseqs, self_and_desc, overall, yes,
+ compare_ps_callseqs_both_overall, filter_ps_callseqs_both).
+find_top_sort_predicate(cost_callseqs, self_and_desc, per_call, yes,
+ compare_ps_callseqs_both_percall, filter_ps_callseqs_both).
+
+find_top_sort_predicate(cost_allocs, self, overall, yes,
compare_ps_allocs_self_overall, filter_ps_allocs_self).
-find_top_sort_predicate(allocs, self, per_call, yes,
+find_top_sort_predicate(cost_allocs, self, per_call, yes,
compare_ps_allocs_self_percall, filter_ps_allocs_self).
-find_top_sort_predicate(allocs, self_and_desc, overall, yes,
+find_top_sort_predicate(cost_allocs, self_and_desc, overall, yes,
compare_ps_allocs_both_overall, filter_ps_allocs_both).
-find_top_sort_predicate(allocs, self_and_desc, per_call, yes,
+find_top_sort_predicate(cost_allocs, self_and_desc, per_call, yes,
compare_ps_allocs_both_percall, filter_ps_allocs_both).
-find_top_sort_predicate(words, self, overall, yes,
+
+find_top_sort_predicate(cost_words, self, overall, yes,
compare_ps_words_self_overall, filter_ps_words_self).
-find_top_sort_predicate(words, self, per_call, yes,
+find_top_sort_predicate(cost_words, self, per_call, yes,
compare_ps_words_self_percall, filter_ps_words_self).
-find_top_sort_predicate(words, self_and_desc, overall, yes,
+find_top_sort_predicate(cost_words, self_and_desc, overall, yes,
compare_ps_words_both_overall, filter_ps_words_both).
-find_top_sort_predicate(words, self_and_desc, per_call, yes,
+find_top_sort_predicate(cost_words, self_and_desc, per_call, yes,
compare_ps_words_both_percall, filter_ps_words_both).
:- pred find_threshold_predicate(cost_kind::in, include_descendants::in,
bool::out, pred(deep, float, int)::out(pred(in, in, in) is semidet))
is det.
-find_threshold_predicate(calls, self, no, threshold_ps_time_self).
-find_threshold_predicate(calls, self_and_desc, no, threshold_ps_time_self).
-find_threshold_predicate(redos, self, no, threshold_ps_time_self).
-find_threshold_predicate(redos, self_and_desc, no, threshold_ps_time_self).
-find_threshold_predicate(time, self, yes, threshold_ps_time_self).
-find_threshold_predicate(time, self_and_desc, yes, threshold_ps_time_both).
-find_threshold_predicate(allocs, self, yes, threshold_ps_allocs_self).
-find_threshold_predicate(allocs, self_and_desc, yes, threshold_ps_allocs_both).
-find_threshold_predicate(words, self, yes, threshold_ps_words_self).
-find_threshold_predicate(words, self_and_desc, yes, threshold_ps_words_both).
+find_threshold_predicate(cost_calls, self, no,
+ threshold_ps_time_self).
+find_threshold_predicate(cost_calls, self_and_desc, no,
+ threshold_ps_time_self).
+
+find_threshold_predicate(cost_redos, self, no,
+ threshold_ps_time_self).
+find_threshold_predicate(cost_redos, self_and_desc, no,
+ threshold_ps_time_self).
+
+find_threshold_predicate(cost_time, self, yes,
+ threshold_ps_time_self).
+find_threshold_predicate(cost_time, self_and_desc, yes,
+ threshold_ps_time_both).
+
+find_threshold_predicate(cost_callseqs, self, yes,
+ threshold_ps_callseqs_self).
+find_threshold_predicate(cost_callseqs, self_and_desc, yes,
+ threshold_ps_callseqs_both).
+
+find_threshold_predicate(cost_allocs, self, yes,
+ threshold_ps_allocs_self).
+find_threshold_predicate(cost_allocs, self_and_desc, yes,
+ threshold_ps_allocs_both).
+
+find_threshold_predicate(cost_words, self, yes,
+ threshold_ps_words_self).
+find_threshold_predicate(cost_words, self_and_desc, yes,
+ threshold_ps_words_both).
%-----------------------------------------------------------------------------%
@@ -286,6 +317,68 @@
TotalQuantaPerCall2 = float(TotalQuanta2) / float(Calls2),
compare(Result, TotalQuantaPerCall2, TotalQuantaPerCall1).
+:- func compare_ps_callseqs_self_overall(deep, int, int) = comparison_result.
+
+compare_ps_callseqs_self_overall(Deep, PSI1, PSI2) = Result :-
+ PSOwn = Deep ^ ps_own,
+ array.lookup(PSOwn, PSI1, Own1),
+ array.lookup(PSOwn, PSI2, Own2),
+ OwnCallSeqs1 = callseqs(Own1),
+ OwnCallSeqs2 = callseqs(Own2),
+ compare(Result, OwnCallSeqs2, OwnCallSeqs1).
+
+:- func compare_ps_callseqs_self_percall(deep, int, int) = comparison_result.
+
+compare_ps_callseqs_self_percall(Deep, PSI1, PSI2) = Result :-
+ PSOwn = Deep ^ ps_own,
+ array.lookup(PSOwn, PSI1, Own1),
+ array.lookup(PSOwn, PSI2, Own2),
+ Calls1 = calls(Own1),
+ Calls2 = calls(Own2),
+ OwnCallSeqs1 = callseqs(Own1),
+ OwnCallSeqs2 = callseqs(Own2),
+ OwnCallSeqsPerCall1 = float(OwnCallSeqs1) / float(Calls1),
+ OwnCallSeqsPerCall2 = float(OwnCallSeqs2) / float(Calls2),
+ compare(Result, OwnCallSeqsPerCall2, OwnCallSeqsPerCall1).
+
+:- func compare_ps_callseqs_both_overall(deep, int, int) = comparison_result.
+
+compare_ps_callseqs_both_overall(Deep, PSI1, PSI2) = Result :-
+ PSOwn = Deep ^ ps_own,
+ PSDesc = Deep ^ ps_desc,
+ array.lookup(PSOwn, PSI1, Own1),
+ array.lookup(PSOwn, PSI2, Own2),
+ array.lookup(PSDesc, PSI1, Desc1),
+ array.lookup(PSDesc, PSI2, Desc2),
+ OwnCallSeqs1 = callseqs(Own1),
+ OwnCallSeqs2 = callseqs(Own2),
+ DescCallSeqs1 = inherit_callseqs(Desc1),
+ DescCallSeqs2 = inherit_callseqs(Desc2),
+ TotalCallSeqs1 = OwnCallSeqs1 + DescCallSeqs1,
+ TotalCallSeqs2 = OwnCallSeqs2 + DescCallSeqs2,
+ compare(Result, TotalCallSeqs2, TotalCallSeqs1).
+
+:- func compare_ps_callseqs_both_percall(deep, int, int) = comparison_result.
+
+compare_ps_callseqs_both_percall(Deep, PSI1, PSI2) = Result :-
+ PSOwn = Deep ^ ps_own,
+ PSDesc = Deep ^ ps_desc,
+ array.lookup(PSOwn, PSI1, Own1),
+ array.lookup(PSOwn, PSI2, Own2),
+ array.lookup(PSDesc, PSI1, Desc1),
+ array.lookup(PSDesc, PSI2, Desc2),
+ Calls1 = calls(Own1),
+ Calls2 = calls(Own2),
+ OwnCallSeqs1 = callseqs(Own1),
+ OwnCallSeqs2 = callseqs(Own2),
+ DescCallSeqs1 = inherit_callseqs(Desc1),
+ DescCallSeqs2 = inherit_callseqs(Desc2),
+ TotalCallSeqs1 = OwnCallSeqs1 + DescCallSeqs1,
+ TotalCallSeqs2 = OwnCallSeqs2 + DescCallSeqs2,
+ TotalCallSeqsPerCall1 = float(TotalCallSeqs1) / float(Calls1),
+ TotalCallSeqsPerCall2 = float(TotalCallSeqs2) / float(Calls2),
+ compare(Result, TotalCallSeqsPerCall2, TotalCallSeqsPerCall1).
+
:- func compare_ps_allocs_self_overall(deep, int, int) = comparison_result.
compare_ps_allocs_self_overall(Deep, PSI1, PSI2) = Result :-
@@ -448,6 +541,26 @@
TotalQuanta1 = OwnQuanta1 + DescQuanta1,
TotalQuanta1 > 0.
+:- pred filter_ps_callseqs_self(deep::in, int::in) is semidet.
+
+filter_ps_callseqs_self(Deep, PSI1) :-
+ PSOwn = Deep ^ ps_own,
+ array.lookup(PSOwn, PSI1, Own1),
+ OwnCallSeqs1 = callseqs(Own1),
+ OwnCallSeqs1 > 0.
+
+:- pred filter_ps_callseqs_both(deep::in, int::in) is semidet.
+
+filter_ps_callseqs_both(Deep, PSI1) :-
+ PSOwn = Deep ^ ps_own,
+ PSDesc = Deep ^ ps_desc,
+ array.lookup(PSOwn, PSI1, Own1),
+ array.lookup(PSDesc, PSI1, Desc1),
+ OwnCallSeqs1 = callseqs(Own1),
+ DescCallSeqs1 = inherit_callseqs(Desc1),
+ TotalCallSeqs1 = OwnCallSeqs1 + DescCallSeqs1,
+ TotalCallSeqs1 > 0.
+
:- pred filter_ps_allocs_self(deep::in, int::in) is semidet.
filter_ps_allocs_self(Deep, PSI1) :-
@@ -520,6 +633,36 @@
RootTotalQuanta = RootOwnQuanta + RootDescQuanta,
100.0 * float(TotalQuanta) > Threshold * float(RootTotalQuanta).
+:- pred threshold_ps_callseqs_self(deep::in, float::in, int::in) is semidet.
+
+threshold_ps_callseqs_self(Deep, Threshold, PSI) :-
+ PSOwn = Deep ^ ps_own,
+ array.lookup(PSOwn, PSI, Own),
+ RootOwn = root_own_info(Deep),
+ RootDesc = root_desc_info(Deep),
+ OwnCallSeqs = callseqs(Own),
+ RootOwnCallSeqs = callseqs(RootOwn),
+ RootDescCallSeqs = inherit_callseqs(RootDesc),
+ RootTotalCallSeqs = RootOwnCallSeqs + RootDescCallSeqs,
+ 100.0 * float(OwnCallSeqs) > Threshold * float(RootTotalCallSeqs).
+
+:- pred threshold_ps_callseqs_both(deep::in, float::in, int::in) is semidet.
+
+threshold_ps_callseqs_both(Deep, Threshold, PSI) :-
+ PSOwn = Deep ^ ps_own,
+ PSDesc = Deep ^ ps_desc,
+ array.lookup(PSOwn, PSI, Own),
+ array.lookup(PSDesc, PSI, Desc),
+ RootOwn = root_own_info(Deep),
+ RootDesc = root_desc_info(Deep),
+ OwnCallSeqs = callseqs(Own),
+ RootOwnCallSeqs = callseqs(RootOwn),
+ DescCallSeqs = inherit_callseqs(Desc),
+ RootDescCallSeqs = inherit_callseqs(RootDesc),
+ TotalCallSeqs = OwnCallSeqs + DescCallSeqs,
+ RootTotalCallSeqs = RootOwnCallSeqs + RootDescCallSeqs,
+ 100.0 * float(TotalCallSeqs) > Threshold * float(RootTotalCallSeqs).
+
:- pred threshold_ps_allocs_self(deep::in, float::in, int::in) is semidet.
threshold_ps_allocs_self(Deep, Threshold, PSI) :-
@@ -592,71 +735,91 @@
;
Criteria = by_cost(Measurement, InclDesc, Scope),
(
- Measurement = calls,
+ Measurement = cost_calls,
% We ignore the setting of InclDesc because calls are not
% inherited from descendants, and we ignore the setting of Scope
% because sorting on "calls per call" is not useful.
CompFunc = compare_line_groups_by_calls
;
- Measurement = redos,
+ Measurement = cost_redos,
CompFunc = compare_line_groups_by_redos
;
- Measurement = time,
+ Measurement = cost_time,
InclDesc = self,
Scope = overall,
CompFunc = compare_line_groups_by_time_self_overall
;
- Measurement = time,
+ Measurement = cost_time,
InclDesc = self,
Scope = per_call,
CompFunc = compare_line_groups_by_time_self_percall
;
- Measurement = time,
+ Measurement = cost_time,
InclDesc = self_and_desc,
Scope = overall,
CompFunc = compare_line_groups_by_time_total_overall
;
- Measurement = time,
+ Measurement = cost_time,
InclDesc = self_and_desc,
Scope = per_call,
CompFunc = compare_line_groups_by_time_total_percall
;
- Measurement = allocs,
+ Measurement = cost_callseqs,
+ InclDesc = self,
+ Scope = overall,
+ CompFunc = compare_line_groups_by_callseqs_self_overall
+ ;
+ Measurement = cost_callseqs,
+ InclDesc = self,
+ Scope = per_call,
+ CompFunc = compare_line_groups_by_callseqs_self_percall
+ ;
+ Measurement = cost_callseqs,
+ InclDesc = self_and_desc,
+ Scope = overall,
+ CompFunc = compare_line_groups_by_callseqs_total_overall
+ ;
+ Measurement = cost_callseqs,
+ InclDesc = self_and_desc,
+ Scope = per_call,
+ CompFunc = compare_line_groups_by_callseqs_total_percall
+ ;
+ Measurement = cost_allocs,
InclDesc = self,
Scope = overall,
CompFunc = compare_line_groups_by_allocs_self_overall
;
- Measurement = allocs,
+ Measurement = cost_allocs,
InclDesc = self,
Scope = per_call,
CompFunc = compare_line_groups_by_allocs_self_percall
;
- Measurement = allocs,
+ Measurement = cost_allocs,
InclDesc = self_and_desc,
Scope = overall,
CompFunc = compare_line_groups_by_allocs_total_overall
;
- Measurement = allocs,
+ Measurement = cost_allocs,
InclDesc = self_and_desc,
Scope = per_call,
CompFunc = compare_line_groups_by_allocs_total_percall
;
- Measurement = words,
+ Measurement = cost_words,
InclDesc = self,
Scope = overall,
CompFunc = compare_line_groups_by_words_self_overall
;
- Measurement = words,
+ Measurement = cost_words,
InclDesc = self,
Scope = per_call,
CompFunc = compare_line_groups_by_words_self_percall
;
- Measurement = words,
+ Measurement = cost_words,
InclDesc = self_and_desc,
Scope = overall,
CompFunc = compare_line_groups_by_words_total_overall
;
- Measurement = words,
+ Measurement = cost_words,
InclDesc = self_and_desc,
Scope = per_call,
CompFunc = compare_line_groups_by_words_total_percall
@@ -752,10 +915,8 @@
line_group(FL, LL)) = comparison_result.
compare_line_groups_by_time_total_overall(Group1, Group2) = Result :-
- Quanta1 = quanta(Group1 ^ group_own) +
- inherit_quanta(Group1 ^ group_desc),
- Quanta2 = quanta(Group2 ^ group_own) +
- inherit_quanta(Group2 ^ group_desc),
+ Quanta1 = quanta(Group1 ^ group_own) + inherit_quanta(Group1 ^ group_desc),
+ Quanta2 = quanta(Group2 ^ group_own) + inherit_quanta(Group2 ^ group_desc),
compare(Result, Quanta2, Quanta1).
:- func compare_line_groups_by_time_total_percall(line_group(FL, LL),
@@ -764,10 +925,8 @@
compare_line_groups_by_time_total_percall(Group1, Group2) = Result :-
Calls1 = calls(Group1 ^ group_own),
Calls2 = calls(Group2 ^ group_own),
- Quanta1 = quanta(Group1 ^ group_own) +
- inherit_quanta(Group1 ^ group_desc),
- Quanta2 = quanta(Group2 ^ group_own) +
- inherit_quanta(Group2 ^ group_desc),
+ Quanta1 = quanta(Group1 ^ group_own) + inherit_quanta(Group1 ^ group_desc),
+ Quanta2 = quanta(Group2 ^ group_own) + inherit_quanta(Group2 ^ group_desc),
( Calls1 = 0 ->
QuantaPerCall1 = 0.0
;
@@ -780,6 +939,66 @@
),
compare(Result, QuantaPerCall2, QuantaPerCall1).
+:- func compare_line_groups_by_callseqs_self_overall(line_group(FL, LL),
+ line_group(FL, LL)) = comparison_result.
+
+compare_line_groups_by_callseqs_self_overall(Group1, Group2) = Result :-
+ CallSeqs1 = callseqs(Group1 ^ group_own),
+ CallSeqs2 = callseqs(Group2 ^ group_own),
+ compare(Result, CallSeqs2, CallSeqs1).
+
+:- func compare_line_groups_by_callseqs_self_percall(line_group(FL, LL),
+ line_group(FL, LL)) = comparison_result.
+
+compare_line_groups_by_callseqs_self_percall(Group1, Group2) = Result :-
+ Calls1 = calls(Group1 ^ group_own),
+ Calls2 = calls(Group2 ^ group_own),
+ CallSeqs1 = callseqs(Group1 ^ group_own),
+ CallSeqs2 = callseqs(Group2 ^ group_own),
+ ( Calls1 = 0 ->
+ CallSeqsPerCall1 = 0.0
+ ;
+ CallSeqsPerCall1 = float(CallSeqs1) / float(Calls1)
+ ),
+ ( Calls2 = 0 ->
+ CallSeqsPerCall2 = 0.0
+ ;
+ CallSeqsPerCall2 = float(CallSeqs2) / float(Calls2)
+ ),
+ compare(Result, CallSeqsPerCall2, CallSeqsPerCall1).
+
+:- func compare_line_groups_by_callseqs_total_overall(line_group(FL, LL),
+ line_group(FL, LL)) = comparison_result.
+
+compare_line_groups_by_callseqs_total_overall(Group1, Group2) = Result :-
+ CallSeqs1 = callseqs(Group1 ^ group_own) +
+ inherit_callseqs(Group1 ^ group_desc),
+ CallSeqs2 = callseqs(Group2 ^ group_own) +
+ inherit_callseqs(Group2 ^ group_desc),
+ compare(Result, CallSeqs2, CallSeqs1).
+
+:- func compare_line_groups_by_callseqs_total_percall(line_group(FL, LL),
+ line_group(FL, LL)) = comparison_result.
+
+compare_line_groups_by_callseqs_total_percall(Group1, Group2) = Result :-
+ Calls1 = calls(Group1 ^ group_own),
+ Calls2 = calls(Group2 ^ group_own),
+ CallSeqs1 = callseqs(Group1 ^ group_own) +
+ inherit_callseqs(Group1 ^ group_desc),
+ CallSeqs2 = callseqs(Group2 ^ group_own) +
+ inherit_callseqs(Group2 ^ group_desc),
+ ( Calls1 = 0 ->
+ CallSeqsPerCall1 = 0.0
+ ;
+ CallSeqsPerCall1 = float(CallSeqs1) / float(Calls1)
+ ),
+ ( Calls2 = 0 ->
+ CallSeqsPerCall2 = 0.0
+ ;
+ CallSeqsPerCall2 = float(CallSeqs2) / float(Calls2)
+ ),
+ compare(Result, CallSeqsPerCall2, CallSeqsPerCall1).
+
:- func compare_line_groups_by_allocs_self_overall(line_group(FL, LL),
line_group(FL, LL)) = comparison_result.
@@ -812,10 +1031,8 @@
line_group(FL, LL)) = comparison_result.
compare_line_groups_by_allocs_total_overall(Group1, Group2) = Result :-
- Alloc1 = allocs(Group1 ^ group_own) +
- inherit_allocs(Group1 ^ group_desc),
- Alloc2 = allocs(Group2 ^ group_own) +
- inherit_allocs(Group2 ^ group_desc),
+ Alloc1 = allocs(Group1 ^ group_own) + inherit_allocs(Group1 ^ group_desc),
+ Alloc2 = allocs(Group2 ^ group_own) + inherit_allocs(Group2 ^ group_desc),
compare(Result, Alloc2, Alloc1).
:- func compare_line_groups_by_allocs_total_percall(line_group(FL, LL),
@@ -824,10 +1041,8 @@
compare_line_groups_by_allocs_total_percall(Group1, Group2) = Result :-
Calls1 = calls(Group1 ^ group_own),
Calls2 = calls(Group2 ^ group_own),
- Alloc1 = allocs(Group1 ^ group_own) +
- inherit_allocs(Group1 ^ group_desc),
- Alloc2 = allocs(Group2 ^ group_own) +
- inherit_allocs(Group2 ^ group_desc),
+ Alloc1 = allocs(Group1 ^ group_own) + inherit_allocs(Group1 ^ group_desc),
+ Alloc2 = allocs(Group2 ^ group_own) + inherit_allocs(Group2 ^ group_desc),
( Calls1 = 0 ->
AllocPerCall1 = 0.0
;
@@ -872,10 +1087,8 @@
line_group(FL, LL)) = comparison_result.
compare_line_groups_by_words_total_overall(Group1, Group2) = Result :-
- Words1 = words(Group1 ^ group_own) +
- inherit_words(Group1 ^ group_desc),
- Words2 = words(Group2 ^ group_own) +
- inherit_words(Group2 ^ group_desc),
+ Words1 = words(Group1 ^ group_own) + inherit_words(Group1 ^ group_desc),
+ Words2 = words(Group2 ^ group_own) + inherit_words(Group2 ^ group_desc),
compare(Result, Words2, Words1).
:- func compare_line_groups_by_words_total_percall(line_group(FL, LL),
@@ -884,10 +1097,8 @@
compare_line_groups_by_words_total_percall(Group1, Group2) = Result :-
Calls1 = calls(Group1 ^ group_own),
Calls2 = calls(Group2 ^ group_own),
- Words1 = words(Group1 ^ group_own) +
- inherit_words(Group1 ^ group_desc),
- Words2 = words(Group2 ^ group_own) +
- inherit_words(Group2 ^ group_desc),
+ Words1 = words(Group1 ^ group_own) + inherit_words(Group1 ^ group_desc),
+ Words2 = words(Group2 ^ group_own) + inherit_words(Group2 ^ group_desc),
( Calls1 = 0 ->
WordsPerCall1 = 0.0
;
cvs diff: Diffing notes
--------------------------------------------------------------------------
mercury-reviews mailing list
Post messages to: mercury-reviews at csse.unimelb.edu.au
Administrative Queries: owner-mercury-reviews at csse.unimelb.edu.au
Subscriptions: mercury-reviews-request at csse.unimelb.edu.au
--------------------------------------------------------------------------
More information about the reviews
mailing list