[m-rev.] diff: move call_site_{static,dynamic} queries to report framework

Zoltan Somogyi zs at csse.unimelb.edu.au
Tue Aug 5 10:54:00 AEST 2008


Use reports to handle the call_site_static and call_site_dynamic queries.

deep_profiler/report.m:
	Add the two new report types.

	Give a better name to a type.

deep_profiler/create_report.m:
	Add the code for the two new report types.

	Make the predicate for creating a perf_row_data more general,
	and avoid defining the perf_row_data field-by-field.

deep_profiler/display.m:
	Rename a table_class that is now used not just by the top_procs
	command.

	Represent columns as cords, to avoid the need for keeping track
	of whether the list of columns is reversed.

deep_profiler/display_report.m:
	Add the code to handle the two new report types.

	Refactor some existing code to allow it to called by the new code.

	Conform to the other changes in report.m.

deep_profiler/html_format.m:
	Add newlines to the output, in order to make it more readable
	and to make using diff between two versions of the output feasible.

	Print the HTML title as a heading.

	Add a XXX about a disrespected control.

deep_profiler/query.m:
	Use the new method to handle the two query types.

Zoltan.

cvs diff: Diffing .
Index: create_report.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/deep_profiler/create_report.m,v
retrieving revision 1.3
diff -u -b -r1.3 create_report.m
--- create_report.m	4 Aug 2008 08:50:04 -0000	1.3
+++ create_report.m	4 Aug 2008 14:45:42 -0000
@@ -77,6 +77,16 @@
         generate_proc_dynamic_dump_report(Deep, PDI, MaybeProcDynamicDumpInfo),
         Report = report_proc_dynamic_dump(MaybeProcDynamicDumpInfo)
     ;
+        Cmd = deep_cmd_call_site_static(CSSI),
+        generate_call_site_static_dump_report(Deep, CSSI,
+            MaybeCallSiteStaticDumpInfo),
+        Report = report_call_site_static_dump(MaybeCallSiteStaticDumpInfo)
+    ;
+        Cmd = deep_cmd_call_site_dynamic(CSDI),
+        generate_call_site_dynamic_dump_report(Deep, CSDI,
+            MaybeCallSiteStaticDumpInfo),
+        Report = report_call_site_dynamic_dump(MaybeCallSiteStaticDumpInfo)
+    ;
         Cmd = deep_cmd_restart,
         error("create_report/3", "unexpected restart command")
     ;
@@ -86,8 +96,6 @@
         ; Cmd = deep_cmd_proc_callers(_, _, _)
         ; Cmd = deep_cmd_modules
         ; Cmd = deep_cmd_module(_)
-        ; Cmd = deep_cmd_call_site_static(_)
-        ; Cmd = deep_cmd_call_site_dynamic(_)
         ; Cmd = deep_cmd_raw_clique(_)
         ),
         error("create_report/3", "Command not supported: " ++ string(Cmd))
@@ -147,11 +155,11 @@
     PSPtr = proc_static_ptr(PSI),
     ( valid_proc_static_ptr(Deep, PSPtr) ->
         deep_lookup_proc_statics(Deep, PSPtr, PS),
-        RawName = PS ^ ps_raw_id,
-        RefinedName = PS ^ ps_refined_id,
-        FileName = PS ^ ps_file_name,
-        LineNumber = PS ^ ps_line_number,
-        array.max(PS ^ ps_sites, NumCallSites),
+        % Should we dump some other fields?
+        PS = proc_static(_ProcId, _DeclModule, RefinedName, RawName,
+            FileName, LineNumber, _InInterface, CallSites, _CoveragePoints,
+            _IsZeroed),
+        array.max(CallSites, NumCallSites),
         ProcStaticDumpInfo = proc_static_dump_info(PSPtr, RawName, RefinedName,
             FileName, LineNumber, NumCallSites),
         MaybeProcStaticDumpInfo = ok(ProcStaticDumpInfo)
@@ -178,97 +186,141 @@
         MaybeProcDynamicDumpInfo = error("invalid proc_dynamic index")
     ).
 
+:- pred generate_call_site_static_dump_report(deep::in, int::in,
+    maybe_error(call_site_static_dump_info)::out) is det.
+
+generate_call_site_static_dump_report(Deep, CSSI,
+        MaybeCallSiteStaticDumpInfo) :-
+    CSSPtr = call_site_static_ptr(CSSI),
+    ( valid_call_site_static_ptr(Deep, CSSPtr) ->
+        deep_lookup_call_site_statics(Deep, CSSPtr, CSS),
+        CSS = call_site_static(ContainingPSPtr, SlotNumber, CallSiteKind,
+            LineNumber, GoalPath),
+        CallSiteStaticDumpInfo = call_site_static_dump_info(CSSPtr,
+            ContainingPSPtr, SlotNumber, LineNumber, GoalPath, CallSiteKind),
+        MaybeCallSiteStaticDumpInfo = ok(CallSiteStaticDumpInfo)
+    ;
+        MaybeCallSiteStaticDumpInfo = error("invalid call_site_static index")
+    ).
+
+:- pred generate_call_site_dynamic_dump_report(deep::in, int::in,
+    maybe_error(call_site_dynamic_dump_info)::out) is det.
+
+generate_call_site_dynamic_dump_report(Deep, CSDI,
+        MaybeCallSiteDynamicDumpInfo) :-
+    CSDPtr = call_site_dynamic_ptr(CSDI),
+    ( valid_call_site_dynamic_ptr(Deep, CSDPtr) ->
+        deep_lookup_call_site_dynamics(Deep, CSDPtr, CSD),
+        CSD = call_site_dynamic(CallerPSPtr, CalleePSDPtr, Own),
+        Desc = zero_inherit_prof_info,
+        deep_lookup_call_site_static_map(Deep, CSDPtr, CSSPtr),
+        CallSiteDesc = describe_call_site(Deep, CSSPtr),
+        own_and_inherit_to_perf_row_data(Deep, CallSiteDesc, Own, Desc,
+            PerfRowData),
+        CallSiteDynamicDumpInfo = call_site_dynamic_dump_info(CSDPtr,
+            CallerPSPtr, CalleePSDPtr, PerfRowData),
+        MaybeCallSiteDynamicDumpInfo = ok(CallSiteDynamicDumpInfo)
+    ;
+        MaybeCallSiteDynamicDumpInfo = error("invalid call_site_dynamic index")
+    ).
+
 %-----------------------------------------------------------------------------%
 
     % Lookup the proc_static structure with the given PSI index number
     % and return performance information about it.
     %
