diff: Runtime support for stack layouts, round 2

Tyson Dowd trd at cs.mu.oz.au
Wed Nov 26 17:06:05 AEDT 1997


Hi,

Here's round 2 of this review. 

Zoltans comments from the last review have been addressed, except for
the XXX I've added to mercury_label.c. I'm pretty sure I know how
to fix this, but it will require testing that the change doesn't
break the profiler as well.

Because of the separate renaming of files in the runtime,
this diff is a lot smaller than its last incarnation.

===================================================================

Estimated hours taken: 25

Add library and runtime support for stack layouts.

library/array.m:
library/benchmarking.m:
library/mercury_builtin.m:
library/std_util.m:
library/string.m:
runtime/mercury_engine.c:
runtime/mercury_ho_call.c:
runtime/mercury_type_info.c:
	Add MR_MAKE_STACK_LAYOUT_* macros to add basic stack layouts for
	handwritten C code.

runtime/mercury_calls.h:
	Instead of doing ASM_FIXUP_REGS as part of the call macro, do
	it as part of the proceed macro.
	As part of the call macro, the succip would always be set
	to the "fixup_gp" label, so it was difficult to find the
	caller using the succip. Using this technique, it is set
	correctly.
	(There's a small cost - with the call macro, you only did
	ASM_FIXUP_REGS after you returned from a non-local call, using
	"proceed" you do this at every call. The only way I can see
	to avoid this cost is to actually change the code generator
	so that it outputs two labels for continuations, one used
	for local calls, and one for non-local calls. The nonlocal
	label does ASM_FIXUP_REGS and falls through to the local label).
	But the current cost is about 30k in the compiler on the alpha,
	and any speed difference appears to be lost in noise (note that
	for non-local calls, the new code is probably a little more
	efficient).

runtime/mercury_label.c:
runtime/mercury_label.h:
runtime/mercury_goto.h:
	Insert references to stack layouts into the label table.
	Use the label table when NATIVE_GC is defined.
	Modify the way labels are declared so they have the necessary
	scope.

runtime/mercury_imp.h:
	Include mercury_accurate_gc.h

runtime/mercury_accurate_gc.h:
	Add some macros to define stack layouts for handwritten
	code, and access various fields of the stack layouts.

util/mkinit.c:
	Add NATIVE_GC to the #ifdef .... that controls the running of
	the initialization code for each module. NATIVE_GC requires the
	label table to be initialized.
	Fix this code so the two instances of this list of #defines are
	replaced by a single string constant. I've been bitten _twice_
	by this double definition, and I refuse to be bitten again.

compiler/stack_layout.m:
	Rename MR_LIVE_LVAL to Mr_Live_Lval in the documentation.


Index: compiler/stack_layout.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/stack_layout.m,v
retrieving revision 1.1
diff -u -r1.1 stack_layout.m
--- stack_layout.m	1997/11/08 13:11:46	1.1
+++ stack_layout.m	1997/11/17 06:36:42
@@ -24,7 +24,7 @@
 % 	number of stack slots	(Integer) 
 % 	code_model		(Integer) actually, type MR_Code_Model 
 % 					0 = DET, 1 = NONDET
-% 	succip stack location	(Integer) actually, type MR_LIVE_LVAL
+% 	succip stack location	(Integer) actually, type MR_Live_Lval
 % 					(the location will be set to -1
 % 					if there is no succip available).
 %
@@ -35,9 +35,9 @@
 %	procedure info		(Word *) - pointer to procedure stack layout
 %	number of live vars	(Integer)
 %	live data locations and (Word *) - pointer to vector of 
-%		types			MR_LIVE_LVAL and MR_LIVE_TYPE pairs
+%		types			MR_Live_Lval and MR_Live_Type pairs
 %	type parameters		(Word *) - pointer to vector of 
-%					MR_LIVE_LVAL
+%					MR_Live_Lval
 %
 % If the number of live vars is 0, there could be two explanations. The
 % continuation label might actually have no live data, or (more likely)
Index: library/array.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/library/array.m,v
retrieving revision 1.39
diff -u -r1.39 array.m
--- array.m	1997/11/02 12:30:23	1.39
+++ array.m	1997/11/26 04:54:24
@@ -255,6 +255,9 @@
 Define_extern_entry(mercury____Unify___array__array_1_0);
 Define_extern_entry(mercury____Index___array__array_1_0);
 Define_extern_entry(mercury____Compare___array__array_1_0);
+MR_MAKE_STACK_LAYOUT_ENTRY(mercury____Unify___array__array_1_0);
+MR_MAKE_STACK_LAYOUT_ENTRY(mercury____Index___array__array_1_0);
+MR_MAKE_STACK_LAYOUT_ENTRY(mercury____Compare___array__array_1_0);
 
 #ifdef  USE_TYPE_LAYOUT
 
Index: library/benchmarking.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/library/benchmarking.m,v
retrieving revision 1.3
diff -u -r1.3 benchmarking.m
--- benchmarking.m	1997/11/21 06:49:21	1.3
+++ benchmarking.m	1997/11/23 13:44:37
@@ -130,6 +130,9 @@
 Define_extern_entry(mercury__benchmarking__benchmark_nondet_5_0);
 Declare_label(mercury__benchmarking__benchmark_nondet_5_0_i1);
 Declare_label(mercury__benchmarking__benchmark_nondet_5_0_i2);
