mirror of
https://github.com/Mercury-Language/mercury.git
synced 2025-12-14 21:35:49 +00:00
Estimated hours taken: 8
Branches: main
Satisfy a request by Peter Ross: give mdb users the ability to specify
exactly which events inside a procedure they want to put breakpoints on.
Amongst other things, this can make checking postconditions easier:
you can now put a conditional breakpoint on only the exit event.
runtime/mercury_stack_layout.h:
Add to the exec trace part of proc layouts fields describing an array
of the label layouts describing the events of the procedure. This is
the most direct way to implement the new functionality. (In theory,
we could search the data structures that map file names and line
numbers to label layouts, but that would be complex, inefficient,
and *error prone*.)
To make room for the new fields, and to prepare for making the
procedure body available to the deep profiler as well (which could
use it to map execution frequencies of calls back to their location
in the procedure body, and thus to things like the frequencies with
which various switch arms are selected), move the procedure body
of the execution-trace-specific part of the proc layout, and to
where the deep profiler could in the future also get at it.
runtime/mercury_goto.h:
Add macros for declaring more than one label layout structure at a
time.
compiler/layout.m:
Implement the changes in mercury_stack_layout.h in the compiler's
data structures as well.
compiler/stack_layout.m:
Conform to the changes in mercury_stack_layout.h.
Turn some tuples into named types.
compiler/layout_out.m:
Conform to the changes in mercury_stack_layout.h.
Add a mechanism to declare the label layouts in the new array before
referring to them, by generalizing some existing code. Make this code
require that the label layouts we refer to via the macros in
mercury_goto.h match the declarations generated by those macros,
i.e. that they have information about variables (if debugging is
enabled, they will).
compiler/opt_debug.m:
Conform to the change to layout.m.
compiler/prog_rep.m:
Make a predicate name more expressive.
trace/mercury_trace_cmd_breakpoint.c:
Implement the new way of using the "break" command, which is
to add a port name after the procedure specification.
Register procedures at the start of the function implementing
the "break" command, instead of "on demand", since all alternatives
eventually do demand it.
Write ambiguity reports wholly to mdb's stdout, instead of partially to
stderr and partially to stdout.
trace/mercury_trace_spy.c:
Print the port and the goal path for breakpoints on specific events.
Make the invocation conditions left-aligned, not right-aligned.
doc/user_guide.texi:
Document the new way of using the "break" command.
NEWS:
Announce the new capability.
tests/queens.{inp,exp,exp2}:
Add tests of the new capability.
tests/breakpoints.{exp,exp}:
tests/lval_desc_array.{exp,exp2}:
Expect the new alignment of invocation conditions.
268 lines
12 KiB
Mathematica
268 lines
12 KiB
Mathematica
%-----------------------------------------------------------------------------%
|
|
% vim: ft=mercury ts=4 sw=4 et
|
|
%-----------------------------------------------------------------------------%
|
|
% Copyright (C) 2001-2007 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.
|
|
%-----------------------------------------------------------------------------%
|
|
%
|
|
% File: layout.m.
|
|
% Author: zs.
|
|
%
|
|
% 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.
|
|
%
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
:- module ll_backend.layout.
|
|
:- interface.
|
|
|
|
:- import_module hlds.hlds_pred.
|
|
:- import_module hlds.hlds_rtti.
|
|
:- import_module libs.trace_params.
|
|
:- import_module ll_backend.llds.
|
|
:- import_module mdbcomp.prim_data.
|
|
:- import_module parse_tree.prog_data.
|
|
|
|
:- import_module assoc_list.
|
|
:- import_module bool.
|
|
:- import_module list.
|
|
:- import_module map.
|
|
:- import_module maybe.
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
% This type is for strings which may contain embedded null characters.
|
|
% When a string_with_0s is written, a null character will be written
|
|
% in between each string in the list.
|
|
:- type string_with_0s
|
|
---> string_with_0s(list(string)).
|
|
|
|
:- type event_set_layout_data
|
|
---> event_set_layout_data(
|
|
event_set_data,
|
|
map(int, rval) % Maps each event number to an rval
|
|
% that gives the vector of typeinfos
|
|
% for the arguments of that event.
|
|
).
|
|
|
|
:- type layout_data
|
|
---> label_layout_data( % defines MR_LabelLayout
|
|
proc_label :: proc_label,
|
|
label_num :: int,
|
|
proc_layout_name :: layout_name,
|
|
maybe_port :: maybe(trace_port),
|
|
maybe_is_hidden :: maybe(bool),
|
|
label_num_in_module :: int,
|
|
maybe_goal_path :: maybe(int), % offset
|
|
maybe_user_info :: maybe(user_event_data),
|
|
maybe_var_info :: maybe(label_var_info)
|
|
)
|
|
; proc_layout_data( % defines MR_ProcLayout
|
|
proc_layout_label :: rtti_proc_label,
|
|
proc_layout_trav :: proc_layout_stack_traversal,
|
|
proc_layout_more :: maybe_proc_id_and_more
|
|
)
|
|
; module_layout_data( % defines MR_ModuleLayout
|
|
module_name :: module_name,
|
|
string_table_size :: int,
|
|
string_table :: string_with_0s,
|
|
proc_layout_names :: list(layout_name),
|
|
file_layouts :: list(file_layout_data),
|
|
trace_level :: trace_level,
|
|
suppressed_events :: int,
|
|
num_label_exec_count :: int,
|
|
maybe_event_specs :: maybe(event_set_layout_data)
|
|
)
|
|
; closure_proc_id_data( % defines MR_ClosureId
|
|
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_origin :: pred_origin,
|
|
closure_goal_path :: string
|
|
)
|
|
; table_io_decl_data(
|
|
table_io_decl_proc_ptr :: rtti_proc_label,
|
|
table_io_decl_kind :: proc_layout_kind,
|
|
table_io_decl_num_ptis :: int,
|
|
table_io_decl_ptis :: rval,
|
|
% pseudo-typeinfos for headvars
|
|
table_io_decl_type_params :: rval
|
|
).
|
|
|
|
:- type user_event_data
|
|
---> user_event_data(
|
|
user_event_number :: int,
|
|
user_event_locns :: rval,
|
|
user_event_var_nums :: list(maybe(int))
|
|
).
|
|
|
|
:- type label_var_info
|
|
---> label_var_info( % part of MR_LabelLayout
|
|
encoded_var_count :: int,
|
|
locns_types :: rval,
|
|
var_nums :: rval,
|
|
type_params :: rval
|
|
).
|
|
|
|
:- type proc_layout_stack_traversal % defines MR_StackTraversal
|
|
---> 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
|
|
).
|
|
|
|
% The deep_slot_info gives the stack slot numbers that hold
|
|
% the values returned by the call port code, which are needed to let
|
|
% exception.throw perform the work we need to do at the excp port.
|
|
% The old_outermost slot is needed only with the save/restore approach;
|
|
% the old_outermost field contain -1 otherwise. All fields will contain
|
|
% -1 if the variables are never saved on the stack because the
|
|
% predicate makes no calls (in which case it cannot throw exceptions,
|
|
% because to do that it would need to call exception.throw, directly or
|
|
% indirectly.)
|
|
:- type deep_excp_slots
|
|
---> deep_excp_slots(
|
|
top_csd :: int,
|
|
middle_csd :: int,
|
|
old_outermost :: int
|
|
).
|
|
|
|
:- type proc_layout_proc_static
|
|
---> proc_layout_proc_static(
|
|
hlds_proc_static :: hlds_proc_static,
|
|
deep_excp_slots :: deep_excp_slots
|
|
).
|
|
|
|
:- type maybe_proc_id_and_more
|
|
---> no_proc_id
|
|
; proc_id(
|
|
maybe_proc_static :: maybe(proc_layout_proc_static),
|
|
maybe_exec_trace :: maybe(proc_layout_exec_trace),
|
|
proc_body_bytes :: list(int)
|
|
% The procedure body represented as
|
|
% a list of bytecodes.
|
|
).
|
|
|
|
:- type proc_layout_exec_trace % defines MR_ExecTrace
|
|
---> proc_layout_exec_trace(
|
|
maybe_call_label_layout :: maybe(label_layout_details),
|
|
|
|
proc_label_layouts :: list(data_addr),
|
|
% The label layouts of the events in
|
|
% the predicate. Interface events
|
|
% first, internal events second.
|
|
|
|
maybe_table_info :: maybe(data_addr),
|
|
head_var_nums :: list(int),
|
|
% The variable numbers of the
|
|
% head variables, including the
|
|
% ones added by the compiler,
|
|
% in order. The length of the
|
|
% list must be the same as the
|
|
% procedure's arity.
|
|
|
|
var_names :: list(int),
|
|
% Each variable name is an offset into
|
|
% the module's string table.
|
|
|
|
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),
|
|
eff_trace_level :: trace_level,
|
|
exec_trace_flags :: 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(proc_label, int, label_vars)
|
|
; user_event_layout(proc_label, int)
|
|
; user_event_attr_var_nums(proc_label, int)
|
|
; proc_layout(rtti_proc_label, proc_layout_kind)
|
|
% A proc layout structure for stack tracing, accurate gc,
|
|
% deep profiling and/or execution tracing.
|
|
; proc_layout_exec_trace(rtti_proc_label)
|
|
; proc_layout_label_layouts(rtti_proc_label)
|
|
; proc_layout_head_var_nums(rtti_proc_label)
|
|
% A vector of variable numbers, containing the numbers of the
|
|
% procedure's head variables, including the ones generated by
|
|
% the compiler.
|
|
; proc_layout_var_names(rtti_proc_label)
|
|
% A vector of variable names (represented as offsets into
|
|
% the string table) for a procedure layout structure.
|
|
; proc_layout_body_bytecode(rtti_proc_label)
|
|
; table_io_decl(rtti_proc_label)
|
|
; 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_label_exec_count(module_name, int)
|
|
; module_layout_event_set_desc(module_name)
|
|
; module_layout_event_arg_names(module_name, int)
|
|
; module_layout_event_synth_attrs(module_name, int)
|
|
; module_layout_event_synth_attr_args(module_name, int, int)
|
|
; module_layout_event_synth_attr_order(module_name, int, int)
|
|
; module_layout_event_synth_order(module_name, int)
|
|
; module_layout_event_specs(module_name)
|
|
; module_layout(module_name)
|
|
; proc_static(rtti_proc_label)
|
|
; proc_static_call_sites(rtti_proc_label).
|
|
|
|
:- type label_layout_details
|
|
---> label_layout_details(proc_label, int, label_vars).
|
|
|
|
:- 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_uci).
|
|
|
|
:- type proc_layout_user_or_uci
|
|
---> user
|
|
; uci.
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
:- end_module layout.
|
|
%-----------------------------------------------------------------------------%
|