diff: Runtime support for stack layouts, round 3

Tyson Dowd trd at cs.mu.oz.au
Wed Dec 3 14:05:48 AEDT 1997


Hi,

Here's round 3 of this review. 

I've just changed the handling of calls in "mercury_calls.h", and
documented why it works. 

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


Estimated hours taken: 30

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_type_info.c:
	Remove some duplicate label declarations.

runtime/mercury_calls.h:
	Don't use ASM_FIXUP_REGS in calls with NATIVE_GC - we don't
	want (or need) to use it. We define all labels as entry labels
	anyway, so an ASM_FIXUP_REGS is done at each label.

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/12/02 03:56:54
@@ -26,8 +26,15 @@
 ** 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.
+**
+** We *don't* need to do this if we are using NATIVE_GC, because all
+** labels are defined as entry labels anyway. Entry labels do 
+** ASM_FIXUP_REGS immediately. Also, for NATIVE_GC we need the succip
+** set to the address of the continuation label, not the fixup_gp:
+** label.
 */
-#if defined(USE_GCC_NONLOCAL_GOTOS) && defined(NEED_ASM_FIXUP_REGS)
+#if defined(USE_GCC_NONLOCAL_GOTOS) && defined(NEED_ASM_FIXUP_REGS) &&	\
+	!defined(NATIVE_GC)
   #define	noprof_call(proc, succ_cont)			\
 		({						\
 			__label__ fixup_gp;			\
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