[m-dev.] for review: per-module string tables

Zoltan Somogyi zs at cs.mu.OZ.AU
Wed May 26 12:42:24 AEST 1999


For review by Tyson.

Estimated hours taken: 14

Add a module layout structure containing a string table and a table of
pointers to the proc layouts of the module's procedures. This speeds up
debugger initialization, and reduces the executable size of the compiler
by almost 1.2 Mb (about 3.7%) when compiled with debugging.

Instead of representing variables names as strings (32 or 64 bit pointers)
in the debugger's static data structures, with the string's prefix representing
the variable's number (e.g. "5:X"), represent them as a 16-bit variable number
and a 16 bit offset into the module-wide string table. This gains simplicity
of processing (no more search for the ":") and reduces the amount of storage
required, a bit on 32-bit platforms (we don't have to store "5:ModuleInfo"
and "10:ModuleInfo" strings separately, and there are no string prefixes to
store) and more on 64-bit platforms.

The 16-bit limits are generous. A procedure with more than 64K variables will
take forever to compile (that is why we impose a 4K limit on the number
of variables in inlining), and even the string tables of typecheck.m and
make_hlds require less than four kilobytes each. Exceeding the limits
would require code no human would write. Automatically generated code may
be a problem, but the help the debugger can give on such code is limited
already. In any case, we detect overflows and handle them sensibly.

This change does not enhance the debugger to take advantage of the easier
availability of variable numbers, except to improve the implementation 
of retry; that will come later.

The inclusion of the procedure table in the module layout structure
reduces the cost of registering all procedures in all modules,
a task usually performed at the time of the setting of the first breakpoint.
This used to require processing all the internal labels in the label table,
and thus used to take a few seconds for large executables. The sweep of
all internal labels is no longer required, so registering is now much faster.

runtime/mercury_stack_layout.h:
	Add the definition of MR_Module_Layout.

	Modify label layouts to represent names as offsets in the string table,
	not as raw character pointers. This required modifing proc layouts
	to include a pointer to the module's layout, so you can find the
	string table.

	Update the macros that look up variable names.

runtime/mercury_layout_util.h:
	Use the updated macros for looking up variable names.

runtime/mercury_wrapper.[ch]:
	Add a new indirect pointer, MR_register_module_layout, which points
	to a function that registers a module layout, or is NULL if debugging
	is not enabled.

runtime/mercury_init.h:
	Declare the function whose address may be assigned to
	MR_register_module_layout in a <main>_init.c file.

util/mkinit.c:
	Initialize MR_register_module_layout with either the address of
	MR_register_module_layout_real or NULL, depending on whether
	debugging is enabled or not.

compiler/continuation_info.m:
	Don't give names (V_n) to nameless variables, because we don't want
	them to be included in the variables debugging knows about.

compiler/llds.m:
	Add a new function symbol to the type data_addr, which stands for
	the module layout structure of the named (now always the current)
	module.

	Add a new function symbol to the type rval_const. The new function
	symbols, multi_string_const, contains an array of characters of an
	explicitly given length, which consists of several strings, each
	terminated by a null character.

compiler/llds_out.m:
	Accommodate the changes to llds.m, and expand the module initialization
	code to register the module layout structure, if the pointer to the
	registration function is not NULL.

compiler/stack_layout.m:
	Generate the new data structures for representing variable names,
	as well as the module layout.

compiler/mercury_compile.m:
	Rename some variables to reflect the fact that stack_layout.m can
	now include a module layout structure in the list of static layout
	structures it returns.

compiler/dupelim.m:
compiler/exprn_aux.m:
compiler/jumpopt.m:
compiler/opt_debug.m:
	Minor changes to accommodate multi_string_consts.

trace/mercury_trace_tables.[ch]:
	Replace the old data structures for recording information about
	each debuggable module with the module layout structure, and
	register module layout structures directly, instead of trying
	to discover them through the internal label table.

trace/mercury_trace.[ch]:
	Now that it is more easily accessible, use variable numbers
	instead of variable names to find the current locations of
	the input arguments when implementing retry. Unlike our previous
	method, this works even if the user names some variables HeadVar__1,
	etc.

	Remove an unnecessary export of an internal function.

trace/mercury_trace_external.c:
trace/mercury_trace_internal.c:
runtime/mercury_layout_util.c:
	Use the updated macros for looking up variable names.

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/continuation_info.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/continuation_info.m,v
retrieving revision 1.20
diff -u -b -u -r1.20 continuation_info.m
--- continuation_info.m	1999/04/16 06:04:25	1.20
+++ continuation_info.m	1999/05/01 10:15:36
@@ -546,7 +546,11 @@
 		LiveValueType, TypeVars) :-
 	proc_info_varset(ProcInfo, VarSet),
 	proc_info_vartypes(ProcInfo, VarTypes),
-	varset__lookup_name(VarSet, Var, "V_", Name),
+	( varset__search_name(VarSet, Var, GivenName) ->
+		Name = GivenName
+	;
+		Name = ""
+	),
 	instmap__lookup_var(InstMap, Var, Inst),
 	map__lookup(VarTypes, Var, Type),
 	LiveValueType = var(Var, Name, Type, Inst),
Index: compiler/dupelim.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/dupelim.m,v
retrieving revision 1.39
diff -u -b -u -r1.39 dupelim.m
--- dupelim.m	1999/04/30 06:19:21	1.39
+++ dupelim.m	1999/05/01 09:29:40
@@ -928,6 +928,8 @@
 dupelim__replace_labels_rval_const(int_const(N), _, int_const(N)).
 dupelim__replace_labels_rval_const(float_const(N), _, float_const(N)).
 dupelim__replace_labels_rval_const(string_const(S), _, string_const(S)).
+dupelim__replace_labels_rval_const(multi_string_const(L, S), _,
+	multi_string_const(L, S)).
 dupelim__replace_labels_rval_const(code_addr_const(Addr0), ReplMap,
 		code_addr_const(Addr)) :-
 	dupelim__replace_labels_code_addr(Addr0, ReplMap, Addr).
Index: compiler/exprn_aux.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/exprn_aux.m,v
retrieving revision 1.34
diff -u -b -u -r1.34 exprn_aux.m
--- exprn_aux.m	1999/04/30 06:19:23	1.34
+++ exprn_aux.m	1999/05/01 09:09:01
@@ -129,6 +129,7 @@
 		IsConst = StaticGroundTerms
 	).
 exprn_aux__const_is_constant(string_const(_), _, yes).
+exprn_aux__const_is_constant(multi_string_const(_, _), _, yes).
 exprn_aux__const_is_constant(code_addr_const(CodeAddr), ExprnOpts, IsConst) :-
 	exprn_aux__addr_is_constant(CodeAddr, ExprnOpts, IsConst).
 exprn_aux__const_is_constant(data_addr_const(_), _, yes).
Index: compiler/jumpopt.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/jumpopt.m,v
retrieving revision 1.45
diff -u -b -u -r1.45 jumpopt.m
--- jumpopt.m	1999/04/30 06:19:27	1.45
+++ jumpopt.m	1999/05/01 09:09:42
@@ -665,6 +665,8 @@
 jumpopt__short_labels_const(int_const(I), _, int_const(I)).
 jumpopt__short_labels_const(float_const(F), _, float_const(F)).
 jumpopt__short_labels_const(string_const(S), _, string_const(S)).
+jumpopt__short_labels_const(multi_string_const(L, S), _,
+		multi_string_const(L, S)).
 jumpopt__short_labels_const(label_entry(Label0), Instrmap,
 		label_entry(Label)) :-
 	jumpopt__short_label(Label0, Instrmap, Label).
Index: compiler/llds.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/llds.m,v
retrieving revision 1.240
diff -u -b -u -r1.240 llds.m
--- llds.m	1999/04/30 08:23:48	1.240
+++ llds.m	1999/05/01 08:55:51
@@ -729,6 +729,10 @@
 	;	int_const(int)
 	;	float_const(float)
 	;	string_const(string)
+	;	multi_string_const(int, string)
+			% a string containing embedded NULLs,
+			% whose real length is given by the integer,
+			% and not the location of the first NULL
 	;	code_addr_const(code_addr)
 	;	data_addr_const(data_addr)
 	;	label_entry(label).
@@ -745,6 +749,8 @@
 	;	base_typeclass_info(class_id, string)
 			% class name & class arity, names and arities of the
 			% types
+	;	module_layout
+			% Layout information for the current module.
 	;	proc_layout(label)
 			% Layout structure for the procedure with the given
 			% entry label.
@@ -1006,6 +1012,7 @@
 llds__const_type(int_const(_), integer).
 llds__const_type(float_const(_), float).
 llds__const_type(string_const(_), data_ptr).
+llds__const_type(multi_string_const(_, _), data_ptr).
 llds__const_type(code_addr_const(_), code_ptr).
 llds__const_type(data_addr_const(_), data_ptr).
 llds__const_type(label_entry(_), code_ptr).
Index: compiler/llds_out.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/llds_out.m,v
retrieving revision 1.112
diff -u -b -u -r1.112 llds_out.m
--- llds_out.m	1999/05/10 06:08:44	1.112
+++ llds_out.m	1999/05/24 08:20:03
@@ -108,6 +108,11 @@
 :- pred output_c_quoted_string(string, io__state, io__state).
 :- mode output_c_quoted_string(in, di, uo) is det.
 