+MR_MAKE_STACK_LAYOUT_ENTRY(mercury__benchmarking__benchmark_nondet_5_0);
+MR_MAKE_STACK_LAYOUT_INTERNAL(mercury__benchmarking__benchmark_nondet_5_0, 1);
+MR_MAKE_STACK_LAYOUT_INTERNAL(mercury__benchmarking__benchmark_nondet_5_0, 2);
 
 BEGIN_MODULE(benchmark_nondet_module)
 	init_entry(mercury__benchmarking__benchmark_nondet_5_0);
@@ -216,6 +219,8 @@
 
 Define_extern_entry(mercury__benchmarking__benchmark_det_5_0);
 Declare_label(mercury__benchmarking__benchmark_det_5_0_i1);
+MR_MAKE_STACK_LAYOUT_ENTRY(mercury__benchmarking__benchmark_det_5_0);
+MR_MAKE_STACK_LAYOUT_INTERNAL(mercury__benchmarking__benchmark_det_5_0, 1);
 
 BEGIN_MODULE(benchmark_det_module)
 	init_entry(mercury__benchmarking__benchmark_det_5_0);
Index: library/mercury_builtin.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/library/mercury_builtin.m,v
retrieving revision 1.85
diff -u -r1.85 mercury_builtin.m
--- mercury_builtin.m	1997/11/21 06:49:25	1.85
+++ mercury_builtin.m	1997/11/23 13:44:40
@@ -719,6 +719,8 @@
 :- pragma c_code("
 Define_extern_entry(mercury__copy_2_0);
 Define_extern_entry(mercury__copy_2_1);
+MR_MAKE_STACK_LAYOUT_ENTRY(mercury__copy_2_0);
+MR_MAKE_STACK_LAYOUT_ENTRY(mercury__copy_2_1);
 
 BEGIN_MODULE(copy_module)
 	init_entry(mercury__copy_2_0);
@@ -799,6 +801,9 @@
 Define_extern_entry(mercury____Unify___mercury_builtin__c_pointer_0_0);
 Define_extern_entry(mercury____Index___mercury_builtin__c_pointer_0_0);
 Define_extern_entry(mercury____Compare___mercury_builtin__c_pointer_0_0);
+MR_MAKE_STACK_LAYOUT_ENTRY(mercury____Unify___mercury_builtin__c_pointer_0_0);
+MR_MAKE_STACK_LAYOUT_ENTRY(mercury____Index___mercury_builtin__c_pointer_0_0);
+MR_MAKE_STACK_LAYOUT_ENTRY(mercury____Compare___mercury_builtin__c_pointer_0_0);
 
 BEGIN_MODULE(unify_c_pointer_module)
 	init_entry(mercury____Unify___mercury_builtin__c_pointer_0_0);
Index: library/std_util.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/library/std_util.m,v
retrieving revision 1.110
diff -u -r1.110 std_util.m
--- std_util.m	1997/11/21 06:49:26	1.110
+++ std_util.m	1997/11/26 04:56:25
@@ -483,6 +483,15 @@
 Declare_label(mercury__std_util__builtin_aggregate_4_0_i1);
 Declare_label(mercury__std_util__builtin_aggregate_4_0_i2);
 Declare_label(mercury__std_util__builtin_aggregate_4_0_i3);
+MR_MAKE_STACK_LAYOUT_ENTRY(mercury__std_util__builtin_aggregate_4_0);
+MR_MAKE_STACK_LAYOUT_ENTRY(mercury__std_util__builtin_aggregate_4_1);
+MR_MAKE_STACK_LAYOUT_ENTRY(mercury__std_util__builtin_aggregate_4_2);
+MR_MAKE_STACK_LAYOUT_ENTRY(mercury__std_util__builtin_aggregate_4_3);
+MR_MAKE_STACK_LAYOUT_ENTRY(mercury__std_util__builtin_aggregate_4_4);
+MR_MAKE_STACK_LAYOUT_ENTRY(mercury__std_util__builtin_aggregate_4_5);
+MR_MAKE_STACK_LAYOUT_INTERNAL(mercury__std_util__builtin_aggregate_4_0, 1);
+MR_MAKE_STACK_LAYOUT_INTERNAL(mercury__std_util__builtin_aggregate_4_0, 2);
+MR_MAKE_STACK_LAYOUT_INTERNAL(mercury__std_util__builtin_aggregate_4_0, 3);
 
 BEGIN_MODULE(builtin_aggregate_module)
 	init_entry(mercury__std_util__builtin_aggregate_4_0);
@@ -1154,10 +1163,17 @@
 Define_extern_entry(mercury____Index___std_util__univ_0_0);
 Define_extern_entry(mercury____Compare___std_util__univ_0_0);
 Declare_label(mercury____Compare___std_util__univ_0_0_i1);
+MR_MAKE_STACK_LAYOUT_ENTRY(mercury____Unify___std_util__univ_0_0);
+MR_MAKE_STACK_LAYOUT_ENTRY(mercury____Index___std_util__univ_0_0);
+MR_MAKE_STACK_LAYOUT_ENTRY(mercury____Compare___std_util__univ_0_0);
+MR_MAKE_STACK_LAYOUT_INTERNAL(mercury____Compare___std_util__univ_0_0, 1);
 
 Define_extern_entry(mercury____Unify___std_util__type_info_0_0);
 Define_extern_entry(mercury____Index___std_util__type_info_0_0);
 Define_extern_entry(mercury____Compare___std_util__type_info_0_0);
+MR_MAKE_STACK_LAYOUT_ENTRY(mercury____Unify___std_util__type_info_0_0);
+MR_MAKE_STACK_LAYOUT_ENTRY(mercury____Index___std_util__type_info_0_0);
+MR_MAKE_STACK_LAYOUT_ENTRY(mercury____Compare___std_util__type_info_0_0);
 
 BEGIN_MODULE(unify_univ_module)
 	init_entry(mercury____Unify___std_util__univ_0_0);
Index: library/string.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/library/string.m,v
retrieving revision 1.96
diff -u -r1.96 string.m
--- string.m	1997/10/11 16:11:25	1.96
+++ string.m	1997/10/23 01:44:30
@@ -1720,6 +1720,8 @@
 
 Define_extern_entry(mercury__string__append_3_3_xx);
 Declare_label(mercury__string__append_3_3_xx_i1);
+MR_MAKE_STACK_LAYOUT_ENTRY(mercury__string__append_3_3_xx);
+MR_MAKE_STACK_LAYOUT_INTERNAL(mercury__string__append_3_3_xx, 1);
 
 BEGIN_MODULE(string_append_module)
 	init_entry(mercury__string__append_3_3_xx);
Index: runtime/mercury_accurate_gc.h
===================================================================
RCS file: /home/staff/zs/imp/mercury/runtime/mercury_accurate_gc.h,v
retrieving revision 1.2
diff -u -r1.2 mercury_accurate_gc.h
--- mercury_accurate_gc.h	1997/07/27 15:08:27	1.2
+++ mercury_accurate_gc.h	1997/11/25 16:32:19
@@ -4,14 +4,236 @@
 ** Public License - see the file COPYING.LIB in the Mercury distribution.
 */
 
+#ifndef MERCURY_ACCURATE_GC_H
+#define MERCURY_ACCURATE_GC_H
+
 /*
 ** mercury_accurate_gc.h -
 **	Definitions for use by the accurate garbage collector (and
 **	supporting code).
 */
 
-#ifndef MERCURY_ACCURATE_GC_H
-#define MERCURY_ACCURATE_GC_H
+/*---------------------------------------------------------------------------*/
+
+/*
+** Defintions used for accessing and creating stack_layouts.
+**
+** NOTE: The constants and data-structures used here need to be kept in
+** 	 sync with the ones generated in the compiler. If you change
+** 	 anything here, you may need to change compiler/stack_layout.m
+** 	 as well.
+*/
+
+#ifdef NATIVE_GC
+ #define MR_USE_STACK_LAYOUTS
+#endif
+
+/*
+** Definitions for MR_Stack_Specifier
+*/
+
+typedef enum { MR_STACK_DET, MR_STACK_NONDET } MR_Stack_Specifier;
+
+/*
+** 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.
+**
+** MR_Live_Lval is encoded using an 8 bit low tag, the rest of the word is a 
+** data field describing which stack slot number or register number.
+**
+**  Lval		Tag	Rest
+**  r(Num)		 0	Num
+**  f(Num)		 1	Num
+**  stackvar(Num)	 2	Num
+**  framevar(Num)	 3	Num
+**  succip		 4
+**  maxfr		 5
+**  curfr		 6
+**  hp			 7
+**  sp			 8
+**  unknown		 9		(The location is not known)
+**
+** The type MR_Lval_Type describes the different tag values.
+**
+** This data is generated in compiler/stack_layout.m must be kept
+** in sync with the constants defined here.
+*/
+
+typedef Word MR_Live_Lval;
+
+typedef enum { 
+	MR_LVAL_TYPE_R,
+	MR_LVAL_TYPE_F,
+	MR_LVAL_TYPE_STACKVAR,
+	MR_LVAL_TYPE_FRAMEVAR,
+	MR_LVAL_TYPE_SUCCIP,
+	MR_LVAL_TYPE_MAXFR,
+	MR_LVAL_TYPE_CURFR,
+	MR_LVAL_TYPE_HP,
+	MR_LVAL_TYPE_SP,
+	MR_LVAL_TYPE_UNKNOWN 
+} MR_Lval_Type;
+
+#define MR_LIVE_LVAL_TAGBITS	8
+
+#define MR_LIVE_LVAL_TYPE(Lval) 			\
+	((MR_Lval_Type) ((Lval) & ((1 << MR_LIVE_LVAL_TAGBITS) - 1)))
+
+#define MR_LIVE_LVAL_NUMBER(Lval) 			\
+	((Word) (Lval) >> MR_LIVE_LVAL_TAGBITS)
+
+/*
+** Definitions for MR_Live_Type
+**
+** MR_Live_Type describes live data. This includes:
+** 	- succip, hp, curfr, maxfr, redoip, and
+** 	  mercury data values (vars).
+**
+** The data is encoded such that low values (less than
+** TYPELAYOUT_MAX_VARINT) represent succip, hp, etc.  Higher values
+** represent data variables, and are pointers to a 2 word cell, 
+** containing a type_info and an instantiation represention.
+**
+** This data is generated in compiler/stack_layout.m must be kept
+** in sync with the constants defined here.
+*/
+
+typedef Word MR_Live_Type;
+
+typedef enum { 
+	MR_LIVE_TYPE_SUCCIP,
+	MR_LIVE_TYPE_HP,
+	MR_LIVE_TYPE_CURFR,
+	MR_LIVE_TYPE_MAXFR,
+	MR_LIVE_TYPE_REDOIP,
+	MR_LIVE_TYPE_UNWANTED 
+} MR_Lval_NonVar;
+
+typedef struct { 
+	Word	type;
+	Word	inst;
+} MR_Var_Shape_Info;
+
+#define MR_LIVE_TYPE_IS_VAR(T)         ( (Word) T > TYPELAYOUT_MAX_VARINT )
+
+#define MR_LIVE_TYPE_GET_NONVAR(T)			\
+		((MR_Lval_NonVar) T)
+
+#define MR_LIVE_TYPE_GET_VAR_TYPE(T)   			\
+		((Word) ((MR_Var_Shape_Info *) T)->type)
+
+#define MR_LIVE_TYPE_GET_VAR_INST(T)   			\
+		((Word) ((MR_Var_Shape_Info *) T)->inst)
+
+
+/*
+** Macros to support hand-written C code.
+*/
+
+/*
+** Define a stack layout for a label that you know very little about.
+** It's just a generic entry label, no useful information, except
+** the code address for the label.
+*/ 
+#ifdef MR_USE_STACK_LAYOUTS
+ #define MR_MAKE_STACK_LAYOUT_ENTRY(l) 					\
+ const struct mercury_data__stack_layout__##l##_struct {		\
+	Code * f1;							\
+	Integer f2;							\
+	Integer f3;							\
+	Integer f4;							\
+ } mercury_data__stack_layout__##l = {					\
+	STATIC(l),							\
+	(Integer) -1,	/* Unknown number of stack slots */		\
+	(Integer) -1, 	/* Unknown code model */			\
+        (Integer) MR_LVAL_TYPE_UNKNOWN 	/* Unknown succip location */	\
+ };
+#else
+ #define MR_MAKE_STACK_LAYOUT_ENTRY(l)        
+#endif	/* MR_USE_STACK_LAYOUTS */
+
+/*
+** Define a stack layout for an internal label. Need to supply the
+** label name (l) and the entry label name (e).
+**
+** The only useful information in this structure is the code address
+** and the reference to the entry for this label.
+*/ 
+#ifdef MR_USE_STACK_LAYOUTS
+ #define MR_MAKE_STACK_LAYOUT_INTERNAL_WITH_ENTRY(l, e)			\
+ const struct mercury_data__stack_layout__##l##_struct {		\
+	Code * f1;							\
+	const Word * f2;						\
+	Integer f3;							\
+	const Word * f4;						\
+ } mercury_data__stack_layout__##l = {					\
+	ENTRY(l),							\
+	(const Word *) &mercury_data__stack_layout__##e,		\
+	(Integer) -1,		/* Unknown number of live values */	\
+	(const Word *) NULL	/* No list of live valeus */		\
+ };
+#else
+ #define MR_MAKE_STACK_LAYOUT_INTERNAL_WITH_ENTRY(l, e)        
+#endif	/* MR_USE_STACK_LAYOUTS */
+
+/*
+** Define a stack layout for an internal label.
+** Need to supply the label name (l) and the number (x), eg for
+** label_name_i3, x is 3. It is assumed the entry label for that
+** corresponds to this label is the label name without the _iX suffix.
+**
+** (MR_MAKE_STACK_LAYOUT_INTERNAL_WITH_ENTRY, above, is a little
+** more general than MR_MAKE_STACK_LAYOUT_INTERNAL. This macro can
+** only describe relationships between labels that have the same
+** base -- MR_MAKE_STACK_LAYOUT_INTERNAL_WITH_ENTRY can create layouts
+** for internal labels no matter what the name of the entry layout is).
+**
+** The only useful information in this structure is the code address
+** and the reference to the entry for this label.
+*/ 
+#ifdef MR_USE_STACK_LAYOUTS
+ #define MR_MAKE_STACK_LAYOUT_INTERNAL(l, x)				\
+ const struct mercury_data__stack_layout__##l##_i##x##_struct {		\
+	Code * f1;							\
+	const Word * f2;						\
+	Integer f3;							\
+	const Word * f4;						\
+ } mercury_data__stack_layout__##l##_i##x = {				\
+	ENTRY(l),							\
+	(const Word *) &mercury_data__stack_layout__##l,		\
+	(Integer) -1,		/* Unknown number of live values */	\
+	(const Word *) NULL	/* No list of live valeus */		\
+ };
+#else
+ #define MR_MAKE_STACK_LAYOUT_INTERNAL(l, x)        
+#endif	/* MR_USE_STACK_LAYOUTS */
+
+
+/*
+** Macros to support stack layouts.
+** XXX ought to use a MR_Entry_Stack_Layout and MR_Cont_Stack_Layout
+** struct to make it easier to access the fields.
+*/
+#define MR_CONT_STACK_LAYOUT_GET_LABEL_ADDRESS(s)		\
+		((Code *) field(0, (s), 0))
+
+#define MR_ENTRY_STACK_LAYOUT_GET_LABEL_ADDRESS(s)		\
+		MR_CONT_STACK_LAYOUT_GET_LABEL_ADDRESS(s)
+
+#define MR_CONT_STACK_LAYOUT_GET_ENTRY_LAYOUT(s)		\
+		(field(0, (s), 1))
+
+#define MR_ENTRY_STACK_LAYOUT_GET_NUM_SLOTS(s)			\
+		(field(0, (s), 1))
+
+#define MR_ENTRY_STACK_LAYOUT_GET_CODE_MODEL(s)			\
+		(field(0, (s), 2))
+
+#define MR_ENTRY_STACK_LAYOUT_GET_SUCCIP_LOC(s)			\
+		(field(0, (s), 3))
 
 /*---------------------------------------------------------------------------*/
 #endif /* not MERCURY_ACCURATE_GC_H */
