[m-rev.] accurate GC for type class methods
Fergus Henderson
fjh at cs.mu.OZ.AU
Wed Aug 20 22:32:42 AEST 2003
Estimated hours taken: 24
Branches: main
Implement accurate GC for type class methods.
Accurate GC now supports the whole Mercury language.
compiler/ml_closure_gen.m:
Generate GC tracing code for the type class method instance
wrapper functions whose addresses get stored in typeclass_infos.
This code generates a closure layout for the method instance
procedure, and then calls MR_materialize_closure_params(),
passing it the typeclass_info and the closure layout.
runtime/mercury_layout_util.h:
runtime/mercury_layout_util.c:
Add new routine MR_materialize_typeclass_info_params(), for use
by the code generated by ml_closure_gen.m.
This is similar to MR_materialize_closure_params() except that
it works on a typeclass_info rather than an MR_Closure.
compiler/rtti_to_mlds.m:
Update to reflect the changed interface to ml_gen_closure_wrapper.
compiler/ml_elim_nested.m:
Update the accurate GC TODO list.
compiler/options.m:
doc/user_guide.texi:
Document that accurate GC is now supported.
NEWS:
Mention that we now support accurate GC.
Workspace: /home/ceres/fjh/mercury
Index: NEWS
===================================================================
RCS file: /home/mercury1/repository/mercury/NEWS,v
retrieving revision 1.318
diff -u -d -r1.318 NEWS
--- NEWS 18 Aug 2003 11:35:28 -0000 1.318
+++ NEWS 20 Aug 2003 12:30:43 -0000
@@ -15,6 +15,8 @@
required to be defined in the same module as the type.
Changes to the Mercury compiler:
+* We have added optional support for a new type-accurate garbage collector
+ as an alternative to using the Boehm et al conservative collector.
* Better support for incremental program development:
there's two new compiler options, `--allow-stubs' and `--no-warn-stubs',
to support execution of incomplete programs.
@@ -198,6 +200,22 @@
* Nothing yet.
Changes to the Mercury compiler:
+
+* We have added optional support for a new type-accurate garbage collector
+ as an alternative to using the Boehm et al conservative collector.
+
+ The new collector is enabled by `--grade hlc.agc'.
+ For details about how it works, see the paper
+ "Accurate garbage collection in an uncooperative environment"
+ which is available via our web page.
+
+ Note that the new collector is a very naive copying collector, and still
+ has a number of serious limitations which may make it undesirable for
+ most applications. It only works with `--high-level-code'. The heap
+ size is fixed at program startup; the collector does not attempt to
+ resize the heap. It does not do cheap heap reclamation on backtracking.
+ There is no support for passing terms on the Mercury heap to C code.
+ In most cases, the Boehm et all conservative collector will perform better.
* There's a new warning option `--warn-dead-procs' which can be used
for detecting unreachable code.
Index: compiler/ml_closure_gen.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/ml_closure_gen.m,v
retrieving revision 1.18
diff -u -d -r1.18 ml_closure_gen.m
--- compiler/ml_closure_gen.m 26 May 2003 09:00:01 -0000 1.18
+++ compiler/ml_closure_gen.m 20 Aug 2003 11:49:57 -0000
@@ -48,17 +48,22 @@
% field in the ml_gen_info, and return the wrapper function's
% rval and type.
%
+ % The ClosureKind parameter specifies whether the closure is
+ % an ordinary closure, used for higher-order procedure calls,
+ % or a typeclass_info, used for class method calls.
% The NumClosuresArgs parameter specifies how many arguments
- % to extract from the closure. The Offset parameter specifies
- % the offset to add to the argument number to get the field
- % number within the closure. (Argument numbers start from 1,
- % and field numbers start from 0.)
+ % to extract from the closure.
%
-:- pred ml_gen_closure_wrapper(pred_id, proc_id, int, int, prog_context,
- mlds__rval, mlds__type, ml_gen_info, ml_gen_info).
+:- pred ml_gen_closure_wrapper(pred_id, proc_id, closure_kind, int,
+ prog_context, mlds__rval, mlds__type,
+ ml_gen_info, ml_gen_info).
:- mode ml_gen_closure_wrapper(in, in, in, in, in, out, out,
in, out) is det.
+:- type closure_kind
+ ---> higher_order_proc_closure
+ ; typeclass_info_closure.
+
% ml_gen_local_for_output_arg(VarName, Type, ArgNum, Context,
% LocalVarDefn):
% Generate a declaration for a local variable with the specified
@@ -137,10 +142,9 @@
% it and will insert it before the mlds__defn for the current
% procedure.
%
- { Offset = ml_closure_arg_offset },
{ list__length(ArgVars, NumArgs) },
- ml_gen_closure_wrapper(PredId, ProcId, Offset, NumArgs,
- Context, WrapperFuncRval0, WrapperFuncType0),
+ ml_gen_closure_wrapper(PredId, ProcId, higher_order_proc_closure,
+ NumArgs, Context, WrapperFuncRval0, WrapperFuncType0),
%
% Compute the rval which holds the number of arguments
@@ -588,12 +592,24 @@
% void *closure;
% #endif
%
- % #ifdef MR_NATIVE_GC
+ % #if defined(MR_NATIVE_GC)
+ % MR_Closure_Layout *closure_layout_ptr;
% MR_TypeInfo *type_params;
% #if 0 /* GC tracing code */
+ % #if CLOSURE_KIND == HIGHER_ORDER_PROC_CLOSURE
+ % closure_layout_ptr =
+ % ((MR_Closure *)closure_arg)->MR_closure_layout;
% type_params =
% MR_materialize_closure_typeinfos(closure_arg);
- % #endif
+ % #else /* CLOSURE_KIND == TYPECLASS_INFO_CLOSURE */
+ % {
+ % static const MR_Closure_Layout closure_layout = ...;
+ % closure_layout_ptr = &closure_layout;
+ % }
+ % type_params =
+ % MR_materialize_closure_typeinfos(closure_arg);
+ % #endif
+ % #endif /* GC tracing code */
% #endif
%
% /* declarations needed for converting output args */
@@ -603,18 +619,19 @@
%
% /* declarations needed for by-value outputs */
% RetType conv_retval;
- % #ifdef MR_NATIVE_GC
+ % #if defined(MR_NATIVE_GC)
% #if 0 /* GC tracing code */
% {
% MR_TypeInfo type_info;
% 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> - 1],
+ % closure_layout_ptr->MR_closure_arg_pseudo_type_info
+ % [<arg number> - 1],
% NULL, NULL, &allocated_memory_cells);
% mercury__private_builtin__gc_trace_1_0(type_info, &conv_retval);
% MR_deallocate(allocated_memory_cells);
% }
+ % #endif
% #endif
% #endif
%
@@ -685,7 +702,7 @@
% foo_1);
% #endif
%
-ml_gen_closure_wrapper(PredId, ProcId, Offset, NumClosureArgs,
+ml_gen_closure_wrapper(PredId, ProcId, ClosureKind, NumClosureArgs,
Context, WrapperFuncRval, WrapperFuncType) -->
%
% grab the relevant information about the called procedure
@@ -694,8 +711,8 @@
{ ml_gen_info_get_module_info(Info, ModuleInfo) },
{ module_info_pred_proc_info(ModuleInfo, PredId, ProcId,
PredInfo, ProcInfo) },
- { pred_info_get_purity(PredInfo, Purity) },
- { pred_info_arg_types(PredInfo, ProcArgTypes) },
+ %{ pred_info_purity(PredInfo, Purity) },
+ %{ pred_info_arg_types(PredInfo, ProcArgTypes) },
{ pred_info_get_is_pred_or_func(PredInfo, PredOrFunc) },
{ proc_info_headvars(ProcInfo, ProcHeadVars) },
{ proc_info_argmodes(ProcInfo, ProcArgModes) },
@@ -721,13 +738,13 @@
{
list__drop(NumClosureArgs, ProcHeadVars, WrapperHeadVars0),
list__drop(NumClosureArgs, ProcArgModes, WrapperArgModes0),
- list__drop(NumClosureArgs, ProcArgTypes, WrapperArgTypes0),
+ %list__drop(NumClosureArgs, ProcArgTypes, WrapperArgTypes0),
list__drop(NumClosureArgs, ProcBoxedArgTypes,
WrapperBoxedArgTypes0)
->
WrapperHeadVars = WrapperHeadVars0,
WrapperArgModes = WrapperArgModes0,
- WrapperArgTypes = WrapperArgTypes0,
+ %WrapperArgTypes = WrapperArgTypes0,
WrapperBoxedArgTypes = WrapperBoxedArgTypes0
;
unexpected(this_file,
@@ -752,20 +769,23 @@
% then insert the `closure_arg' parameter
{ ClosureArgType = mlds__generic_type },
- { ClosureArgDeclType = list__det_head(ml_make_boxed_types(1)) },
- { ClosureArgName = var_name("closure_arg", no) },
- % We can't use WrapperArgTypes here,
- % because we don't have type_infos for the type variables in
- % WrapperArgTypes; those type variables come from the callee.
- % But when copying closures, we don't care what the types of the
- % not-yet-applied arguments are. So we can just use dummy values here.
- { HigherOrderArgTypes = list__duplicate(list__length(WrapperArgTypes),
- c_pointer_type) },
- { LambdaEvalMethod = normal },
- { construct_higher_order_type(Purity, PredOrFunc, LambdaEvalMethod,
- HigherOrderArgTypes, ClosureActualType) },
- ml_gen_maybe_gc_trace_code(ClosureArgName, ClosureArgDeclType,
- ClosureActualType, Context, ClosureArgGCTraceCode),
+ { ClosureArgName = mlds__var_name("closure_arg", no) },
+ % If we were to generate GC tracing code for the closure arg,
+ % it would look like this:
+ % { ClosureArgDeclType = list__det_head(ml_make_boxed_types(1)) },
+ % { gen_closure_gc_trace_code(ClosureArgName, ClosureArgDeclType,
+ % ClosureKind, WrapperArgTypes, Purity, PredOrFunc,
+ % ClosureArgGCTraceCode) },
+ % But we don't need any GC tracing code for the closure arg,
+ % because it won't be live across an allocation.
+ % However, we do need to give it a yes(_) GC tracing code,
+ % because it is referred to from other GC tracing code;
+ % without this, ml_elim_nested.m won't put it into the GC stack frame
+ % struct, and then those other references will be dangling.
+ % (XXX Maybe ml_elim_nested should be smarter about that.)
+ { MLDS_Context = mlds__make_context(Context) },
+ { ClosureArgGCTraceCode = yes(mlds__statement(block([],[]),
+ MLDS_Context)) },
{ ClosureArg = mlds__argument(
data(var(ClosureArgName)),
ClosureArgType,
@@ -793,14 +813,14 @@
% closure = closure_arg;
%
{ ClosureName = mlds__var_name("closure", no) },
- { ClosureArgName = mlds__var_name("closure_arg", no) },
{ ClosureType = mlds__generic_type },
- { ClosureDeclType = list__det_head(ml_make_boxed_types(1)) },
% The GC tracing code for `closure' is essentially the same as
- % for `closure_arg' (see above)
- ml_gen_maybe_gc_trace_code(ClosureName, ClosureDeclType,
- ClosureActualType, Context, ClosureGCTraceCode),
- { MLDS_Context = mlds__make_context(Context) },
+ % for `closure_arg' (see above).
+ % { ClosureDeclType = list__det_head(ml_make_boxed_types(1)) },
+ % { gen_closure_gc_trace_code(ClosureName, ClosureDeclType,
+ % ClosureKind, WrapperArgTypes, ClosureGCTraceCode) },
+ { ClosureGCTraceCode = yes(mlds__statement(block([],[]),
+ MLDS_Context)) },
{ ClosureDecl = ml_gen_mlds_var_decl(var(ClosureName),
ClosureType, ClosureGCTraceCode, MLDS_Context) },
ml_gen_var_lval(ClosureName, ClosureType, ClosureLval),
@@ -834,7 +854,7 @@
[]
),
- % prepare to generate code to call the function:
+ % generate code to call the function:
% XXX currently we're using a low-level data representation
% in the closure
%
@@ -849,6 +869,16 @@
% unbox(wrapper_arg1), &conv_arg2, wrapper_arg3, ...
% );
%
+ % `Offset' specifies the offset to add to the argument number to
+ % get the field number within the closure. (Argument numbers start
+ % from 1, and field numbers start from 0.)
+ {
+ ClosureKind = higher_order_proc_closure,
+ Offset = ml_closure_arg_offset
+ ;
+ ClosureKind = typeclass_info_closure,
+ Offset = ml_typeclass_info_arg_offset
+ },
ml_gen_closure_field_lvals(ClosureLval, Offset, 1, NumClosureArgs,
ClosureArgLvals),
{ CallLvals = list__append(ClosureArgLvals, WrapperHeadVarLvals) },
@@ -880,8 +910,8 @@
%
{ module_info_globals(ModuleInfo, Globals) },
( { globals__get_gc_method(Globals, accurate) } ->
- ml_gen_closure_wrapper_gc_decls(ClosureArgName,
- ClosureArgType, MLDS_Context, GC_Decls)
+ ml_gen_closure_wrapper_gc_decls(ClosureKind, ClosureArgName,
+ ClosureArgType, PredId, ProcId, Context, GC_Decls)
;
{ GC_Decls = [] }
),
@@ -919,6 +949,36 @@
Argument0 = mlds__argument(Name, Type, _GCTraceCode),
Argument = mlds__argument(Name, Type, no).
+ % generate the GC tracing code for `closure_arg' or `closure'
+ % (see ml_gen_closure_wrapper above).
+:- pred gen_closure_gc_trace_code(mlds__var_name, prog_type, closure_kind,
+ list(mlds__type), purity, pred_or_func, prog_context,
+ mlds__maybe_gc_trace_code, ml_gen_info, ml_gen_info) is det.
+:- mode gen_closure_gc_trace_code(in, in, in, in, in, in, in, out, in, out)
+ is det.
+gen_closure_gc_trace_code(ClosureName, ClosureDeclType,
+ ClosureKind, WrapperArgTypes, Purity, PredOrFunc,
+ Context, ClosureGCTraceCode) -->
+ % We can't use WrapperArgTypes here,
+ % because we don't have type_infos for the type variables in
+ % WrapperArgTypes; those type variables come from the callee.
+ % But when copying closures, we don't care what the types of the
+ % not-yet-applied arguments are. So we can just use dummy values here.
+ { HigherOrderArgTypes = list__duplicate(list__length(WrapperArgTypes),
+ c_pointer_type) },
+ (
+ { ClosureKind = higher_order_proc_closure },
+ { LambdaEvalMethod = normal },
+ { construct_higher_order_type(Purity, PredOrFunc,
+ LambdaEvalMethod, HigherOrderArgTypes,
+ ClosureActualType) }
+ ;
+ { ClosureKind = typeclass_info_closure },
+ { ClosureActualType = sample_typeclass_info_type }
+ ),
+ ml_gen_maybe_gc_trace_code(ClosureName, ClosureDeclType,
+ ClosureActualType, Context, ClosureGCTraceCode).
+
:- 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.
@@ -1035,34 +1095,97 @@
).
% This is used for accurate GC with the MLDS->C back-end.
- % It generates the following variable declaration:
+ % It generates the following variable declarations:
+ % MR_Closure_Layout *closure_layout_ptr;
% MR_TypeInfo *type_params;
- % and code to initialize it
+ % and code to initialize them: either
+ % closure_layout_ptr =
+ % ((MR_Closure *)closure_arg)->MR_closure_layout;
% type_params = MR_materialize_closure_typeinfos(closure_arg);
-:- pred ml_gen_closure_wrapper_gc_decls(mlds__var_name, mlds__type,
- mlds__context, mlds__defns, ml_gen_info, ml_gen_info).
-:- mode ml_gen_closure_wrapper_gc_decls(in, in, in, out, in, out) is det.
+ % or
+ % {
+ % static const MR_Closure_Layout closure_layout = { ... }
+ % closure_layout_ptr = &closure_layout;
+ % }
+ % type_params = MR_materialize_typeclass_info_typeinfos(
+ % closure_arg, closure_layout);
+ %
+:- pred ml_gen_closure_wrapper_gc_decls(closure_kind, mlds__var_name,
+ mlds__type, pred_id, proc_id, prog_context, mlds__defns,
+ ml_gen_info, ml_gen_info).
+:- mode ml_gen_closure_wrapper_gc_decls(in, in, in, in, in, in, out, in, out)
+ is det.
+
+ml_gen_closure_wrapper_gc_decls(ClosureKind, ClosureArgName, ClosureArgType,
+ PredId, ProcId, Context, GC_Decls) -->
+ { MLDS_Context = mlds__make_context(Context) },
-ml_gen_closure_wrapper_gc_decls(ClosureArgName, ClosureArgType, Context,
- GC_Decls) -->
ml_gen_var_lval(ClosureArgName, ClosureArgType, ClosureArgLval),
+
+ { ClosureLayoutPtrName = var_name("closure_layout_ptr", no) },
+ % This type is really `const MR_Closure_Layout *', but there's no easy
+ % way to represent that in the MLDS; using MR_Box instead works fine.
+ { ClosureLayoutPtrType = mlds__generic_type },
+ { ClosureLayoutPtrDecl = ml_gen_mlds_var_decl(var(ClosureLayoutPtrName),
+ ClosureLayoutPtrType, yes(ClosureLayoutPtrGCInit),
+ MLDS_Context) },
+ ml_gen_var_lval(ClosureLayoutPtrName, ClosureLayoutPtrType,
+ ClosureLayoutPtrLval),
+
{ TypeParamsName = var_name("type_params", no) },
% This type is really MR_TypeInfoParams, but there's no easy way to
% represent that in the MLDS; using MR_Box instead works fine.
{ TypeParamsType = mlds__generic_type },
{ TypeParamsDecl = ml_gen_mlds_var_decl(var(TypeParamsName),
- TypeParamsType, yes(GC_Init), Context) },
+ TypeParamsType, yes(TypeParamsGCInit), MLDS_Context) },
ml_gen_var_lval(TypeParamsName, TypeParamsType, TypeParamsLval),
- { GC_Decls = [TypeParamsDecl] },
- { GC_Init = mlds__statement(atomic(inline_target_code(lang_C, [
- % MR_TypeInfo *type_params =
- % MR_materialize_closure_typeinfos(closure);
- target_code_output(TypeParamsLval),
- raw_target_code(
- " = (MR_Box) MR_materialize_closure_type_params(\n", []),
- target_code_input(lval(ClosureArgLval)),
- raw_target_code(");\n", [])
- ])), Context) }.
+
+ (
+ { ClosureKind = higher_order_proc_closure },
+ { ClosureLayoutPtrGCInitFragments = [
+ target_code_output(ClosureLayoutPtrLval),
+ raw_target_code(" = (MR_Box) ((MR_Closure *)\n", []),
+ target_code_input(lval(ClosureArgLval)),
+ raw_target_code("->MR_closure_layout);\n", [])
+ ] },
+ { ClosureLayoutPtrGCInit = mlds__statement(atomic(
+ inline_target_code(lang_C,
+ ClosureLayoutPtrGCInitFragments)), MLDS_Context) },
+ { TypeParamsGCInitFragments = [
+ target_code_output(TypeParamsLval),
+ raw_target_code(" = (MR_Box) " ++
+ "MR_materialize_closure_type_params(\n", []),
+ target_code_input(lval(ClosureArgLval)),
+ raw_target_code(");\n", [])
+ ] }
+ ;
+ { ClosureKind = typeclass_info_closure },
+ ml_gen_closure_layout(PredId, ProcId, Context,
+ ClosureLayoutRval, ClosureLayoutType,
+ ClosureLayoutDefns),
+ { ClosureLayoutPtrGCInit = mlds__statement(
+ mlds__block(
+ ClosureLayoutDefns,
+ [mlds__statement(atomic(
+ assign(ClosureLayoutPtrLval,
+ unop(box(ClosureLayoutType),
+ ClosureLayoutRval)
+ )), MLDS_Context)]
+ ), MLDS_Context) },
+ { TypeParamsGCInitFragments = [
+ target_code_output(TypeParamsLval),
+ raw_target_code(" = (MR_Box) " ++
+ "MR_materialize_typeclass_info_type_params(\n" ++
+ "(MR_Word) ", []),
+ target_code_input(lval(ClosureArgLval)),
+ raw_target_code(", (MR_Closure_Layout *) ", []),
+ target_code_input(lval(ClosureLayoutPtrLval)),
+ raw_target_code(");\n", [])
+ ] }
+ ),
+ { TypeParamsGCInit = mlds__statement(atomic(inline_target_code(
+ lang_C, TypeParamsGCInitFragments)), MLDS_Context) },
+ { GC_Decls = [ClosureLayoutPtrDecl, TypeParamsDecl] }.
ml_gen_local_for_output_arg(VarName, Type, ArgNum, Context, LocalVarDefn) -->
%
@@ -1083,16 +1206,19 @@
%
{ MLDS_Context = mlds__make_context(Context) },
+ { ClosureLayoutPtrName = var_name("closure_layout_ptr", no) },
+ % This type is really `const MR_Closure_Layout *', but there's no easy
+ % way to represent that in the MLDS; using MR_Box instead works fine.
+ { ClosureLayoutPtrType = mlds__generic_type },
+ ml_gen_var_lval(ClosureLayoutPtrName, ClosureLayoutPtrType,
+ ClosureLayoutPtrLval),
+
{ TypeParamsName = var_name("type_params", no) },
% This type is really MR_TypeInfoParams, but there's no easy way to
% represent that in the MLDS; using MR_Box instead works fine.
{ TypeParamsType = mlds__generic_type },
ml_gen_var_lval(TypeParamsName, TypeParamsType, TypeParamsLval),
- { ClosureArgName = var_name("closure_arg", no) },
- { ClosureArgType = mlds__generic_type },
- ml_gen_var_lval(ClosureArgName, ClosureArgType, ClosureArgLval),
-
{ TypeInfoName = var_name("type_info", no) },
% the type for this should match the type of the first argument
% of private_builtin__gc_trace/1, i.e. `mutvar(T)', which is
@@ -1119,10 +1245,9 @@
" = (MR_C_Pointer) " ++
"MR_make_type_info_maybe_existq(\n\t", []),
target_code_input(lval(TypeParamsLval)),
- raw_target_code(", ((MR_Closure *)\n\t", []),
- target_code_input(lval(ClosureArgLval)),
- raw_target_code(string__format(
- ")->MR_closure_layout->" ++
+ raw_target_code(", ((MR_Closure_Layout *)\n\t", []),
+ target_code_input(lval(ClosureLayoutPtrLval)),
+ raw_target_code(string__format(")->" ++
"MR_closure_arg_pseudo_type_info[%d - 1],\n\t" ++
"NULL, NULL, &allocated_mem);\n",
[i(ArgNum)]), [])
Index: compiler/ml_elim_nested.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/ml_elim_nested.m,v
retrieving revision 1.62
diff -u -d -r1.62 ml_elim_nested.m
--- compiler/ml_elim_nested.m 28 Mar 2003 06:42:48 -0000 1.62
+++ compiler/ml_elim_nested.m 20 Aug 2003 12:00:25 -0000
@@ -154,13 +154,15 @@
% "Accurate garbage collection in an uncooperative environment".
% International Symposium on Memory Management, Berlin, Germany, 2002.
%
-% XXX Accurate GC is still not yet fully implemented.
+% In theory accurate GC is now fully implemented,
+% i.e. it should support the whole Mercury language,
+% modulo the caveats below.
% TODO:
-% - Support type classes: currently we generate code for type class
-% method wrappers which calls MR_materialize_closure_type_params(),
-% which only works for closures, not for typeclass_infos.
+% - XXX Need to test the GC tracing code for type class methods.
+% This code in theory ought to work, I think, but it has not
+% really been tested.
%
-% - The garbage collector should resize the heap if/when it fills up.
+% - XXX The garbage collector should resize the heap if/when it fills up.
% We should allocate a large amount of virtual memory for each heap,
% but we should collect when we've allocated a small part of it.
%
@@ -203,7 +205,7 @@
% and MR_deep_copy() needs to call MR_GC_check() before each
% heap allocation.
%
-% - We need to handle `pragma export'.
+% - XXX We need to handle `pragma export'.
%
% The C interface in general is a bit problematic for GC.
% But for code which does not call back to Mercury,
@@ -223,7 +225,7 @@
% But if Mercury code calls C code which calls back to Mercury
% code, and the C code uses pointers to the Mercury heap,
% then there could be serious problems (i.e. dangling pointers).
-% Even you just use `pragma export' to export a procedure
+% Even if you just use `pragma export' to export a procedure
% and `pragma import' to import it back again, there may be
% trouble.
% The code generated for the exported functions can include
Index: compiler/options.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/options.m,v
retrieving revision 1.416
diff -u -d -r1.416 options.m
--- compiler/options.m 6 Aug 2003 12:38:11 -0000 1.416
+++ compiler/options.m 20 Aug 2003 12:15:10 -0000
@@ -3061,9 +3061,11 @@
"\t\t\t\t`.mps' grades use `--gc mps',",
"\t\t\t\tother grades use `--gc none'.)",
"\tSpecify which method of garbage collection to use",
- "\t(default: boehm). `accurate' GC is not yet supported.",
+ "\t(default: boehm).",
"\t`conservative' or `boehm' is Hans Boehm et al's conservative",
"\tcollector.",
+ "\t`accurate' is our own type-accurate copying GC;",
+ "\tit requires `--high-level-code'.",
"\t`mps' is a different conservative collector, based on",
"\tRavenbrook Limited's MPS (Memory Pool System) kit.",
"\tThis option is ignored for the IL and Java back-ends,",
Index: compiler/rtti_to_mlds.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/rtti_to_mlds.m,v
retrieving revision 1.40
diff -u -d -r1.40 rtti_to_mlds.m
--- compiler/rtti_to_mlds.m 14 May 2003 00:10:03 -0000 1.40
+++ compiler/rtti_to_mlds.m 20 Aug 2003 08:08:54 -0000
@@ -1007,10 +1007,9 @@
%
% Now we can safely go ahead and generate the wrapper function
%
- Offset = ml_typeclass_info_arg_offset,
term__context_init(Context),
- ml_gen_closure_wrapper(PredId, ProcId, Offset, NumExtra,
- Context, WrapperFuncRval, WrapperFuncType,
+ ml_gen_closure_wrapper(PredId, ProcId, typeclass_info_closure,
+ NumExtra, Context, WrapperFuncRval, WrapperFuncType,
MLGenInfo1, MLGenInfo),
ml_gen_info_get_extra_defns(MLGenInfo, ExtraDefns1),
ExtraDefns = list__append(ExtraDefns1, ExtraDefns0),
Index: doc/user_guide.texi
===================================================================
RCS file: /home/mercury1/repository/mercury/doc/user_guide.texi,v
retrieving revision 1.374
diff -u -d -r1.374 user_guide.texi
--- doc/user_guide.texi 6 Aug 2003 12:38:13 -0000 1.374
+++ doc/user_guide.texi 20 Aug 2003 12:17:01 -0000
@@ -5390,9 +5390,10 @@
Grades containing @samp{.gc} use @samp{--gc boehm},
grades containing @samp{.mps} use @samp{--gc mps},
other grades use @samp{--gc none}.
- at samp{accurate} is not yet implemented.
@samp{conservative} or @samp{boehm} is Hans Boehm et al's conservative
garbage collector.
+ at samp{accurate} is our own type-accurate copying collector.
+It requires @samp{--high-level-code}.
@samp{mps} is another conservative collector based on Ravenbrook Limited's
MPS (Memory Pool System) kit.
This option is ignored by the IL and Java back-ends, which always use
Index: runtime/mercury_layout_util.c
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_layout_util.c,v
retrieving revision 1.30
diff -u -d -r1.30 mercury_layout_util.c
--- runtime/mercury_layout_util.c 2 Apr 2003 23:01:39 -0000 1.30
+++ runtime/mercury_layout_util.c 20 Aug 2003 10:14:32 -0000
@@ -17,6 +17,8 @@
static MR_Word MR_lookup_closure_long_lval(MR_Long_Lval locn,
MR_Closure *closure, MR_bool *succeeded);
+static MR_Word MR_lookup_typeclass_info_long_lval(MR_Long_Lval locn,
+ MR_Word typeclass_info, MR_bool *succeeded);
static MR_Word MR_lookup_answer_block_long_lval(MR_Long_Lval locn,
MR_Word *answer_block, int block_size, MR_bool *succeeded);
@@ -154,6 +156,44 @@
}
MR_TypeInfoParams
+MR_materialize_typeclass_info_params(MR_Word typeclass_info,
+ MR_Closure_Layout *closure_layout)
+{
+ const MR_Type_Param_Locns *tvar_locns;
+
+ tvar_locns = closure_layout->MR_closure_type_params;
+ if (tvar_locns != NULL) {
+ MR_TypeInfoParams type_params;
+ MR_bool succeeded;
+ MR_Integer count;
+ int i;
+
+ count = tvar_locns->MR_tp_param_count;
+ type_params = (MR_TypeInfoParams)
+ MR_NEW_ARRAY(MR_Word, count + 1);
+
+ for (i = 0; i < count; i++) {
+ if (tvar_locns->MR_tp_param_locns[i] != 0)
+ {
+ type_params[i + 1] = (MR_TypeInfo)
+ MR_lookup_typeclass_info_long_lval(
+ tvar_locns->
+ MR_tp_param_locns[i],
+ typeclass_info, &succeeded);
+ if (! succeeded) {
+ MR_fatal_error("missing type param in "
+ "MR_materialize_typeclass_info_type_params");
+ }
+ }
+ }
+
+ return type_params;
+ } else {
+ return NULL;
+ }
+}
+
+MR_TypeInfoParams
MR_materialize_answer_block_type_params(const MR_Type_Param_Locns *tvar_locns,
MR_Word *answer_block, int block_size)
{
@@ -321,6 +361,114 @@
default:
if (MR_print_locn) {
printf("closure DEFAULT\n");
+ }
+ break;
+ }
+
+ return value;
+}
+
+static MR_Word
+MR_lookup_typeclass_info_long_lval(MR_Long_Lval locn, MR_Word typeclass_info,
+ MR_bool *succeeded)
+{
+ int locn_num;
+ int offset;
+ MR_Word value;
+ MR_Word baseaddr;
+ MR_Word sublocn;
+
+ *succeeded = MR_FALSE;
+ value = 0;
+
+ locn_num = (int) MR_LONG_LVAL_NUMBER(locn);
+ switch (MR_LONG_LVAL_TYPE(locn)) {
+ case MR_LONG_LVAL_TYPE_R:
+ if (MR_print_locn) {
+ printf("typeclassinfo r%d\n", locn_num);
+ }
+ if (locn_num <=
+ MR_typeclass_info_num_extra_instance_args(
+ typeclass_info))
+ {
+ value = MR_typeclass_info_arg_typeclass_info(
+ typeclass_info, locn_num);
+ *succeeded = MR_TRUE;
+ }
+ break;
+
+ case MR_LONG_LVAL_TYPE_F:
+ if (MR_print_locn) {
+ printf("typeclassinfo f%d\n", locn_num);
+ }
+ break;
+
+ case MR_LONG_LVAL_TYPE_STACKVAR:
+ if (MR_print_locn) {
+ printf("typeclassinfo stackvar%d\n", locn_num);
+ }
+ break;
+
+ case MR_LONG_LVAL_TYPE_FRAMEVAR:
+ if (MR_print_locn) {
+ printf("typeclassinfo framevar%d\n", locn_num);
+ }
+ break;
+
+ case MR_LONG_LVAL_TYPE_SUCCIP:
+ if (MR_print_locn) {
+ printf("typeclassinfo succip\n");
+ }
+ break;
+
+ case MR_LONG_LVAL_TYPE_MAXFR:
+ if (MR_print_locn) {
+ printf("typeclassinfo maxfr\n");
+ }
+ break;
+
+ case MR_LONG_LVAL_TYPE_CURFR:
+ if (MR_print_locn) {
+ printf("typeclassinfo curfr\n");
+ }
+ break;
+
+ case MR_LONG_LVAL_TYPE_HP:
+ if (MR_print_locn) {
+ printf("typeclassinfo hp\n");
+ }
+ break;
+
+ case MR_LONG_LVAL_TYPE_SP:
+ if (MR_print_locn) {
+ printf("typeclassinfo sp\n");
+ }
+ break;
+
+ case MR_LONG_LVAL_TYPE_INDIRECT:
+ offset = MR_LONG_LVAL_INDIRECT_OFFSET(locn_num);
+ sublocn = MR_LONG_LVAL_INDIRECT_BASE_LVAL(locn_num);
+ if (MR_print_locn) {
+ printf("typeclassinfo offset %d from ", offset);
+ }
+ baseaddr = MR_lookup_typeclass_info_long_lval(sublocn,
+ typeclass_info, succeeded);
+ if (! *succeeded) {
+ break;
+ }
+ value = MR_typeclass_info_type_info(baseaddr, offset);
+ *succeeded = MR_TRUE;
+ break;
+
+ case MR_LONG_LVAL_TYPE_UNKNOWN:
+ if (MR_print_locn) {
+ printf("typeclassinfo unknown\n");
+ }
+ break;
+
+ default:
+ if (MR_print_locn) {
+ printf("typeclassinfo DEFAULT\n");
}
break;
}
Index: runtime/mercury_layout_util.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_layout_util.h,v
retrieving revision 1.21
diff -u -d -r1.21 mercury_layout_util.h
--- runtime/mercury_layout_util.h 2 Apr 2003 23:01:39 -0000 1.21
+++ runtime/mercury_layout_util.h 20 Aug 2003 10:13:05 -0000
@@ -52,6 +52,11 @@
** it takes an MR_Closure rather than an MR_Label_Layout,
** and it gets the type_infos from a closure using the closure_layout,
** rather than getting them from the registers/stacks using a label_layout.
+**
+** MR_materialize_typeclass_info_type_params is the same as
+** MR_materialize_closure_type_params except that it takes
+** a typeclass_info and a closure layout (for the type class method)
+** and it gets the type_infos from the typeclass_info.
*/
extern MR_TypeInfoParams MR_materialize_type_params(
@@ -63,6 +68,9 @@
MR_Word *base_sp, MR_Word *base_curfr);
extern MR_TypeInfoParams MR_materialize_closure_type_params(
MR_Closure *closure);
+extern MR_TypeInfoParams MR_materialize_typeclass_info_type_params(
+ MR_Word typeclass_info,
+ MR_Closure_Layout *closure_layout);
extern MR_TypeInfoParams MR_materialize_answer_block_type_params(
const MR_Type_Param_Locns *tvar_locns,
MR_Word *answer_block, int block_size);
--
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