+	% Like quote_c_quoted_string except that the string may have
+	% NULL characters embedded in it.
+:- pred output_c_quoted_multi_string(int, string, io__state, io__state).
+:- mode output_c_quoted_multi_string(in, in, di, uo) is det.
+
 	% Create a name for type_ctor_*
 
 :- pred llds_out__make_type_ctor_name(base_data, string, arity, string).
@@ -559,6 +564,15 @@
 		io__write_int(Arity),
 		io__write_string("_0);\n")
 	;
+		{ Data = comp_gen_c_data(ModuleName, DataName, _, _, _, _) },
+		{ DataName = module_layout }
+	->
+		io__write_string("\t\tif (MR_register_module_layout != NULL)"),
+		io__write_string("{\n\t\t\t(*MR_register_module_layout)("),
+		io__write_string("(MR_Module_Layout *)\n\t\t\t\t& "),
+		output_data_addr(ModuleName, DataName),
+		io__write_string(");\n\t\t}\n")
+	;
 		[]
 	),
 	output_c_data_init_list(Datas).
@@ -2253,6 +2267,7 @@
 data_name_would_include_code_address(type_ctor(layout, _, _), no).
 data_name_would_include_code_address(type_ctor(functors, _, _), no).
 data_name_would_include_code_address(base_typeclass_info(_, _), yes).
+data_name_would_include_code_address(module_layout, no).
 data_name_would_include_code_address(proc_layout(_), yes).
 data_name_would_include_code_address(internal_layout(_), no).
 data_name_would_include_code_address(tabling_pointer(_), no).
@@ -2745,6 +2760,7 @@
 linkage(type_ctor(layout, _, _),   static).
 linkage(type_ctor(functors, _, _), static).
 linkage(base_typeclass_info(_, _), extern).
+linkage(module_layout,             static).
 linkage(proc_layout(_),            static).
 linkage(internal_layout(_),        static).
 linkage(tabling_pointer(_),        static).
@@ -2993,6 +3009,11 @@
 		io__write_string("mercury_data___"),
 		io__write_string(Str)
 	;
+		{ VarName = module_layout },
+		io__write_string("mercury_data__module_layout_"),
+		{ llds_out__sym_name_mangle(ModuleName, MangledModuleName) },
+		io__write_string(MangledModuleName)
+	;
 		% Keep this code in sync with make_stack_layout_name/3.
 		{ VarName = proc_layout(Label) },
 		io__write_string("mercury_data__layout__"),