Index: runtime/mercury_calls.h
===================================================================
RCS file: /home/staff/zs/imp/mercury/runtime/mercury_calls.h,v
retrieving revision 1.2
diff -u -r1.2 mercury_calls.h
--- mercury_calls.h	1997/11/23 07:21:14	1.2
+++ mercury_calls.h	1997/11/25 06:33:12
@@ -22,46 +22,15 @@
 			GOTO_LABEL(label);			\
 		} while (0)
 
-/*
-** On some systems [basically those using PIC (Position Independent Code)],
-** if we're using gcc non-local gotos to jump between functions then
-** we need to do ASM_FIXUP_REGS after each return from a procedure call.
-*/
-#if defined(USE_GCC_NONLOCAL_GOTOS) && defined(NEED_ASM_FIXUP_REGS)
-  #define	noprof_call(proc, succ_cont)			\
-		({						\
-			__label__ fixup_gp;			\
-			debugcall((proc), (succ_cont));		\
-			MR_succip = (&&fixup_gp);		\
-			set_prof_current_proc(proc);		\
-			GOTO(proc);				\
-		fixup_gp:					\
-			ASM_FIXUP_REGS				\
-			GOTO(succ_cont); 			\
-		})
-	/* same as above, but with GOTO_LABEL rather than GOTO */
-  #define	noprof_call_localret(proc, succ_cont)		\
-		({						\
-			__label__ fixup_gp;			\
-			debugcall((proc), (succ_cont));		\
-			MR_succip = (&&fixup_gp);		\
-			set_prof_current_proc(proc);		\
-			GOTO(proc);				\
-		fixup_gp:					\
-			ASM_FIXUP_REGS				\
-			GOTO_LABEL(succ_cont); 			\
-		})
-#else
-  #define	noprof_call(proc, succ_cont)			\
+#define	noprof_call(proc, succ_cont)				\
 		do {						\
 			debugcall((proc), (succ_cont));		\
 			MR_succip = (succ_cont);		\
 			set_prof_current_proc(proc);		\
 			GOTO(proc);				\
 		} while (0)
