[m-dev.] for review: bug fix for exception ports

Zoltan Somogyi zs at cs.mu.OZ.AU
Thu Dec 9 18:27:48 AEDT 1999


For review by fjh or trd.

Estimated hours taken: 3

Fix two related bugs in the debugger. The first was that the code in jumpopt.m
for preventing the redirecting of call returns away from labels with layout
structures was only partially effective, since some call return sites have
their layout structures generated only *after* optimization. The second bug
was that the exception events generated by library/exception.m took the label
layouts of call return sites within a predicate and passed them to MR_trace
as if they were the layouts of compiler-generated trace events. However,
while at compiler-generated trace events, all the variables mentioned in the
associated layout structure are supposed to be live, at return sites only
the variables stored in stack slots are live.

compiler/jumpopt.m:
	Do not redirect call returns if execution tracing is enabled.

compiler/optimize.m:
	Pass the trace level to jumpopt.m.

trace/mercury_trace_vars.[ch]:
	Remember the port type of the event, and do not consider the registers
	to contain valid contents even at ancestor level zero if the port type
	is exception.

trace/mercury_trace_{in,ex}ternal.c:
	Pass the port type to mercury_trace_vars.c.

tests/debugger/exception_vars.{m,inp,exp,exp2}:
	Regression test for the fixed bugs. The .exp2 file is not yet filled
	in.

tests/debugger/Mmakefile:
	Enable the new test case.

Zoltan.

cvs diff: Diffing .
cvs diff: Diffing bindist
cvs diff: Diffing boehm_gc
cvs diff: Diffing boehm_gc/Mac_files
cvs diff: Diffing boehm_gc/cord
cvs diff: Diffing boehm_gc/cord/private
cvs diff: Diffing boehm_gc/include
cvs diff: Diffing boehm_gc/include/private
cvs diff: Diffing browser
cvs diff: Diffing bytecode
cvs diff: Diffing compiler
Index: compiler/jumpopt.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/jumpopt.m,v
retrieving revision 1.49
diff -u -b -r1.49 jumpopt.m
--- jumpopt.m	1999/11/15 00:42:26	1.49
+++ jumpopt.m	1999/12/09 07:14:21
@@ -14,7 +14,7 @@
 
 :- interface.
 
-:- import_module llds.
+:- import_module llds, globals.
 :- import_module list, set, bool.
 
 	% Take an instruction list and optimize jumps. This includes jumps
@@ -23,7 +23,8 @@
 	% The second argument gives the set of labels that have layout
 	% structures. This module will not optimize jumps to labels in this
 	% set, since this may interfere with the RTTI recorded for these
-	% labels.
+	% labels. The third argument gives the trace level, which we also
+	% use to avoid optimizations that may interfere with RTTI.
 	%
 	% The three bool inputs should be
 	%
@@ -37,9 +38,9 @@
 	% The bool output says whether the instruction sequence was modified
 	% by the optimization.
 
-:- pred jumpopt_main(list(instruction), set(label), bool, bool, bool,
-	list(instruction), bool).
-:- mode jumpopt_main(in, in, in, in, in, out, out) is det.
+:- pred jumpopt_main(list(instruction)::in, set(label)::in, trace_level::in,
+	bool::in, bool::in, bool::in, list(instruction)::out, bool::out)
+	is det.
 
 %-----------------------------------------------------------------------------%
 
@@ -74,8 +75,8 @@
 % numbering, which can do a better job of optimizing this block, have
 % been applied.
 
-jumpopt_main(Instrs0, LayoutLabels, Blockopt, Recjump, MostlyDetTailCall,
-		Instrs, Mod) :-
+jumpopt_main(Instrs0, LayoutLabels, TraceLevel, Blockopt, Recjump,
+		MostlyDetTailCall, Instrs, Mod) :-
 	map__init(Instrmap0),
 	map__init(Lvalmap0),
 	map__init(Procmap0),