-:- pred psi_to_perf_row_data(deep::in, int::in,
-    perf_row_data(report_proc)::out) is det.
+:- pred psi_to_perf_row_data(deep::in, int::in, perf_row_data(proc_desc)::out)
+    is det.
 
 psi_to_perf_row_data(Deep, PSI, RowData) :-
-    % Gather global deep profiling information.
+    PSPtr = proc_static_ptr(PSI),
+    ProcDesc = describe_proc(Deep, PSPtr),
+    deep_lookup_ps_own(Deep, PSPtr, Own),
+    deep_lookup_ps_desc(Deep, PSPtr, Desc),
+    own_and_inherit_to_perf_row_data(Deep, ProcDesc, Own, Desc, RowData).
+
+:- pred own_and_inherit_to_perf_row_data(deep::in, T::in,
+    own_prof_info::in, inherit_prof_info::in, perf_row_data(T)::out) is det.
+
+own_and_inherit_to_perf_row_data(Deep, Subject, Own, Desc, RowData) :-
+    % Look up global parameters and totals.
     ProfileStats = Deep ^ profile_stats,
     TicksPerSec = ProfileStats ^ ticks_per_sec,
     WordSize = ProfileStats ^ word_size,
-    Root = root_total_info(Deep),
-
-    PSPtr = wrap_proc_static_ptr(PSI),
 
-    % Retrive data.
-    deep_lookup_ps_own(Deep, PSPtr, Own),
-    deep_lookup_ps_desc(Deep, PSPtr, Desc),
+    Root = root_total_info(Deep),
+    TotalQuanta = inherit_quanta(Root),
+    TotalCallseqs = inherit_callseqs(Root),
+    TotalAllocs = inherit_allocs(Root),
+    TotalWords = inherit_words(Root),
 
-    % Set Subject.
-    psptr_to_report_proc(Deep, PSPtr, ReportProc),
-    RowData ^ subject = ReportProc,
-
-    % Set port counts.
-    Calls = calls(Own), % Calls is needed below, so create a variable here.
-    RowData ^ calls = Calls,
-    RowData ^ exits = exits(Own),
-    RowData ^ fails = fails(Own),
-    RowData ^ redos = redos(Own),
-    RowData ^ excps = excps(Own),
+    % Port counts.
+    Calls = calls(Own),
+    Exits = exits(Own),
+    Fails = fails(Own),
+    Redos = redos(Own),
+    Excps = excps(Own),
 
-    % Set self times.
-    TotalQuanta = inherit_quanta(Root),
+    % Self times.
     SelfTicks = quanta(Own),
     ticks_to_time(SelfTicks, TicksPerSec, SelfTime),
-    time_percall(SelfTime, Calls, SelfTimePercall),
     SelfTimePercent = percent_from_ints(SelfTicks, TotalQuanta),
-    RowData ^ self_ticks = quanta(Own),
-    RowData ^ self_time = SelfTime,
-    RowData ^ self_time_percent = SelfTimePercent,
-    RowData ^ self_time_percall = SelfTimePercall,
+    time_percall(SelfTime, Calls, SelfTimePerCall),
 
-    % Set times for self + descendants.
+    % Self + descendants times.
     Ticks = SelfTicks + inherit_quanta(Desc),
     ticks_to_time(Ticks, TicksPerSec, Time),
-    time_percall(Time, Calls, TimePercall),
     TimePercent = percent_from_ints(Ticks, TotalQuanta),
-    RowData ^ ticks = Ticks,
-    RowData ^ time = Time,
-    RowData ^ time_percent = TimePercent,
-    RowData ^ time_percall = TimePercall,
+    time_percall(Time, Calls, TimePerCall),
 
-    % Call sequence counts.
-    TotalCallseqs = inherit_callseqs(Root),
+    % Self call sequence counts.
     SelfCallseqs = callseqs(Own),
-    RowData ^ self_callseqs = SelfCallseqs,
-    RowData ^ self_callseqs_percent =
-        percent_from_ints(SelfCallseqs, TotalCallseqs),
-    RowData ^ self_callseqs_percall = divide_ints(SelfCallseqs, Calls),
+    SelfCallseqsPercent = percent_from_ints(SelfCallseqs, TotalCallseqs),
+    SelfCallseqsPerCall = divide_ints(SelfCallseqs, Calls),
 
+    % Self + descendants call sequence counts.
     Callseqs = callseqs(Own) + inherit_callseqs(Desc),
