for review: cleanup of mercury_stack_layout.h

Zoltan Somogyi zs at cs.mu.OZ.AU
Wed Jul 8 15:43:37 AEST 1998


This is for Tyson.

runtime/mercury_stack_layout.h:
	Reorder the components of this file into a sequence of submodules,
	with each submodule containing the definition of a type and all
	the macros that operate on that type. This should remind people
	that updating a type without updating the macros is not a good idea.

	Remove obsolete, unused and incorrect macros.

	Modify the conventions for the use of incomplete fragments of
	proc layout structures, so that by looking at a proc layout
	fragment, one can tell how much of it is actually present and
	meaningful. This is necessary to avoid references to fields
	that are not present or not meaningful.

compiler/stack_layout.m:
	Emit data structures that conform to the new convention.

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: ignoring bytecode (CVS/Entries missing)
cvs diff: Diffing compiler
Index: compiler/stack_layout.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/stack_layout.m,v
retrieving revision 1.14
diff -u -u -r1.14 stack_layout.m
--- stack_layout.m	1998/06/18 06:06:49	1.14
+++ stack_layout.m	1998/07/08 07:11:38
@@ -61,7 +61,9 @@
 %
 % The runtime system can figure out which form is present by testing
 % the value of the first slot. A value of 0 or 1 indicates the first form;
-% any higher value indicates the second form.
+% any higher value indicates the second form. A negative value indicates
+% that procid_stack_layout is not set, and that the later fields are not
+% present.
 %
 % The meanings of the fields in both forms are the same as in procedure labels.
 %
@@ -75,6 +77,8 @@
 % information is to allow the runtime debugger to find out which variables
 % are where on entry, so it can reexecute the procedure if asked to do so
 % and if the values of the required variables are still available.
+% (If trace_stack_layout is not set, this field will be present,
+% but it will be set to NULL.)
 %
 % If the option basic_stack_layout is set, we generate stack layout tables
 % for some labels internal to the procedure. This table will be stored in the
@@ -289,7 +293,8 @@
 		{ stack_layout__construct_procid_rvals(ProcLabel, IdRvals) },
 		{ list__append(MaybeRvals0, IdRvals, MaybeRvals1) }
 	;
-		{ MaybeRvals1 = MaybeRvals0 }
+		{ NoIdRvals = yes(const(int_const(-1))) },
+		{ list__append(MaybeRvals0, [NoIdRvals], MaybeRvals1) }
 	),
 
 	stack_layout__get_module_name(ModuleName),
@@ -306,7 +311,8 @@
 			{ error("stack_layout__construct_proc_layout: call label not present") }
 		)
 	;
-		{ MaybeRvals = MaybeRvals1 }
+		{ NoCallRval = yes(const(int_const(0))) },
+		{ list__append(MaybeRvals1, [NoCallRval], MaybeRvals) }
 	),
 
 	{ Exported = no },	% XXX With the new profiler, we will need to
cvs diff: Diffing compiler/notes
cvs diff: Diffing doc
cvs diff: Diffing extras
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/graphics
cvs diff: Diffing extras/graphics/Togl-1.2
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/odbc
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 lp_solve/lp_examples
cvs diff: Diffing profiler
cvs diff: Diffing runtime
Index: runtime/mercury_stack_layout.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_stack_layout.h,v
retrieving revision 1.7
diff -u -u -r1.7 mercury_stack_layout.h
--- mercury_stack_layout.h	1998/06/18 06:08:03	1.7
+++ mercury_stack_layout.h	1998/07/08 07:02:57
@@ -16,15 +16,13 @@
 ** you may need to change compiler/stack_layout.m as well.
 */
 
-/*
-** Definitions for MR_PredFunc
-*/
+/* MR_PredFunc ----------------------------------------------------------- */
 
 typedef	enum { MR_PREDICATE, MR_FUNCTION } MR_PredFunc;
 