@@ -96,7 +97,7 @@
 	),
 	jumpopt__instr_list(Instrs0, comment(""), Instrmap, Blockmap, Lvalmap,
 		Procmap, Sdprocmap, Forkmap, Succmap, LayoutLabels,
-		CheckedNondetTailCallInfo, _, Instrs1),
+		TraceLevel, CheckedNondetTailCallInfo, _, Instrs1),
 	opt_util__filter_out_bad_livevals(Instrs1, Instrs),
 	( Instrs = Instrs0 ->
 		Mod = no
@@ -214,19 +215,19 @@
 	% between the if-val and the goto.
 
 :- pred jumpopt__instr_list(list(instruction), instr, instrmap, tailmap,
-	lvalmap, tailmap, tailmap, tailmap, tailmap, set(label),
+	lvalmap, tailmap, tailmap, tailmap, tailmap, set(label), trace_level,
 	maybe(pair(proc_label, int)), maybe(pair(proc_label, int)),
 	list(instruction)).
-:- mode jumpopt__instr_list(in, in, in, in, in, in, in, in, in, in,
+:- mode jumpopt__instr_list(in, in, in, in, in, in, in, in, in, in, in,
 	in, out, out) is det.
 
 jumpopt__instr_list([], _PrevInstr, _Instrmap, _Blockmap, _Lvalmap,
 		_Procmap, _Sdprocmap, _Forkmap, _Succmap, _LayoutLabels,
-		CheckedNondetTailCallInfo, CheckedNondetTailCallInfo, []).
+		_, CheckedNondetTailCallInfo, CheckedNondetTailCallInfo, []).
 jumpopt__instr_list([Instr0 | Instrs0], PrevInstr, Instrmap, Blockmap,
 		Lvalmap, Procmap, Sdprocmap, Forkmap, Succmap, LayoutLabels,
-		CheckedNondetTailCallInfo0, CheckedNondetTailCallInfo,
-		Instrs) :-
+		TraceLevel, CheckedNondetTailCallInfo0,
+		CheckedNondetTailCallInfo, Instrs) :-
 	Instr0 = Uinstr0 - Comment0,
 	string__append(Comment0, " (redirected return)", Redirect),
 	(
@@ -241,6 +242,7 @@
 			( CallModel = det ; CallModel = semidet ),
 			map__search(Procmap, RetLabel, Between0),
 			PrevInstr = livevals(Livevals),
+			TraceLevel = none,
 			not set__member(RetLabel, LayoutLabels)
 		->
 			opt_util__filter_out_livevals(Between0, Between1),
@@ -253,6 +255,7 @@
 			CallModel = semidet,
 			map__search(Forkmap, RetLabel, Between),
 			PrevInstr = livevals(Livevals),
+			TraceLevel = none,
 			not set__member(RetLabel, LayoutLabels)
 		->
 			list__append(Between, [livevals(Livevals) - "",
@@ -266,6 +269,7 @@
 			map__search(Succmap, RetLabel, BetweenIncl),
 			BetweenIncl = [livevals(_) - _, goto(_) - _],
 			PrevInstr = livevals(Livevals),
+			TraceLevel = none,
 			not set__member(RetLabel, LayoutLabels)
 		->
 			NewInstrs = [
@@ -289,6 +293,7 @@
 			map__search(Succmap, RetLabel, BetweenIncl),
 			BetweenIncl = [livevals(_) - _, goto(_) - _],
 			PrevInstr = livevals(Livevals),
+			TraceLevel = none,
 			not set__member(RetLabel, LayoutLabels)
 		->
 			NewLabel = local(ProcLabel, LabelNum0),
@@ -313,6 +318,7 @@
 		;
 			% Short circuit the return label if possible.
 			map__search(Instrmap, RetLabel, RetInstr),
+			TraceLevel = none,
 			not set__member(RetLabel, LayoutLabels)
 		->
 			jumpopt__final_dest(RetLabel, RetInstr, Instrmap,
@@ -413,7 +419,7 @@
 			jumpopt__instr_list(AdjustedBlock, comment(""),
 				Instrmap, CrippledBlockmap, Lvalmap, Procmap,
 				Sdprocmap, Forkmap, Succmap, LayoutLabels,
-				CheckedNondetTailCallInfo0,
+				TraceLevel, CheckedNondetTailCallInfo0,
 				CheckedNondetTailCallInfo1, NewInstrs),
 			RemainInstrs = Instrs0
 		;
@@ -607,8 +613,8 @@
 	),
 	jumpopt__instr_list(RemainInstrs, NewPrevInstr, Instrmap, Blockmap,
 		Lvalmap, Procmap, Sdprocmap, Forkmap, Succmap, LayoutLabels,
-		CheckedNondetTailCallInfo1, CheckedNondetTailCallInfo,
-		Instrs9),
+		TraceLevel, CheckedNondetTailCallInfo1,
+		CheckedNondetTailCallInfo, Instrs9),
 	list__append(NewInstrs, Instrs9, Instrs).
 
 % We avoid generating statements that redefine the value of a location
Index: compiler/optimize.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/optimize.m,v
retrieving revision 1.19
diff -u -b -r1.19 optimize.m
--- optimize.m	1999/11/15 00:42:43	1.19
+++ optimize.m	1999/12/09 03:13:44
@@ -136,6 +136,7 @@
 	globals__io_lookup_bool_option(optimize_fulljumps, FullJumpopt),
 	globals__io_lookup_bool_option(checked_nondet_tailcalls,
 		CheckedNondetTailCalls),
+	globals__io_get_trace_level(TraceLevel),
 	( { Jumpopt = yes } ->
 		( { VeryVerbose = yes } ->
 			io__write_string("% Optimizing jumps for "),
@@ -144,8 +145,9 @@
 		;
 			[]
 		),
-		{ jumpopt_main(Instrs1, LayoutLabelSet, FullJumpopt, Final,
-			CheckedNondetTailCalls, Instrs2, Mod1) },
+		{ jumpopt_main(Instrs1, LayoutLabelSet, TraceLevel,
+			FullJumpopt, Final, CheckedNondetTailCalls,
+			Instrs2, Mod1) },
 		( { Mod1 = yes } ->
 			opt_debug__msg(DebugOpt, "after jump optimization"),
 			opt_debug__dump_instrs(DebugOpt, Instrs2)
@@ -253,6 +255,7 @@
 		globals__io_lookup_bool_option(optimize_fulljumps, FullJumpopt),
 		globals__io_lookup_bool_option(checked_nondet_tailcalls,
 			CheckedNondetTailCalls),
+		globals__io_get_trace_level(TraceLevel),
 		( { Jumps = yes, FullJumpopt = yes } ->
 			( { VeryVerbose = yes } ->
 				io__write_string("% Optimizing jumps for "),
@@ -261,9 +264,9 @@
 			;
 				[]
 			),
-			{ jumpopt_main(Instrs1, LayoutLabelSet, FullJumpopt,
-				Final, CheckedNondetTailCalls, Instrs2,
-				Mod2) },
+			{ jumpopt_main(Instrs1, LayoutLabelSet, TraceLevel,
+				FullJumpopt, Final, CheckedNondetTailCalls,
+				Instrs2, Mod2) },
 			( { Mod2 = yes } ->
 				opt_debug__msg(DebugOpt, "after jump optimization"),
 				opt_debug__dump_instrs(DebugOpt, Instrs2)
cvs diff: Diffing compiler/notes
cvs diff: Diffing debian
cvs diff: Diffing doc
cvs diff: Diffing extras
cvs diff: Diffing extras/aditi
cvs diff: Diffing extras/cgi
cvs diff: Diffing extras/complex_numbers
cvs diff: Diffing extras/complex_numbers/samples
cvs diff: Diffing extras/complex_numbers/tests
cvs diff: Diffing extras/dynamic_linking
cvs diff: Diffing extras/graphics
cvs diff: Diffing extras/graphics/mercury_opengl
cvs diff: Diffing extras/graphics/mercury_tcltk
cvs diff: Diffing extras/graphics/samples
cvs diff: Diffing extras/graphics/samples/calc
cvs diff: Diffing extras/graphics/samples/maze
cvs diff: Diffing extras/graphics/samples/pent
cvs diff: Diffing extras/lazy_evaluation
cvs diff: Diffing extras/odbc
cvs diff: Diffing extras/opium_m
cvs diff: Diffing extras/opium_m/non-regression-tests
cvs diff: Diffing extras/opium_m/scripts
cvs diff: Diffing extras/opium_m/source
cvs diff: Diffing extras/posix
cvs diff: Diffing extras/references
cvs diff: Diffing extras/references/samples
cvs diff: Diffing extras/references/tests
cvs diff: Diffing extras/trailed_update
cvs diff: Diffing extras/trailed_update/samples
cvs diff: Diffing extras/trailed_update/tests
cvs diff: Diffing library
cvs diff: Diffing lp_solve
cvs diff: Diffing profiler
cvs diff: Diffing runtime
cvs diff: Diffing runtime/GETOPT
cvs diff: Diffing runtime/machdeps
cvs diff: Diffing samples
cvs diff: Diffing samples/c_interface
cvs diff: Diffing samples/c_interface/c_calls_mercury
cvs diff: Diffing samples/c_interface/cplusplus_calls_mercury
cvs diff: Diffing samples/c_interface/mercury_calls_c
cvs diff: Diffing samples/c_interface/mercury_calls_cplusplus
cvs diff: Diffing samples/c_interface/mercury_calls_fortran
cvs diff: Diffing samples/c_interface/simpler_c_calls_mercury
cvs diff: Diffing samples/c_interface/simpler_cplusplus_calls_mercury
cvs diff: Diffing samples/diff
cvs diff: Diffing samples/muz
cvs diff: Diffing samples/rot13
cvs diff: Diffing samples/solutions
cvs diff: Diffing scripts
cvs diff: Diffing tests
cvs diff: Diffing tests/benchmarks
cvs diff: Diffing tests/debugger
Index: tests/debugger/Mmakefile
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/Mmakefile,v
retrieving revision 1.30
diff -u -b -r1.30 Mmakefile
--- Mmakefile	1999/11/20 12:50:03	1.30
+++ Mmakefile	1999/12/08 06:22:21
@@ -20,6 +20,7 @@
 	breakpoints			\
 	browser_test			\
 	debugger_regs			\
+	exception_vars			\
 	existential_type_classes	\
 	implied_instance		\
 	interpreter			\
@@ -70,6 +71,9 @@
 
 debugger_regs.out: debugger_regs debugger_regs.inp
 	$(MDB) ./debugger_regs < debugger_regs.inp > debugger_regs.out 2>&1
+
+exception_vars.out: exception_vars exception_vars.inp
+	$(MDB) ./exception_vars < exception_vars.inp > exception_vars.out 2>&1
 
 existential_type_classes.out: existential_type_classes \
 			existential_type_classes.inp
Index: tests/debugger/exception_vars.exp
===================================================================
RCS file: exception_vars.exp
diff -N exception_vars.exp
--- /dev/null	Thu Dec  9 18:24:38 1999
+++ exception_vars.exp	Thu Dec  9 14:42:26 1999
@@ -0,0 +1,8 @@
+       1:      1  1 CALL pred exception_vars:main/2-0 (det) exception_vars.m:12
+mdb> goto 2
+       2:      2  2 CALL pred exception_vars:test/2-0 (det) exception_vars.m:19 (exception_vars.m:12)
+mdb> finish
+       4:      2  2 EXCP pred exception_vars:test/2-0 (det) exception_vars.m:18 (exception_vars.m:12)
+mdb> print *
+       HeadVar__1             	42
+mdb> continue
Index: tests/debugger/exception_vars.exp2
===================================================================
RCS file: exception_vars.exp2
diff -N exception_vars.exp2
Index: tests/debugger/exception_vars.inp
===================================================================
RCS file: exception_vars.inp
diff -N exception_vars.inp
--- /dev/null	Thu Dec  9 18:24:38 1999
+++ exception_vars.inp	Wed Dec  8 17:23:16 1999
@@ -0,0 +1,4 @@
+goto 2
+finish
+print *
+continue
Index: tests/debugger/exception_vars.m
===================================================================
RCS file: exception_vars.m
diff -N exception_vars.m
--- /dev/null	Thu Dec  9 18:24:38 1999
+++ exception_vars.m	Wed Dec  8 17:21:09 1999
@@ -0,0 +1,21 @@
+:- module exception_vars.
+
+:- interface.
+:- import_module io.
+
+:- pred main(io__state::di, io__state::uo) is det.
+
+:- implementation.
+
+:- import_module require, int.
+
+main --> { test(42, X) }, print(X).
+
+:- pred test(int::in, int::out) is det.
+
+test(X, Y) :-
+	( X > 0 ->
+		error("oops")
+	;
+		Y = X + 1
+	).
cvs diff: Diffing tests/debugger/declarative
cvs diff: Diffing tests/dppd
cvs diff: Diffing tests/general
cvs diff: Diffing tests/general/accumulator
cvs diff: Diffing tests/hard_coded
cvs diff: Diffing tests/hard_coded/exceptions
cvs diff: Diffing tests/hard_coded/sub-modules
cvs diff: Diffing tests/hard_coded/typeclasses
cvs diff: Diffing tests/invalid
cvs diff: Diffing tests/misc_tests
cvs diff: Diffing tests/tabling
cvs diff: Diffing tests/term
cvs diff: Diffing tests/valid
cvs diff: Diffing tests/warnings
cvs diff: Diffing tools
cvs diff: Diffing trace
Index: trace/mercury_trace_external.c
===================================================================
RCS file: /home/mercury1/repository/mercury/trace/mercury_trace_external.c,v
retrieving revision 1.32
diff -u -b -r1.32 mercury_trace_external.c
--- mercury_trace_external.c	1999/11/15 00:43:55	1.32
+++ mercury_trace_external.c	1999/12/08 06:40:28
@@ -514,8 +514,7 @@
 	event_details.MR_event_number = MR_trace_event_number;
 
 	MR_trace_init_point_vars(event_info->MR_event_sll,
-		event_info->MR_saved_regs);
-
+		event_info->MR_saved_regs, event_info->MR_trace_port);
 
 	switch(external_debugger_mode) {
 		case MR_searching:
Index: trace/mercury_trace_internal.c
===================================================================
RCS file: /home/mercury1/repository/mercury/trace/mercury_trace_internal.c,v
retrieving revision 1.59
diff -u -b -r1.59 mercury_trace_internal.c
--- mercury_trace_internal.c	1999/12/08 04:56:14	1.59
+++ mercury_trace_internal.c	1999/12/09 02:30:56
@@ -234,7 +234,7 @@
 	event_details.MR_event_number = MR_trace_event_number;
 
 	MR_trace_init_point_vars(event_info->MR_event_sll,
-		event_info->MR_saved_regs);
+		event_info->MR_saved_regs, event_info->MR_trace_port);
 
 	/* by default, return where we came from */
 	jumpaddr = NULL;
Index: trace/mercury_trace_vars.c
===================================================================
RCS file: /home/mercury1/repository/mercury/trace/mercury_trace_vars.c,v
retrieving revision 1.10
diff -u -b -r1.10 mercury_trace_vars.c
--- mercury_trace_vars.c	1999/11/15 00:43:59	1.10
+++ mercury_trace_vars.c	1999/12/08 06:41:33
@@ -65,9 +65,9 @@
 ** where a program point is defined as the combination of a debugger
 ** event and an ancestor level.
 **
-** The top_layout and top_saved_regs fields together describe the abstract
-** machine state at the current debugger event. The problem field points 
-** to a string containing an error message describing why the debugger
+** The top_layout, top_saved_regs and top_port fields together describe the
+** abstract machine state at the current debugger event. The problem field
+** points to a string containing an error message describing why the debugger
 ** can't print any variables at the current point. It will of course be
 ** NULL if the debugger can do so, which requires not only that the
 ** debugger have all the information it needs about the current point.
@@ -92,6 +92,7 @@
 typedef struct {
 	const MR_Stack_Layout_Label	*MR_point_top_layout;
 	Word				*MR_point_top_saved_regs;
+	MR_Trace_Port			MR_point_top_port;
 	const char			*MR_point_problem;
 	int				MR_point_level;
 	const MR_Stack_Layout_Entry	*MR_point_level_entry;
@@ -196,10 +197,11 @@
 
 void
 MR_trace_init_point_vars(const MR_Stack_Layout_Label *top_layout,
-	Word *saved_regs)
+	Word *saved_regs, MR_Trace_Port port)
 {
 	MR_point.MR_point_top_layout = top_layout;
 	MR_point.MR_point_top_saved_regs = saved_regs;
+	MR_point.MR_point_top_port = port;
 	MR_point.MR_point_level = 0;
 	MR_point.MR_point_problem = MR_trace_set_level(0);
 }
@@ -300,7 +302,9 @@
 		return "there are no names for the live variables";
 	}
 
-	if (ancestor_level == 0) {
+	if (ancestor_level == 0 &&
+			MR_point.MR_point_top_port != MR_PORT_EXCEPTION)
+	{
 		valid_saved_regs = MR_point.MR_point_top_saved_regs;
 	} else {
 		valid_saved_regs = NULL;
Index: trace/mercury_trace_vars.h
===================================================================
RCS file: /home/mercury1/repository/mercury/trace/mercury_trace_vars.h,v
retrieving revision 1.3
diff -u -b -r1.3 mercury_trace_vars.h
--- mercury_trace_vars.h	1999/11/15 00:43:59	1.3
+++ mercury_trace_vars.h	1999/12/08 06:39:28
@@ -52,8 +52,9 @@
 	const char		*MR_var_spec_name;  /* valid if NAME   */
 } MR_Var_Spec;
 
-extern	void		MR_trace_init_point_vars(const MR_Stack_Layout_Label
-				*top_layout, Word *saved_regs);
+extern	void		MR_trace_init_point_vars(
+				const MR_Stack_Layout_Label *top_layout,
+				Word *saved_regs, MR_Trace_Port port);
 extern	const char	*MR_trace_set_level(int ancestor_level);
 extern	int		MR_trace_current_level(void);
 extern	void		MR_trace_current_level_details(
cvs diff: Diffing trial
cvs diff: Diffing util
--------------------------------------------------------------------------
mercury-developers mailing list
Post messages to:       mercury-developers at cs.mu.oz.au
Administrative Queries: owner-mercury-developers at cs.mu.oz.au
Subscriptions:          mercury-developers-request at cs.mu.oz.au
--------------------------------------------------------------------------



More information about the developers mailing list