[m-rev.] hlc.agc: fix GC of closure wrappers
Fergus Henderson
fjh at cs.mu.OZ.AU
Sun Jun 2 21:13:10 AEST 2002
Estimated hours taken: 16
Branches: main
Implement the last remaining bits needed to do accurate GC for
closure wrappers.
compiler/ml_call_gen.m:
Add an extra boolean argument to ml_gen_call and
ml_gen_box_or_unbox_lval specifying whether or not
the calling procedure is a closure wrapper.
If it is, declare any local variables allocated
to hold temporaries needed for boxing/unboxing
using ml_gen_local_for_output_arg from ml_closure_gen.m,
so that the GC tracing code gets handled right.
compiler/ml_closure_gen.m:
Pass `yes' for the new boolean argument to ml_gen_call.
Export ml_gen_local_for_output_arg, for use by ml_call_gen.m.
Fix a bug where the `allocated_memory_cells' list was not being
initialized.
compiler/ml_code_gen.m:
Pass `no' for the new boolean argument to ml_gen_call
and ml_gen_box_or_unbox_lval.
Workspace: /home/ceres/fjh/mercury
Index: compiler/ml_call_gen.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/ml_call_gen.m,v
retrieving revision 1.34
diff -u -d -r1.34 ml_call_gen.m
--- compiler/ml_call_gen.m 2 Apr 2002 16:36:09 -0000 1.34
+++ compiler/ml_call_gen.m 2 Jun 2002 11:01:17 -0000
@@ -21,7 +21,7 @@
:- import_module backend_libs__code_model.
:- import_module ml_backend__mlds, ml_backend__ml_code_util.
-:- import_module list.
+:- import_module list, bool.
% Generate MLDS code for an HLDS generic_call goal.
% This includes boxing/unboxing the arguments if necessary.
@@ -31,13 +31,23 @@
:- mode ml_gen_generic_call(in, in, in, in, in, out, out, in, out) is det.
%
+ % ml_gen_call(PredId, ProcId, ArgNames, ArgLvals, ArgTypes,
+ % CodeModel, Context, ForClosureWrapper,
+ % MLDS_Defns, MLDS_Statements):
+ %
% Generate MLDS code for an HLDS procedure call, making sure to
% box/unbox the arguments if necessary.
%
+ % If ForClosureWrapper = yes, then the type_info for type variables
+ % in CallerType may not be available in the current procedure, so
+ % the GC tracing code for temps introduced for boxing/unboxing (if any)
+ % should obtain the type_info from the corresponding entry in the
+ % `type_params' local.
+ %
:- pred ml_gen_call(pred_id, proc_id, list(var_name), list(mlds__lval),
- list(prog_data__type), code_model, prog_context,
+ list(prog_data__type), code_model, prog_context, bool,
mlds__defns, mlds__statements, ml_gen_info, ml_gen_info).
-:- mode ml_gen_call(in, in, in, in, in, in, in, out, out, in, out) is det.
+:- mode ml_gen_call(in, in, in, in, in, in, in, in, out, out, in, out) is det.
%
% Generate MLDS code for a call to a builtin procedure.
@@ -63,7 +73,7 @@
:- mode ml_gen_box_or_unbox_rval(in, in, in, out, in, out) is det.
% ml_gen_box_or_unbox_lval(CallerType, CalleeType, VarLval, VarName,
- % Context,
+ % Context, ForClosureWrapper,
% ArgLval, ConvDecls, ConvInputStatements, ConvOutputStatements):
%
% This is like `ml_gen_box_or_unbox_rval', except that it
@@ -77,16 +87,20 @@
% to the destination lval, and code to assign from the
% destination lval (suitable converted) to the source lval.
%
+ % If ForClosureWrapper = yes, then the type_info for type variables
+ % in CallerType may not be available in the current procedure, so
+ % the GC tracing code for the ConvDecls (if any) should obtain the
+ % type_info from the corresponding entry in the `type_params' local.
+ %
:- pred ml_gen_box_or_unbox_lval(prog_type, prog_type, mlds__lval, var_name,
- prog_context, mlds__lval, mlds__defns, mlds__statements,
+ prog_context, bool, mlds__lval, mlds__defns, mlds__statements,
mlds__statements, ml_gen_info, ml_gen_info).
-:- mode ml_gen_box_or_unbox_lval(in, in, in, in, in, out, out, out, out,
+:- mode ml_gen_box_or_unbox_lval(in, in, in, in, in, in, out, out, out, out,
in, out) is det.
% Generate the appropriate MLDS type for a continuation function
% for a nondet procedure whose output arguments have the
% specified types.
- %
%
:- pred ml_gen_cont_params(list(mlds__type), mlds__func_params,
ml_gen_info, ml_gen_info).
@@ -97,6 +111,7 @@
:- implementation.
+:- import_module ml_backend__ml_closure_gen.
:- import_module hlds__hlds_module, hlds__hlds_data.
:- import_module backend_libs__builtin_ops.
:- import_module check_hlds__type_util, check_hlds__mode_util.
@@ -231,7 +246,7 @@
ml_gen_var_list(ArgVars, ArgLvals),
ml_variable_types(ArgVars, ActualArgTypes),
ml_gen_arg_list(ArgNames, ArgLvals, ActualArgTypes, BoxedArgTypes,
- ArgModes, PredOrFunc, CodeModel, Context,
+ ArgModes, PredOrFunc, CodeModel, Context, no,
InputRvals, OutputLvals, OutputTypes,
ConvArgDecls, ConvOutputStatements),
{ ClosureRval = unop(unbox(ClosureArgType), lval(ClosureLval)) },
@@ -315,7 +330,7 @@
% we just pass the original argument unchanged.
%
ml_gen_call(PredId, ProcId, ArgNames, ArgLvals, ActualArgTypes, CodeModel,
- Context, MLDS_Decls, MLDS_Statements) -->
+ Context, ForClosureWrapper, MLDS_Decls, MLDS_Statements) -->
%
% Compute the function signature
%
@@ -344,7 +359,7 @@
% to pass as the function call's arguments and return values
%
ml_gen_arg_list(ArgNames, ArgLvals, ActualArgTypes, PredArgTypes,
- ArgModes, PredOrFunc, CodeModel, Context,
+ ArgModes, PredOrFunc, CodeModel, Context, ForClosureWrapper,
InputRvals, OutputLvals, OutputTypes,
ConvArgDecls, ConvOutputStatements),
@@ -599,14 +614,14 @@
%
:- pred ml_gen_arg_list(list(var_name), list(mlds__lval), list(prog_type),
list(prog_type), list(mode), pred_or_func, code_model,
- prog_context, list(mlds__rval), list(mlds__lval),
+ prog_context, bool, list(mlds__rval), list(mlds__lval),
list(mlds__type), mlds__defns, mlds__statements,
ml_gen_info, ml_gen_info).
-:- mode ml_gen_arg_list(in, in, in, in, in, in, in, in, out, out, out, out, out,
- in, out) is det.
+:- mode ml_gen_arg_list(in, in, in, in, in, in, in, in, in,
+ out, out, out, out, out, in, out) is det.
ml_gen_arg_list(VarNames, VarLvals, CallerTypes, CalleeTypes, Modes,
- PredOrFunc, CodeModel, Context,
+ PredOrFunc, CodeModel, Context, ForClosureWrapper,
InputRvals, OutputLvals, OutputTypes,
ConvDecls, ConvOutputStatements) -->
(
@@ -630,7 +645,7 @@
->
ml_gen_arg_list(VarNames1, VarLvals1,
CallerTypes1, CalleeTypes1, Modes1,
- PredOrFunc, CodeModel, Context,
+ PredOrFunc, CodeModel, Context, ForClosureWrapper,
InputRvals1, OutputLvals1, OutputTypes1,
ConvDecls1, ConvOutputStatements1),
=(MLDSGenInfo),
@@ -674,8 +689,8 @@
% it's an output argument, or an unused argument
%
ml_gen_box_or_unbox_lval(CallerType, CalleeType,
- VarLval, VarName, Context, ArgLval,
- ThisArgConvDecls, _ThisArgConvInput,
+ VarLval, VarName, Context, ForClosureWrapper,
+ ArgLval, ThisArgConvDecls, _ThisArgConvInput,
ThisArgConvOutput),
{ ConvDecls = ThisArgConvDecls ++ ConvDecls1 },
{ ConvOutputStatements =
@@ -826,8 +841,8 @@
).
ml_gen_box_or_unbox_lval(CallerType, CalleeType, VarLval, VarName, Context,
- ArgLval, ConvDecls, ConvInputStatements, ConvOutputStatements)
- -->
+ ForClosureWrapper, ArgLval, ConvDecls,
+ ConvInputStatements, ConvOutputStatements) -->
%
% First see if we can just convert the lval as an rval;
% if no boxing/unboxing is required, then ml_box_or_unbox_rval
@@ -868,11 +883,28 @@
"conv%d_%s", [i(ConvVarNum), s(VarNameStr)]),
MaybeNum) },
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)) },
+ ( { ForClosureWrapper = yes } ->
+ % For closure wrappers, the argument type_infos are
+ % stored in the `type_params' local, so we need to
+ % handle the GC tracing code specially
+ ( { type_util__var(CallerType, TypeVar) } ->
+ % XXX here we rely on the allocation order
+ % of type variable numbers
+ { term__var_to_int(TypeVar, ArgNum) },
+ ml_gen_local_for_output_arg(ArgVarName,
+ CalleeType, ArgNum, Context,
+ ArgVarDecl)
+ ;
+ { unexpected(this_file,
+ "invalid CalleeType for closure wrapper") }
+ )
+ ;
+ 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
Index: compiler/ml_closure_gen.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/ml_closure_gen.m,v
retrieving revision 1.10
diff -u -d -r1.10 ml_closure_gen.m
--- compiler/ml_closure_gen.m 12 Apr 2002 01:24:07 -0000 1.10
+++ compiler/ml_closure_gen.m 2 Jun 2002 11:04:51 -0000
@@ -57,6 +57,17 @@
:- mode ml_gen_closure_wrapper(in, in, in, in, in, out, out,
in, out) is det.
+ % ml_gen_local_for_output_arg(VarName, Type, ArgNum, Context,
+ % LocalVarDefn):
+ % Generate a declaration for a local variable with the specified
+ % VarName and Type. However, don't use the normal GC tracing code;
+ % instead, generate GC tracing code that gets the typeinfo from
+ % the ArgNum-th entry in `type_params'.
+
+:- pred ml_gen_local_for_output_arg(var_name, prog_type, int, prog_context,
+ mlds__defn, ml_gen_info, ml_gen_info).
+:- mode ml_gen_local_for_output_arg(in, in, in, in, out, in, out) is det.
+
%-----------------------------------------------------------------------------%
:- implementation.
@@ -579,7 +590,6 @@
% /* declarations needed for converting output args */
% Arg2Type conv_arg2;
% /* GC tracing code same as below */
- % /* XXX FIXME generation of this is N.Y.I. */
% ...
%
% /* declarations needed for by-value outputs */
@@ -588,7 +598,7 @@
% #if 0 /* GC tracing code */
% {
% MR_TypeInfo type_info;
- % MR_MemoryList allocated_memory_cells;
+ % MR_MemoryList allocated_memory_cells = NULL;
% type_info = MR_make_type_info_maybe_existq(type_params,
% ((MR_Closure*)closure)->MR_closure_layout
% ->MR_closure_arg_pseudo_type_info[ <arg number> ],
@@ -840,14 +850,11 @@
ClosureArgLvals),
{ CallLvals = list__append(ClosureArgLvals, WrapperHeadVarLvals) },
ml_gen_call(PredId, ProcId, ProcHeadVarNames, CallLvals,
- ProcBoxedArgTypes, CodeModel, Context, Decls0, Statements0),
- % XXX FIXME the accurate GC handling for Decls0 is wrong,
- % because we don't have type_infos for the type variables in
- % ProcBoxedArgTypes.
- { FixedDecls0 = list__map(cannot_gc, Decls0) },
+ ProcBoxedArgTypes, CodeModel, Context, yes,
+ Decls0, Statements0),
% insert the stuff to declare and initialize the closure
- { Decls1 = [ClosureDecl | FixedDecls0] },
+ { Decls1 = [ClosureDecl | Decls0] },
{ Statements1 = [InitClosure | Statements0] },
%
@@ -909,29 +916,6 @@
Argument0 = mlds__argument(Name, Type, _GCTraceCode),
Argument = mlds__argument(Name, Type, no).
-% XXX FIXME Accurate GC of variables declared in closure wrapper
-% functions is not yet implemented. We use the following hack
-% to make sure that it crashes nicely at runtime if GC ever occurs
-% while one of these variables is live.
-:- func cannot_gc(mlds__defn) = mlds__defn.
-cannot_gc(Defn0) = Defn :-
- (
- Defn0 = mlds__defn(Name, Context, Flags, Body0),
- Body0 = mlds__data(Type, Init, yes(_GCTraceCode))
- ->
- Abort = mlds__statement(atomic(
- inline_target_code(lang_C, [raw_target_code(
- "MR_fatal_error(""don't know how to GC this\\n"");\n",
- [])])),
- Context),
- MaybeGCTraceCode = yes(Abort),
- % MaybeGCTraceCode = no,
- Body = mlds__data(Type, Init, MaybeGCTraceCode),
- Defn = mlds__defn(Name, Context, Flags, Body)
- ;
- Defn = Defn0
- ).
-
:- pred ml_gen_wrapper_func(ml_label_func, mlds__func_params, prog_context,
mlds__statement, mlds__defn, ml_gen_info, ml_gen_info).
:- mode ml_gen_wrapper_func(in, in, in, in, out, in, out) is det.
@@ -1077,10 +1061,6 @@
raw_target_code(");\n", [])
])), Context) }.
-:- pred ml_gen_local_for_output_arg(var_name, prog_type, int, prog_context,
- mlds__defn, ml_gen_info, ml_gen_info).
-:- mode ml_gen_local_for_output_arg(in, in, in, in, out, in, out) is det.
-
ml_gen_local_for_output_arg(VarName, Type, ArgNum, Context, LocalVarDefn) -->
%
% Generate a declaration for a corresponding local variable.
@@ -1089,6 +1069,7 @@
% the following code:
%
% MR_TypeInfo type_info;
+ % MR_MemoryList allocated_memory_cells = NULL;
% type_info = MR_make_type_info_maybe_existq(type_params,
% closure_layout->MR_closure_arg_pseudo_type_info[<ArgNum>],
% NULL, NULL, &allocated_memory_cells);
@@ -1128,7 +1109,8 @@
{ MaybeGCTraceCode0 = yes(CallTraceFuncCode) ->
MakeTypeInfoCode = atomic(inline_target_code(lang_C, [
raw_target_code("{\n", []),
- raw_target_code("MR_MemoryList allocated_mem;\n", []),
+ raw_target_code(
+ "MR_MemoryList allocated_mem = NULL;\n", []),
target_code_output(TypeInfoLval),
raw_target_code(
" = (MR_C_Pointer) " ++
Index: compiler/ml_code_gen.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/ml_code_gen.m,v
retrieving revision 1.116
diff -u -d -r1.116 ml_code_gen.m
--- compiler/ml_code_gen.m 30 May 2002 11:00:10 -0000 1.116
+++ compiler/ml_code_gen.m 2 Jun 2002 08:12:38 -0000
@@ -1412,7 +1412,7 @@
{ ml_gen_info_get_varset(MLDSGenInfo, VarSet) },
{ VarName = ml_gen_var_name(VarSet, Var) },
ml_gen_box_or_unbox_lval(HeadType, BodyType, HeadVarLval,
- VarName, Context, BodyLval, ConvDecls,
+ VarName, Context, no, BodyLval, ConvDecls,
ConvInputStatements, ConvOutputStatements),
%
@@ -2054,7 +2054,7 @@
{ ArgNames = ml_gen_var_names(VarSet, ArgVars) },
ml_variable_types(ArgVars, ActualArgTypes),
ml_gen_call(PredId, ProcId, ArgNames, ArgLvals, ActualArgTypes,
- CodeModel, Context, MLDS_Decls, MLDS_Statements)
+ CodeModel, Context, no, MLDS_Decls, MLDS_Statements)
;
% For the MLDS back-end, we can't treat
% private_builtin:unsafe_type_cast as an
@@ -3016,8 +3016,8 @@
ml_variable_type(Var, VarType),
ml_gen_var(Var, VarLval),
ml_gen_box_or_unbox_lval(VarType, OrigType, VarLval,
- mlds__var_name(ArgName, no),
- Context, ArgLval, ConvDecls, _ConvInputStatements,
+ mlds__var_name(ArgName, no), Context, no,
+ ArgLval, ConvDecls, _ConvInputStatements,
ConvOutputStatements),
% At this point we have an lval with the right type for
% *internal* use in the code generated by the Mercury
--
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