[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