[m-rev.] for the record: GC & stack scanning

Fergus Henderson fjh at cs.mu.OZ.AU
Tue Apr 10 12:00:24 AEST 2001


I spent some time working on getting the Boehm collector to only scan the
live parts of the LLDS back-end stacks.  But I ran into a problem where
gcc wouldn't compile the Boehm collector if global register declarations
were included.  

It might be possible to work around this by hacking the Boehm collector,
but those changes couldn't be folded back into the main distribution of
the Boehm collector, so they'd cause us continuing maintenance difficulty.
In the long term, I think the right approach is either to fix gcc (also
a lot of work, most likely), or to abandon the use of global register
variables (e.g. by switching to the MLDS back-end).

In the mean time, I think we'll just have to live with the GC scanning
the whole of the LLDS stacks.

Because of the problems mentioned, I won't commit this change.

----------

Estimated hours taken: 6
Branches: none

Get the Boehm collector to only scan the live parts of the Mercury stacks.

XXX This change is incomplete:
XXX - need to conditionalize so that it only does this for the LLDS back-end
XXX - need to deal with transient registers on SPARC
XXX - need to fix the XXXs below

boehm_gc/Makefile:
	Ensure that the boehm_gc directory gets compiled with the
	GNU C global register variable declarations visible,
	XXX With recent versions of gcc, this change stops the
	collector compiling, because gcc doesn't support global
	register variables; it gets an "internal error / impossible asm"
	error.

runtime/mercury_engine.h:
	Add a comment.

runtime/mercury_memory.c:
runtime/mercury_wrapper.c:
	Move MR_init_conservative_GC() from mercury_wrapper.c to
	mercury_memory.c, because the latter is more a appropriate place,
	and to match where it is declared (mercury_memory.h).

runtime/mercury_memory.c:
	Add new function MR_push_other_roots() to push the live parts of
	the Mercury stacks onto the GC mark stack.
	Change MR_init_conservative_GC() so that it registers the
	MR_push_other_roots callback with the GC.

runtime/mercury_memory_zones.c:
	Don't scan the zones allocated with memalign(), even if
	conservative GC is enabled.  These should now be handled
	by MR_push_other_roots() instead.

runtime/Mmakefile:
	Compile mercury_memory.c with -Wno-strict-prototypes,
	to avoid spurious warnings in gc_priv.h.
	(XXX this is wrong for compilers other than gcc)

Index: runtime/Mmakefile
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/Mmakefile,v
retrieving revision 1.70
diff -u -d -u -r1.70 Mmakefile
--- runtime/Mmakefile	2001/03/16 01:40:39	1.70
+++ runtime/Mmakefile	2001/04/08 08:46:51
@@ -24,6 +24,10 @@
 MGNUCFLAGS	= --no-ansi
 MOD2C		= $(SCRIPTS_DIR)/mod2c
 
+# mercury_memory.c #includes gc_priv.h,
+# which has lots of unprototyped functions
+MGNUCFLAGS-mercury_memory = -Wno-strict-prototypes
+
 #-----------------------------------------------------------------------------#
 
 # All the headers in $(HDRS) should be syntactically well-formed
Index: runtime/mercury_engine.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_engine.h,v
retrieving revision 1.21
diff -u -d -u -r1.21 mercury_engine.h
--- runtime/mercury_engine.h	2000/12/04 18:28:39	1.21
+++ runtime/mercury_engine.h	2001/04/06 08:02:30
@@ -220,6 +220,11 @@
 #endif
 	jmp_buf		*e_jmp_buf;
 	MR_Word		*e_exception;
+	/*
+	** Note: if you add any new memory zones, you may need to modify
+	** MR_push_other_roots() to register these with the conservative
+	** garbage collector.
+	*/
 #ifndef	CONSERVATIVE_GC
 	MR_MemoryZone	*heap_zone;
 	MR_MemoryZone	*solutions_heap_zone;
Index: runtime/mercury_memory.c
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_memory.c,v
retrieving revision 1.24
diff -u -d -u -r1.24 mercury_memory.c
--- runtime/mercury_memory.c	2000/11/24 06:03:37	1.24
+++ runtime/mercury_memory.c	2001/04/06 07:59:59
@@ -96,6 +96,8 @@
 #include "mercury_trace_base.h"
 #include "mercury_memory_handlers.h"
 
+#include "gc_priv.h" /* for GC_push_other_roots() and GC_push_all() */
+
 /*---------------------------------------------------------------------------*/
 
 #if defined(HAVE_SYSCONF) && defined(_SC_PAGESIZE)
