[m-rev.] diff: more fixes for MLDS->C accurate GC
Fergus Henderson
fjh at cs.mu.OZ.AU
Sat Feb 2 09:00:50 AEDT 2002
Estimated hours taken: 8
Branches: main
Some more bug fixes for accurate GC with the MLDS->C back-end.
With these changes, and a few hacks (see http://www.cs.mu.oz.au/research/
mercury/mailing-lists/mercury-reviews/mercury-reviews.0201/0188.html),
I was able to run all of the programs in tests/benchmarks in grade hlc.agc,
even with MERCURY_OPTIONS set to "-r10000" so as to run them enough times to
force garbage collection.
compiler/ml_elim_nested.m:
- Fix a bug where we were not saving/restoring the stack chain
pointer when doing commits (setjmp/longjmp).
- Fix a bug where we were not calling GC_check() for the nested
functions used for continuations in nondeterministic procedures.
- Remove the GC tracing annotations from function arguments
once they have been put into the GC tracing function,
to avoid cluttering the generated C code.
- Update the TODO list for accurate GC.
compiler/ml_code_util.m:
Allocate type_infos used for GC tracing on the stack,
rather than on the heap. This avoids a problem where
we were running out of heap space during garbage collection,
because the tracing routines were themselves allocating heap space.
runtime/mercury_accurate_gc.c:
Delete a call to MR_reset_redzone() in the MR_garbage_collect()
function, since the MLDS accurate garbage collector doesn't use
redzones.
Also update a comment to reflect the change to ml_code_util.m.
Workspace: /home/earth/fjh/ws-earth4/mercury
Index: compiler/ml_code_util.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/ml_code_util.m,v
retrieving revision 1.52
diff -u -d -r1.52 ml_code_util.m
--- compiler/ml_code_util.m 30 Jan 2002 12:46:58 -0000 1.52
+++ compiler/ml_code_util.m 1 Feb 2002 18:50:47 -0000
@@ -779,7 +779,7 @@
:- import_module ml_code_gen, ml_call_gen.
:- import_module globals, options.
-:- import_module stack, string, require, set, term, varset.
+:- import_module counter, stack, string, require, set, term, varset.
%-----------------------------------------------------------------------------%
%
@@ -2159,7 +2159,19 @@
{ conj_list_to_goal(HLDS_TypeInfoGoals, GoalInfo, Conj) },
% Convert this HLDS code to MLDS
- ml_gen_goal(model_det, Conj, MLDS_TypeInfoStatement),
+ ml_gen_goal(model_det, Conj, MLDS_TypeInfoStatement0),
+
+ % Replace all heap allocation (new_object instructions)
+ % with stack allocation (local variable declarations)
+ % in the code to construct type_infos. This is safe
+ % because those type_infos will only be used in the
+ % immediately following call to gc_trace/1.
+ =(MLGenInfo),
+ { ml_gen_info_get_module_info(MLGenInfo, ModuleInfo) },
+ { module_info_name(ModuleInfo, ModuleName) },
+ { fixup_newobj(MLDS_TypeInfoStatement0,
+ mercury_module_name_to_mlds(ModuleName),
+ MLDS_TypeInfoStatement, MLDS_NewobjLocals) },
% Build MLDS code to trace the variable
ml_gen_trace_var(VarName, DeclType, TypeInfoVar, Context,
@@ -2174,8 +2186,6 @@
% get put in the GC frame, rather than these declarations,
% which will get ignored.
% XXX This is not a very robust way of doing things...
- =(MLGenInfo),
- { ml_gen_info_get_module_info(MLGenInfo, ModuleInfo) },
{ ml_gen_info_get_varset(MLGenInfo, VarSet) },
{ ml_gen_info_get_var_types(MLGenInfo, VarTypes) },
{ MLDS_Context = mlds__make_context(Context) },
@@ -2188,11 +2198,12 @@
LocalVarType),
no, MLDS_Context)
) },
- { set__to_sorted_list(NonLocals, VarList) },
- { MLDS_VarDecls = list__map(GenLocalVarDecl, VarList) },
+ { set__to_sorted_list(NonLocals, NonLocalVarList) },
+ { MLDS_NonLocalVarDecls = list__map(GenLocalVarDecl, NonLocalVarList) },
% Combine the MLDS code fragments together.
- { GC_TraceCode = ml_gen_block(MLDS_VarDecls,
+ { GC_TraceCode = ml_gen_block(
+ MLDS_NewobjLocals ++ MLDS_NonLocalVarDecls,
[MLDS_TypeInfoStatement] ++ [MLDS_TraceStatement],
Context) }.
@@ -2276,6 +2287,198 @@
MLGenInfo = (((MLGenInfo0 ^ module_info := ModuleInfo)
^ varset := VarSet)
^ var_types := VarTypes).
+
+%-----------------------------------------------------------------------------%
+
+:- type fixup_newobj_info
+ ---> fixup_newobj_info(
+ module_name :: mlds_module_name,% the current module
+ context :: mlds__context, % the current context
+ locals :: mlds__defns, % the local variable declarations
+ % accumulated so far
+ next_id :: counter % a counter used to allocate
+ % variable names
+ ).
+
+ % Replace all heap allocation (new_object instructions)
+ % with stack allocation (local variable declarations)
+ % in the specified statement, returning the local
+ % variable declarations needed for the stack allocation.
+ %
+:- pred fixup_newobj(mlds__statement::in, mlds_module_name::in,
+ mlds__statement::out, mlds__defns::out) is det.
+
+fixup_newobj(Statement0, ModuleName, Statement, Defns) :-
+ Statement0 = mlds__statement(Stmt0, Context),
+ Info0 = fixup_newobj_info(ModuleName, Context, [], counter__init(0)),
+ fixup_newobj_in_stmt(Stmt0, Stmt, Info0, Info),
+ Statement = mlds__statement(Stmt, Context),
+ Defns = Info^locals.
+
+:- pred fixup_newobj_in_statement(mlds__statement::in, mlds__statement::out,
+ fixup_newobj_info::in, fixup_newobj_info::out) is det.
+fixup_newobj_in_statement(MLDS_Statement0, MLDS_Statement) -->
+ { MLDS_Statement0 = mlds__statement(MLDS_Stmt0, Context) },
+ ^context := Context,
+ fixup_newobj_in_stmt(MLDS_Stmt0, MLDS_Stmt),
+ { MLDS_Statement = mlds__statement(MLDS_Stmt, Context) }.
+
+:- pred fixup_newobj_in_stmt(mlds__stmt::in, mlds__stmt::out,
+ fixup_newobj_info::in, fixup_newobj_info::out) is det.
+
+fixup_newobj_in_stmt(Stmt0, Stmt) -->
+ (
+ { Stmt0 = block(Defns, Statements0) },
+ list__map_foldl(fixup_newobj_in_statement,
+ Statements0, Statements),
+ { Stmt = block(Defns, Statements) }
+ ;
+ { Stmt0 = while(Rval, Statement0, Once) },
+ fixup_newobj_in_statement(Statement0, Statement),
+ { Stmt = while(Rval, Statement, Once) }
+ ;
+ { Stmt0 = if_then_else(Cond, Then0, MaybeElse0) },
+ fixup_newobj_in_statement(Then0, Then),
+ fixup_newobj_in_maybe_statement(MaybeElse0, MaybeElse),
+ { Stmt = if_then_else(Cond, Then, MaybeElse) }
+ ;
+ { Stmt0 = switch(Type, Val, Range, Cases0, Default0) },
+ list__map_foldl(fixup_newobj_in_case, Cases0, Cases),
+ fixup_newobj_in_default(Default0, Default),
+ { Stmt = switch(Type, Val, Range, Cases, Default) }
+ ;
+ { Stmt0 = label(_) },
+ { Stmt = Stmt0 }
+ ;
+ { Stmt0 = goto(_) },
+ { Stmt = Stmt0 }
+ ;
+ { Stmt0 = computed_goto(Rval, Labels) },
+ { Stmt = computed_goto(Rval, Labels) }
+ ;
+ { Stmt0 = call(_Sig, _Func, _Obj, _Args, _RetLvals,
+ _TailCall) },
+ { Stmt = Stmt0 }
+ ;
+ { Stmt0 = return(_Rvals) },
+ { Stmt = Stmt0 }
+ ;
+ { Stmt0 = do_commit(_Ref) },
+ { Stmt = Stmt0 }
+ ;
+ { Stmt0 = try_commit(Ref, Statement0, Handler0) },
+ fixup_newobj_in_statement(Statement0, Statement),
+ fixup_newobj_in_statement(Handler0, Handler),
+ { Stmt = try_commit(Ref, Statement, Handler) }
+ ;
+ { Stmt0 = atomic(AtomicStmt0) },
+ fixup_newobj_in_atomic_statement(AtomicStmt0, Stmt)
+ ).
+
+:- pred fixup_newobj_in_case(mlds__switch_case, mlds__switch_case,
+ fixup_newobj_info, fixup_newobj_info).
+:- mode fixup_newobj_in_case(in, out, in, out) is det.
+
+fixup_newobj_in_case(Conds - Statement0, Conds - Statement) -->
+ fixup_newobj_in_statement(Statement0, Statement).
+
+:- pred fixup_newobj_in_maybe_statement(maybe(mlds__statement),
+ maybe(mlds__statement), fixup_newobj_info, fixup_newobj_info).
+:- mode fixup_newobj_in_maybe_statement(in, out, in, out) is det.
+
+fixup_newobj_in_maybe_statement(no, no) --> [].
+fixup_newobj_in_maybe_statement(yes(Statement0), yes(Statement)) -->
+ fixup_newobj_in_statement(Statement0, Statement).
+
+:- pred fixup_newobj_in_default(mlds__switch_default, mlds__switch_default,
+ fixup_newobj_info, fixup_newobj_info).
+:- mode fixup_newobj_in_default(in, out, in, out) is det.
+
+fixup_newobj_in_default(default_is_unreachable, default_is_unreachable) --> [].
+fixup_newobj_in_default(default_do_nothing, default_do_nothing) --> [].
+fixup_newobj_in_default(default_case(Statement0), default_case(Statement)) -->
+ fixup_newobj_in_statement(Statement0, Statement).
+
+:- pred fixup_newobj_in_atomic_statement(mlds__atomic_statement::in,
+ mlds__stmt::out, fixup_newobj_info::in,
+ fixup_newobj_info::out) is det.
+fixup_newobj_in_atomic_statement(AtomicStatement0, Stmt, Info0, Info) :-
+ (
+ AtomicStatement0 = new_object(Lval, MaybeTag, _HasSecTag,
+ PointerType, _MaybeSizeInWordsRval, _MaybeCtorName,
+ ArgRvals, _ArgTypes)
+ ->
+ %
+ % generate the declaration of the new local variable
+ %
+ % XXX Using array(generic_type) is wrong for
+ % --high-level-data.
+ %
+ % We need to specify an initializer to tell the
+ % C back-end what the length of the array is.
+ % We initialize it with null pointers and then
+ % later generate assignment statements to fill
+ % in the values properly (see below).
+ %
+ counter__allocate(Id, Info0 ^ next_id, NextId),
+ VarName = var_name("new_obj", yes(Id)),
+ VarType = mlds__array_type(mlds__generic_type),
+ NullPointers = list__duplicate(list__length(ArgRvals),
+ init_obj(const(mlds__null(mlds__generic_type)))),
+ Initializer = init_array(NullPointers),
+ % this is used for the type_infos allocated during tracing,
+ % and we don't need to trace them
+ MaybeGCTraceCode = no,
+ Context = Info0 ^ context,
+ VarDecl = ml_gen_mlds_var_decl(var(VarName),
+ VarType, Initializer, MaybeGCTraceCode, Context),
+ Info1 = Info0 ^ next_id := NextId,
+ Info = Info1 ^ locals := Info1 ^ locals ++ [VarDecl],
+ %
+ % Generate code to initialize the variable.
+ %
+ % Note that we need to use assignment statements,
+ % rather than an initializer, to initialize the
+ % local variable, because the initialization code
+ % needs to occur at exactly the point where the
+ % atomic_statement occurs, rather than at the
+ % local variable declaration.
+ %
+ VarLval = mlds__var(qual(Info ^ module_name, VarName),
+ VarType),
+ PtrRval = mlds__unop(cast(PointerType), mem_addr(VarLval)),
+ list__map_foldl(
+ init_field_n(PointerType, PtrRval, Context),
+ ArgRvals, ArgInitStatements, 0, _NumFields),
+ %
+ % generate code to assign the address of the new local
+ % variable to the Lval
+ %
+ TaggedPtrRval = maybe_tag_rval(MaybeTag, PointerType, PtrRval),
+ AssignStmt = atomic(assign(Lval, TaggedPtrRval)),
+ AssignStatement = mlds__statement(AssignStmt, Context),
+ Stmt = block([], ArgInitStatements ++ [AssignStatement])
+ ;
+ Stmt = atomic(AtomicStatement0),
+ Info = Info0
+ ).
+
+:- pred init_field_n(mlds__type::in, mlds__rval::in,
+ mlds__context::in, mlds__rval::in, mlds__statement::out,
+ int::in, int::out) is det.
+init_field_n(PointerType, PointerRval, Context, ArgRval, Statement,
+ FieldNum, FieldNum + 1) :-
+ FieldId = offset(const(int_const(FieldNum))),
+ % XXX FieldType is wrong for --high-level-data
+ FieldType = mlds__generic_type,
+ MaybeTag = yes(0),
+ Field = field(MaybeTag, PointerRval, FieldId, FieldType, PointerType),
+ AssignStmt = atomic(assign(Field, ArgRval)),
+ Statement = mlds__statement(AssignStmt, Context).
+
+:- func maybe_tag_rval(maybe(mlds__tag), mlds__type, mlds__rval) = mlds__rval.
+maybe_tag_rval(no, _Type, Rval) = Rval.
+maybe_tag_rval(yes(Tag), Type, Rval) = unop(cast(Type), mkword(Tag, Rval)).
%-----------------------------------------------------------------------------%
%
Index: compiler/ml_elim_nested.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/ml_elim_nested.m,v
retrieving revision 1.47
diff -u -d -r1.47 ml_elim_nested.m
--- compiler/ml_elim_nested.m 28 Jan 2002 05:30:23 -0000 1.47
+++ compiler/ml_elim_nested.m 1 Feb 2002 21:44:03 -0000
@@ -152,12 +152,16 @@
% XXX Accurate GC is still not yet fully implemented.
% TODO:
% - fix problem with undeclared local vars for some test cases
-% (e.g. tests/valid/agc_unbound_typevars*).
-% - fix problem with type classes & `constraint(...)' types
-% (the compiler goes into an infinite loop and runs out of
-% stack space for test cases using type classes)
+% (this seems to be due to the problems with higher-order code)
% - handle `pragma export'
% - support higher-order code: fix problems with tracing closures
+% (the MLDS back-end doesn't generate closure layouts)
+% and with tracing the wrapper functions generated for
+% higher-order code.
+% - support type classes: same issues as for higher-order code, I think
+% - support --nondet-copy-out (see comment in flatten_nested_defn)
+% - support --high-level-data (fixup_newobj_in_atomic_statement
+% gets the types wrong; see comment in ml_code_util.m)
%
% There are also some things that could be done to improve efficiency,
% e.g.
@@ -393,8 +397,10 @@
ml_elim_nested_defns(Action, ModuleName, Globals, OuterVars, Defn0)
= Defns :-
Defn0 = mlds__defn(Name, Context, Flags, DefnBody0),
- ( DefnBody0 = mlds__function(PredProcId, Params0,
- defined_here(FuncBody0), Attributes) ->
+ (
+ DefnBody0 = mlds__function(PredProcId, Params0,
+ defined_here(FuncBody0), Attributes)
+ ->
EnvName = ml_env_name(Name, Action),
EnvTypeName = ml_create_env_type_name(EnvName,
ModuleName, Globals),
@@ -408,15 +414,17 @@
% structure (e.g. because they occur in nested functions,
% or to make them visible to the garbage collector)
%
+ % Also, for accurate GC, add code to save and restore the
+ % stack chain pointer at any `try_commit' statements.
+ %
ElimInfo0 = elim_info_init(Action, ModuleName,
OuterVars, EnvTypeName, EnvPtrTypeName),
Params0 = mlds__func_params(Arguments0, RetValues),
ml_maybe_add_args(Arguments0, FuncBody0, ModuleName,
Context, ElimInfo0, ElimInfo1),
- flatten_arguments(Arguments0, Arguments, ElimInfo1, ElimInfo2),
+ flatten_arguments(Arguments0, Arguments1, ElimInfo1, ElimInfo2),
flatten_statement(FuncBody0, FuncBody1, ElimInfo2, ElimInfo),
elim_info_finish(ElimInfo, NestedFuncs0, Locals),
- Params = mlds__func_params(Arguments, RetValues),
%
% Split the locals that we need to process
@@ -496,7 +504,7 @@
% variables in the environment
% structure.
%
- ml_maybe_copy_args(Arguments, FuncBody0,
+ ml_maybe_copy_args(Arguments1, FuncBody0,
ElimInfo, EnvTypeName, EnvPtrTypeName,
Context, _ArgsToCopy, CodeToCopyArgs),
@@ -577,6 +585,20 @@
HoistedDefns = [EnvTypeDefn | HoistedDefns0]
)
),
+ (
+ Action = chain_gc_stack_frames,
+ % This pass will have put the GC tracing code for the
+ % arguments in the GC tracing function. So we don't
+ % need the GC tracing code annotation on the arguments
+ % anymore. We delete them here, because otherwise
+ % the `#if 0 ... #endif' blocks output for the
+ % annotations clutter up the generated C files.
+ Arguments = list__map(strip_gc_trace_code, Arguments1)
+ ;
+ Action = hoist_nested_funcs,
+ Arguments = Arguments1
+ ),
+ Params = mlds__func_params(Arguments, RetValues),
DefnBody = mlds__function(PredProcId, Params,
defined_here(FuncBody), Attributes),
Defn = mlds__defn(Name, Context, Flags, DefnBody),
@@ -586,6 +608,11 @@
Defns = [Defn0]
).
+:- func strip_gc_trace_code(mlds__argument) = mlds__argument.
+strip_gc_trace_code(Argument0) = Argument :-
+ Argument0 = mlds__argument(Name, Type, _MaybeGCTraceCode),
+ Argument = mlds__argument(Name, Type, no).
+
%
% Add any arguments which are used in nested functions
% to the local_data field in the elim_info.
@@ -848,7 +875,7 @@
%
PrevFieldName = data(var(var_name("prev", no))),
PrevFieldFlags = ml_gen_public_field_decl_flags,
- PrevFieldType = mlds__generic_env_ptr_type,
+ PrevFieldType = ml_stack_chain_type,
PrevFieldDefnBody = mlds__data(PrevFieldType,
no_initializer, no),
PrevFieldDecl = mlds__defn(PrevFieldName, Context,
@@ -1158,7 +1185,11 @@
mercury_private_builtin_module(PrivateBuiltin),
MLDS_Module = mercury_module_name_to_mlds(PrivateBuiltin),
StackChain = var(qual(MLDS_Module, var_name("stack_chain", no)),
- mlds__generic_env_ptr_type).
+ ml_stack_chain_type).
+
+ % the type of the `stack_chain' pointer, i.e. `void *'.
+:- func ml_stack_chain_type = mlds__type.
+ml_stack_chain_type = mlds__generic_env_ptr_type.
%-----------------------------------------------------------------------------%
%
@@ -1250,6 +1281,9 @@
% for every definition they contain (e.g. definitions of local
% variables and nested functions).
%
+% Also, for Action = chain_gc_stack_frames, add code to save and
+% restore the stack chain pointer at any `try_commit' statements.
+%
:- pred flatten_arguments(mlds__arguments, mlds__arguments,
elim_info, elim_info).
@@ -1353,9 +1387,32 @@
;
{ Stmt0 = try_commit(Ref0, Statement0, Handler0) },
fixup_lval(Ref0, Ref),
- flatten_statement(Statement0, Statement),
- flatten_statement(Handler0, Handler),
- { Stmt = try_commit(Ref, Statement, Handler) }
+ flatten_statement(Statement0, Statement1),
+ flatten_statement(Handler0, Handler1),
+ %
+ % add code to save/restore the stack chain pointer
+ %
+ Action =^ action,
+ ModuleName =^ module_name,
+ { Action = chain_gc_stack_frames ->
+ Statement1 = mlds__statement(_, StatementContext),
+ Handler1 = mlds__statement(_, HandlerContext),
+ Handler = mlds__statement(
+ block(
+ [],
+ [gen_restore_stack_chain_var(ModuleName,
+ HandlerContext),
+ Handler1]
+ ),
+ HandlerContext),
+ TryCommit = try_commit(Ref, Statement1, Handler),
+ Stmt = block(
+ [gen_saved_stack_chain_var(StatementContext)],
+ [mlds__statement(TryCommit, StatementContext)]
+ )
+ ;
+ Stmt = try_commit(Ref, Statement1, Handler1)
+ }
;
{ Stmt0 = atomic(AtomicStmt0) },
fixup_atomic_stmt(AtomicStmt0, AtomicStmt),
@@ -1411,7 +1468,41 @@
%
% recursively flatten the nested function
%
- flatten_function_body(FuncBody0, FuncBody),
+ flatten_function_body(FuncBody0, FuncBody1),
+
+ %
+ % for accurate GC,
+ % add a call to GC_check() at start of every
+ % nested function that might allocate memory
+ %
+ % (XXX we could perhaps reduce the overhead of
+ % this slightly by only doing it for
+ % possibly-recursive functions, i.e.
+ % by not doing it for leaf functions).
+ %
+ % XXX This won't work properly with --nondet-copy-out:
+ % we'd need to check out to come after
+ % we copy the arguments to the GC frame struct.
+ % In fact, do we even copy the arguments of
+ % nested functions to the GC frame struct?
+ %
+ {
+ FuncBody1 = defined_here(FuncBody2),
+ Action = chain_gc_stack_frames,
+ some [NewObjectStmt] (
+ statement_contains_statement(FuncBody2,
+ NewObjectStmt),
+ NewObjectStmt = mlds__statement(atomic(
+ new_object(_, _, _, _, _, _, _, _)
+ ), _)
+ )
+ ->
+ GC_Check = mlds__statement(atomic(gc_check), Context),
+ FuncBody = defined_here(mlds__statement(
+ block([], [GC_Check, FuncBody2]), Context))
+ ;
+ FuncBody = FuncBody1
+ },
%
% mark the function as private / one_copy,
@@ -2204,6 +2295,8 @@
%-----------------------------------------------------------------------------%
+% Add code to unlink the stack chain before any explicit returns or tail calls.
+
:- pred add_unchain_stack_to_maybe_statement(maybe(mlds__statement),
maybe(mlds__statement), elim_info, elim_info).
:- mode add_unchain_stack_to_maybe_statement(in, out, in, out) is det.
@@ -2347,6 +2440,34 @@
PrevFieldType, EnvPtrTypeName)),
Assignment = assign(StackChain, PrevFieldRval),
UnchainFrame = mlds__statement(atomic(Assignment), Context).
+
+ % Generate a local variable declaration
+ % to save the stack chain pointer:
+ % void *saved_stack_chain = stack_chain;
+:- func gen_saved_stack_chain_var(mlds__context) = mlds__defn.
+gen_saved_stack_chain_var(Context) = Defn :-
+ Name = data(var(ml_saved_stack_chain_name)),
+ Flags = ml_gen_local_var_decl_flags,
+ Type = ml_stack_chain_type,
+ Initializer = init_obj(lval(ml_stack_chain_var)),
+ % The saved stack chain never needs to be traced by the GC,
+ % since it will always point to the stack, not into the heap.
+ GCTraceCode = no,
+ DefnBody = mlds__data(Type, Initializer, GCTraceCode),
+ Defn = mlds__defn(Name, Context, Flags, DefnBody).
+
+ % Generate a statement to restore the stack chain pointer:
+ % stack_chain = saved_stack_chain;
+:- func gen_restore_stack_chain_var(mlds_module_name, mlds__context) =
+ mlds__statement.
+gen_restore_stack_chain_var(MLDS_Module, Context) = RestoreStatement :-
+ SavedStackChain = var(qual(MLDS_Module,
+ ml_saved_stack_chain_name), ml_stack_chain_type),
+ Assignment = assign(ml_stack_chain_var, lval(SavedStackChain)),
+ RestoreStatement = mlds__statement(atomic(Assignment), Context).
+
+:- func ml_saved_stack_chain_name = mlds__var_name.
+ml_saved_stack_chain_name = var_name("saved_stack_chain", no).
%-----------------------------------------------------------------------------%
Index: runtime/mercury_accurate_gc.c
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_accurate_gc.c,v
retrieving revision 1.13
diff -u -d -r1.13 mercury_accurate_gc.c
--- runtime/mercury_accurate_gc.c 28 Jan 2002 05:30:32 -0000 1.13
+++ runtime/mercury_accurate_gc.c 1 Feb 2002 21:03:59 -0000
@@ -156,9 +156,6 @@
#endif
- /* Reset the redzone on the old heap */
- MR_reset_redzone(old_heap);
-
#ifdef MR_DEBUG_AGC_COLLECTION
fprintf(stderr, "garbage_collect() done.\n\n");
#endif
@@ -168,10 +165,8 @@
traverse_stack(struct MR_StackChain *stack_chain)
{
/*
- ** The trace() routines may themselves allocate heap space.
- ** However, the space that they allocate is only used transiently.
- ** XXX We ought to therefore reset the heap pointer
- ** after each iteration of this loop.
+ ** The trace() routines themselves should not allocate heap space;
+ ** they should use stack allocation.
*/
while (stack_chain != NULL) {
(*stack_chain->trace)(stack_chain);
--
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