-    RowData ^ callseqs = Callseqs,
-    RowData ^ callseqs_percent = percent_from_ints(Callseqs, TotalCallseqs),
-    RowData ^ callseqs_percall = divide_ints(Callseqs, Calls),
+    CallseqsPercent = percent_from_ints(Callseqs, TotalCallseqs),
+    CallseqsPerCall = divide_ints(Callseqs, Calls),
 
-    % Set memory allocations.
-    TotalAllocs = inherit_allocs(Root),
+    % Self memory allocations.
     SelfAllocs = allocs(Own),
+    SelfAllocsPercent = percent_from_ints(SelfAllocs, TotalAllocs),
+    SelfAllocsPerCall = divide_ints(SelfAllocs, Calls),
+
+    % Self + descendants memory allocations.
     Allocs = SelfAllocs + inherit_allocs(Desc),
-    RowData ^ self_allocs = SelfAllocs,
-    RowData ^ self_allocs_percent = percent_from_ints(SelfAllocs, TotalAllocs),
-    RowData ^ self_allocs_percall = divide_ints(SelfAllocs, Calls),
-    RowData ^ allocs = Allocs,
-    RowData ^ allocs_percent = percent_from_ints(Allocs, TotalAllocs),
-    RowData ^ allocs_percall = divide_ints(Allocs, Calls),
+    AllocsPercent = percent_from_ints(Allocs, TotalAllocs),
+    AllocsPerCall = divide_ints(Allocs, Calls),
 
-    % set memory information.
-    TotalWords = inherit_words(Root),
+    % Self memory words.
     SelfWords = words(Own),
     SelfMemory = memory_words(SelfWords, WordSize),
-    RowData ^ bytes_per_word = WordSize,
-    RowData ^ self_mem = SelfMemory,
-    RowData ^ self_mem_percent = percent_from_ints(SelfWords, TotalWords),
-    RowData ^ self_mem_percall = SelfMemory / Calls,
+    SelfMemoryPercent = percent_from_ints(SelfWords, TotalWords),
+    SelfMemoryPerCall = SelfMemory / Calls,
+
+    % Self + descendants memory words.
     Words = SelfWords + inherit_words(Desc),
     Memory = memory_words(Words, WordSize),
-    RowData ^ mem = Memory,
-    RowData ^ mem_percent = percent_from_ints(Words, TotalWords),
-    RowData ^ mem_percall = Memory / Calls.
+    MemoryPercent = percent_from_ints(Words, TotalWords),
+    MemoryPerCall = Memory / Calls,
+
+    RowData = perf_row_data(Subject,
+        Calls, Exits, Fails, Redos, Excps,
+
+        SelfTicks, SelfTime, SelfTimePercent, SelfTimePerCall,
+        Ticks, Time, TimePercent, TimePerCall,
+
+        SelfCallseqs, SelfCallseqsPercent, SelfCallseqsPerCall,
+        Callseqs, CallseqsPercent, CallseqsPerCall,
+
+        SelfAllocs, SelfAllocsPercent, SelfAllocsPerCall,
+        Allocs, AllocsPercent, AllocsPerCall,
+
+        WordSize,
+        SelfMemory, SelfMemoryPercent, SelfMemoryPerCall,
+        Memory, MemoryPercent, MemoryPerCall
+    ).
 
 %-----------------------------------------------------------------------------%
 
@@ -291,10 +343,9 @@
 
     % Create a report_proc structure for a given proc static pointer.
     %
-:- pred psptr_to_report_proc(deep::in, proc_static_ptr::in, report_proc::out)
-    is det.
+:- func describe_proc(deep, proc_static_ptr) = proc_desc.
 
-psptr_to_report_proc(Deep, PSPtr, Report) :-
+describe_proc(Deep, PSPtr) = ProcDesc :-
     ( valid_proc_static_ptr(Deep, PSPtr) ->
         deep_lookup_proc_statics(Deep, PSPtr, PS),
         FileName = PS ^ ps_file_name,
@@ -305,7 +356,30 @@
         LineNumber = 0,
         RefinedName = "mercury_runtime"
     ),
-    Report = report_proc(PSPtr, FileName, LineNumber, RefinedName).
+    ProcDesc = proc_desc(PSPtr, FileName, LineNumber, RefinedName).
+
+    % Create a report_call_site structure for a given call site static pointer.
+    %
+:- func describe_call_site(deep, call_site_static_ptr) = call_site_desc.
+
+describe_call_site(Deep, CSSPtr) = CallSiteDesc :-
+    ( valid_call_site_static_ptr(Deep, CSSPtr) ->
+        deep_lookup_call_site_statics(Deep, CSSPtr, CSS),
+        CSS = call_site_static(ContainingPSPtr, SlotNumber, _Kind, LineNumber,
+            GoalPath),
+        deep_lookup_proc_statics(Deep, ContainingPSPtr, ContainingPS),
+        FileName = ContainingPS ^ ps_file_name,
+        RefinedName = ContainingPS ^ ps_refined_id
+    ;
+        ContainingPSPtr = dummy_proc_static_ptr,
+        FileName = "",
+        LineNumber = 0,
+        RefinedName = "mercury_runtime",
+        SlotNumber = -1,
+        GoalPath = ""
+    ),
+    CallSiteDesc = call_site_desc(CSSPtr, ContainingPSPtr,
+        FileName, LineNumber, RefinedName, SlotNumber, GoalPath).
 
 %-----------------------------------------------------------------------------%
 %