@@ -362,5 +364,90 @@
 
 	return ptr;
 }
+
+/*---------------------------------------------------------------------------*/
+/*
+** Support routines for use of the conservative garbage collector.
+*/
+
+#ifdef	CONSERVATIVE_GC
+
+static void (*orig_push_other_roots)(void);
+
+/*
+** This function registers the Mercury stacks with the
+** conservative garbage collector.
+*/
+static void
+MR_push_other_roots(void)
+{
+#if defined(__sparc__) && defined(USE_GCC_GLOBAL_REGISTERS)
+	MR_restore_transient_stack_ptrs();
+#endif
+
+	GC_push_all(MR_CONTEXT(detstack_zone)->min, MR_sp + 1);
+	GC_push_all(MR_CONTEXT(nondetstack_zone)->min, MR_maxfr + 1);
+#ifdef MR_USE_TRAIL
+	GC_push_all(MR_trail_zone->min, MR_trail_ptr + 1);
+#endif
+#ifdef MR_USE_MINIMAL_MODEL
+	/* XXX handle cutstack and generatorstack */
+#endif
+
+	if (orig_push_other_roots != NULL) (*orig_push_other_roots)();
+}
+
+void
+MR_init_conservative_GC(void)
+{
+	/*
+	** sometimes mercury apps fail the GC_is_visible() test.
+	** dyn_load.c traverses the entire address space and registers
+	** all segments that could possibly have been written to, which
+	** makes us suspect that &MR_runqueue_head is not in the registered
+	** roots.  So we force a write to that address, which seems to make
+	** the problem go away.
+	*/
+	MR_runqueue_head = NULL;
+
+	GC_quiet = TRUE;
+
+	/*
+	** Call GC_INIT() to tell the garbage collector about this DLL.
+	** (This is necessary to support Windows DLLs using gnu-win32.)
+	*/
+	GC_INIT();
+
+	/*
+	** call the init_gc() function defined in <foo>_init.c,
+	** which calls GC_INIT() to tell the GC about the main program.
+	** (This is to work around a Solaris 2.X (X <= 4) linker bug,
+	** and also to support Windows DLLs using gnu-win32.)
+	*/
+	(*MR_address_of_init_gc)();
+
+	/*
+	** Double-check that the garbage collector knows about
+	** global variables in shared libraries.
+	*/
+	GC_is_visible(&MR_runqueue_head);
+
+	/* The following code is necessary to tell the conservative */
+	/* garbage collector that we are using tagged pointers */
+	{
+		int i;
+
+		for (i = 1; i < (1 << TAGBITS); i++) {
+			GC_REGISTER_DISPLACEMENT(i);
+		}
+	}
+
+	/*
+	** Ensure that the GC will scan the Mercury stacks properly.
+	*/
+	orig_push_other_roots = GC_push_other_roots;
+	GC_push_other_roots = MR_push_other_roots;
+}
+#endif /* CONSERVATIVE_GC */
 
 /*---------------------------------------------------------------------------*/
Index: runtime/mercury_wrapper.c
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_wrapper.c,v
retrieving revision 1.87
diff -u -d -u -r1.87 mercury_wrapper.c
--- runtime/mercury_wrapper.c	2001/03/28 08:18:11	1.87
+++ runtime/mercury_wrapper.c	2001/04/06 07:58:59
@@ -399,54 +399,6 @@
 
 } /* end runtime_mercury_init() */
 