+/* MR_Determinism -------------------------------------------------------- */
+
 /*
-** Definitions for MR_Determinism
-**
 ** The max_soln component of the determinism is encoded in the 1 and 2 bits.
 ** The can_fail component of the determinism is encoded in the 4 bit.
 ** The first_solution component of the determinism is encoded in the 8 bit.
@@ -56,9 +54,9 @@
 #define MR_DETISM_DET_STACK(d)		(!MR_DETISM_AT_MOST_MANY(d) \
 					|| MR_DETISM_FIRST_SOLN(d))
 
+/* MR_Live_Lval ---------------------------------------------------------- */
+
 /*
-** Definitions for "MR_Live_Lval"
-**
 ** MR_Live_Lval is a Word which describes an lval. This includes:
 ** 	- stack slots, registers, and special lvals such as succip, hp,
 ** 	  etc.
@@ -107,9 +105,9 @@
 #define MR_LIVE_LVAL_NUMBER(Lval) 			\
 	((int) ((Word) Lval) >> MR_LIVE_LVAL_TAGBITS)
 
+/* MR_Live_Type ---------------------------------------------------------- */
+
 /*
-** Definitions for MR_Live_Type
-**
 ** MR_Live_Type describes live data. This includes:
 ** 	- succip, hp, curfr, maxfr, redoip, and
 ** 	  mercury data values (vars).
@@ -150,10 +148,91 @@
 #define MR_LIVE_TYPE_GET_VAR_INST(T)   			\
 		(((MR_Var_Shape_Info *) T)->inst)
 
+/* MR_Stack_Layout_Var --------------------------------------------------- */
+
+typedef	struct MR_Stack_Layout_Var_Struct {
+	MR_Live_Lval		MR_slv_locn;
+	MR_Live_Type		MR_slv_live_type;
+} MR_Stack_Layout_Var;
+
+/* MR_Stack_Layout_Vars -------------------------------------------------- */
+
+/*
+** If MR_slvs_tvars == NULL, there are no type parameters.
+** If it is != NULL, then (Integer) MR_slvs_tvars[0] is the index
+** of the highest numbered type parameter, and MR_slvs_tvars[i]
+** for values of i between 1 and (Integer) MR_slvs_tvars[0] (both inclusive)
+** describe the location of the typeinfo structure for the type variable
+** of the corresponding number. If one of these type variables
+** is not referred to by the variables described in MR_slvs_pairs,
+** the corresponding entry will be zero.
+*/
+
+typedef	struct MR_Stack_Layout_Vars_Struct {
+	MR_Stack_Layout_Var	*MR_slvs_pairs;
+	String			*MR_slvs_names;
+	MR_Live_Lval		*MR_slvs_tvars;
+} MR_Stack_Layout_Vars;
+
+#define	MR_name_if_present(vars, i)					\
+				((vars->MR_slvs_names != NULL		\
+				&& vars->MR_slvs_names[(i)] != NULL)	\
+				? vars->MR_slvs_names[(i)]		\
+				: "")
+
+/* MR_Stack_Layout_Entry ------------------------------------------------- */
+
 /*
-** Macros to support hand-written C code.
+** This structure records information about a procedure.
+** The structure has three groups of fields:
+**
+**	(1) those needed for travesing the stack;
+**	(2) those needed for identifying the procedure;
+**	(3) those needed for execution tracing.
+**
+** For accurate garbage collection, we only need group (1).
+** For stack tracing, we need groups (1) and (2).
+** For execution tracing, we need groups (1), (2) and (3).
+**
+** To save space, for each use we only include the fields that belong
+** to the needed groups, plus the first field in the first non-included group,
+** which is set to a special value to indicate the absence of the group
+** and any following groups.
+**
+** Group (1) is always be present and meaningful.
+** Group (2) is be present and meaningful
+** if MR_ENTRY_LAYOUT_HAS_PROC_ID(entry) evaluates to true.
+** Group (3) is be present and meaningful
+** if MR_ENTRY_LAYOUT_HAS_EXEC_TRACE(entry) evaluates to true.
 */
 