Index: display.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/deep_profiler/display.m,v
retrieving revision 1.3
diff -u -b -r1.3 display.m
--- display.m	4 Aug 2008 08:50:04 -0000	1.3
+++ display.m	4 Aug 2008 15:45:13 -0000
@@ -17,13 +17,14 @@
 :- module display.
 :- interface.
 
+:- import_module measurement_units.
+:- import_module query.
+
+:- import_module cord.
 :- import_module list.
 :- import_module maybe.
 :- import_module string.
 
-:- import_module measurement_units.
-:- import_module query.
-
 %-----------------------------------------------------------------------------%
 
 :- type display
@@ -111,7 +112,7 @@
 
 :- type table_class
     --->    table_class_plain
-    ;       table_class_top_procs.
+    ;       table_class_boxed.
 
 :- type table_col_class
     --->    table_col_class_allocations
@@ -184,18 +185,18 @@
 % Predicates for working with display structures.
 %
 
-    % If given a header this predicate adds it to the head of the list and adds
-    % the correct number of columns to the column count.
+    % If given a header, this predicate adds it to the end of the cord
+    % and adds the correct number of columns to the column count.
     %
 :- pred table_maybe_add_header_col(maybe(table_header_cell)::in,
-    list(table_header_cell)::in, list(table_header_cell)::out,
+    cord(table_header_cell)::in, cord(table_header_cell)::out,
     int::in, int::out) is det.
 
-    % Given a header this predicate adds it to the head of the list and adds
-    % the correct number of columns to the column count.
+    % Given a header, this predicate adds it to the end of the cord
+    % and adds the correct number of columns to the column count.
     %
 :- pred table_add_header_col(table_header_cell::in,
-    list(table_header_cell)::in, list(table_header_cell)::out,
+    cord(table_header_cell)::in, cord(table_header_cell)::out,
     int::in, int::out) is det.
 
 %-----------------------------------------------------------------------------%
@@ -206,20 +207,19 @@
 :- import_module int.
 
 table_maybe_add_header_col(no, !Cols, !NumCols).
-
 table_maybe_add_header_col(yes(HeaderCol), !Cols, !NumCols) :-
     table_add_header_col(HeaderCol, !Cols, !NumCols).
 
 table_add_header_col(Cell, !Cols, !NumCols) :-
     (
         Cell = table_header_cell(_, _),
-        ColsAddend = 1
+        CellCols = 1
     ;
         Cell = table_header_group(_, SubHeaders, _),
-        length(SubHeaders, ColsAddend)
+        list.length(SubHeaders, CellCols)
     ),
-    !:NumCols = !.NumCols + ColsAddend,
-    list.cons(Cell, !Cols).
+    !:Cols = cord.snoc(!.Cols, Cell),
+    !:NumCols = !.NumCols + CellCols.
 
 %-----------------------------------------------------------------------------%
 :- end_module display.
Index: display_report.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/deep_profiler/display_report.m,v
retrieving revision 1.3
diff -u -b -r1.3 display_report.m
--- display_report.m	4 Aug 2008 08:50:04 -0000	1.3
+++ display_report.m	4 Aug 2008 16:14:57 -0000
@@ -39,6 +39,7 @@
 
 :- import_module array.
 :- import_module bool.
+:- import_module cord.
 :- import_module counter.
 :- import_module float.
 :- import_module int.
@@ -90,6 +91,26 @@
             MaybeProcDynamicDumpInfo = error(Msg),
             Display = display(no, [display_message(Msg)])
         )
+    ;
+        Report = report_call_site_static_dump(MaybeCallSiteStaticDumpInfo),
+        (
+            MaybeCallSiteStaticDumpInfo = ok(CallSiteStaticDumpInfo),
+            display_report_call_site_static_dump(Prefs, CallSiteStaticDumpInfo,
+                Display)
+        ;
+            MaybeCallSiteStaticDumpInfo = error(Msg),
+            Display = display(no, [display_message(Msg)])
+        )
+    ;
+        Report = report_call_site_dynamic_dump(MaybeCallSiteDynamicDumpInfo),
+        (
+            MaybeCallSiteDynamicDumpInfo = ok(CallSiteDynamicDumpInfo),
+            display_report_call_site_dynamic_dump(Prefs,
+                CallSiteDynamicDumpInfo, Display)
+        ;
+            MaybeCallSiteDynamicDumpInfo = error(Msg),
+            Display = display(no, [display_message(Msg)])
+        )
     ).
 
 %-----------------------------------------------------------------------------%
@@ -354,6 +375,98 @@
     EmptyCell = table_cell(s("")),
     Row = table_row([EmptyCell, CSDCell]).
 
