[m-rev.] diff: MLDS->C accurate GC bug fixes

Fergus Henderson fjh at cs.mu.OZ.AU
Wed Jan 30 22:57:17 AEDT 2002


Estimated hours taken: 16
Branches: main

Various bug fixes for accurate GC with the MLDS->C back-end.

runtime/mercury.c:
	Fix a typo in the definition of the `stack_chain' global.

compiler/ml_code_util.m:
compiler/ml_call_gen.m:
	Fix several bugs:
	- generate appropriate GC tracing code for tracing type_infos
	  and typeclass_infos.  These need to be handled specially
	  because of the parameters of private_builtin:type_info/1 etc.
	  don't affect the representation of the type, and need to
	  be ignored (to avoid infinite recursion).
	- don't generate GC tracing code for no_type_info_builtin procedures,
	  because the generated GC tracing code would refer to
	  type_info arguments that don't get passed.
	- in ml_call_gen.m, we were generating incorrect GC tracing code
	  for the `conv_*' variables introduced to hold output arguments
	  of polymorphically typed procedures.

compiler/type_util.m:
library/private_builtin.m:
	Add types `sample_type_info' and `sample_typeclass_info',
	so that ml_code_util.m can use them when tracing type_infos
	and typeclass_infos (respectively).

library/private_builtin.m:
	Fix some software rot in gc_trace/1: add `MR_eng_' prefixes.

library/io.m:
runtime/mercury_library_types.h:
	Implement stream ids for NATIVE_GC.

Workspace: /home/earth/fjh/ws-earth4/mercury
Index: compiler/ml_call_gen.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/ml_call_gen.m,v
retrieving revision 1.27
diff -u -d -r1.27 ml_call_gen.m
--- compiler/ml_call_gen.m	11 Jan 2002 07:41:22 -0000	1.27
+++ compiler/ml_call_gen.m	30 Jan 2002 07:50:01 -0000
@@ -837,17 +837,32 @@
 		%
 
 		% generate a declaration for the fresh variable
+		%
+		% Note that generating accurate GC tracing code for this
+		% variable requires some care, because CalleeType might be a
+		% type variable from the callee, not from the caller,
+		% and we can't generate type_infos for type variables
+		% from the callee.  Hence we need to call the version of
+		% ml_gen_maybe_gc_trace_code which takes two types:
+		% the CalleeType is used to determine the type for the
+		% temporary variable declaration, but the CallerType is
+		% used to construct the type_info.
+
 		ml_gen_info_new_conv_var(ConvVarNum),
 		{ VarName = mlds__var_name(VarNameStr, MaybeNum) },
 		{ ArgVarName = mlds__var_name(string__format(
 			"conv%d_%s", [i(ConvVarNum), s(VarNameStr)]),
 			MaybeNum) },
-		ml_gen_var_decl(ArgVarName, CalleeType, Context, ArgVarDecl),
+		ml_gen_type(CalleeType, MLDS_CalleeType),
+		ml_gen_maybe_gc_trace_code(ArgVarName, CalleeType, CallerType,
+			Context, GC_TraceCode),
+		{ ArgVarDecl = ml_gen_mlds_var_decl(var(ArgVarName),
+			MLDS_CalleeType, GC_TraceCode,
+			mlds__make_context(Context)) },
 		{ ConvDecls = [ArgVarDecl] },
 
 		% create the lval for the variable and use it for the
 		% argument lval
-		ml_gen_type(CalleeType, MLDS_CalleeType),
 		ml_gen_var_lval(ArgVarName, MLDS_CalleeType, ArgLval),
 
 		( { type_util__is_dummy_argument_type(CallerType) } ->
Index: compiler/ml_code_util.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/ml_code_util.m,v
retrieving revision 1.51
diff -u -d -r1.51 ml_code_util.m
--- compiler/ml_code_util.m	28 Jan 2002 05:30:23 -0000	1.51
+++ compiler/ml_code_util.m	30 Jan 2002 07:46:59 -0000
@@ -489,14 +489,38 @@
 % Code to handle accurate GC
 %
 
+	% ml_gen_maybe_gc_trace_code(Var, Type, Context, Code):
+	%
 	% If accurate GC is enabled, and the specified
 	% variable might contain pointers, generate code to call
 	% `private_builtin__gc_trace' to trace the variable.