-  #define noprof_call_localret(proc, succ_cont) 		\
+#define noprof_call_localret(proc, succ_cont)	 		\
 		noprof_call((proc), LABEL(succ_cont))
-#endif
 
 #define	localcall(label, succ_cont, current_label)		\
 		do {						\
@@ -121,9 +90,15 @@
 			GOTO(proc);				\
 		} while (0)
 
+/*
+** On some systems [basically those using PIC (Position Independent Code)],
+** if we're using gcc non-local gotos to jump between functions then
+** we need to do ASM_FIXUP_REGS after each return from a procedure call.
+*/
 #define	proceed()						\
 		do {						\
 			debugproceed();				\
+			ASM_FIXUP_REGS				\
 			GOTO(MR_succip);			\
 		} while (0)
 
Index: runtime/mercury_engine.c
===================================================================
RCS file: /home/staff/zs/imp/mercury/runtime/mercury_engine.c,v
retrieving revision 1.2
diff -u -r1.2 mercury_engine.c
--- mercury_engine.c	1997/11/23 07:21:20	1.2
+++ mercury_engine.c	1997/11/25 06:58:29
@@ -396,6 +396,12 @@
 Define_extern_entry(do_last_succeed);
 Define_extern_entry(do_not_reached);
 
+MR_MAKE_STACK_LAYOUT_ENTRY(do_redo);
+MR_MAKE_STACK_LAYOUT_ENTRY(do_fail);
+MR_MAKE_STACK_LAYOUT_ENTRY(do_succeed);
+MR_MAKE_STACK_LAYOUT_ENTRY(do_last_succeed);
+MR_MAKE_STACK_LAYOUT_ENTRY(do_not_reached);
+
 BEGIN_MODULE(special_labels_module)
 	init_entry(do_redo);
 	init_entry(do_fail);
