mirror of
https://github.com/Mercury-Language/mercury.git
synced 2025-12-15 05:44:58 +00:00
Estimated hours taken: 80 Branches: main Major enhancements of the deep profiler. The most important ones are: - The addition of several new classes of preferences, including: the use of colour, boxing, sorting, summarizing of higher order call sites, and time formats. - Making preferences persistent across different queries, so that once a preference is set, it "sticks" until the user changes it. Previously, preferences stuck during query sequences of the same command type. - Several new command types: - listing all the modules of the program - listing all the procedures in a module - listing all the callers of a procedure, grouped by calling call site, procedure, module, or clique, and filtering out certain classes of ancestors - jumping into the call graph close to the action - restarting the server (useful when the data file changes) - New optional columns showing time per call, allocations per call and words allocated per call. - Can now display memory consumption in bytes as well as words. - More robustness in the face of external events, e.g. machine shutdowns. - Fix a bug reported by Tom in the summaries of procedures that make higher order calls. The new functionality required adding some fields to ProcStatic structures; as a result, compilers and runtime systems that have this change are incompatible with compilers and runtime systems before this change in deep profiling grades. (They of course remain compatible in other grades.) compiler/deep_profiling.m: compiler/layout.m: compiler/layout_out.m: Add two new fields to ProcStatic structures, one giving the line number of procedure's context and one stating whether the procedure is exported from its module. compiler/layout.m: Be consistent about filename vs file_name in field names. compiler/*.m: Minor changes to handle the new fields. deep_profiler/interface.m: Define new command types, modify some of the parameters of existing ones, and delete obsolete ones. Define the types and predicates used by the new system of preferences, Update the predicates for recognizing and generating queries accordingly. Make the order of declarations and definitions more consistent. deep_profiler/split.m: Complete rewrite of the only predicate of this module. The old split predicate deleted any empty substrings resulting from the breakup of the original string. The new one preserves them, because they are needed by the new encoding scheme used in interface.m. deep_profiler/query.m: New module, containing code dealing with the computational issues of queries. Some of its code is old (from server.m), much of it is new. deep_profiler/html_format.m: New module, containing code dealing with HTML formatting. Some of its code is old (from server.m), much of it is new. deep_profiler/top_procs.m: New module, containing code dealing with issues involving sorting by various criteria. Some of its code is old (from server.m), much of it is new. deep_profiler/exclude.m: New module to handle contour exclusion. This means that when listing the callers of a procedure, we display the nearest parent that is *not* excluded by virtue of being in a given module. The set of modules so excluded forms a contour drawn through the program. deep_profiler/mdprof_cgi.m: deep_profiler/mdprof_server.m: deep_profiler/server.m: Minor changes to adapt to the new system of preferences. deep_profiler/array_util.m: Add a mode to foldl2. deep_profiler/io_combinator.m: Add predicates for reading in sequences of ten things. deep_profiler/measurements.m: Add a function needed by new code. deep_profiler/timeout.m: Make the profiler robust in the face of signals. deep_profiler/canonical.m: Some more work towards working canonicalization; not there yet. Move some procedures to profile.m, since other modules also need them now. deep_profiler/profile.m: Add the new fields to ProcStatic structures. Record the word size. Record more information about procedures whose activation counters are ever zeroed, in order to allow query.m to avoid giving misleading information in cases where a procedure calls itself through a higher order call site. Record information about the modules of the program. Add a bunch of lookup predicates, some moved from canonical.m. deep_profiler/call_graph.m: Minor changes to conform to changes in profile.m. deep_profiler/startup.m: Fill in the new parts of the profile data structure. deep_profiler/read_profile.m: Read the new fields in ProcStatic structures. Read in the id of the root node as a fixed part of the header, not as a node. Read in the word size. Make it easier to find all the debugging output sites. Record, for each call site which can call more than one procedure, whether this causes the caller's ProcStatic structure's activation count to be zeroed. runtime/mercury_deep_profiling.h: Add the new fields to ProcStatic structures. runtime/mercury_deep_profiling.c: Write out the new fields to ProcStatic structures. Write out the id of the root node as a fixed part of the header, not as a node. Write out the word size. Remove incorrect L suffixes on constants. Record that the artificial procedure "parent of main" is called once, not zero times, to avoid division by zero when computing per-call statistics. runtime/mercury_deep_profiling_hand.h: Add the new fields to the macros for creating ProcStatic structures. runtime/mercury_ho_call.c: library/array.m: library/builtin.m: library/exception.m: library/std_util.m: Add the new fields to the invocations of those macros.
186 lines
5.8 KiB
Mathematica
186 lines
5.8 KiB
Mathematica
%-----------------------------------------------------------------------------%
|
|
% Copyright (C) 2001 The University of Melbourne.
|
|
% This file may only be copied under the terms of the GNU General
|
|
% Public License - see the file COPYING in the Mercury distribution.
|
|
%-----------------------------------------------------------------------------%
|
|
%
|
|
% Definitions of Mercury types for representing layout structures within
|
|
% the compiler. Layout structures are generated by the compiler, and are
|
|
% used by the parts of the runtime system that need to look at the stacks
|
|
% (and sometimes the registers) and make sense of their contents. The parts
|
|
% of the runtime system that need to do this include exception handling,
|
|
% the debugger, the deep profiler and (eventually) the accurate garbage
|
|
% collector.
|
|
%
|
|
% When output by layout_out.m, values of most these types will correspond
|
|
% to the C types defined in runtime/mercury_stack_layout.h or
|
|
% runtime/mercury_deep_profiling.h; the documentation of those types
|
|
% can be found there. The names of the C types are listed next to the
|
|
% function symbol whose arguments represent their contents.
|
|
%
|
|
% The code to generate values of these types is in stack_layout.m and
|
|
% deep_profiling.m.
|
|
%
|
|
% This module should be, but as yet isn't, independent of whether we are
|
|
% compiling to LLDS or MLDS.
|
|
%
|
|
% Author: zs.
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
:- module layout.
|
|
|
|
:- interface.
|
|
|
|
:- import_module prog_data, trace_params, llds, rtti, hlds_goal.
|
|
:- import_module bool, std_util, list, assoc_list.
|
|
|
|
:- type layout_data
|
|
---> label_layout_data( % defines MR_Label_Layout
|
|
label :: label,
|
|
proc_layout_name :: layout_name,
|
|
maybe_port :: maybe(trace_port),
|
|
maybe_goal_path :: maybe(int), % offset
|
|
maybe_var_info :: maybe(label_var_info)
|
|
)
|
|
; proc_layout_data( % defines MR_Proc_Layout
|
|
proc_label,
|
|
proc_layout_stack_traversal,
|
|
maybe_proc_id_and_exec_trace
|
|
)
|
|
; module_layout_data( % defines MR_Module_Layout
|
|
module_name :: module_name,
|
|
string_table_size :: int,
|
|
string_table :: string,
|
|
proc_layout_names :: list(layout_name),
|
|
file_layouts :: list(file_layout_data),
|
|
trace_level :: trace_level
|
|
)
|
|
; closure_proc_id_data( % defines MR_Closure_Id
|
|
caller_proc_label :: proc_label,
|
|
caller_closure_seq_no :: int,
|
|
closure_proc_label :: proc_label,
|
|
closure_module_name :: module_name,
|
|
closure_file_name :: string,
|
|
closure_line_number :: int,
|
|
closure_goal_path :: string
|
|
)
|
|
; proc_static_data( % defines MR_ProcStatic
|
|
proc_static_id :: rtti_proc_label,
|
|
proc_static_file_name :: string,
|
|
proc_static_line_number :: int,
|
|
proc_is_in_interface :: bool,
|
|
call_site_statics :: list(call_site_static_data)
|
|
).
|
|
|
|
:- type call_site_static_data % defines MR_CallSiteStatic
|
|
---> normal_call(
|
|
normal_callee :: rtti_proc_label,
|
|
normal_type_subst :: string,
|
|
normal_file_name :: string,
|
|
normal_line_number :: int,
|
|
normal_goal_path :: goal_path
|
|
)
|
|
; special_call(
|
|
special_file_name :: string,
|
|
special_line_number :: int,
|
|
special_goal_path :: goal_path
|
|
)
|
|
; higher_order_call(
|
|
higher_order_file_name :: string,
|
|
ho_line_number :: int,
|
|
ho_goal_path :: goal_path
|
|
)
|
|
; method_call(
|
|
method_file_name :: string,
|
|
method_line_number :: int,
|
|
method_goal_path :: goal_path
|
|
)
|
|
; callback(
|
|
callback_file_name :: string,
|
|
callback_line_number :: int,
|
|
callback_goal_path :: goal_path
|
|
).
|
|
|
|
:- type label_var_info
|
|
---> label_var_info( % part of MR_Label_Layout
|
|
encoded_var_count :: int,
|
|
locns_types :: rval,
|
|
var_nums :: rval,
|
|
type_params :: rval
|
|
).
|
|
|
|
:- type proc_layout_stack_traversal % defines MR_Stack_Traversal
|
|
---> proc_layout_stack_traversal(
|
|
entry_label :: maybe(label),
|
|
% The proc entry label; will be
|
|
% `no' if we don't have static
|
|
% code addresses.
|
|
succip_slot :: maybe(int),
|
|
stack_slot_count :: int,
|
|
detism :: determinism
|
|
).
|
|
|
|
:- type maybe_proc_id_and_exec_trace
|
|
---> no_proc_id
|
|
; proc_id_only
|
|
; proc_id_and_exec_trace(proc_layout_exec_trace).
|
|
|
|
:- type proc_layout_exec_trace % defines MR_Exec_Trace
|
|
---> proc_layout_exec_trace(
|
|
call_label_layout :: layout_name,
|
|
proc_body :: maybe(rval),
|
|
var_names :: list(int), % offsets
|
|
max_var_num :: int,
|
|
max_r_num :: int,
|
|
maybe_from_full_slot :: maybe(int),
|
|
maybe_io_seq_slot :: maybe(int),
|
|
maybe_trail_slot :: maybe(int),
|
|
maybe_maxfr_slot :: maybe(int),
|
|
eval_method :: eval_method,
|
|
maybe_call_table_slot :: maybe(int),
|
|
maybe_decl_debug_slot :: maybe(int)
|
|
).
|
|
|
|
:- type file_layout_data
|
|
---> file_layout_data(
|
|
file_name :: string,
|
|
line_no_label_list :: assoc_list(int, layout_name)
|
|
).
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
:- type layout_name
|
|
---> label_layout(label, label_vars)
|
|
; proc_layout(proc_label, proc_layout_kind)
|
|
% A proc layout structure for stack tracing, accurate gc
|
|
% and/or execution tracing.
|
|
; proc_layout_var_names(proc_label)
|
|
% A vector of variable names (represented as offsets into
|
|
% the string table) for a procedure layout structure.
|
|
; closure_proc_id(proc_label, int, proc_label)
|
|
; file_layout(module_name, int)
|
|
; file_layout_line_number_vector(module_name, int)
|
|
; file_layout_label_layout_vector(module_name, int)
|
|
; module_layout_string_table(module_name)
|
|
; module_layout_file_vector(module_name)
|
|
; module_layout_proc_vector(module_name)
|
|
; module_layout(module_name)
|
|
; proc_static(rtti_proc_label)
|
|
; proc_static_call_sites(rtti_proc_label).
|
|
|
|
:- type label_vars
|
|
---> label_has_var_info
|
|
; label_has_no_var_info.
|
|
|
|
:- type proc_layout_kind
|
|
---> proc_layout_traversal
|
|
; proc_layout_proc_id(proc_layout_user_or_compiler)
|
|
; proc_layout_exec_trace(proc_layout_user_or_compiler).
|
|
|
|
:- type proc_layout_user_or_compiler
|
|
---> user
|
|
; compiler.
|
|
|
|
%-----------------------------------------------------------------------------%
|