-	% 
 :- pred ml_gen_maybe_gc_trace_code(var_name, prog_type, prog_context,
 		maybe(mlds__statement), ml_gen_info, ml_gen_info).
 :- mode ml_gen_maybe_gc_trace_code(in, in, in, out, in, out) is det.
 
+	% ml_gen_maybe_gc_trace_code(Var, DeclType, ActualType, Context, Code):
+	%
+	% This is the same as the //4 version (above), except that it takes
+	% two type arguments, rather than one.  The first
+	% (DeclType) is the type that the variable was declared with,
+	% while the second (ActualType) is that type that the variable
+	% is known to have.  This is used to generate GC tracing code
+	% for the temporaries variables used when calling procedures with
+	% polymorphically-typed output arguments.
+	% In that case, DeclType may be a type variable from the callee's
+	% type declaration, but ActualType will be the type from the caller.
+	%
+	% We can't just use DeclType to generate the GC trace code,
+	% because there's no way to compute the type_info for type variables
+	% that come from the callee rather than the current procedure.
+	% And we can't just use ActualType, since DeclType may contain
+	% pointers even when ActualType doesn't (e.g. because DeclType
+	% may be a boxed float).  So we need to pass both.
+	% 
+:- pred ml_gen_maybe_gc_trace_code(var_name, prog_type, prog_type, prog_context,
+		maybe(mlds__statement), ml_gen_info, ml_gen_info).
+:- mode ml_gen_maybe_gc_trace_code(in, in, in, in, out, in, out) is det.
+
 %-----------------------------------------------------------------------------%
 %
 % Magic numbers relating to the representation of
@@ -747,7 +771,7 @@
 
 :- implementation.
 
-:- import_module prog_data.
+:- import_module prog_data, prog_io.
 :- import_module hlds_goal, (inst), instmap, polymorphism.
 :- import_module foreign.
 :- import_module prog_util, type_util, mode_util, special_pred, error_util.
@@ -1058,8 +1082,20 @@
 	proc_info_argmodes(ProcInfo, HeadModes),
 	proc_info_interface_code_model(ProcInfo, CodeModel),
 	HeadVarNames = ml_gen_var_names(VarSet, HeadVars),
-	ml_gen_params(HeadVarNames, HeadTypes, HeadModes, PredOrFunc,
-		CodeModel, FuncParams, MLGenInfo0, MLGenInfo).
+	% we must not generate GC tracing code for no_type_info_builtin
+	% procedures, because the generated GC tracing code would refer
+	% to type_infos that don't get passed
+	pred_info_module(PredInfo, PredModule),
+	pred_info_name(PredInfo, PredName),
+	pred_info_arity(PredInfo, PredArity),
+	( no_type_info_builtin(PredModule, PredName, PredArity) ->
+		FuncParams = ml_gen_params(ModuleInfo, HeadVarNames, HeadTypes,
+			HeadModes, PredOrFunc, CodeModel),
+		MLGenInfo = MLGenInfo0
+	;
+		ml_gen_params(HeadVarNames, HeadTypes, HeadModes, PredOrFunc,
+			CodeModel, FuncParams, MLGenInfo0, MLGenInfo)
+	).
 
 	% As above, but from the rtti_proc_id rather than
 	% from the module_info, pred_id, and proc_id.