Index: runtime/mercury_goto.h
===================================================================
RCS file: /home/staff/zs/imp/mercury/runtime/mercury_goto.h,v
retrieving revision 1.2
diff -u -r1.2 mercury_goto.h
--- mercury_goto.h	1997/11/23 07:21:23	1.2
+++ mercury_goto.h	1997/11/25 16:55:04
@@ -12,36 +12,46 @@
 #include "mercury_types.h"	/* for `Code *' */
 #include "mercury_debug.h"	/* for debuggoto() */
 
+#define paste(a,b) a##b
+#define stringify(string) #string
+#define entry(label) paste(_entry_,label)
+#define skip(label) paste(skip_,label)
+
+#ifdef MR_USE_STACK_LAYOUTS
+ #define MR_STACK_LAYOUT(label)        (Word *) (Word) \
+	&(paste(mercury_data__stack_layout__,label))
+#else
+ #define MR_STACK_LAYOUT(label) (Word *) NULL
+#endif /* MR_USE_STACK_LAYOUTS */
+
+
 /*
 ** Taking the address of a label can inhibit gcc's optimization,
 ** because it assumes that anything can jump there.
 ** Therefore we want to do it only if we're debugging,
-** or if we need the label address for profiling.
+** or if we need the label address for profiling or
+** accurate garbage collection.
 */
 
 #if defined(SPEED) && !defined(DEBUG_GOTOS)