@@ -3600,6 +3621,12 @@
 	io__write_string(""", "),
 	io__write_int(StringLength),
 	io__write_string(")").
+output_rval_const(multi_string_const(Length, String)) -->
+	io__write_string("string_const("""),
+	output_c_quoted_multi_string(Length, String),
+	io__write_string(""", "),
+	io__write_int(Length),
+	io__write_string(")").
 output_rval_const(true) -->
 	io__write_string("TRUE").
 output_rval_const(false) -->
@@ -3666,6 +3693,12 @@
 	io__write_string(""", "),
 	io__write_int(StringLength),
 	io__write_string(")").
+output_rval_static_const(multi_string_const(Length, String)) -->
+	io__write_string("(String) string_const("""),
+	output_c_quoted_multi_string(Length, String),
+	io__write_string(""", "),
+	io__write_int(Length),
+	io__write_string(")").
 output_rval_static_const(true) -->
 	io__write_string("TRUE").
 output_rval_static_const(false) -->
@@ -3789,6 +3822,30 @@
 			io__write_char(Char)
 		),
 		output_c_quoted_string(S1)
+	;
+		[]
+	).
+
+output_c_quoted_multi_string(Len, S) -->
+	output_c_quoted_multi_string_2(0, Len, S).
+
+:- pred output_c_quoted_multi_string_2(int::in, int::in, string::in,
+	io__state::di, io__state::uo) is det.
+
+output_c_quoted_multi_string_2(Cur, Len, S) -->
+	( { Cur < Len } ->
+			% we must use unsafe index, because we want to be able
+			% to access chars beyond the first NULL
+		{ string__unsafe_index(S, Cur, Char) },
+		( { char__to_int(Char, 0) } ->
+			io__write_string("\\0")
+		; { quote_c_char(Char, QuoteChar) } ->
+			io__write_char('\\'),
+			io__write_char(QuoteChar)
+		;
+			io__write_char(Char)
+		),
+		output_c_quoted_multi_string_2(Cur + 1, Len, S)
 	;
 		[]
 	).
Index: compiler/mercury_compile.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/mercury_compile.m,v
retrieving revision 1.125
diff -u -b -u -r1.125 mercury_compile.m
--- mercury_compile.m	1999/04/30 08:23:51	1.125
+++ mercury_compile.m	1999/04/30 11:58:47
@@ -1987,16 +1987,17 @@
 	{ base_type_info__generate_llds(HLDS0, TypeCtorInfos) },
 	{ base_type_layout__generate_llds(HLDS0, HLDS1, TypeCtorLayouts) },
 	{ stack_layout__generate_llds(HLDS1, HLDS,
-		ProcLayouts, InternalLayouts, LayoutLabels) },
+		PossiblyDynamicLayouts, StaticLayouts, LayoutLabels) },
 	{ get_c_interface_info(HLDS, C_InterfaceInfo) },
 	{ module_info_get_global_data(HLDS, GlobalData) },
 	{ global_data_get_all_proc_vars(GlobalData, GlobalVars) },
 	{ global_data_get_all_non_common_static_data(GlobalData,
 		NonCommonStaticData) },
-	{ list__append(InternalLayouts, TypeCtorLayouts, StaticData0) },
+	{ list__append(StaticLayouts, TypeCtorLayouts, StaticData0) },
 	{ llds_common(Procs0, StaticData0, ModuleName, Procs1, StaticData1) },
 	{ list__append(StaticData1, NonCommonStaticData, StaticData) },
-	{ list__condense([TypeCtorInfos, ProcLayouts, StaticData], AllData) },
+	{ list__condense([TypeCtorInfos, PossiblyDynamicLayouts, StaticData],
+		AllData) },
 	mercury_compile__construct_c_file(C_InterfaceInfo, Procs1, GlobalVars,
 		AllData, CFile, NumChunks),
 	mercury_compile__output_llds(ModuleName, CFile, LayoutLabels,
Index: compiler/opt_debug.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/opt_debug.m,v
retrieving revision 1.91
diff -u -b -u -r1.91 opt_debug.m
--- opt_debug.m	1999/04/30 06:19:42	1.91
+++ opt_debug.m	1999/05/01 09:22:25
@@ -689,8 +689,11 @@
 	string__int_to_string(I, Str).
 opt_debug__dump_const(float_const(F), Str) :-
 	string__float_to_string(F, Str).
-opt_debug__dump_const(string_const(I), Str) :-
-	string__append_list(["""", I, """"], Str).
+opt_debug__dump_const(string_const(S), Str) :-
+	string__append_list(["""", S, """"], Str).
+opt_debug__dump_const(multi_string_const(L, _S), Str) :-
+	string__int_to_string(L, L_str),
+	string__append_list(["multi_string(", L_str, ")"], Str).
 opt_debug__dump_const(code_addr_const(CodeAddr), Str) :-
 	opt_debug__dump_code_addr(CodeAddr, C_str),
 	string__append_list(["code_addr_const(", C_str, ")"], Str).
@@ -709,6 +712,7 @@
 	llds_out__make_type_ctor_name(BaseData, TypeName, TypeArity, Str).
 opt_debug__dump_data_name(base_typeclass_info(ClassId, InstanceNum), Str) :-
 	llds_out__make_base_typeclass_info_name(ClassId, InstanceNum, Str).
+opt_debug__dump_data_name(module_layout, "module_layout").
 opt_debug__dump_data_name(proc_layout(Label), Str) :-
 	opt_debug__dump_label(Label, LabelStr),
 	string__append_list(["proc_layout(", LabelStr, ")"], Str).
Index: compiler/stack_layout.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/stack_layout.m,v
retrieving revision 1.29
diff -u -b -u -r1.29 stack_layout.m
--- stack_layout.m	1999/05/07 08:08:56	1.29
+++ stack_layout.m	1999/05/26 02:32:31
@@ -66,9 +66,12 @@
 % The meanings of the fields in both forms are the same as in procedure labels.
 %
 % If the option trace_stack_layout is set, i.e. if we are doing execution
-% tracing, the structure will also include three extra fields:
+% tracing, the structure will also include some extra fields:
 %
-%	call trace info		(Word *) - pointer to label stack layout
+%	call trace info		(MR_Stack_Layout_Label *) - points to the
+%				layout structure of the call event
+%	module layout		(MR_Module_Layout *) - points to the layout
+%				struct of the containing module.
 %	maybe from full		(int_least16_t) - number of the stack slot of
 %				the from_full flag, if the procedure is
 %				shallow traced
@@ -84,14 +87,14 @@
 % (If trace_stack_layout is not set, this field will be present,
 % but it will be set to NULL.)
 %
-% If the procedure is compiled with deep tracing, the second field will contain
+% If the procedure is compiled with deep tracing, the third field will contain
 % a negative number. If it is compiled with shallow tracing, it will contain
 % the number of the stack slot that holds the flag that says whether this
 % incarnation of the procedure was called from deeply traced code or not.
 % (The determinism of the procedure decides whether the stack slot refers
 % to a stackvar or a framevar.)
 %
-% If --trace-decl is not set, the third field will contain a negative number.
+% If --trace-decl is not set, the fourth field will contain a negative number.
 % If it is set, it will contain the number of the first of two stack slots
 % used by the declarative debugger; the other slot is the next higher numbered
 % one. (The determinism of the procedure decides whether the stack slot refers
@@ -109,8 +112,9 @@
 % 	live data types locns 	(void *) - pointer to an area of memory
 %				containing information about where the live
 %				data items are and what their types are
-% 	live data names	 	(String *) - pointer to vector of String
-%				giving the names of the data items, if any
+% 	live data names	 	(MR_Var_Name *) - pointer to vector of
+%				MR_Var_Name structs giving the HLDS var numbers
+%				as well as the names of live data items.
 %	type parameters		(MR_Long_Lval *) - pointer to vector of
 %			 	MR_Long_Lval giving the locations of the
 %				typeinfos for the type parameters that may
@@ -151,13 +155,25 @@
 % otherwise.
 %
 % The live data pair vector will have an entry for each live variable.
-% The entry will give the location of the variable and its type. (It also
-% has room for its instantiation state, but this is not filled in yet.)
+% The entry will give the location of the variable and its type.
 %
 % The live data name vector pointer may be NULL. If it is not, the vector
-% will have an entry for each live variable, with each entry giving the name
-% of the variable (it is either a pointer to a string, or a NULL pointer,
-% which means that the variable has no name).
+% will have an entry consisting of two 16-bit numbers for each live data item.
+% The first is the live data item's HLDS variable number, or one of two
+% special values. Zero means that the live data item is not a variable
+% (e.g. it is a saved copy of succip). The largest possible 16-bit number
+% on the other hand means "the number of this variable does not fit into
+% 16 bits". With the exception of these special values, the value in this
+% slot uniquely identifies the variable. The second 16-bit number is an offset
+% into the module-wide string table; the string at that offset is the
+% variable's name. If the variable or data item has no name, the offset
+% will be zero (at which offset one will find an empty string). The string
+% table is restricted to be small enough to be addressed with 16 bits;
+% a string is reserved near the start for a string that says "too many
+% variables". Stack_layout.m will generate a reference to this string
+% instead of generating an offset that does not fit into 16 bits.
+% Therefore using the stored offset to index into the string table
+% is always safe.
 %
 % If the number of type parameters is not zero, we store the number,
 % so that the code that needs the type parameters can materialize
@@ -235,7 +251,7 @@
 	% converting it into LLDS data structures.
 
 stack_layout__generate_llds(ModuleInfo0, ModuleInfo,
-		ProcLayouts, InternalLayouts, LayoutLabels) :-
+		PossiblyDynamicLayouts, StaticLayouts, LayoutLabels) :-
 	module_info_get_global_data(ModuleInfo0, GlobalData),
 	global_data_get_all_proc_layouts(GlobalData, ProcLayoutList),
 
@@ -249,18 +265,85 @@
 	globals__have_static_code_addresses(Globals, StaticCodeAddr),
 	set_bbbtree__init(LayoutLabels0),
 
+	map__init(StringMap0),
+	StringTable0 = string_table(StringMap0, [], 0),
 	LayoutInfo0 = stack_layout_info(ModuleName, CellCount, AgcLayout,
 		TraceLayout, ProcInfoLayout, StaticCodeAddr,
-		[], [], LayoutLabels0),
+		[], [], LayoutLabels0, [], StringTable0),
+	stack_layout__lookup_string_in_table("", _, LayoutInfo0, LayoutInfo1),
+	stack_layout__lookup_string_in_table("TOO_MANY_VARIABLES", _,
+		LayoutInfo1, LayoutInfo2),
 	list__foldl(stack_layout__construct_layouts, ProcLayoutList,
-		LayoutInfo0, LayoutInfo),
-
-	LayoutInfo  = stack_layout_info(_, FinalCellCount, _,
-		_, _, _, ProcLayouts, InternalLayouts, LayoutLabels),
+		LayoutInfo2, LayoutInfo3),
+	stack_layout__get_next_cell_number(ProcVectorCellNum,
+		LayoutInfo3, LayoutInfo),
+	LayoutInfo  = stack_layout_info(_, FinalCellCount, _, _, _, _,
+		ProcLayouts, InternalLayouts, LayoutLabels, ProcLayoutArgs,
+		StringTable),
+	StringTable = string_table(_, RevStringList, StringOffset),
+	list__reverse(RevStringList, StringList),
+	stack_layout__concat_string_list(StringList, StringOffset,
+		ConcatStrings),
+
+	( TraceLayout = yes ->
+		Exported = no,	% ignored; see linkage/2 in llds_out.m
+		list__length(ProcLayoutList, NumProcLayouts),
+		llds_out__sym_name_mangle(ModuleName, ModuleNameStr),
+		ProcLayoutVector = create(0, ProcLayoutArgs,
+			uniform(yes(data_ptr)), must_be_static, 
+			ProcVectorCellNum, "proc_layout_vector"),
+		Rvals = [yes(const(string_const(ModuleNameStr))),
+			yes(const(int_const(StringOffset))),
+			yes(const(multi_string_const(StringOffset,
+				ConcatStrings))),
+			yes(const(int_const(NumProcLayouts))),
+			yes(ProcLayoutVector)],
+		ModuleLayouts = comp_gen_c_data(ModuleName, module_layout,
+			Exported, Rvals, uniform(no), []),
+		StaticLayouts = [ModuleLayouts | InternalLayouts]
+	;
+		StaticLayouts = InternalLayouts
+	),
+	PossiblyDynamicLayouts = ProcLayouts,
 	module_info_set_cell_count(ModuleInfo0, FinalCellCount, ModuleInfo).
 
 %---------------------------------------------------------------------------%
 
+:- pred stack_layout__concat_string_list(list(string)::in, int::in,
+	string::out) is det.
+
+:- pragma c_code(stack_layout__concat_string_list(StringList::in,
+		ArenaSize::in, Arena::out),
+		[will_not_call_mercury, thread_safe], "{
+	Word	cur_node;
+	Integer	cur_offset;
+	Word	tmp;
+
+	incr_hp_atomic(tmp, (ArenaSize + sizeof(Word)) / sizeof(Word));
+	Arena = (char *) tmp;
+
+	cur_offset = 0;
+	cur_node = StringList;
+
+	while (! MR_list_is_empty(cur_node)) {
+		(void) strcpy(&Arena[cur_offset],
+			(char *) MR_list_head(cur_node));
+		cur_offset += strlen((char *) MR_list_head(cur_node)) + 1;
+		cur_node = MR_list_tail(cur_node);
+	}
+
+	if (cur_offset != ArenaSize) {
+		char	msg[256];
+
+		sprintf(msg, ""internal error in creating string table;\n""
+			""cur_offset = %ld, ArenaSize = %ld\n"",
+			(long) cur_offset, (long) ArenaSize);
+		fatal_error(msg);
+	}
+}").
+
+%---------------------------------------------------------------------------%
+
 	% Construct the layouts that concern a single procedure:
 	% the procedure-specific layout and the layouts of the labels
 	% inside that procedure.
@@ -371,9 +454,10 @@
 	{ list__append(TraversalRvals, IdTraceRvals, Rvals) },
 	{ ArgTypes = initial(TraversalArgTypes, IdTraceArgTypes) },
 	stack_layout__get_module_name(ModuleName),
-	{ CData = comp_gen_c_data(ModuleName, proc_layout(EntryLabel),
-		Exported, Rvals, ArgTypes, []) },
-	stack_layout__add_proc_layout_data(CData, EntryLabel).
+	{ CDataName = proc_layout(EntryLabel) },
+	{ CData = comp_gen_c_data(ModuleName, CDataName, Exported,
+		Rvals, ArgTypes, []) },
+	stack_layout__add_proc_layout_data(CData, CDataName, EntryLabel).
 
 :- pred stack_layout__construct_trace_layout(maybe(label)::in,
 	trace_slot_info::in, list(maybe(rval))::out, create_arg_types::out,
@@ -393,6 +477,8 @@
 		;
 			error("stack_layout__construct_trace_layout: call label not present")
 		),
+		ModuleRval = yes(const(data_addr_const(
+				data_addr(ModuleName, module_layout)))),
 		TraceSlotInfo = trace_slot_info(MaybeFromFullSlot,
 			MaybeDeclSlots),
 		( MaybeFromFullSlot = yes(FromFullSlot) ->
@@ -405,8 +491,8 @@
 		;
 			DeclRval = yes(const(int_const(-1)))
 		),
-		Rvals = [CallRval, FromFullRval, DeclRval],
-		ArgTypes = initial([1 - yes(data_ptr), 2 - yes(int_least16)],
+		Rvals = [CallRval, ModuleRval, FromFullRval, DeclRval],
+		ArgTypes = initial([2 - yes(data_ptr), 2 - yes(int_least16)],
 			none)
 	;
 		% Indicate the absence of the trace layout fields.
@@ -710,11 +796,16 @@
 			rval,	% Rval describing the type of a live value.
 			llds_type, % The llds type of the rval describing the
 				% type.
-			rval	% Rval describing the name of a live value.
-				% Always of llds type string.
+			rval,	% Rval describing the variable number of a
+				% live value. Always of llds uint_least16.
+				% Contains zero if the live value is not
+				% a variable.
+			rval	% Rval describing the variable name of a
+				% live value. Always of llds uint_least16.
+				% Contains zero if the live value is not
+				% a variable, or if it is a variable with
+				% no name.
 		).
-		% Rvals describing the location, type (eventually: shape)
-		% and name of a live value.
 
 	% Construct a vector of (locn, live_value_type) pairs,
 	% and a corresponding vector of variable names.
@@ -738,20 +829,21 @@
 	{ LengthRval = const(int_const(EncodedLength)) },
 
 	{ SelectLocns = lambda([ArrayInfo::in, MaybeLocnRval::out] is det, (
-		ArrayInfo = live_array_info(LocnRval, _, _, _),
+		ArrayInfo = live_array_info(LocnRval, _, _, _, _),
 		MaybeLocnRval = yes(LocnRval)
 	)) },
 	{ SelectTypes = lambda([ArrayInfo::in, MaybeTypeRval::out] is det, (
-		ArrayInfo = live_array_info(_, TypeRval, _, _),
+		ArrayInfo = live_array_info(_, TypeRval, _, _, _),
 		MaybeTypeRval = yes(TypeRval)
 	)) },
 	{ SelectTypeTypes = lambda([ArrayInfo::in, CountTypeType::out] is det,(
-		ArrayInfo = live_array_info(_, _, TypeType, _),
+		ArrayInfo = live_array_info(_, _, TypeType, _, _),
 		CountTypeType = 1 - yes(TypeType)
 	)) },
-	{ SelectNames = lambda([ArrayInfo::in, MaybeNameRval::out] is det, (
-		ArrayInfo = live_array_info(_, _, _, NameRval),
-		MaybeNameRval = yes(NameRval)
+	{ AddRevNumsNames = lambda([ArrayInfo::in, NumNameRvals0::in,
+			NumNameRvals::out] is det, (
+		ArrayInfo = live_array_info(_, _, _, NumRval, NameRval),
+		NumNameRvals = [yes(NameRval), yes(NumRval) | NumNameRvals0]
 	)) },
 
 	{ list__map(SelectTypes, AllArrayInfo, AllTypes) },
@@ -768,10 +860,11 @@
 		initial(ArgTypes, none), must_be_static, CNum1,
 		"stack_layout_locn_vector") },
 
-	{ list__map(SelectNames, AllArrayInfo, AllNames) },
+	{ list__foldl(AddRevNumsNames, AllArrayInfo, [], RevVarNumNameRvals) },
+	{ list__reverse(RevVarNumNameRvals, VarNumNameRvals) },
 	stack_layout__get_next_cell_number(CNum2),
-	{ NameVector = create(0, AllNames, uniform(yes(string)),
-		must_be_static, CNum2, "stack_layout_name_vector") }.
+	{ NameVector = create(0, VarNumNameRvals, uniform(yes(uint_least16)),
+		must_be_static, CNum2, "stack_layout_num_name_vector") }.
 
 :- pred stack_layout__construct_liveval_array_infos(list(var_info)::in,
 	int::in, int::in,
@@ -784,48 +877,52 @@
 	{ VarInfo = var_info(Locn, LiveValueType) },
 	stack_layout__represent_live_value_type(LiveValueType, TypeRval,
 		TypeRvalType),
-	{ stack_layout__construct_liveval_name(VarInfo, NameRval) },
+	stack_layout__construct_liveval_name_rvals(VarInfo,
+		VarNumRval, VarNameRval),
 	(
 		{ BytesSoFar < BytesLimit },
 		{ stack_layout__represent_locn_as_byte(Locn, LocnByteRval) }
 	->
 		{ Var = live_array_info(LocnByteRval, TypeRval, TypeRvalType,
-			NameRval) },
+			VarNumRval, VarNameRval) },
 		stack_layout__construct_liveval_array_infos(VarInfos,
 			BytesSoFar + 1, BytesLimit, IntVars, ByteVars0),
 		{ ByteVars = [Var | ByteVars0] }
 	;
 		{ stack_layout__represent_locn_as_int(Locn, LocnRval) },
 		{ Var = live_array_info(LocnRval, TypeRval, TypeRvalType,
-			NameRval) },
+			VarNumRval, VarNameRval) },
 		stack_layout__construct_liveval_array_infos(VarInfos,
 			BytesSoFar, BytesLimit, IntVars0, ByteVars),
 		{ IntVars = [Var | IntVars0] }
 	).
 
-:- pred stack_layout__construct_liveval_name(var_info::in, rval::out)
-	is det.
+:- pred stack_layout__construct_liveval_name_rvals(var_info::in, rval::out,
+	rval::out, stack_layout_info::in, stack_layout_info::out) is det.
 
-stack_layout__construct_liveval_name(var_info(_, LiveValueType), Rval) :-
-	(
-		LiveValueType = var(Var, Name, _, _),
-		Name \= ""
-	->
-		% We include a representation of the variable number at the
-		% start of the variable name, because some functions of the
-		% debugger (e.g. restart) require it to be able to distinguish
-		% between distinct variables that happen to have the same name.
-		% We represent the number as a string, because most variable
-		% numbers are so small that this is a very compact
-		% representation.
-		term__var_to_int(Var, Int),
-		string__int_to_string(Int, IntStr),
-		string__append_list([IntStr, ":", Name], NumberedName),
-		Rval = const(string_const(NumberedName))
-	;
-		% We prefer a null pointer to a pointer to an empty string,
-		% since this way we don't need many copies of the empty string.
-		Rval = const(int_const(0))
+stack_layout__construct_liveval_name_rvals(var_info(_, LiveValueType),
+		VarNumRval, VarNameRval, SLI0, SLI) :-
+	( LiveValueType = var(Var, Name, _, _) ->
+		term__var_to_int(Var, VarNum0),
+			% The variable number has to fit into two bytes.
+			% We reserve the largest such number (Limit)
+			% to mean that the variable number is too large
+			% to be represented. This ought not to happen,
+			% since compilation would be glacial at best
+			% for procedures with that many variables.
+		Limit = (1 << (2 * stack_layout__byte_bits)) - 1,
+		( VarNum0 >= Limit ->
+			VarNum = Limit
+		;
+			VarNum = VarNum0
+		),
+		VarNumRval = const(int_const(VarNum)),
+		stack_layout__lookup_string_in_table(Name, Offset, SLI0, SLI),
+		VarNameRval = const(int_const(Offset))
+	;
+		VarNumRval = const(int_const(0)),
+		VarNameRval = const(int_const(0)),
+		SLI = SLI0
 	).
 
 %---------------------------------------------------------------------------%
@@ -1108,8 +1205,8 @@
 :- pred stack_layout__make_tagged_byte(int::in, int::in, int::out) is semidet.
 
 stack_layout__make_tagged_byte(Tag, Value, TaggedValue) :-
-	int__pow(2, stack_layout__byte_bits
-		- stack_layout__short_lval_tag_bits, Limit),
+	Limit = 1 << (stack_layout__byte_bits -
+		stack_layout__short_lval_tag_bits),
 	Value < Limit,
 	TaggedValue is unchecked_left_shift(Value,
 		stack_layout__short_lval_tag_bits) + Tag.
@@ -1180,8 +1277,13 @@
 		bool,		% have static code addresses?
 		list(comp_gen_c_data),	% generated proc layouts
 		list(comp_gen_c_data),	% generated label layouts
-		set_bbbtree(label)
-				% the set of labels with layouts
+		set_bbbtree(label),
+				% the set of labels (both entry and internal)
+				% with layouts
+		list(maybe(rval)),
+				% the list of proc_layouts in the module,
+				% represented as create args
+		string_table
 	).
 
 :- pred stack_layout__get_module_name(module_name::out,
@@ -1211,62 +1313,115 @@
 :- pred stack_layout__get_label_set(set_bbbtree(label)::out,
 	stack_layout_info::in, stack_layout_info::out) is det.
 
+:- pred stack_layout__get_string_table(string_table::out,
+	stack_layout_info::in, stack_layout_info::out) is det.
+
 stack_layout__get_module_name(A, LayoutInfo, LayoutInfo) :-
-	LayoutInfo = stack_layout_info(A, _, _, _, _, _, _, _, _).
+	LayoutInfo = stack_layout_info(A, _, _, _, _, _, _, _, _, _, _).
 
 stack_layout__get_cell_number(B, LayoutInfo, LayoutInfo) :-
-	LayoutInfo = stack_layout_info(_, B, _, _, _, _, _, _, _).
+	LayoutInfo = stack_layout_info(_, B, _, _, _, _, _, _, _, _, _).
 
 stack_layout__get_agc_stack_layout(C, LayoutInfo, LayoutInfo) :-
-	LayoutInfo = stack_layout_info(_, _, C, _, _, _, _, _, _).
+	LayoutInfo = stack_layout_info(_, _, C, _, _, _, _, _, _, _, _).
 
 stack_layout__get_trace_stack_layout(D, LayoutInfo, LayoutInfo) :-
-	LayoutInfo = stack_layout_info(_, _, _, D, _, _, _, _, _).
+	LayoutInfo = stack_layout_info(_, _, _, D, _, _, _, _, _, _, _).
 
 stack_layout__get_procid_stack_layout(E, LayoutInfo, LayoutInfo) :-
-	LayoutInfo = stack_layout_info(_, _, _, _, E, _, _, _, _).
+	LayoutInfo = stack_layout_info(_, _, _, _, E, _, _, _, _, _, _).
 
 stack_layout__get_static_code_addresses(F, LayoutInfo, LayoutInfo) :-
-	LayoutInfo = stack_layout_info(_, _, _, _, _, F, _, _, _).
+	LayoutInfo = stack_layout_info(_, _, _, _, _, F, _, _, _, _, _).
 
 stack_layout__get_proc_layout_data(G, LayoutInfo, LayoutInfo) :-
-	LayoutInfo = stack_layout_info(_, _, _, _, _, _, G, _, _).
+	LayoutInfo = stack_layout_info(_, _, _, _, _, _, G, _, _, _, _).
 
 stack_layout__get_internal_layout_data(H, LayoutInfo, LayoutInfo) :-
-	LayoutInfo = stack_layout_info(_, _, _, _, _, _, _, H, _).
+	LayoutInfo = stack_layout_info(_, _, _, _, _, _, _, H, _, _, _).
 
 stack_layout__get_label_set(I, LayoutInfo, LayoutInfo) :-
-	LayoutInfo = stack_layout_info(_, _, _, _, _, _, _, _, I).
+	LayoutInfo = stack_layout_info(_, _, _, _, _, _, _, _, I, _, _).
 
-:- pred stack_layout__add_proc_layout_data(comp_gen_c_data::in, label::in,
-	stack_layout_info::in, stack_layout_info::out) is det.
+stack_layout__get_string_table(K, LayoutInfo, LayoutInfo) :-
+	LayoutInfo = stack_layout_info(_, _, _, _, _, _, _, _, _, _, K).
+
+:- pred stack_layout__add_proc_layout_data(comp_gen_c_data::in, data_name::in,
+	label::in, stack_layout_info::in, stack_layout_info::out) is det.
 
-stack_layout__add_proc_layout_data(NewG, NewI, LayoutInfo0, LayoutInfo) :-
-	LayoutInfo0 = stack_layout_info(A, B, C, D, E, F, G0, H, I0),
+stack_layout__add_proc_layout_data(NewG, NewJ, NewI, LayoutInfo0, LayoutInfo) :-
+	LayoutInfo0 = stack_layout_info(A, B, C, D, E, F, G0, H, I0, J0, K),
 	G = [NewG | G0],
 	set_bbbtree__insert(I0, NewI, I),
-	LayoutInfo  = stack_layout_info(A, B, C, D, E, F, G , H, I).
+	J = [yes(const(data_addr_const(data_addr(A, NewJ)))) | J0],
+	LayoutInfo  = stack_layout_info(A, B, C, D, E, F, G , H, I , J , K).
 
 :- pred stack_layout__add_internal_layout_data(comp_gen_c_data::in, label::in,
 	stack_layout_info::in, stack_layout_info::out) is det.
 
 stack_layout__add_internal_layout_data(NewH, NewI, LayoutInfo0, LayoutInfo) :-
-	LayoutInfo0 = stack_layout_info(A, B, C, D, E, F, G, H0, I0),
+	LayoutInfo0 = stack_layout_info(A, B, C, D, E, F, G, H0, I0, J, K),
 	H = [NewH | H0],
 	set_bbbtree__insert(I0, NewI, I),
-	LayoutInfo  = stack_layout_info(A, B, C, D, E, F, G, H , I ).
+	LayoutInfo  = stack_layout_info(A, B, C, D, E, F, G, H , I , J, K).
 
 :- pred stack_layout__get_next_cell_number(int::out,
 	stack_layout_info::in, stack_layout_info::out) is det.
 
 stack_layout__get_next_cell_number(B, LayoutInfo0, LayoutInfo) :-
-	LayoutInfo0 = stack_layout_info(A, B0, C, D, E, F, G, H, I),
+	LayoutInfo0 = stack_layout_info(A, B0, C, D, E, F, G, H, I, J, K),
 	B is B0 + 1,
-	LayoutInfo  = stack_layout_info(A, B,  C, D, E, F, G, H, I).
+	LayoutInfo  = stack_layout_info(A, B,  C, D, E, F, G, H, I, J, K).
 
 :- pred stack_layout__set_cell_number(int::in,
 	stack_layout_info::in, stack_layout_info::out) is det.
 
 stack_layout__set_cell_number(B, LayoutInfo0, LayoutInfo) :-
-	LayoutInfo0 = stack_layout_info(A, _, C, D, E, F, G, H, I),
-	LayoutInfo  = stack_layout_info(A, B, C, D, E, F, G, H, I).
+	LayoutInfo0 = stack_layout_info(A, _, C, D, E, F, G, H, I, J, K),
+	LayoutInfo  = stack_layout_info(A, B, C, D, E, F, G, H, I, J, K).
+
+:- pred stack_layout__set_string_table(string_table::in,
+	stack_layout_info::in, stack_layout_info::out) is det.
+
+stack_layout__set_string_table(K, LayoutInfo0, LayoutInfo) :-
+	LayoutInfo0 = stack_layout_info(A, B, C, D, E, F, G, H, I, J, _),
+	LayoutInfo  = stack_layout_info(A, B, C, D, E, F, G, H, I, J, K).
+
+%---------------------------------------------------------------------------%
+
+	% Access to the string_table data structure.
+
+:- type string_table 	--->
+	string_table(
+		map(string, int),	% Maps strings to their offsets.
+		list(string),		% List of strings so far,
+					% in reverse order.
+		int			% Next available offset
+	).
+
+:- pred stack_layout__lookup_string_in_table(string::in, int::out,
+	stack_layout_info::in, stack_layout_info::out) is det.
+
+stack_layout__lookup_string_in_table(String, Offset) -->
+	stack_layout__get_string_table(StringTable0),
+	{ StringTable0 = string_table(TableMap0, TableList0, TableOffset0) },
+	(
+		{ map__search(TableMap0, String, OldOffset) }
+	->
+		{ Offset = OldOffset }
+	;
+		{ string__length(String, Length) },
+		{ TableOffset is TableOffset0 + Length + 1 },
+		{ TableOffset < (1 << (2 * stack_layout__byte_bits)) }
+	->
+		{ Offset = TableOffset0 },
+		{ map__det_insert(TableMap0, String, TableOffset0,
+			TableMap) },
+		{ TableList = [String | TableList0] },
+		{ StringTable = string_table(TableMap, TableList,
+			TableOffset) },
+		stack_layout__set_string_table(StringTable)
+	;
+		% Says that the name of the variable is "TOO_MANY_VARIABLES".
+		{ Offset = 1 }
+	).
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/exceptions
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/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 profiler
cvs diff: Diffing runtime
Index: runtime/mercury_init.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_init.h,v
retrieving revision 1.13
diff -u -b -u -r1.13 mercury_init.h
--- mercury_init.h	1999/05/14 02:25:02	1.13
+++ mercury_init.h	1999/05/24 08:21:36
@@ -154,6 +154,9 @@
 extern	Code	*MR_trace_real(const MR_Stack_Layout_Label *, MR_Trace_Port,
 			Unsigned, Unsigned, const char *, int);
 
+/* in trace/mercury_trace_tables.c */
+extern	void	MR_register_module_layout_real(const MR_Module_Layout *);
+
 /* in library/std_util.h  */
 extern	String	ML_type_name(Word);
 
Index: runtime/mercury_layout_util.c
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_layout_util.c,v
retrieving revision 1.9
diff -u -b -u -r1.9 mercury_layout_util.c
--- mercury_layout_util.c	1999/05/21 14:38:20	1.9
+++ mercury_layout_util.c	1999/05/24 08:30:06
@@ -108,7 +108,7 @@
 }
 
 Word
-MR_make_var_list(const MR_Stack_Layout_Label *layout, Word *saved_regs)
+MR_make_var_list(const MR_Stack_Layout_Label *label_layout, Word *saved_regs)
 {
 	const MR_Stack_Layout_Vars 	*vars;
 	int 				var_count;
@@ -125,7 +125,7 @@
 
 	int				i;
 
-	vars = &layout->MR_sll_var_info;
+	vars = &label_layout->MR_sll_var_info;
 	var_count = MR_all_desc_var_count(vars);
 	long_count = MR_long_desc_var_count(vars);
 	base_sp = MR_saved_sp(saved_regs);
@@ -154,7 +154,7 @@
 		** in the list that we return)
 		*/
 
-		name = MR_name_if_present(vars, i);
+		name = MR_name_if_present_from_label(label_layout, i);
 		if (! MR_get_type_and_value_filtered(vars, i, saved_regs,
 			name, type_params, &type_info, &value))
 		{
@@ -545,16 +545,16 @@
 			return NULL;	/* represents success */
 		}
 	} else if (var_spec.MR_var_spec_kind == VAR_NAME) {
-		const MR_Stack_Layout_Vars	*vars;
 		const char 			*name;
 		bool				collision = FALSE;
 		int				i;
 
-		vars = &layout->MR_sll_var_info;
 		*which_var_ptr = -1;
 		name = var_spec.MR_var_spec_name;
 		for (i = 0; i < var_count; i++) {
-			if (streq(name, MR_name_if_present(vars, i))) {
+			if (streq(name,
+				MR_name_if_present_from_label(layout, i)))
+			{
 				if (*which_var_ptr >= 0) {
 					collision = TRUE;
 				}
Index: runtime/mercury_stack_layout.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_stack_layout.h,v
retrieving revision 1.24
diff -u -b -u -r1.24 mercury_stack_layout.h
--- mercury_stack_layout.h	1999/05/07 08:09:05	1.24
+++ mercury_stack_layout.h	1999/05/26 01:16:53
@@ -218,6 +218,23 @@
 } MR_Type_Param_Locns;
 
 /*
+** This structure describes the name of a live value, if it has any.
+**
+** The MR_var_num field is zero if the live value is not a variable;
+** if it is, it gives the HLDS number of the variable.
+**
+** The MR_var_name_offset field gives the offset, within the string
+** table of the module containing the layout structure, of the name
+** of the variable. If the variable has no name, or if the live value
+** is not a variable, the offset will be zero.
+*/
+
+typedef	struct MR_Var_Name_Struct {
+	uint_least16_t		MR_var_num;
+	uint_least16_t		MR_var_name_offset;
+} MR_Var_Name;
+
+/*
 ** The MR_slvs_var_count field should be set to a negative number
 ** if there is no information about the variables live at the label.
 */
@@ -226,7 +243,7 @@
 	void			*MR_slvs_var_count;
 	/* the remaining fields are present only if MR_sll_var_count > 0 */
 	void			*MR_slvs_locns_types;
-	String			*MR_slvs_names;
+	MR_Var_Name		*MR_slvs_names;
 	MR_Type_Param_Locns	*MR_slvs_tvars;
 } MR_Stack_Layout_Vars;
 
@@ -254,17 +271,16 @@
 #define	MR_short_desc_var_locn(slvs, i)					    \
 		(((uint_least8_t *) MR_end_of_long_desc_var_locns(slvs))[(i)])
 
-#define	MR_name_if_present(vars, i)					    \
-				((vars->MR_slvs_names != NULL		    \
-				&& vars->MR_slvs_names[(i)] != NULL)	    \
-				? strchr(vars->MR_slvs_names[(i)], ':') + 1 \
-				: "")
-
-#define	MR_numbered_name_if_present(vars, i)				    \
-				((vars->MR_slvs_names != NULL	 	    \
-				&& vars->MR_slvs_names[(i)] != NULL)	    \
-				? vars->MR_slvs_names[(i)]		    \
-				: "")
+#define	MR_name_if_present(module_layout, vars, i)			    \
+		(((vars)->MR_slvs_names == NULL) ? "" :			    \
+		((module_layout)->MR_ml_string_table +			    \
+			(vars)->MR_slvs_names[(i)].MR_var_name_offset))
+
+#define	MR_name_if_present_from_label(label_layout, i)			    \
+		MR_name_if_present(					    \
+			(label_layout)->MR_sll_entry->MR_sle_module_layout, \
+			&((label_layout)->MR_sll_var_info),		    \
+			(i))
 
 /*-------------------------------------------------------------------------*/
 /*
@@ -344,6 +360,8 @@
 	/* exec trace group */
 	struct MR_Stack_Layout_Label_Struct
 				*MR_sle_call_label;
+	struct MR_Module_Layout_Struct
+				*MR_sle_module_layout;
 	int_least16_t		MR_sle_maybe_from_full;
 	int_least16_t		MR_sle_maybe_decl_debug;
 } MR_Stack_Layout_Entry;
@@ -520,5 +538,27 @@
 
 #define MR_MAKE_INTERNAL_LAYOUT(e, n)					\
 	MR_MAKE_INTERNAL_LAYOUT_WITH_ENTRY(e##_i##n, e)
+
+/*-------------------------------------------------------------------------*/
+/*
+** Definitions for MR_Module_Layout
+**
+** The layout struct for a module contains two main components.
+**
+** The first is a string table, which contains strings referred to by other
+** layout structures in the module (initially only the name tables of label
+** layout structures).
+**
+** The second is a table containing pointers to the proc layout structures
+** of all the procedures in the module.
+*/
+
+typedef	struct MR_Module_Layout_Struct {
+	String			MR_ml_name;
+	Integer			MR_ml_string_table_size;
+	char			*MR_ml_string_table;
+	Integer			MR_ml_proc_count;
+	MR_Stack_Layout_Entry	**MR_ml_procs;
+} MR_Module_Layout;
 
 #endif /* not MERCURY_STACK_LAYOUT_H */
Index: runtime/mercury_wrapper.c
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_wrapper.c,v
retrieving revision 1.39
diff -u -b -u -r1.39 mercury_wrapper.c
--- mercury_wrapper.c	1999/05/14 02:25:09	1.39
+++ mercury_wrapper.c	1999/05/24 08:21:40
@@ -186,6 +186,8 @@
 Code	*(*MR_trace_func_ptr)(const MR_Stack_Layout_Label *, MR_Trace_Port,
 		Unsigned, Unsigned, const char *, int);
 
+void	(*MR_register_module_layout)(const MR_Module_Layout *);
+
 #ifdef USE_GCC_NONLOCAL_GOTOS
 
 #define	SAFETY_BUFFER_SIZE	1024	/* size of stack safety buffer */
Index: runtime/mercury_wrapper.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_wrapper.h,v
retrieving revision 1.20
diff -u -b -u -r1.20 mercury_wrapper.h
--- mercury_wrapper.h	1999/05/14 02:25:10	1.20
+++ mercury_wrapper.h	1999/05/24 08:21:41
@@ -14,7 +14,7 @@
 
 #include <stddef.h>			/* for `size_t' */
 #include "mercury_std.h"		/* for `bool' */
-#include "mercury_stack_layout.h"	/* for `MR_Stack_Layout_Label' */
+#include "mercury_stack_layout.h"	/* for `MR_Stack_Layout_Label' etc */
 #include "mercury_trace_base.h"		/* for `MR_trace_port' */
 #include "mercury_stacks.h"		/* for `MR_{Cut,Generator}StackFrame' */
 
@@ -105,8 +105,12 @@
 ** depending on whether tracing was enabled when creating the _init.c
 ** file.  It is called from MR_trace (runtime/mercury_trace_base.c).
 */
+
 extern	Code    *(*MR_trace_func_ptr)(const MR_Stack_Layout_Label *,
-			MR_Trace_Port, Unsigned, Unsigned, const char *, int);
+				MR_Trace_Port, Unsigned, Unsigned,
+				const char *, int);
+
+extern	void		(*MR_register_module_layout)(const MR_Module_Layout *);
 
 extern	void		do_init_modules(void);
 
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 scripts
cvs diff: Diffing tests
cvs diff: Diffing tests/benchmarks
cvs diff: Diffing tests/debugger
cvs diff: Diffing tests/dppd
cvs diff: Diffing tests/general
cvs diff: Diffing tests/hard_coded
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.c
===================================================================
RCS file: /home/mercury1/repository/mercury/trace/mercury_trace.c,v
retrieving revision 1.9
diff -u -b -u -r1.9 mercury_trace.c
--- mercury_trace.c	1999/04/30 06:21:44	1.9
+++ mercury_trace.c	1999/05/26 01:57:22
@@ -53,11 +53,13 @@
 Code 		*MR_trace_real(const MR_Stack_Layout_Label *layout,
 			MR_Trace_Port port, Unsigned seqno, Unsigned depth,
 			const char *path, int max_r_num);
-
 static	Code	*MR_trace_event(MR_Trace_Cmd_Info *cmd, bool interactive,
 			const MR_Stack_Layout_Label *layout,
 			MR_Trace_Port port, Unsigned seqno, Unsigned depth,
 			const char *path, int max_r_num);
+static	Word	MR_trace_find_input_arg(const MR_Stack_Layout_Label *label, 
+			Word *saved_regs, uint_least16_t var_num,
+			bool *succeeded);
 
 /*
 ** Reserve room for event counts for this many depths initially.
@@ -323,7 +325,8 @@
 
 	for (i = 0; i < MR_all_desc_var_count(input_args); i++) {
 		arg_value = MR_trace_find_input_arg(event_info->MR_event_sll,
-				saved_regs, input_args->MR_slvs_names[i],
+				saved_regs,
+				input_args->MR_slvs_names[i].MR_var_num,
 				&succeeded);
 
 		if (! succeeded) {
@@ -418,9 +421,9 @@
 }
 
 
-extern Word
+static Word
 MR_trace_find_input_arg(const MR_Stack_Layout_Label *label, Word *saved_regs,
-	const char *name, bool *succeeded)
+	uint_least16_t var_num, bool *succeeded)
 {
 	const MR_Stack_Layout_Vars	*vars;
 	int				i;
@@ -432,7 +435,7 @@
 	}
 
 	for (i = 0; i < MR_all_desc_var_count(vars); i++) {
-		if (streq(vars->MR_slvs_names[i], name)) {
+		if (var_num == vars->MR_slvs_names[i].MR_var_num) {
 			if (i < MR_long_desc_var_count(vars)) {
 				return MR_lookup_long_lval_base(
 					MR_long_desc_var_locn(vars, i),
Index: trace/mercury_trace.h
===================================================================
RCS file: /home/mercury1/repository/mercury/trace/mercury_trace.h,v
retrieving revision 1.8
diff -u -b -u -r1.8 mercury_trace.h
--- mercury_trace.h	1999/02/23 08:06:55	1.8
+++ mercury_trace.h	1999/05/05 04:45:41
@@ -55,8 +55,6 @@
 
 const char *	MR_trace_retry(MR_Event_Info *event_info,
 			MR_Event_Details *event_details, Code **jumpaddr);
-Word		MR_trace_find_input_arg(const MR_Stack_Layout_Label *label, 
-			Word *saved_regs, const char *name, bool *succeeded);
 
 /*
 ** MR_trace_cmd says what mode the tracer is in, i.e. how events should be
Index: trace/mercury_trace_external.c
===================================================================
RCS file: /home/mercury1/repository/mercury/trace/mercury_trace_external.c,v
retrieving revision 1.17
diff -u -b -u -r1.17 mercury_trace_external.c
--- mercury_trace_external.c	1999/05/21 14:38:21	1.17
+++ mercury_trace_external.c	1999/05/26 01:57:22
@@ -857,7 +857,7 @@
     MR_TRACE_USE_HP(
 	var_names_list = list_empty();
 	for (i = var_count - 1; i >= 0; i--) {
-		name = MR_name_if_present(vars, i);
+		name = MR_name_if_present_from_label(layout, i);
 		/*
 		** XXX The printing of type_infos is buggy at the moment
 		** due to the fake arity of the type private_builtin:typeinfo/1.
@@ -919,7 +919,7 @@
 
 	for (i = var_count - 1; i >= 0; i--) {
 
-		name = MR_name_if_present(vars, i);
+		name = MR_name_if_present_from_label(layout, i);
 		if (! MR_get_type_filtered(vars, i, saved_regs,
 			name, type_params, &type_info))
 		{
@@ -962,7 +962,7 @@
 		/* debugger_request should be of the form: 
 		   current_nth_var(var_number) */
 	vars = &layout->MR_sll_var_info;
-	name = MR_name_if_present(vars, var_number);
+	name = MR_name_if_present_from_label(layout, var_number);
 	base_sp = MR_saved_sp(saved_regs);
 	base_curfr = MR_saved_curfr(saved_regs);
 	
@@ -1234,7 +1234,8 @@
 	vars = &level_layout->MR_sll_var_info;
 	type_params = MR_materialize_typeinfos_base(vars,
 				valid_saved_regs, base_sp, base_curfr);
-	MR_trace_browse_var_external(MR_name_if_present(vars, which_var),
+	MR_trace_browse_var_external(
+		MR_name_if_present_from_label(level_layout, which_var),
 		vars, which_var, valid_saved_regs,
 		base_sp, base_curfr, type_params);
 	free(type_params);
Index: trace/mercury_trace_internal.c
===================================================================
RCS file: /home/mercury1/repository/mercury/trace/mercury_trace_internal.c,v
retrieving revision 1.43
diff -u -b -u -r1.43 mercury_trace_internal.c
--- mercury_trace_internal.c	1999/05/21 14:38:20	1.43
+++ mercury_trace_internal.c	1999/05/26 01:57:22
@@ -1651,7 +1651,7 @@
 	vars = &level_layout->MR_sll_var_info;
 	for (i = 0; i < var_count; i++) {
 		fprintf(MR_mdb_out, "%9d %s\n",
-			i, MR_name_if_present(vars, i));
+			i, MR_name_if_present_from_label(level_layout, i));
 	}
 }
 
@@ -1743,7 +1743,8 @@
 	vars = &level_layout->MR_sll_var_info;
 	type_params = MR_materialize_typeinfos_base(vars,
 				valid_saved_regs, base_sp, base_curfr);
-	MR_trace_browse_var(MR_name_if_present(vars, which_var),
+	MR_trace_browse_var(
+		MR_name_if_present_from_label(level_layout, which_var),
 		vars, which_var, valid_saved_regs,
 		base_sp, base_curfr, type_params, browse);
 	free(type_params);
@@ -1760,7 +1761,9 @@
 	Word				*valid_saved_regs;
 	int				var_count;
 	const MR_Stack_Layout_Vars	*vars;
+	const MR_Module_Layout		*module_layout;
 	const char 			*problem;
+	int				offset;
 	int				i;
 
 	base_sp = MR_saved_sp(saved_regs);
@@ -1791,8 +1794,11 @@
 	type_params = MR_materialize_typeinfos_base(vars,
 				valid_saved_regs, base_sp, base_curfr);
 
+	module_layout = level_layout->MR_sll_entry->MR_sle_module_layout;
 	for (i = 0; i < var_count; i++) {
-		MR_trace_browse_var(MR_name_if_present(vars, i),
+		offset = vars->MR_slvs_names[i].MR_var_name_offset;
+		MR_trace_browse_var(
+			module_layout->MR_ml_string_table + offset,
 			vars, i, valid_saved_regs,
 			base_sp, base_curfr, type_params, FALSE);
 	}
@@ -1822,7 +1828,7 @@
 	/* the variable names from the prompt. */
 
 	if (!browse) {
-		if (name != NULL) {
+		if (name != NULL && *name != '\0') {
 			fprintf(MR_mdb_out, "%7s%-21s\t", "", name);
 		} else {
 			fprintf(MR_mdb_out, "%7s%-21s\t", "",
Index: trace/mercury_trace_tables.c
===================================================================
RCS file: /home/mercury1/repository/mercury/trace/mercury_trace_tables.c,v
retrieving revision 1.6
diff -u -b -u -r1.6 mercury_trace_tables.c
--- mercury_trace_tables.c	1999/02/23 08:06:52	1.6
+++ mercury_trace_tables.c	1999/05/26 01:57:22
@@ -20,22 +20,17 @@
 #include <string.h>
 #include <ctype.h>
 
-static	MR_Module_Info	*MR_module_infos;
+static	const MR_Module_Layout	**MR_module_infos;
 static	int		MR_module_info_next = 0;
 static	int		MR_module_info_max  = 0;
 static	int		MR_module_info_proc_count = 0;
 
 #define	INIT_MODULE_TABLE_SIZE	10
 
-static	void		MR_register_from_internal_label(const void *info);
-static	void		MR_ensure_proc_node_is_present(MR_Module_Info *module,
-				const MR_Stack_Layout_Entry *entry);
-static	MR_Module_Info	*MR_search_module_info(const char *name);
-static	MR_Module_Info	*MR_insert_module_info(const char *name);
-static	MR_Module_Info	*MR_ensure_module_info_is_present(const char *name);
-
+static	const MR_Module_Layout	*MR_search_module_info(const char *name);
+static	void	MR_insert_module_info(const MR_Module_Layout *);
 static	void		MR_process_matching_procedures_in_module(
-				MR_Module_Info *module, MR_Proc_Spec *spec,
+			const MR_Module_Layout *module, MR_Proc_Spec *spec,
 				void f(void *, const MR_Stack_Layout_Entry *),
 				void *);
 
@@ -51,7 +46,6 @@
 		}
 
 		do_init_modules();
-		MR_process_all_internal_labels(MR_register_from_internal_label);
 		done = TRUE;
 		if (verbose) {
 			fprintf(fp, "done.\n");
@@ -71,113 +65,63 @@
 	}
 }
 
-static void
-MR_register_from_internal_label(const void *info)
-{
-	const MR_Stack_Layout_Label	*label;
-	const MR_Stack_Layout_Entry	*entry;
-	MR_Module_Info			*module;
-
-	label = ((const MR_Internal *) info)->i_layout;
-
-	if (label == NULL) {
-		/* some labels have no layout structure */
-		return;
-	}
-
-	if (label->MR_sll_entry == NULL) {
-		/* some hand-crafted label structures have no entry */
-		return;
-	}
-
-	entry = label->MR_sll_entry;
-
-	if (MR_ENTRY_LAYOUT_HAS_EXEC_TRACE(entry) &&
-			! MR_ENTRY_LAYOUT_COMPILER_GENERATED(entry))
-	{
-		module = MR_ensure_module_info_is_present(
-				entry->MR_sle_user.MR_user_decl_module);
-		MR_ensure_proc_node_is_present(module, entry);
-	}
-}
-
-static void
-MR_ensure_proc_node_is_present(MR_Module_Info *module,
-	const MR_Stack_Layout_Entry *entry)
+void
+MR_register_module_layout_real(const MR_Module_Layout *module)
 {
-	MR_Proc_Node	*cur;
+	/*
+	** MR_register_module_layout_real should only be called from
+	** the initialization function of a module, which should be
+	** called only once. The check here whether the module layout
+	** already exists in the table is really only for paranoia.
+	*/
 
-	for (cur = module->MR_module_procs; cur != NULL;
-			cur = cur->MR_proc_next) {
-		if (entry == cur->MR_proc_layout) {
-			return;
-		}
+	if (MR_search_module_info(module->MR_ml_name) == NULL) {
+		MR_insert_module_info(module);
 	}
-
-	cur = checked_malloc(sizeof(MR_Proc_Node));
-	cur->MR_proc_layout = entry;
-	cur->MR_proc_next   = module->MR_module_procs;
-	module->MR_module_procs = cur;
-	MR_module_info_proc_count++;
 }
 
-static MR_Module_Info *
+static const MR_Module_Layout *
 MR_search_module_info(const char *name)
 {
 	int	slot;
 	bool	found;
 
 	MR_bsearch(MR_module_info_next, slot, found,
-		strcmp(MR_module_infos[slot].MR_module_name, name));
+		strcmp(MR_module_infos[slot]->MR_ml_name, name));
 	if (found) {
-		return &MR_module_infos[slot];
+		return MR_module_infos[slot];
 	} else {
 		return NULL;
 	}
 }
 
-static MR_Module_Info *
-MR_insert_module_info(const char *name)
+static void
+MR_insert_module_info(const MR_Module_Layout *module)
 {
 	int	slot;
 
-	MR_ensure_room_for_next(MR_module_info, MR_Module_Info,
+	MR_ensure_room_for_next(MR_module_info, MR_Module_Layout *,
 		INIT_MODULE_TABLE_SIZE);
 	MR_prepare_insert_into_sorted(MR_module_infos, MR_module_info_next,
-		slot, strcmp(MR_module_infos[slot].MR_module_name, name));
+		slot,
+		strcmp(MR_module_infos[slot]->MR_ml_name, module->MR_ml_name));
 
-	MR_module_infos[slot].MR_module_name = name;
-	MR_module_infos[slot].MR_module_procs = NULL;
-	return &MR_module_infos[slot];
-}
-
-static MR_Module_Info *
-MR_ensure_module_info_is_present(const char *name)
-{
-	MR_Module_Info	*module;
-
-	module = MR_search_module_info(name);
-	if (module != NULL) {
-		return module;
-	} else {
-		return MR_insert_module_info(name);
-	}
+	MR_module_infos[slot] = module;
+	MR_module_info_proc_count += module->MR_ml_proc_count;
 }
 
 void
 MR_dump_module_tables(FILE *fp)
 {
-	const MR_Proc_Node	*cur;
-	int			i;
+	int	i, j;
 
 	for (i = 0; i < MR_module_info_next; i++) {
 		fprintf(fp, "====================\n");
-		fprintf(fp, "module %s\n", MR_module_infos[i].MR_module_name);
+		fprintf(fp, "module %s\n", MR_module_infos[i]->MR_ml_name);
 		fprintf(fp, "====================\n");
-		for (cur = MR_module_infos[i].MR_module_procs; cur != NULL;
-				cur = cur->MR_proc_next) {
-			MR_print_proc_id(fp, cur->MR_proc_layout, NULL,
-				NULL, NULL);
+		for (j = 0; j < MR_module_infos[i]->MR_ml_proc_count; j++) {
+			MR_print_proc_id_for_debugger(fp,
+				MR_module_infos[i]->MR_ml_procs[j]);
 		}
 	}
 }
@@ -189,15 +133,15 @@
 
 	fprintf(fp, "List of debuggable modules\n\n");
 	for (i = 0; i < MR_module_info_next; i++) {
-		fprintf(fp, "%s\n", MR_module_infos[i].MR_module_name);
+		fprintf(fp, "%s\n", MR_module_infos[i]->MR_ml_name);
 	}
 }
 
 void
 MR_dump_module_procs(FILE *fp, const char *name)
 {
-	MR_Module_Info		*module;
-	const MR_Proc_Node	*cur;
+	const MR_Module_Layout		*module;
+	int				j;
 
 	module = MR_search_module_info(name);
 	if (module == NULL) {
@@ -205,10 +149,9 @@
 				name);
 	} else {
 		fprintf(fp, "List of procedures in module `%s'\n\n", name);
-		for (cur = module->MR_module_procs; cur != NULL;
-				cur = cur->MR_proc_next) {
-			MR_print_proc_id(fp, cur->MR_proc_layout, NULL,
-				NULL, NULL);
+		for (j = 0; j < module->MR_ml_proc_count; j++) {
+			MR_print_proc_id_for_debugger(fp,
+				module->MR_ml_procs[j]);
 		}
 	}
 }
@@ -336,7 +279,7 @@
 	void *data)
 {
 	if (spec->MR_proc_module != NULL) {
-		MR_Module_Info			*module;
+		const MR_Module_Layout	*module;
 
 		module = MR_search_module_info(spec->MR_proc_module);
 		if (module != NULL) {
@@ -348,7 +291,7 @@
 
 		for (i = 0; i < MR_module_info_next; i++) {
 			MR_process_matching_procedures_in_module(
-				&MR_module_infos[i], spec, f, data);
+				MR_module_infos[i], spec, f, data);
 		}
 	}
 }
@@ -370,16 +313,15 @@
 					cur->MR_sle_user.MR_user_pred_or_func)
 
 static void
-MR_process_matching_procedures_in_module(MR_Module_Info *module,
+MR_process_matching_procedures_in_module(const MR_Module_Layout *module,
 	MR_Proc_Spec *spec, void f(void *, const MR_Stack_Layout_Entry *),
 	void *data)
 {
-	MR_Proc_Node			*cur;
 	const MR_Stack_Layout_Entry	*cur_entry;
+	int				j;
 
-	for (cur = module->MR_module_procs; cur != NULL;
-			cur = cur->MR_proc_next) {
-		cur_entry = cur->MR_proc_layout;
+	for (j = 0; j < module->MR_ml_proc_count; j++) {
+		cur_entry = module->MR_ml_procs[j];
 		if (match_name(spec, cur_entry) &&
 				match_arity(spec, cur_entry) &&
 				match_mode(spec, cur_entry) &&
Index: trace/mercury_trace_tables.h
===================================================================
RCS file: /home/mercury1/repository/mercury/trace/mercury_trace_tables.h,v
retrieving revision 1.4
diff -u -b -u -r1.4 mercury_trace_tables.h
--- mercury_trace_tables.h	1999/02/23 08:06:53	1.4
+++ mercury_trace_tables.h	1999/05/05 01:54:52
@@ -18,25 +18,6 @@
 #include	<stdio.h>
 
 /*
-** The module info table is an array with one element for each module
-** that has procedures with execution tracing information. This element
-** gives the module's name and points to a list of the procedure layouts
-** of the traceable procedures of the module.
-*/
-
-typedef struct MR_Proc_Node_Struct	MR_Proc_Node;
-
-struct MR_Proc_Node_Struct {
-	const MR_Stack_Layout_Entry	*MR_proc_layout;
-	MR_Proc_Node			*MR_proc_next;
-};
-
-typedef struct {
-	const char 			*MR_module_name;
-	MR_Proc_Node			*MR_module_procs;
-} MR_Module_Info;
-
-/*
 ** MR_register_all_modules_and_procs gathers all available debugging info
 ** about the modules and procedures of the program into the module info table.
 ** If verbose is TRUE, print progress and summary messages.
@@ -46,6 +27,16 @@
 				bool verbose);
 
 /*
+** MR_register_module_layout_real registers a module layout structure.
+** It is called indirectly, through the function pointer
+** MR_register_module_layout, by the module initialization code
+** of modules compiled with debugging.
+*/
+
+extern	void		MR_register_module_layout_real(const MR_Module_Layout
+				*module);
+
+/*
 ** These functions print (parts of) the module info table.
 **
 ** MR_dump_module_tables lists all procedures in all modules.
@@ -120,7 +111,6 @@
 extern	void	MR_process_matching_procedures(MR_Proc_Spec *spec,
 			void f(void *, const MR_Stack_Layout_Entry *), 
 			void *data);
-
 
 extern	void	MR_print_proc_id_for_debugger(FILE *fp,
 			const MR_Stack_Layout_Entry *entry);
cvs diff: Diffing trial
cvs diff: Diffing util
Index: util/mkinit.c
===================================================================
RCS file: /home/mercury1/repository/mercury/util/mkinit.c,v
retrieving revision 1.50
diff -u -b -u -r1.50 mkinit.c
--- mkinit.c	1999/05/14 02:25:53	1.50
+++ mkinit.c	1999/05/24 08:23:15
@@ -175,8 +175,10 @@
 	"#endif\n"
 	"#if MR_TRACE_ENABLED\n"
 	"	MR_trace_func_ptr = MR_trace_real;\n"
+	"	MR_register_module_layout = MR_register_module_layout_real;\n"
 	"#else\n"
 	"	MR_trace_func_ptr = MR_trace_fake;\n"
+	"	MR_register_module_layout = NULL;\n"
 	"#endif\n"
 	"#if defined(USE_GCC_NONLOCAL_GOTOS) && !defined(USE_ASM_LABELS)\n"
 	"	do_init_modules();\n"
--------------------------------------------------------------------------
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