+    % Create a display_report structure for a call_site_static_dump report.
+    %
+:- pred display_report_call_site_static_dump(preferences::in,
+    call_site_static_dump_info::in, display::out) is det.
+
+display_report_call_site_static_dump(Prefs, CallSiteStaticDumpInfo, Display) :-
+    CallSiteStaticDumpInfo = call_site_static_dump_info(CSSPtr,
+        ContainingPSPtr, SlotNumber, LineNumber, GoalPath, CallSiteKind),
+    CSSPtr = call_site_static_ptr(CSSI),
+    string.format("Dump of call_site_static %d", [i(CSSI)], Title),
+    ContainingPSPtr = proc_static_ptr(ContainingPSI),
+
+    ContainingProcStaticLink = deep_link(deep_cmd_proc_static(ContainingPSI),
+        yes(Prefs), string.int_to_string(ContainingPSI), link_class_link),
+
+    (
+        CallSiteKind = normal_call_and_callee(CalleePSPtr, TypeSpecDesc),
+        CalleePSPtr = proc_static_ptr(CalleePSI),
+        CalleeDesc0 = "normal, callee " ++ string.int_to_string(CalleePSI),
+        ( TypeSpecDesc = "" ->
+            CalleeDesc = CalleeDesc0
+        ;
+            CalleeDesc = CalleeDesc0 ++ " typespec " ++ TypeSpecDesc
+        ),
+        CalleeProcStaticLink = deep_link(deep_cmd_proc_static(CalleePSI),
+            yes(Prefs), CalleeDesc, link_class_link),
+        CallSiteKindData = l(CalleeProcStaticLink)
+    ;
+        CallSiteKind = special_call_and_no_callee,
+        CallSiteKindData = s("special_call")
+    ;
+        CallSiteKind = higher_order_call_and_no_callee,
+        CallSiteKindData = s("higher_order_call")
+    ;
+        CallSiteKind = method_call_and_no_callee,
+        CallSiteKindData = s("method_call")
+    ;
+        CallSiteKind = callback_and_no_callee,
+        CallSiteKindData = s("callback")
+    ),
+
+    Values =
+        [("Containing proc_static:" - l(ContainingProcStaticLink)),
+        ("Slot number:"             - i(SlotNumber)),
+        ("Line number:"             - i(LineNumber)),
+        ("Goal path:"               - s(GoalPath)),
+        ("Call site kind:"          - CallSiteKindData)],
+
+    Rows = list.map(make_labelled_table_row, Values),
+    Table = table(table_class_plain, 2, no, Rows),
+    Display = display(yes(Title), [display_table(Table)]).
+
+    % Create a display_report structure for a call_site_dynamic_dump report.
+    %
+:- pred display_report_call_site_dynamic_dump(preferences::in,
+    call_site_dynamic_dump_info::in, display::out) is det.
+
+display_report_call_site_dynamic_dump(Prefs, CallSiteStaticDumpInfo,
+        Display) :-
+    CallSiteStaticDumpInfo = call_site_dynamic_dump_info(CSDPtr,
+        CallerPSPtr, CalleePSPtr, RowData),
+    CSDPtr = call_site_dynamic_ptr(CSDI),
+    string.format("Dump of call_site_dynamic %d", [i(CSDI)], Title),
+
+    CallerPSPtr = proc_dynamic_ptr(CallerPSI),
+    CallerProcDynamicLink = deep_link(deep_cmd_proc_dynamic(CallerPSI),
+        yes(Prefs), string.int_to_string(CallerPSI), link_class_link),
+
+    CalleePSPtr = proc_dynamic_ptr(CalleePSI),
+    CalleeProcDynamicLink = deep_link(deep_cmd_proc_dynamic(CalleePSI),
+        yes(Prefs), string.int_to_string(CalleePSI), link_class_link),
+
+    FirstValues =
+        [("Caller proc_dynamic:"    - l(CallerProcDynamicLink)),
+        ("Callee proc_dynamic:"     - l(CalleeProcDynamicLink))],
+
+    FirstRows = list.map(make_labelled_table_row, FirstValues),
+    FirstTable = table(table_class_plain, 2, no, FirstRows),
+
+    % The value of Ordering here shouldn't matter.
+    Ordering = report_ordering(rank_range(1, 100), cost_time, self, overall),
+    TableInfo = table_info(table_class_boxed, non_ranked, Prefs, Ordering),
+
+    proc_table_header(TableInfo, NumCols, Header),
+    perf_table_row(TableInfo, call_site_desc_to_cell,
+        RowData, PerfRow, 1, _),
+    PerfTable =
+        table(TableInfo ^ table_class, NumCols, yes(Header), [PerfRow]),
+
+    Display = display(yes(Title),
+        [display_table(FirstTable), display_table(PerfTable)]).
+
 %-----------------------------------------------------------------------------%
 
     % Create a phrase describing how the top procedures may be sorted.
@@ -406,21 +519,18 @@
             ).
 
 :- pred top_procs_table(preferences::in, report_ordering::in,
-    list(perf_row_data(report_proc))::in, table::out) is det.
+    list(perf_row_data(proc_desc))::in, table::out) is det.
 
 top_procs_table(Prefs, Ordering, TopProcs, Table) :-
-    TableInfo = table_info(table_class_top_procs, ranked, Prefs, Ordering),
+    TableInfo = table_info(table_class_boxed, ranked, Prefs, Ordering),
     proc_table(TableInfo, TopProcs, Table).
 
 %-----------------------------------------------------------------------------%
 %
 % Code for creating procedure tables.
 %
-
-%
 % TODO: The code in this section should be generalised as new reports are added
-% which may have simliar tables.
-%
+% which may have similar tables.
 
     % Describes whether a table should be ranked or not,  This means that each
     % item has an ordinal number associated with it in an initial column
@@ -432,13 +542,14 @@
 
     % Produce a table for all these procedures.
     %