-#define	make_label(n, a)	/* nothing */
+#define	make_label(n, a, l)	/* nothing */
 #else
-#define	make_label(n, a)	make_entry(n, a)
+#define	make_label(n, a, l)	make_entry(n, a, l)
 #endif
 
 #if defined(SPEED) && !defined(DEBUG_GOTOS) && !defined(PROFILE_CALLS)
-#define make_local(n, a)	/* nothing */
+#define make_local(n, a, l)	/* nothing */
 #else 
-#define make_local(n, a)	make_entry(n, a)
+#define make_local(n, a, l)	make_entry(n, a, l)
 #endif
 
 #if defined(SPEED) && !defined(DEBUG_LABELS) && !defined(DEBUG_GOTOS) \
 			&& !defined(PROFILE_CALLS)
-#define make_entry(n, a)	/* nothing */
+#define make_entry(n, a, l)	/* nothing */
 #else
-#define make_entry(n, a)	insert_entry(n, a)
+#define make_entry(n, a, l)	insert_entry(n, a, MR_STACK_LAYOUT(l))
 #endif
 
-#define paste(a,b) a##b
-#define stringify(string) #string
-#define entry(label) paste(_entry_,label)
-#define skip(label) paste(skip_,label)
 
 #ifdef SPLIT_C_FILES
 #define MODULE_STATIC_OR_EXTERN extern
@@ -459,7 +469,7 @@
     */
     #define init_entry(label)	\
 	PRETEND_ADDRESS_IS_USED(&&label); \
-	make_entry(stringify(label), label)
+	make_entry(stringify(label), label, label)
 
     #define ENTRY(label) 	(&label)
     #define STATIC(label) 	(&label)