-#ifdef CONSERVATIVE_GC
-void
-MR_init_conservative_GC(void)
-{
-	/*
-	** sometimes mercury apps fail the GC_is_visible() test.
-	** dyn_load.c traverses the entire address space and registers
-	** all segments that could possibly have been written to, which
-	** makes us suspect that &MR_runqueue_head is not in the registered
-	** roots.  So we force a write to that address, which seems to make
-	** the problem go away.
-	*/
-	MR_runqueue_head = NULL;
-
-	GC_quiet = TRUE;
-
-	/*
-	** Call GC_INIT() to tell the garbage collector about this DLL.
-	** (This is necessary to support Windows DLLs using gnu-win32.)
-	*/
-	GC_INIT();
-
-	/*
-	** call the init_gc() function defined in <foo>_init.c,
-	** which calls GC_INIT() to tell the GC about the main program.
-	** (This is to work around a Solaris 2.X (X <= 4) linker bug,
-	** and also to support Windows DLLs using gnu-win32.)
-	*/
-	(*MR_address_of_init_gc)();
-
-	/*
-	** Double-check that the garbage collector knows about
-	** global variables in shared libraries.
-	*/
-	GC_is_visible(&MR_runqueue_head);
-
-	/* The following code is necessary to tell the conservative */
-	/* garbage collector that we are using tagged pointers */
-	{
-		int i;
-
-		for (i = 1; i < (1 << TAGBITS); i++) {
-			GC_REGISTER_DISPLACEMENT(i);
-		}
-	}
-}
-#endif /* CONSERVATIVE_GC */
-
 void 
 MR_do_init_modules(void)
 {
Index: runtime/mercury_memory_zones.c
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_memory_zones.c,v
retrieving revision 1.16
diff -u -d -r1.16 mercury_memory_zones.c
--- runtime/mercury_memory_zones.c	2001/03/13 18:02:26	1.16
+++ runtime/mercury_memory_zones.c	2001/04/10 01:55:22
@@ -129,14 +129,8 @@
 				(unsigned long) GetLastError());
 	}
 
-  #ifdef CONSERVATIVE_GC
-	if (ptr != NULL)
-		GC_add_roots((char *)ptr, (char *)ptr + size);
-  #endif
 	return ptr;
 }
-#elif defined(CONSERVATIVE_GC)
-  #define	memalign(a,s)   GC_MALLOC_UNCOLLECTABLE(s)
 #elif defined(HAVE_MEMALIGN)
   extern void	*memalign(size_t, size_t);
 #else
cvs diff: Diffing runtime/GETOPT
cvs diff: Diffing runtime/machdeps
cvs diff: Diffing samples
cvs diff: Diffing samples/c_interface
cvs diff: Diffing samples/c_interface/c_calls_mercury
cvs diff: Diffing samples/c_interface/cplusplus_calls_mercury
cvs diff: Diffing samples/c_interface/mercury_calls_c
cvs diff: Diffing samples/c_interface/mercury_calls_cplusplus
cvs diff: Diffing samples/c_interface/mercury_calls_fortran
cvs diff: Diffing samples/c_interface/simpler_c_calls_mercury
cvs diff: Diffing samples/c_interface/simpler_cplusplus_calls_mercury
cvs diff: Diffing samples/diff
cvs diff: Diffing samples/muz
cvs diff: Diffing samples/rot13
cvs diff: Diffing samples/solutions
cvs diff: Diffing samples/tests
cvs diff: Diffing samples/tests/c_interface
cvs diff: Diffing samples/tests/c_interface/c_calls_mercury
cvs diff: Diffing samples/tests/c_interface/cplusplus_calls_mercury
cvs diff: Diffing samples/tests/c_interface/mercury_calls_c
cvs diff: Diffing samples/tests/c_interface/mercury_calls_cplusplus
cvs diff: Diffing samples/tests/c_interface/mercury_calls_fortran
cvs diff: Diffing samples/tests/c_interface/simpler_c_calls_mercury
cvs diff: Diffing samples/tests/c_interface/simpler_cplusplus_calls_mercury
cvs diff: Diffing samples/tests/diff
cvs diff: Diffing samples/tests/muz
cvs diff: Diffing samples/tests/rot13
cvs diff: Diffing samples/tests/solutions
cvs diff: Diffing samples/tests/toplevel
cvs diff: Diffing scripts
cvs diff: Diffing tests
cvs diff: Diffing tests/benchmarks
cvs diff: Diffing tests/debugger
cvs diff: Diffing tests/debugger/declarative
cvs diff: Diffing tests/dppd
cvs diff: Diffing tests/general
cvs diff: Diffing tests/general/accumulator
cvs diff: Diffing tests/general/structure_reuse
cvs diff: Diffing tests/hard_coded
cvs diff: Diffing tests/hard_coded/exceptions
cvs diff: Diffing tests/hard_coded/purity
cvs diff: Diffing tests/hard_coded/sub-modules
cvs diff: Diffing tests/hard_coded/typeclasses
cvs diff: Diffing tests/invalid
cvs diff: Diffing tests/invalid/purity
cvs diff: Diffing tests/misc_tests
cvs diff: Diffing tests/tabling
cvs diff: Diffing tests/term
cvs diff: Diffing tests/valid
cvs diff: Diffing tests/warnings
cvs diff: Diffing tools
cvs diff: Diffing trace
cvs diff: Diffing util


-- 
Fergus Henderson <fjh at cs.mu.oz.au>  |  "I have always known that the pursuit
                                    |  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