@@ -1990,36 +2026,49 @@
 	% `private_builtin__gc_trace' to trace the variable.
 	%
 ml_gen_maybe_gc_trace_code(VarName, Type, Context, Maybe_GC_TraceCode) -->
+	ml_gen_maybe_gc_trace_code(VarName, Type, Type, Context,
+		Maybe_GC_TraceCode).
+
+ml_gen_maybe_gc_trace_code(VarName, DeclType, ActualType0, Context,
+		Maybe_GC_TraceCode) -->
 	=(MLDSGenInfo),
 	{ ml_gen_info_get_module_info(MLDSGenInfo, ModuleInfo) },
 	{ module_info_globals(ModuleInfo, Globals) },
 	{ globals__get_gc_method(Globals, GC) },
 	(
 		{ GC = accurate },
-		{ MLDS_Type = mercury_type_to_mlds_type(ModuleInfo, Type) },
-		{ ml_type_might_contain_pointers(MLDS_Type) = yes },
-		% check that the Type is not `constraint(...)',
-		% which is a special case
-		% XXX maybe there is a better way of handling this...
-		% XXX FIXME this doesn't work, since it doesn't
-		% catch types which _contain_ `constraint(...)'.
-		{ Type = term__variable(_)
-		; type_to_type_id(Type, _, _)
-		}
+		{ MLDS_DeclType = mercury_type_to_mlds_type(ModuleInfo,
+			DeclType) },
+		{ ml_type_might_contain_pointers(MLDS_DeclType) = yes },
+		% don't generate GC tracing code in no_type_info_builtins
+		{ ml_gen_info_get_pred_id(MLDSGenInfo, PredId) },
+		{ predicate_id(ModuleInfo, PredId,
+			PredModule, PredName, PredArity) },
+		\+ { no_type_info_builtin(PredModule, PredName, PredArity) }
 	->
-		ml_gen_gc_trace_code(VarName, Type, Context, GC_TraceCode),
+		% We need to handle type_info/1 and typeclass_info/1 types
+		% specially, to avoid infinite recursion here...
+		{ trace_type_info_type(ActualType0, ActualType1) ->
+			ActualType = ActualType1
+		;
+			ActualType = ActualType0
+		},
+		ml_gen_gc_trace_code(VarName, DeclType, ActualType, Context,
+			GC_TraceCode),
 		{ Maybe_GC_TraceCode = yes(GC_TraceCode) }
 	;
 		{ Maybe_GC_TraceCode = no }
-	 ).
+	).
 
 	% Return `yes' if the type needs to be traced by
 	% the accurate garbage collector, i.e. if it might
 	% contain pointers.
 	%
-	% It's always safe to return `yes' here, so if in doubt, we do.
+	% Any type for which we return `yes' here must be word-sized,
+	% because we will call private_builtin__gc_trace with its address,
+	% and that procedure assumes that its argument is an `MR_Word *'.
 	%
-	% For floats, we can return `no' even though they might
+	% For floats, we can (and must) return `no' even though they might
 	% get boxed in some circumstances, because if they are
 	% boxed then they will be represented as mlds__generic_type.
 	%
@@ -2042,7 +2091,14 @@
 ml_type_might_contain_pointers(mlds__native_float_type) = no.
 ml_type_might_contain_pointers(mlds__native_bool_type) = no.
 ml_type_might_contain_pointers(mlds__native_char_type) = no.
-ml_type_might_contain_pointers(mlds__foreign_type(_, _, _)) = yes.
+ml_type_might_contain_pointers(mlds__foreign_type(_, _, _)) = _ :-
+	% It might contain pointers, so it's not safe to return `no',
+	% but it also might not be word-sized, so it's not safe to
+	% return `yes'.  Currently this case should not occur, since
+	% currently `foreign_type' is only used for the IL back-end,
+	% where GC is handled by the target language.
+	unexpected(this_file, "--gc accurate and foreign_type").
+	
 ml_type_might_contain_pointers(mlds__class_type(_, _, Category)) =
 	(if Category = mlds__enum then no else yes).
 ml_type_might_contain_pointers(mlds__ptr_type(_)) = yes.
@@ -2067,17 +2123,31 @@
 ml_type_category_might_contain_pointers(polymorphic_type) = yes.
 ml_type_category_might_contain_pointers(user_type) = yes.
 