-:- pred proc_table(table_info::in, list(perf_row_data(report_proc))::in,
+:- pred proc_table(table_info::in, list(perf_row_data(proc_desc))::in,
     table::out) is det.
 
 proc_table(TableInfo, TopProcs, Table) :-
     % Later add support for non-ranked tables.
     proc_table_header(TableInfo, NumCols, Header),
-    list.map_foldl(proc_table_row(TableInfo), TopProcs, Rows, 1, _),
+    list.map_foldl(perf_table_row(TableInfo, proc_desc_to_cell),
+        TopProcs, Rows, 1, _),
     Table = table(TableInfo ^ table_class, NumCols, yes(Header), Rows).
 
 %-----------------------------------------------------------------------------%
@@ -527,10 +638,13 @@
     % Convert row data of procedures from the deep profiler into a table row
     % according to the preferences.
     %
-:- pred proc_table_row(table_info::in, perf_row_data(report_proc)::in,
-    table_row::out, int::in, int::out) is det.
+:- pred perf_table_row(table_info::in,
+    (func(table_info, Subject) = table_cell)::in,
+    perf_row_data(Subject)::in, table_row::out,
+    int::in, int::out) is det.
 
-proc_table_row(TableInfo, RowData, table_row(Cells), Rank, Rank+1) :-
+perf_table_row(TableInfo, SubjectCellFunc, RowData, table_row(Cells),
+        Rank, Rank + 1) :-
     Ranked = TableInfo ^ table_ranked,
     Prefs = TableInfo ^ prefs,
     Fields = Prefs ^ pref_fields,
@@ -545,7 +659,7 @@
     ),
 
     % The name of the procedure,
-    proc_to_cell(TableInfo, RowData ^ subject, ProcCell),
+    SubjectCells = [SubjectCellFunc(TableInfo, RowData ^ subject)],
 
     % Build the port counts cells.
     PortFields = Fields ^ port_fields,
@@ -689,17 +803,8 @@
         )
     ),
 
-    Cells = RankCells ++ cons(ProcCell, PortCells ++ TimeCells ++
-        CallSeqsCells ++ AllocCells ++ MemoryCells).
-
-:- pred proc_to_cell(table_info::in, report_proc::in, table_cell::out) is det.
-
-proc_to_cell(TableInfo, ReportProc, table_cell(Data)) :-
-    Prefs = TableInfo ^ prefs,
-    ReportProc = report_proc(PSPtr, _, _, Name),
-    PSPtr = proc_static_ptr(PSIndex),
-    Cmd = deep_cmd_proc(PSIndex),
-    Data = l(deep_link(Cmd, yes(Prefs), Name, link_class_link)).
+    Cells = RankCells ++ SubjectCells ++ PortCells ++ TimeCells ++
+        CallSeqsCells ++ AllocCells ++ MemoryCells.
 
     % Create the table header cell for the timing fields.
     %