+typedef	struct MR_Stack_Layout_Entry_Struct {
+	/* stack traversal group */
+	Code			*MR_sle_code_addr;
+	MR_Determinism		MR_sle_detism;
+	Integer			MR_sle_stack_slots;
+	MR_Live_Lval		MR_sle_succip_locn;
+
+	/* proc id group */
+	MR_PredFunc		MR_sle_pred_or_func;
+	String			MR_sle_decl_module;
+	String			MR_sle_def_module;
+	String			MR_sle_name;
+	Integer			MR_sle_arity;
+	Integer			MR_sle_mode;
+
+	/* exec trace group */
+	struct MR_Stack_Layout_Label_Struct
+				*MR_sle_call_label;
+} MR_Stack_Layout_Entry;
+
+#define	MR_ENTRY_LAYOUT_HAS_PROC_ID(entry)			\
+		((int) entry->MR_sle_pred_or_func >= 0)
+
+#define	MR_ENTRY_LAYOUT_HAS_EXEC_TRACE(entry)			\
+		(MR_ENTRY_LAYOUT_HAS_PROC_ID(entry)		\
+		&& entry->MR_sle_call_label != NULL)
+
 /*
 ** Define a stack layout for a label that you know very little about.
 ** It is just a generic entry label, no useful information, except
@@ -163,27 +242,40 @@
 #ifdef MR_USE_STACK_LAYOUTS
   #define MR_MAKE_STACK_LAYOUT_ENTRY(l) 				\
   const struct mercury_data__layout__##l##_struct {			\
-	Code * f1;							\
-	Integer f2;							\
-	Integer f3;							\
-	Integer f4;							\
+	Code	*f1;							\
+	Integer	f2;							\
+	Integer	f3;							\
+	Integer	f4;							\
+	Integer	f5;							\
   } mercury_data__layout__##l = {					\
 	STATIC(l),							\
 	(Integer) -1, 	/* Unknown determinism */			\
 	(Integer) -1,	/* Unknown number of stack slots */		\
-        (Integer) MR_LVAL_TYPE_UNKNOWN 	/* Unknown succip location */	\
+        (Integer) MR_LVAL_TYPE_UNKNOWN,	/* Unknown succip location */	\
+	(Integer) -1, 	/* The procid component is not present */	\
   };
 #else
   #define MR_MAKE_STACK_LAYOUT_ENTRY(l)        
 #endif	/* MR_USE_STACK_LAYOUTS */
 
+/* MR_Stack_Layout_Label ------------------------------------------------- */
+
 /*
-** The layout structure for an internal label will have a field containing
-** the label number of that label (or -1, if the internal label has no
-** label number, being the entry label) only if we are using native gc.
+** The MR_sll_var_count field should be set to a negative number
+** if there is no information about the variables live at the label.
 */
 
-#ifdef	NATIVE_GC
+typedef	struct MR_Stack_Layout_Label_Struct {
+	MR_Stack_Layout_Entry	*MR_sll_entry;
+#ifdef	MR_LABEL_STRUCTS_INCLUDE_NUMBER
+	Integer			MR_sll_label_num;
+#endif
+	Integer			MR_sll_var_count;
+	/* the last field is present only if MR_sll_var_count > 0 */
+	MR_Stack_Layout_Vars	MR_sll_var_info;
+} MR_Stack_Layout_Label;
+
+#ifdef	MR_LABEL_STRUCTS_INCLUDE_NUMBER
   #define	UNKNOWN_INTERNAL_LABEL_FIELD	Integer f2;
   #define	UNKNOWN_INTERNAL_LABEL_NUMBER	(Integer) -1,
 #else
@@ -202,13 +294,13 @@
 #ifdef MR_USE_STACK_LAYOUTS
   #define MR_MAKE_STACK_LAYOUT_INTERNAL_WITH_ENTRY(l, e)		\
   const struct mercury_data__layout__##l##_struct {			\
-	const Word * f1;						\
+	const Word *f1;							\
 	UNKNOWN_INTERNAL_LABEL_FIELD					\
 	Integer f3;							\
   } mercury_data__layout__##l = {					\
 	(const Word *) &mercury_data__layout__##e,			\
 	UNKNOWN_INTERNAL_LABEL_NUMBER					\
-	(Integer) 0		/* No live values */			\
+	(Integer) -1		/* No information about live values */	\
   };
 #else
   #define MR_MAKE_STACK_LAYOUT_INTERNAL_WITH_ENTRY(l, e)        
@@ -233,96 +325,16 @@
 #ifdef MR_USE_STACK_LAYOUTS
   #define MR_MAKE_STACK_LAYOUT_INTERNAL(e, x)				\
   const struct mercury_data__layout__##e##_i##x##_struct {		\
-	const Word * f1;						\
+	const Word *f1;							\
 	UNKNOWN_INTERNAL_LABEL_FIELD					\
 	Integer f3;							\
   } mercury_data__layout__##e##_i##x = {				\
 	(const Word *) &mercury_data__layout__##e,			\
 	UNKNOWN_INTERNAL_LABEL_NUMBER					\
