[m-rev.] diff: hlc.agc: call MR_GC_check() at allocations

Fergus Henderson fjh at cs.mu.OZ.AU
Tue Feb 12 03:12:55 AEDT 2002


Estimated hours taken: 1
Branches: main

For accurate GC with the MLDS->C back-end, check for heap exhaustion at
every allocation, rather than at the start of every function.
This avoids a risk of heap overflow when returning from a
deeply nested call stack (e.g. naive reverse on a long list).

The average impact of this change on performance seems to be small --
less than 1% slowdown for tests/benchmarks overall -- although for
tests/benchmarks/poly.m the slowdown was 7%.  But correctness should
come before performance...

compiler/ml_elim_nested.m:
	Delete code to insert gc_check statements at the start of each
	function.

compiler/mlds_to_c.m:
	Add a call to MR_GC_Check() before every new_object statement.

Workspace: /home/earth/fjh/ws-earth4/mercury
Index: compiler/ml_elim_nested.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/ml_elim_nested.m,v
retrieving revision 1.52
diff -u -d -r1.52 ml_elim_nested.m
--- compiler/ml_elim_nested.m	11 Feb 2002 09:00:21 -0000	1.52
+++ compiler/ml_elim_nested.m	11 Feb 2002 16:07:19 -0000
@@ -149,6 +149,11 @@
 % and chain these structs together.  At GC time, we traverse the chain
 % of structs.  This allows us to accurately scan the C stack.
 %
+% This is described in more detail in the following paper:
+%	Fergus Henderson <fjh at cs.mu.oz.au>,
+%	"Accurate garbage collection in an uncooperative environment".
+%	Submitted for publication.  Available from the author on request.
+%
 % XXX Accurate GC is still not yet fully implemented.
 % TODO:
 %	- fix problem with undeclared local vars for some test cases
@@ -216,6 +221,12 @@
 % efficient and thread-safe.
 % XXX Currently, for simplicity, we're using a global variable.
 %
+% At each allocation, we do a call to MR_GC_check(),
+% which checks for heap exhaustion, and if necessary
+% calls MR_garbage_collect() in runtime/mercury_accurate_gc.c
+% to do the collection.  The calls to MR_GC_check() are
+% inserted by compiler/mlds_to_c.m.
+%
 % As an optimization, we ought to not bother allocating a struct for
 % functions that don't have any variables that might contain pointers.
 % We also ought to not bother allocating a struct for leaf functions that
@@ -277,8 +288,6 @@
 %		this_frame.local1 = NULL;
 %		stack_chain = &this_frame;
 %
-%		GC_check();
-%		
 %		...
 %		this_frame.local1 = MR_new_object(...);
 %		...
@@ -303,8 +312,6 @@
 %		this_frame.arg1 = arg1;
 %		this_frame.local1 = NULL;
 %
-%		GC_check();
-%		
 %		...
 %		this_frame.local1 = MR_new_object(&this_frame, ...);
 %		...
@@ -524,30 +531,6 @@
 					Context, _ArgsToCopy, CodeToCopyArgs),
 
 				%
-				% for accurate GC,
-				% add a call to GC_check() at start of every
-				% 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).
-				% 
-				(
-					Action = chain_gc_stack_frames,
-					statement_contains_statement(FuncBody2,
-						NewObject),
-					NewObject = mlds__statement(atomic(
-					    new_object(_, _, _, _, _, _, _, _)
-					    ), _)
-				->
-					GC_Check = [mlds__statement(
-						atomic(gc_check), Context)]
-				;
-					GC_Check = []
-				),
-
-				%
 				% Insert code to unlink this stack frame
 				% before doing any tail calls or returning
 				% from the function, either explicitly
@@ -588,7 +571,7 @@
 				% (if any) at the end
 				%
 				FuncBody = ml_block(EnvDecls,
-					InitEnv ++ CodeToCopyArgs ++ GC_Check ++
+					InitEnv ++ CodeToCopyArgs ++
 					[FuncBody2] ++ UnchainFrame,
 					Context),
 				%
@@ -1541,41 +1524,7 @@
 		%
 		% recursively flatten the nested function
 		%
-		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
-		},
+		flatten_function_body(FuncBody0, FuncBody),
 
 		%
 		% mark the function as private / one_copy,
Index: compiler/mlds_to_c.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/mlds_to_c.m,v
retrieving revision 1.117
diff -u -d -r1.117 mlds_to_c.m
--- compiler/mlds_to_c.m	6 Feb 2002 10:04:21 -0000	1.117
+++ compiler/mlds_to_c.m	8 Feb 2002 05:43:46 -0000
@@ -2555,6 +2555,16 @@
 	mlds_indent(Indent),
 	io__write_string("{\n"),
 
+	% for --gc accurate, we need to insert a call to GC_check()
+	% before every allocation
+	globals__io_get_gc_method(GC_Method),
+	( { GC_Method = accurate } ->
+		mlds_indent(Context, Indent + 1),
+		io__write_string("MR_GC_check();\n")
+	;
+		[]
+	),
+
 	{ FuncInfo = func_info(FuncName, _FuncSignature) },
 	mlds_maybe_output_heap_profile_instr(Context, Indent + 1, Args,
 			FuncName, MaybeCtorName),

-- 
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