+	% trace_type_info_type(Type, RealType):
+	%	Succeed iff Type is a type_info-related type
+	%	which needs to be copied as if it were some other type,
+	%	binding RealType to that other type.
+:- pred trace_type_info_type(prog_type::in, prog_type::out) is semidet.
+trace_type_info_type(Type, RealType) :-
+	sym_name_and_args(Type, TypeName, _),
+	TypeName = qualified(PrivateBuiltin, Name),
+	mercury_private_builtin_module(PrivateBuiltin),
+	( Name = "type_info", RealType = sample_type_info_type
+	; Name = "type_ctor_info", RealType = c_pointer_type
+	; Name = "typeclass_info", RealType = sample_typeclass_info_type
+	; Name = "base_typeclass_info", RealType = c_pointer_type
+	).
 
 	% Generate code to call to `private_builtin__gc_trace'
 	% to trace the specified variable.
 	%
-:- pred ml_gen_gc_trace_code(var_name, prog_type, prog_context,
+:- pred ml_gen_gc_trace_code(var_name, prog_type, prog_type, prog_context,
 		mlds__statement, ml_gen_info, ml_gen_info).
-:- mode ml_gen_gc_trace_code(in, in, in, out, in, out) is det.
+:- mode ml_gen_gc_trace_code(in, in, in, in, out, in, out) is det.
 
-ml_gen_gc_trace_code(VarName, Type, Context, GC_TraceCode) -->
+ml_gen_gc_trace_code(VarName, DeclType, ActualType, Context, GC_TraceCode) -->
 	% Build HLDS code to construct the type_info for this type.
-	ml_gen_make_type_info_var(Type, Context,
+	ml_gen_make_type_info_var(ActualType, Context,
 		TypeInfoVar, HLDS_TypeInfoGoals),
 	{ NonLocalsList = list__map(
 		(func(_G - GI) = NL :- goal_info_get_nonlocals(GI, NL)),
@@ -2092,7 +2162,7 @@
 	ml_gen_goal(model_det, Conj, MLDS_TypeInfoStatement),
 
 	% Build MLDS code to trace the variable
-	ml_gen_trace_var(VarName, Type, TypeInfoVar, Context,
+	ml_gen_trace_var(VarName, DeclType, TypeInfoVar, Context,
 		MLDS_TraceStatement),
 
 	% Generate declarations for any type_info variables used.
@@ -2472,6 +2542,13 @@
 		globals__lookup_bool_option(Globals,
 			det_copy_out, CopyOut)
 	).
+
+%-----------------------------------------------------------------------------%
+
+:- func this_file = string.
+this_file = "ml_code_util.m".
+
+:- end_module ml_code_util.
 
 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
Index: compiler/type_util.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/type_util.m,v
retrieving revision 1.102
diff -u -d -r1.102 type_util.m
--- compiler/type_util.m	21 Nov 2001 03:53:59 -0000	1.102
+++ compiler/type_util.m	30 Jan 2002 04:46:10 -0000
@@ -165,6 +165,8 @@
 :- func float_type = (type).
 :- func char_type = (type).
 :- func c_pointer_type = (type).
+:- func sample_type_info_type = (type).
+:- func sample_typeclass_info_type = (type).
 
 	% Given a constant and an arity, return a type_id.
 	% Fails if the constant is not an atom.
@@ -789,6 +791,16 @@
 c_pointer_type = Type :-
 	mercury_public_builtin_module(BuiltinModule),
 	construct_type(qualified(BuiltinModule, "c_pointer") - 0, [], Type).
+
+sample_type_info_type = Type :-
+	mercury_private_builtin_module(BuiltinModule),
+	construct_type(qualified(BuiltinModule,
+		"sample_type_info") - 0, [], Type).
+
+sample_typeclass_info_type = Type :-
+	mercury_private_builtin_module(BuiltinModule),
+	construct_type(qualified(BuiltinModule,
+		"sample_typeclass_info") - 0, [], Type).
 
 %-----------------------------------------------------------------------------%
 
Index: library/io.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/io.m,v
retrieving revision 1.239
diff -u -d -r1.239 io.m
--- library/io.m	22 Jan 2002 14:21:50 -0000	1.239
+++ library/io.m	30 Jan 2002 10:33:27 -0000
@@ -2895,19 +2895,19 @@
 :- pragma foreign_proc("C",
 	io__get_stream_id(Stream::in, Id::out), 
 		[will_not_call_mercury, promise_pure], "
+
+#ifndef NATIVE_GC
 	/* 
 	** Most of the time, we can just use the pointer to the stream
 	** as a unique identifier.
 	*/
-	
 	Id = (MR_Word) Stream;
-
-#ifdef NATIVE_GC
+#else
 	/* 
-	** XXX for accurate GC we should embed an ID in the MercuryFile
+	** for accurate GC we embed an ID in the MercuryFile
 	** and retrieve it here.
 	*/
-	MR_fatal_error(""not implemented -- stream ids in native GC grades"");
+	Id = ((MercuryFile *) Stream)->id;
 #endif
 ").
 
Index: library/private_builtin.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/private_builtin.m,v
retrieving revision 1.86
diff -u -d -r1.86 private_builtin.m
--- library/private_builtin.m	20 Jan 2002 07:32:22 -0000	1.86
+++ library/private_builtin.m	30 Jan 2002 09:40:36 -0000
@@ -296,6 +296,12 @@
 						/*, ... */).
 :- type base_typeclass_info(_) ---> typeclass_info(int /*, ... */).
 
+	% The following types are used by compiler/ml_code_util.m
+	% as the types used for copying type_info/1 and typeclass_info/1
+	% types.  XXX Document me better
+:- type sample_type_info ---> sample_type_info(type_info(int)).
+:- type sample_typeclass_info ---> sample_typeclass_info(typeclass_info(int)).
+
 	% type_info_from_typeclass_info(TypeClassInfo, Index, TypeInfo)
 	% extracts TypeInfo from TypeClassInfo, where TypeInfo is the Indexth
 	% type_info in the typeclass_info.
@@ -1095,8 +1101,8 @@
 	*(MR_Word *)Pointer =
 		MR_agc_deep_copy((MR_Word *) Pointer,
 			(MR_TypeInfo) TypeInfo_for_T,
-			MR_ENGINE(heap_zone2->min),
-                        MR_ENGINE(heap_zone2->hardmax));
+			MR_ENGINE(MR_eng_heap_zone2->min),
+                        MR_ENGINE(MR_eng_heap_zone2->hardmax));
 #else
 	MR_fatal_error(""private_builtin__gc_trace/2: ""
 		""called when accurate GC not enabled"");
Index: runtime/mercury.c
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury.c,v
retrieving revision 1.31
diff -u -d -r1.31 mercury.c
--- runtime/mercury.c	25 Jan 2002 08:23:21 -0000	1.31
+++ runtime/mercury.c	28 Jan 2002 08:45:57 -0000
@@ -27,7 +27,7 @@
 */
 
 #ifdef NATIVE_GC
-  void *mercury__private_builtin____stack_chain;
+  void *mercury__private_builtin__stack_chain;
 #endif
 
 MR_Word mercury__private_builtin__dummy_var;
Index: runtime/mercury_library_types.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_library_types.h,v
retrieving revision 1.5
diff -u -d -r1.5 mercury_library_types.h
--- runtime/mercury_library_types.h	11 Aug 2000 16:50:21 -0000	1.5
+++ runtime/mercury_library_types.h	30 Jan 2002 10:30:40 -0000
@@ -27,6 +27,9 @@
   typedef struct mercury_file {
 	FILE *file1;
 	int line_number1;
+  #ifdef NATIVE_GC
+	int id;
+  #endif
   } MercuryFile;
 
   #define MR_file(mf)		(mf).file1
@@ -101,6 +104,9 @@
 	MR_StreamType	stream_type;
 	MR_StreamInfo	stream_info;
 	int		line_number;
+  #ifdef NATIVE_GC
+	int id;
+  #endif
 
 		/* UNBUFFERED FUNCTIONS */
 	MR_Stream_close	*close;    
-- 
Fergus Henderson <fjh at cs.mu.oz.au>  |  "I have always known that the pursuit
The University of Melbourne         |  of excellence is a lethal habit"
WWW: <http://www.cs.mu.oz.au/~fjh>  |     -- the last words of T. S. Garp.
--------------------------------------------------------------------------
mercury-reviews mailing list
post:  mercury-reviews at cs.mu.oz.au
administrative address: owner-mercury-reviews at cs.mu.oz.au
unsubscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: unsubscribe
subscribe:   Address: mercury-reviews-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------



More information about the reviews mailing list