-	(Integer) 0		/* No live values */			\
+	(Integer) -1		/* No information about live values */	\
   };
 #else
   #define MR_MAKE_STACK_LAYOUT_INTERNAL(l, x)        
 #endif	/* MR_USE_STACK_LAYOUTS */
 
-/*
-** Structs and macros to support stack layouts.
-*/
-
-typedef	struct MR_Stack_Layout_Var_Struct {
-	MR_Live_Lval		MR_slv_locn;
-	MR_Live_Type		MR_slv_live_type;
-} MR_Stack_Layout_Var;
-
-typedef	struct MR_Stack_Layout_Vars_Struct {
-	MR_Stack_Layout_Var	*MR_slvs_pairs;
-	String			*MR_slvs_names;
-	MR_Live_Lval		*MR_slvs_tvars;
-				/*
-				** If MR_slvs_tvars == NULL, there are no
-				** type parameters. If it is != NULL, then
-				** (Integer) MR_slvs_tvars[0] is the index
-				** of the highest numbered type parameter,
-				** and MR_slvs_tvars[i] for values of i
-				** between 1 and (Integer) MR_slvs_tvars[0]
-				** (both inclusive) describe the location
-				** of the typeinfo structure for the type
-				** variable of the corresponding number.
-				** If one of these type variables is not
-				** referred to by the variables described in
-				** MR_slvs_pairs, the corresponding entry
-				** will be zero.
-				*/
-} MR_Stack_Layout_Vars;
-
-#define	MR_name_if_present(vars, i)					\
-				((vars->MR_slvs_names != NULL		\
-				&& vars->MR_slvs_names[(i)] != NULL)	\
-				? vars->MR_slvs_names[(i)]		\
-				: "")
-
-typedef	struct MR_Stack_Layout_Entry_Struct {
-	Code			*MR_sle_code_addr;
-	MR_Determinism		MR_sle_detism;
-	Integer			MR_sle_stack_slots;
-	MR_Live_Lval		MR_sle_succip_locn;
-	/* the fields from here onwards are present only with procid layouts */
-	MR_PredFunc		MR_sle_pred_or_func;
-	String			MR_sle_decl_module;
-	String			MR_sle_def_module;
-	String			MR_sle_name;
-	Integer			MR_sle_arity;
-	Integer			MR_sle_mode;
-	/* the fields from here onwards are present only with trace layouts */
-	struct MR_Stack_Layout_Label_Struct
-				*MR_sle_call_label;
-} MR_Stack_Layout_Entry;
-
-typedef	struct MR_Stack_Layout_Label_Struct {
-	MR_Stack_Layout_Entry	*MR_sll_entry;
-#if 0
-	Integer			MR_sll_label_num;
-#endif
-	Integer			MR_sll_var_count;
-	/* the last field is present only if MR_sll_var_count > 0 */
-	MR_Stack_Layout_Vars	MR_sll_var_info;
-} MR_Stack_Layout_Label;
-
-/* The following macros support obsolete code (and probably don't work). */
-#define MR_ENTRY_STACK_LAYOUT_GET_LABEL_ADDRESS(s)		\
-		((Code *) field(0, (s), 0))
-
-#define MR_CONT_STACK_LAYOUT_GET_ENTRY_LAYOUT(s)		\
-		(field(0, (s), 0))
-
-#define MR_ENTRY_STACK_LAYOUT_GET_NUM_SLOTS(s)			\
-		(field(0, (s), 2))
-
-#define MR_ENTRY_STACK_LAYOUT_GET_CODE_MODEL(s)			\
-		(field(0, (s), 1) & 1)
-
-#define MR_ENTRY_STACK_LAYOUT_GET_SUCCIP_LOC(s)			\
-		(field(0, (s), 3))
-
-/*---------------------------------------------------------------------------*/
 #endif /* not MERCURY_STACK_LAYOUT_H */
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 scripts
cvs diff: Diffing tests
cvs diff: Diffing tests/benchmarks
cvs diff: Diffing tests/debugger
cvs diff: Diffing tests/general
cvs diff: Diffing tests/hard_coded
cvs diff: Diffing tests/hard_coded/typeclasses
cvs diff: Diffing tests/invalid
cvs diff: Diffing tests/misc_tests
cvs diff: Diffing tests/term
cvs diff: Diffing tests/valid
cvs diff: Diffing tests/warnings
cvs diff: Diffing tools
cvs diff: Diffing trial
cvs diff: Diffing util



More information about the developers mailing list