@@ -485,7 +495,7 @@
 	label:	\
 	{
     #define init_entry(label)	\
-	make_entry(stringify(label), &&label);	\
+	make_entry(stringify(label), &&label, label);	\
 	entry(label) = &&label
     #define ENTRY(label) 	(entry(label))
     #define STATIC(label) 	(entry(label))
@@ -502,10 +512,15 @@
 	}	\
 	label:	\
 	{
-  #define init_local(label)	make_local(stringify(label), &&label)
-  #define Declare_label(label)	/* no declaration required */
-  #define Define_label(label)	Define_local(label)
-  #define init_label(label)	make_label(stringify(label), &&label)
+  #define init_local(label)	make_local(stringify(label), &&label, label)
+  #ifdef NATIVE_GC
+   #define Declare_label(label)	Define_extern_entry(label)
+   #define Define_label(label)	Define_entry(label)
+  #else
+   #define Declare_label(label)	/* no declaration required */
+   #define Define_label(label)	Define_local(label)
+  #endif
+  #define init_label(label)	make_label(stringify(label), &&label, label)
 
   #define LOCAL(label)		(&&entry(label))
   #define LABEL(label)		(&&entry(label))
@@ -543,21 +558,21 @@
 		GOTO(label);	\
 	}			\
 	static Code* label(void) {
-  #define init_entry(label)	make_entry(stringify(label), label)
+  #define init_entry(label)	make_entry(stringify(label), label, label)
 
   #define Declare_local(label)	static Code *label(void)
   #define Define_local(label)	\
 		GOTO(label);	\
 	}			\
 	static Code* label(void) {
-  #define init_local(label)	make_local(stringify(label), label)
+  #define init_local(label)	make_local(stringify(label), label, label)
 
   #define Declare_label(label)	static Code *label(void)
   #define Define_label(label)	\
 		GOTO(label);	\
 	}			\
 	static Code* label(void) {
-  #define init_label(label)	make_label(stringify(label), label)
+  #define init_label(label)	make_label(stringify(label), label, label)
 
   #define ENTRY(label) 		(label)
   #define STATIC(label) 	(label)
Index: runtime/mercury_ho_call.c
===================================================================
RCS file: /home/staff/zs/imp/mercury/runtime/mercury_ho_call.c,v
retrieving revision 1.2
diff -u -r1.2 mercury_ho_call.c
--- mercury_ho_call.c	1997/11/23 07:21:24	1.2
+++ mercury_ho_call.c	1997/11/25 16:48:10
@@ -45,6 +45,26 @@
 Define_extern_entry(mercury__compare_3_3);
 Declare_label(mercury__compare_3_0_i1);
 
+MR_MAKE_STACK_LAYOUT_ENTRY(do_call_det_closure);
+MR_MAKE_STACK_LAYOUT_INTERNAL_WITH_ENTRY(det_closure_return, 
+	do_call_det_closure);
+MR_MAKE_STACK_LAYOUT_ENTRY(do_call_semidet_closure);
+MR_MAKE_STACK_LAYOUT_INTERNAL_WITH_ENTRY(semidet_closure_return,
+	do_call_semidet_closure);
+MR_MAKE_STACK_LAYOUT_ENTRY(do_call_nondet_closure);
+MR_MAKE_STACK_LAYOUT_INTERNAL_WITH_ENTRY(nondet_closure_return,
+	do_call_nondet_closure);
+
+MR_MAKE_STACK_LAYOUT_ENTRY(mercury__unify_2_0);
+MR_MAKE_STACK_LAYOUT_ENTRY(mercury__index_2_0);
+MR_MAKE_STACK_LAYOUT_INTERNAL(mercury__index_2_0, 1);
+MR_MAKE_STACK_LAYOUT_ENTRY(mercury__compare_3_0);
+MR_MAKE_STACK_LAYOUT_ENTRY(mercury__compare_3_1);
+MR_MAKE_STACK_LAYOUT_ENTRY(mercury__compare_3_2);
+MR_MAKE_STACK_LAYOUT_ENTRY(mercury__compare_3_3);
+MR_MAKE_STACK_LAYOUT_INTERNAL(mercury__compare_3_0, 1);
+
+
 BEGIN_MODULE(call_module)
 	init_entry(do_call_det_closure);
 	init_label(det_closure_return);
Index: runtime/mercury_imp.h
===================================================================
RCS file: /home/staff/zs/imp/mercury/runtime/mercury_imp.h,v
retrieving revision 1.2
diff -u -r1.2 mercury_imp.h
--- mercury_imp.h	1997/11/23 07:21:25	1.2
+++ mercury_imp.h	1997/11/25 16:35:26
@@ -40,6 +40,7 @@
 #include	"mercury_types.h"
 #include	"mercury_string.h"
 #include	"mercury_float.h"
+#include	"mercury_accurate_gc.h"
 
 #include	"mercury_tags.h"
 #include	"mercury_goto.h"
@@ -62,6 +63,7 @@
 #include	"mercury_debug.h"
 #include	"mercury_prof.h"
 #include	"mercury_misc.h"
+
 
 #include	"mercury_grade.h"
 
Index: runtime/mercury_label.c
===================================================================
RCS file: /home/staff/zs/imp/mercury/runtime/mercury_label.c,v
retrieving revision 1.2
diff -u -r1.2 mercury_label.c
--- mercury_label.c	1997/11/23 07:21:26	1.2
+++ mercury_label.c	1997/11/25 06:50:58
@@ -50,15 +50,30 @@
 }
 
 Label *