@@ -876,7 +981,7 @@
     some [!NumCols, !Cols]
     (
         !:NumCols = 0,
-        !:Cols = [],
+        !:Cols = cord.empty,
         (
             Ranked = ranked,
             RankedHeaderCell =
@@ -905,7 +1010,7 @@
         proc_table_memory_header(TableInfo, Fields, MaybeMemoryHeader),
         table_maybe_add_header_col(MaybeMemoryHeader, !Cols, !NumCols),
 
-        Header = table_header(reverse(!.Cols)),
+        Header = table_header(cord.list(!.Cols)),
         NumCols = !.NumCols
     ).
 
@@ -1247,6 +1352,29 @@
 
 %-----------------------------------------------------------------------------%
 
+:- func proc_desc_to_cell(table_info, proc_desc) = table_cell.
+
+proc_desc_to_cell(TableInfo, ProcDesc) = table_cell(Data) :-
+    Prefs = TableInfo ^ prefs,
+    ProcDesc = proc_desc(PSPtr, _FileName, _LineNumber, RefinedName),
+    PSPtr = proc_static_ptr(PSI),
+    Cmd = deep_cmd_proc(PSI),
+    Data = l(deep_link(Cmd, yes(Prefs), RefinedName, link_class_link)).
+
+:- func call_site_desc_to_cell(table_info, call_site_desc) = table_cell.
+
+call_site_desc_to_cell(TableInfo, CallSiteDesc) = table_cell(Data) :-
+    Prefs = TableInfo ^ prefs,
+    CallSiteDesc = call_site_desc(CSSPtr, _ContainerPSPtr,
+        _FileName, _LineNumber, RefinedName, SlotNumber, GoalPath),
+    string.format("%s @ %s #%d", [s(RefinedName), s(GoalPath), i(SlotNumber)],
+        Name),
+    CSSPtr = call_site_static_ptr(CSSI),
+    Cmd = deep_cmd_call_site_static(CSSI),
+    Data = l(deep_link(Cmd, yes(Prefs), Name, link_class_link)).
+
+%-----------------------------------------------------------------------------%
+
     % Make a table row with two columns: a label and a value.
     %
 :- func make_labelled_table_row(pair(string, table_data)) = table_row.
Index: html_format.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/deep_profiler/html_format.m,v
retrieving revision 1.24
diff -u -b -r1.24 html_format.m
--- html_format.m	4 Aug 2008 08:50:04 -0000	1.24
+++ html_format.m	4 Aug 2008 16:21:24 -0000
@@ -197,19 +197,22 @@
         str_to_html(Deep ^ data_file_name),
     (
         MaybeSubTitle = no,
-        Title = MainTitle
+        Title = MainTitle,
+        HeadingHTML = empty_html
     ;
         MaybeSubTitle = yes(Subtitle),
-        Title = MainTitle ++ str_to_html(" - ") ++ str_to_html(Subtitle)
+        SubTitleHTML = str_to_html(Subtitle),
+        Title = MainTitle ++ str_to_html(" - ") ++ SubTitleHTML,
+        HeadingHTML = wrap_tags("<h3>", "</h3>\n", SubTitleHTML)
     ),
-    TitleHTML = wrap_tags("<title>", "</title>", Title),
+    TitleHTML = wrap_tags("<title>", "</title>\n", Title),
     deep_to_http_context(Deep, HTTPContext),
     map_join_html(item_to_html("<div>\n", "</div>\n", HTTPContext),
         Items, ItemsHTML),
     HTML = doc_type_html ++
-        wrap_tags("<html>", "</html>",
-            wrap_tags("<head>", "</head>", TitleHTML ++ css_style_html) ++
-            wrap_tags("<body>", "</body>", ItemsHTML)
+        wrap_tags("<html>", "</html>\n",
+            wrap_tags("<head>", "</head>\n", TitleHTML ++ css_style_html) ++
+            wrap_tags("<body>", "</body>\n", HeadingHTML ++ ItemsHTML)
         ).
 
 :- func doc_type_html = html.
@@ -217,11 +220,14 @@
 doc_type_html =
     str_to_html(
         "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\"
-        \"http://www.w3.org/TR/html4/strict.dtd\">").
+        \"http://www.w3.org/TR/html4/strict.dtd\">\n").
 
 :- func css_style_html = html.
 
 css_style_html =
+    % XXX This ignores colour_column_groups. We should respect it,
+    % and process it either here, or when converting table columns to HTML.
+
     str_to_html("
         <style type=\"text/css\">
             td.allocations
@@ -265,19 +271,19 @@
             {
                 border-style: none;
             }
-            table.top_procs
+            table.boxed
             {
                 border-width: 1px 1px 1px 1px;
                 border-spacing: 2px;
                 border-style: outset outset outset outset;
             }
-            table.top_procs th
+            table.boxed th
             {
                 border-width: 1px 1px 1px 1px;
                 padding: 3px 3px 3px 3px;
                 border-style: inset inset inset inset;
             }
-            table.top_procs td
+            table.boxed td
             {
                 border-width: 1px 1px 1px 1px;
                 padding: 3px 3px 3px 3px;
@@ -453,7 +459,7 @@
     table_col_class_to_string(Class, ClassStr),
     StartTag = string.format("<th rowspan=\"%s\" colspan=\"%s\" class=\"%s\">",
         [s(RowSpan), s(ColSpan), s(ClassStr)]),
-    EndTag = "</th>",
+    EndTag = "</th>\n",
     HTML = wrap_tags(StartTag, EndTag, ContentsHTML).
 
 %-----------------------------------------------------------------------------%
@@ -479,7 +485,7 @@
     table_col_class_to_string(Class, ClassStr),
     TableDataHTML = table_data_to_html(HTTPContext, TableData),
     StartTag = string.format("<th class=\"%s\">", [s(ClassStr)]),
-    EndTag = "</th>",
+    EndTag = "</th>\n",
     HTML = wrap_tags(StartTag, EndTag, TableDataHTML).
 
 %-----------------------------------------------------------------------------%
@@ -505,8 +511,7 @@
         table_col_class_to_string(Class, ClassStr),
         % fold_up is inclusive of the higher number.
         fold_up(insert_col_classmap(ClassStr),
-            !.ColNum, !.ColNum + NumSubCols - 1,
-            !ClassMap)
+            !.ColNum, !.ColNum + NumSubCols - 1, !ClassMap)
     ),
     !:ColNum = !.ColNum + NumSubCols.
 
@@ -530,13 +535,13 @@
         TableRow = table_section_header(Contents),
         ContentsHTML = table_data_to_html(HTTPContext, Contents),
         StartTag = string.format("<tr><td colspan=\"%d\">", [i(NumCols)]),
-        EndTag = "</td></tr>",
+        EndTag = "</td></tr>\n",
         HTML = wrap_tags(StartTag, EndTag, ContentsHTML)
     ;
         TableRow = table_row(Cells),
         map_join_html_count(table_cell_to_html(HTTPContext, MaybeColClassMap),
             0, Cells, InnerHTML),
-        HTML = wrap_tags("<tr>", "</tr>", InnerHTML)
+        HTML = wrap_tags("<tr>", "</tr>\n", InnerHTML)
     ).
 
 %-----------------------------------------------------------------------------%
@@ -571,7 +576,7 @@
         ),
         CellHTML = table_data_to_html(HTTPContext, CellData),
         StartTag = string.format("<td class=\"%s\">", [s(ClassStr)]),
-        EndTag = "</td>",
+        EndTag = "</td>\n",
         HTML = wrap_tags(StartTag, EndTag, CellHTML)
     ).
 
@@ -626,7 +631,7 @@
 :- func table_class_to_string(table_class) = string.
 
 table_class_to_string(table_class_plain) = "plain".
-table_class_to_string(table_class_top_procs) = "top_procs".
+table_class_to_string(table_class_boxed) = "boxed".
 
 %-----------------------------------------------------------------------------%
 
Index: query.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/deep_profiler/query.m,v
retrieving revision 1.23
diff -u -b -r1.23 query.m
--- query.m	4 Aug 2008 08:50:04 -0000	1.23
+++ query.m	4 Aug 2008 16:26:29 -0000
@@ -308,6 +308,8 @@
     ; Cmd = deep_cmd_top_procs(_, _, _, _)
     ; Cmd = deep_cmd_proc_static(_)
     ; Cmd = deep_cmd_proc_dynamic(_)
+    ; Cmd = deep_cmd_call_site_static(_)
+    ; Cmd = deep_cmd_call_site_dynamic(_)
     ),
     create_report(Cmd, Deep, Report),
     Display = report_to_display(Deep, Prefs, Report),
@@ -328,6 +330,10 @@
 %     HTML = generate_proc_static_debug_page(PSI, Deep).
 % exec(deep_cmd_proc_dynamic(PDI), _Pref, Deep, HTML, !IO) :-
 %     HTML = generate_proc_dynamic_debug_page(PDI, Deep).
+% exec(deep_cmd_call_site_static(CSSI), _Pref, Deep, HTML, !IO) :-
+%     HTML = generate_call_site_static_debug_page(CSSI, Deep).
+% exec(deep_cmd_call_site_dynamic(CSDI), _Pref, Deep, HTML, !IO) :-
+%     HTML = generate_call_site_dynamic_debug_page(CSDI, Deep).
 
 exec(Cmd, Pref, Deep, HTML, !IO) :-
     Cmd = deep_cmd_root(MaybePercent),
@@ -387,10 +393,6 @@
             "There is no procedure with that number.\n" ++
             page_footer(Cmd, Pref, Deep)
     ).
-exec(deep_cmd_call_site_static(CSSI), _Pref, Deep, HTML, !IO) :-
-    HTML = generate_call_site_static_debug_page(CSSI, Deep).
-exec(deep_cmd_call_site_dynamic(CSDI), _Pref, Deep, HTML, !IO) :-
-    HTML = generate_call_site_dynamic_debug_page(CSDI, Deep).
 exec(deep_cmd_raw_clique(CI), _Pref, Deep, HTML, !IO) :-
     HTML = generate_clique_debug_page(CI, Deep).
 
@@ -1551,7 +1553,8 @@
     deep_lookup_csd_desc(Deep, CSDPtr, CallSiteDesc),
     deep_lookup_clique_index(Deep, CalleePDPtr, CalleeCliquePtr),
     call_site_dynamic_context(Deep, CSDPtr, FileName, LineNumber),
-    Context = string.format("%s:%d", [s(escape_break_html_string(FileName)), i(LineNumber)]),
+    Context = string.format("%s:%d",
+        [s(escape_break_html_string(FileName)), i(LineNumber)]),
     HTML = call_to_html(Pref, Deep, CallSiteDisplay, Context,
         CallerPDPtr, CalleePDPtr, MaybeCallerCliquePtr, CalleeCliquePtr),
     ProcName = escape_break_html_string(proc_dynamic_name(Deep, CalleePDPtr)),
Index: report.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/deep_profiler/report.m,v
retrieving revision 1.3
diff -u -b -r1.3 report.m
--- report.m	4 Aug 2008 08:50:04 -0000	1.3
+++ report.m	4 Aug 2008 14:40:42 -0000
@@ -38,7 +38,11 @@
     ;       report_menu(maybe_error(menu_info))
     ;       report_top_procs(maybe_error(top_procs_info))
     ;       report_proc_static_dump(maybe_error(proc_static_dump_info))
-    ;       report_proc_dynamic_dump(maybe_error(proc_dynamic_dump_info)).
+    ;       report_proc_dynamic_dump(maybe_error(proc_dynamic_dump_info))
+    ;       report_call_site_static_dump(
+                maybe_error(call_site_static_dump_info))
+    ;       report_call_site_dynamic_dump(
+                maybe_error(call_site_dynamic_dump_info)).
 
 :- type message_info
     --->    message_info(
@@ -73,7 +77,7 @@
                 % the procedures in this report.
 
                 ordering                    :: report_ordering,
-                top_procs                   :: list(perf_row_data(report_proc))
+                top_procs                   :: list(perf_row_data(proc_desc))
             ).
 
 :- type proc_static_dump_info
@@ -96,6 +100,24 @@
                 pddi_call_sites             :: list(call_site_array_slot)
             ).
 
+:- type call_site_static_dump_info
+    --->    call_site_static_dump_info(
+                cssdi_cssptr                :: call_site_static_ptr,
+                cssdi_containing_psptr      :: proc_static_ptr,
+                cssdi_slot_number           :: int,
+                cssdi_line_number           :: int,
+                cssdi_goal_path             :: string,
+                cssdi_callee                :: call_site_kind_and_callee
+            ).
+
+:- type call_site_dynamic_dump_info
+    --->    call_site_dynamic_dump_info(
+                csddi_csdptr                :: call_site_dynamic_ptr,
+                csddi_caller_pdptr          :: proc_dynamic_ptr,
+                csddi_callee_pdptr          :: proc_dynamic_ptr,
+                csddi_own_perf              :: perf_row_data(call_site_desc)
+            ).
+
 :- type perf_row_data(T)
     --->    perf_row_data(
                 % The item represented by this data row.
@@ -168,15 +190,29 @@
                 scope                       :: measurement_scope
             ).
 
-    % The representation of a procedure in the report structure, including
+    % The representation of a procedure in a report structure, including
     % information about its location in Mercury source code.
     %
-:- type report_proc
-    --->    report_proc(
+:- type proc_desc
+    --->    proc_desc(
                 proc_static_ptr             :: proc_static_ptr,
-                proc_filename               :: string,
-                proc_linenumber             :: int,
-                proc_name                   :: string
+                proc_file_name              :: string,
+                proc_line_number            :: int,
+                proc_refined_name           :: string
+            ).
+
+    % The representation of a call site in a report structure, including
+    % information about its location in Mercury source code.
+    %
+:- type call_site_desc
+    --->    call_site_desc(
+                call_site_static_ptr        :: call_site_static_ptr,
+                call_site_container         :: proc_static_ptr,
+                call_site_file_name         :: string,
+                call_site_line_number       :: int,
+                call_site_refined_name      :: string,
+                call_site_slot_number       :: int,
+                call_site_goal_path         :: string
             ).
 
 %-----------------------------------------------------------------------------%
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