-insert_entry(const char *name, Code *addr)
+insert_entry(const char *name, Code *addr, Word *entry_layout_info)
 {
 	Label	*entry;
 
 	do_init_entries();
 
+
+#ifdef MR_USE_STACK_LAYOUTS
+	/* 
+	** The succip will be set to the address stored in the
+	** layout info. For some reason, this is different to
+	** the address passed to insert_entry.
+	** XXX This should be fixed.
+	*/
+	addr = entry_layout_info[0];
+#endif /* MR_USE_STACK_LAYOUTS */
+
+
+
+
 	entry = make(Label);
 	entry->e_name  = name;
 	entry->e_addr  = addr;
+	entry->e_layout = entry_layout_info;
 
 #ifdef	PROFILE_CALLS
 	prof_output_addr_decls(name, addr);
Index: runtime/mercury_label.h
===================================================================
RCS file: /home/staff/zs/imp/mercury/runtime/mercury_label.h,v
retrieving revision 1.2
diff -u -r1.2 mercury_label.h
--- mercury_label.h	1997/11/23 07:21:26	1.2
+++ mercury_label.h	1997/11/25 16:53:49
@@ -6,7 +6,10 @@
 
 /*
 ** mercury_label.h defines the interface to the label table, which is a pair of
-** hash tables mapping from procedure names to addresses and vice versa.
+** hash tables, one mapping from procedure names and the other from
+** addresses to label information.
+** The label information includes the name, address of the code, and
+** layout information for that label.
 */
 
 #ifndef	MERCURY_LABEL_H
@@ -18,10 +21,12 @@
 typedef struct s_label {
 	const char	*e_name;   /* name of the procedure	     */
 	Code		*e_addr;   /* address of the code	     */
+	Word		*e_layout; /* layout info for the procedure  */
 } Label;
 
 extern	void	do_init_entries(void);
-extern	Label	*insert_entry(const char *name, Code *addr);
+extern	Label	*insert_entry(const char *name, Code *addr,
+			Word * entry_layout_info);
 extern	Label	*lookup_label_name(const char *name);
 extern	Label	*lookup_label_addr(const Code *addr);
 extern	List	*get_all_labels(void);
Index: runtime/mercury_type_info.c
===================================================================
RCS file: /home/staff/zs/imp/mercury/runtime/mercury_type_info.c,v
retrieving revision 1.2
diff -u -r1.2 mercury_type_info.c
--- mercury_type_info.c	1997/11/23 07:21:42	1.2
+++ mercury_type_info.c	1997/11/25 07:02:26
@@ -115,7 +115,10 @@
 Define_extern_entry(mercury__builtin_compare_pred_3_0);
 Declare_label(mercury__builtin_compare_pred_3_0_i4);
 
-Define_extern_entry(mercury__builtin_unify_pred_2_0);
+MR_MAKE_STACK_LAYOUT_ENTRY(mercury__builtin_unify_pred_2_0);
+MR_MAKE_STACK_LAYOUT_ENTRY(mercury__builtin_index_pred_2_0);
+MR_MAKE_STACK_LAYOUT_ENTRY(mercury__builtin_compare_pred_3_0);
+MR_MAKE_STACK_LAYOUT_INTERNAL(mercury__builtin_compare_pred_3_0, 4);
 
 BEGIN_MODULE(mercury__builtin_unify_pred_module)
 	init_entry(mercury__builtin_unify_pred_2_0);
@@ -128,8 +131,6 @@
 END_MODULE
 
 
-Define_extern_entry(mercury__builtin_index_pred_2_0);
-
 BEGIN_MODULE(mercury__builtin_index_pred_module)
 	init_entry(mercury__builtin_index_pred_2_0);
 BEGIN_CODE
@@ -139,8 +140,6 @@
 	r1 = (Integer) -1;
 	proceed();
 END_MODULE
-
-Define_extern_entry(mercury__builtin_compare_pred_3_0);
 
 BEGIN_MODULE(mercury__builtin_compare_pred_module)
 	init_entry(mercury__builtin_compare_pred_3_0);
Index: util/mkinit.c
===================================================================
RCS file: /home/staff/zs/imp/mercury/util/mkinit.c,v
retrieving revision 1.24
diff -u -r1.24 mkinit.c
--- mkinit.c	1997/11/24 14:55:44	1.24
+++ mkinit.c	1997/11/26 02:15:55
@@ -170,6 +170,15 @@
 	"}\n"
 	;
 
+
+static const char if_need_to_init[] = 
+	"#if (defined(USE_GCC_NONLOCAL_GOTOS) && !defined(USE_ASM_LABELS)) \\\n"
+	"	|| defined(PROFILE_CALLS) || defined(DEBUG_GOTOS) \\\n"
+	"	|| defined(DEBUG_LABELS) || defined(NATIVE_GC) \\\n"
+	"	|| !defined(SPEED)\n\n"
+	;
+
+
 /* --- function prototypes --- */
 static	void parse_options(int argc, char *argv[]);
 static	void usage(void);
@@ -299,11 +308,7 @@
 {
 	int filenum;
 
-	fputs("#if (defined(USE_GCC_NONLOCAL_GOTOS) && "
-		"!defined(USE_ASM_LABELS)) \\\n", stdout);
-	fputs("\t|| defined(PROFILE_CALLS) || defined(DEBUG_GOTOS) \\\n",
-		stdout);
-	fputs("\t|| defined(DEBUG_LABELS) || !defined(SPEED)\n\n", stdout);
+	fputs(if_need_to_init, stdout);
 
 	fputs("static void init_modules_0(void)\n", stdout);
 	fputs("{\n", stdout);
@@ -325,11 +330,8 @@
 	fputs("static void init_modules(void)\n", stdout);
 	fputs("{\n", stdout);
 
-	fputs("#if (defined(USE_GCC_NONLOCAL_GOTOS) && "
-		"!defined(USE_ASM_LABELS)) \\\n", stdout);
-	fputs("\t|| defined(PROFILE_CALLS) || defined(DEBUG_GOTOS) \\\n",
-		stdout);
-	fputs("\t|| defined(DEBUG_LABELS) || !defined(SPEED)\n\n", stdout);
+	fputs(if_need_to_init, stdout);
+
 	for (i = 0; i <= num_modules; i++)
 		printf("\tinit_modules_%d();\n", i);
 	fputs("#endif\n", stdout);


-- 
       Tyson Dowd           # 
                            #         Linux versus Windows is a 
     trd at cs.mu.oz.au        #            Win lose situation.
http://www.cs.mu.oz.au/~trd #



More information about the developers mailing list