[MLton-commit] r4126

Matthew Fluet MLton@mlton.org
Sun, 30 Oct 2005 18:48:19 -0800


Fixing on a naming convention
----------------------------------------------------------------------

U   mlton/branches/on-20050822-x86_64-branch/runtime/gc/Makefile
U   mlton/branches/on-20050822-x86_64-branch/runtime/gc/align.c
U   mlton/branches/on-20050822-x86_64-branch/runtime/gc/array-allocate.c
A   mlton/branches/on-20050822-x86_64-branch/runtime/gc/array-allocate.h
U   mlton/branches/on-20050822-x86_64-branch/runtime/gc/array.c
U   mlton/branches/on-20050822-x86_64-branch/runtime/gc/array.h
U   mlton/branches/on-20050822-x86_64-branch/runtime/gc/atomic.c
A   mlton/branches/on-20050822-x86_64-branch/runtime/gc/atomic.h
U   mlton/branches/on-20050822-x86_64-branch/runtime/gc/cheney-copy.c
U   mlton/branches/on-20050822-x86_64-branch/runtime/gc/cheney-copy.h
A   mlton/branches/on-20050822-x86_64-branch/runtime/gc/controls.c
U   mlton/branches/on-20050822-x86_64-branch/runtime/gc/controls.h
U   mlton/branches/on-20050822-x86_64-branch/runtime/gc/copy-thread.c
A   mlton/branches/on-20050822-x86_64-branch/runtime/gc/copy-thread.h
U   mlton/branches/on-20050822-x86_64-branch/runtime/gc/current.c
A   mlton/branches/on-20050822-x86_64-branch/runtime/gc/current.h
U   mlton/branches/on-20050822-x86_64-branch/runtime/gc/dfs-mark.c
A   mlton/branches/on-20050822-x86_64-branch/runtime/gc/dfs-mark.h
U   mlton/branches/on-20050822-x86_64-branch/runtime/gc/done.c
U   mlton/branches/on-20050822-x86_64-branch/runtime/gc/enter_leave.c
A   mlton/branches/on-20050822-x86_64-branch/runtime/gc/enter_leave.h
U   mlton/branches/on-20050822-x86_64-branch/runtime/gc/foreach.c
A   mlton/branches/on-20050822-x86_64-branch/runtime/gc/foreach.h
U   mlton/branches/on-20050822-x86_64-branch/runtime/gc/frame.c
U   mlton/branches/on-20050822-x86_64-branch/runtime/gc/frame.h
U   mlton/branches/on-20050822-x86_64-branch/runtime/gc/garbage-collection.c
A   mlton/branches/on-20050822-x86_64-branch/runtime/gc/garbage-collection.h
U   mlton/branches/on-20050822-x86_64-branch/runtime/gc/gc_prefix.c
U   mlton/branches/on-20050822-x86_64-branch/runtime/gc/gc_state.h
U   mlton/branches/on-20050822-x86_64-branch/runtime/gc/generational.c
U   mlton/branches/on-20050822-x86_64-branch/runtime/gc/generational.h
U   mlton/branches/on-20050822-x86_64-branch/runtime/gc/hash-cons.c
U   mlton/branches/on-20050822-x86_64-branch/runtime/gc/hash-cons.h
U   mlton/branches/on-20050822-x86_64-branch/runtime/gc/heap.c
U   mlton/branches/on-20050822-x86_64-branch/runtime/gc/heap.h
U   mlton/branches/on-20050822-x86_64-branch/runtime/gc/heap_predicates.c
U   mlton/branches/on-20050822-x86_64-branch/runtime/gc/init.c
U   mlton/branches/on-20050822-x86_64-branch/runtime/gc/invariant.c
A   mlton/branches/on-20050822-x86_64-branch/runtime/gc/invariant.h
U   mlton/branches/on-20050822-x86_64-branch/runtime/gc/mark-compact.c
A   mlton/branches/on-20050822-x86_64-branch/runtime/gc/mark-compact.h
U   mlton/branches/on-20050822-x86_64-branch/runtime/gc/model.c
U   mlton/branches/on-20050822-x86_64-branch/runtime/gc/model.h
U   mlton/branches/on-20050822-x86_64-branch/runtime/gc/model_predicates.c
A   mlton/branches/on-20050822-x86_64-branch/runtime/gc/new-object.c
A   mlton/branches/on-20050822-x86_64-branch/runtime/gc/new-object.h
D   mlton/branches/on-20050822-x86_64-branch/runtime/gc/new_object.c
A   mlton/branches/on-20050822-x86_64-branch/runtime/gc/object-size.c
A   mlton/branches/on-20050822-x86_64-branch/runtime/gc/object-size.h
U   mlton/branches/on-20050822-x86_64-branch/runtime/gc/object.c
U   mlton/branches/on-20050822-x86_64-branch/runtime/gc/object.h
D   mlton/branches/on-20050822-x86_64-branch/runtime/gc/object_size.c
U   mlton/branches/on-20050822-x86_64-branch/runtime/gc/pack.c
A   mlton/branches/on-20050822-x86_64-branch/runtime/gc/pack.h
U   mlton/branches/on-20050822-x86_64-branch/runtime/gc/pointer.h
U   mlton/branches/on-20050822-x86_64-branch/runtime/gc/pointer_predicates.c
U   mlton/branches/on-20050822-x86_64-branch/runtime/gc/profiling.c
U   mlton/branches/on-20050822-x86_64-branch/runtime/gc/profiling.h
U   mlton/branches/on-20050822-x86_64-branch/runtime/gc/ratios.h
U   mlton/branches/on-20050822-x86_64-branch/runtime/gc/ratios_predicates.c
U   mlton/branches/on-20050822-x86_64-branch/runtime/gc/read_write.c
A   mlton/branches/on-20050822-x86_64-branch/runtime/gc/read_write.h
U   mlton/branches/on-20050822-x86_64-branch/runtime/gc/rusage.c
A   mlton/branches/on-20050822-x86_64-branch/runtime/gc/rusage.h
U   mlton/branches/on-20050822-x86_64-branch/runtime/gc/safe.c
A   mlton/branches/on-20050822-x86_64-branch/runtime/gc/safe.h
U   mlton/branches/on-20050822-x86_64-branch/runtime/gc/share.c
A   mlton/branches/on-20050822-x86_64-branch/runtime/gc/share.h
A   mlton/branches/on-20050822-x86_64-branch/runtime/gc/size.h
U   mlton/branches/on-20050822-x86_64-branch/runtime/gc/stack.c
U   mlton/branches/on-20050822-x86_64-branch/runtime/gc/stack.h
U   mlton/branches/on-20050822-x86_64-branch/runtime/gc/stack_predicates.c
U   mlton/branches/on-20050822-x86_64-branch/runtime/gc/thread.c
U   mlton/branches/on-20050822-x86_64-branch/runtime/gc/thread.h
U   mlton/branches/on-20050822-x86_64-branch/runtime/gc/translate.c
A   mlton/branches/on-20050822-x86_64-branch/runtime/gc/translate.h
U   mlton/branches/on-20050822-x86_64-branch/runtime/gc/util.c
U   mlton/branches/on-20050822-x86_64-branch/runtime/gc/util.h
U   mlton/branches/on-20050822-x86_64-branch/runtime/gc/world.c
U   mlton/branches/on-20050822-x86_64-branch/runtime/gc/world.h

----------------------------------------------------------------------

Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/Makefile
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/Makefile	2005-10-30 14:38:45 UTC (rev 4125)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/Makefile	2005-10-31 02:47:56 UTC (rev 4126)
@@ -70,7 +70,7 @@
 CFLAGS = -O2 $(CWFLAGS) -I. -D_FILE_OFFSET_BITS=64 $(FLAGS)
 DEBUGFLAGS = $(CFLAGS) -Wunused -gstabs+ -g2
 
-## Order matters, as these are concatenated together to form "gc.c".
+## Order matters, as these are concatenated together to form "libgc.c".
 CFILES = 								\
 	gc_prefix.c							\
 	util.c								\
@@ -80,51 +80,54 @@
 	debug.c								\
 	align.c								\
 	virtual-memory.c						\
-	pointer_predicates.c						\
-	pointer.c							\
-	model_predicates.c						\
-	model.c								\
-	object.c							\
+	array-allocate.c						\
 	array.c								\
-	object_size.c							\
+	atomic.c							\
+	cheney-copy.c							\
+	controls.c							\
+	copy-thread.c							\
+	current.c   							\
+	dfs-mark.c							\
+	enter_leave.c							\
+	foreach.c							\
 	frame.c								\
-	stack_predicates.c						\
-	stack.c								\
-	thread.c							\
+	garbage-collection.c						\
+	gc_state.c   							\
 	generational.c							\
-	current.c   							\
-	foreach.c							\
-	translate.c							\
+	hash-cons.c							\
+	heap.c								\
 	heap_predicates.c						\
-	heap.c								\
-	ratios_predicates.c						\
-	atomic.c							\
-	gc_state.c   							\
 	invariant.c   							\
-	enter_leave.c							\
-	cheney-copy.c							\
-	hash-cons.c							\
-	dfs-mark.c							\
-	share.c								\
 	mark-compact.c							\
-	new_object.c   							\
-	garbage-collection.c						\
-	array-allocate.c						\
-	copy-thread.c							\
+	model.c								\
+	model_predicates.c						\
+	new-object.c   							\
+	object.c							\
+	object-size.c							\
 	pack.c								\
+	pointer.c							\
+	pointer_predicates.c						\
+	ratios_predicates.c						\
+	share.c								\
 	size.c								\
+	stack.c								\
+	stack_predicates.c						\
+	thread.c							\
+	translate.c							\
+	weak.c								\
+	world.c								\
 	profiling.c							\
-	world.c								\
-	weak.c								\
 	init.c								\
 	done.c								\
 	assumptions.c							\
 	gc_suffix.c
 
-## Order matters, as these are concatenated together to form "gc.h".
+## Order matters, as these are concatenated together to form "libgc.h".
 HFILES = 								\
 	gc_prefix.h							\
 	util.h								\
+	safe.h								\
+	rusage.h							\
 	virtual-memory.h						\
 	pointer.h							\
 	model.h								\
@@ -134,10 +137,13 @@
 	stack.h								\
 	thread.h							\
 	weak.h								\
+	object-size.h							\
 	int-inf.h							\
 	heap.h								\
 	major.h								\
 	generational.h							\
+	current.h							\
+	foreach.h							\
 	statistics.h							\
 	controls.h							\
 	sysvals.h							\
@@ -148,40 +154,54 @@
 	world.h								\
 	init.h								\
 	gc_state.h							\
+	translate.h							\
+	atomic.h							\
+	invariant.h							\
+	enter_leave.h							\
+	cheney-copy.h							\
+	dfs-mark.h							\
+	share.h								\
+	mark-compact.h							\
+	new-object.h							\
+	garbage-collection.h						\
+	array-allocate.h						\
+	copy-thread.h							\
+	pack.h								\
+	size.h								\
 	gc_suffix.h
 
-all: gc.o gc-gdb.o
+all: libgc.o libgc-gdb.o
 
-gc-gdb.o: gc.c gc.h
-	$(CC) $(DEBUGFLAGS) -DGC_MODEL_$(DEFAULT_MODEL) -O1 -DASSERT=1 -c -o $@ gc.c
+libgc-gdb.o: libgc.c libgc.h
+	$(CC) $(DEBUGFLAGS) -DGC_MODEL_$(DEFAULT_MODEL) -O1 -DASSERT=1 -c -o $@ libgc.c
 
-gc.o: gc.c gc.h
-	$(CC) $(CFLAGS) -DGC_MODEL_$(DEFAULT_MODEL) -c -o $@ gc.c
+libgc.o: libgc.c libgc.h
+	$(CC) $(CFLAGS) -DGC_MODEL_$(DEFAULT_MODEL) -c -o $@ libgc.c
 
-gc.c: $(CFILES)
-	rm -f gc.c
+libgc.c: $(CFILES)
+	rm -f libgc.c
 	(								\
 		for f in $(CFILES); do					\
 			echo "#line 1 \"$$f\"";				\
 			cat $$f;					\
 		done;							\
-	) > gc.c
+	) > libgc.c
 
-gc.h: $(HFILES)
-	rm -f gc.h
+libgc.h: $(HFILES)
+	rm -f libgc.h
 	(								\
 		for f in $(HFILES); do					\
 			echo "#line 1 \"$$f\"";				\
 			cat $$f;					\
 		done;							\
-	) > gc.h
+	) > libgc.h
 
 .PHONY: models
-models: gc.c gc.h
+models: libgc.c libgc.h
 	(								\
 		for m in $(ALL_MODELS); do				\
-			$(CC) $(CFLAGS) -DGC_MODEL_$$m -c -o gc.$$m.o gc.c;	\
-			$(CC) $(DEBUGFLAGS) -O1 -DASSERT=1 -DGC_MODEL_$$m -c -o gc-gdb.$$m.o gc.c;	\
+			$(CC) $(CFLAGS) -DGC_MODEL_$$m -c -o libgc.$$m.o libgc.c;	\
+			$(CC) $(DEBUGFLAGS) -O1 -DASSERT=1 -DGC_MODEL_$$m -c -o libgc-gdb.$$m.o libgc.c;	\
 		done;							\
 	)
 

Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/align.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/align.c	2005-10-30 14:38:45 UTC (rev 4125)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/align.c	2005-10-31 02:47:56 UTC (rev 4126)
@@ -21,6 +21,13 @@
   return a;
 }
 
+static inline uintmax_t alignMaxDown (uintmax_t a, uintmax_t b) {
+  assert (b >= 1);
+  a -= a % b;
+  assert (isAlignedMax (a, b));
+  return a;
+}
+
 static inline size_t align (size_t a, size_t b) {
   assert (b >= 1);
   a += b - 1;
@@ -59,10 +66,6 @@
   return (pointer)res;
 }
 
-pointer GC_alignFrontier (GC_state s, pointer p) {
-  return alignFrontier (s, p);
-}
-
 #if ASSERT
 static inline bool isAlignedStackReserved (GC_state s, size_t reserved) {
   return isAligned (GC_STACK_HEADER_SIZE + sizeof (struct GC_stack) + reserved, 
@@ -75,7 +78,7 @@
   
   res = pad (s, reserved, GC_STACK_HEADER_SIZE + sizeof (struct GC_stack));
   if (DEBUG_STACKS)
-    fprintf (stderr, "%zu = stackReserved (%zu)\n", res, reserved);
+    fprintf (stderr, "%zu = alignStackReserved (%zu)\n", res, reserved);
   assert (isAlignedStackReserved (s, res));
   return res;
 }

Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/array-allocate.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/array-allocate.c	2005-10-30 14:38:45 UTC (rev 4125)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/array-allocate.c	2005-10-31 02:47:56 UTC (rev 4126)
@@ -24,7 +24,7 @@
     fprintf (stderr, "GC_arrayAllocate (%zu, "FMTARRLEN", "FMTHDR")\n",
              ensureBytesFree, numElements, header);
   bytesPerElement = 
-    numNonObjptrsToBytes(numNonObjptrs, ARRAY_TAG) 
+    sizeofNumNonObjptrs (ARRAY_TAG, numNonObjptrs) 
     + (numObjptrs * OBJPTR_SIZE);
   arraySizeMax = 
     alignMax ((uintmax_t)bytesPerElement * (uintmax_t)numElements + GC_ARRAY_HEADER_SIZE,
@@ -82,7 +82,7 @@
       size_t nonObjptrBytes;
       size_t objptrBytes;
         
-      nonObjptrBytes = numNonObjptrsToBytes(numNonObjptrs, ARRAY_TAG);
+      nonObjptrBytes = sizeofNumNonObjptrs (ARRAY_TAG, numNonObjptrs);
       objptrBytes = numObjptrs * OBJPTR_SIZE;
 
       for (p = frontier; p < last; ) {

Added: mlton/branches/on-20050822-x86_64-branch/runtime/gc/array-allocate.h
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/array-allocate.h	2005-10-30 14:38:45 UTC (rev 4125)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/array-allocate.h	2005-10-31 02:47:56 UTC (rev 4126)
@@ -0,0 +1,12 @@
+/* Copyright (C) 1999-2005 Henry Cejtin, Matthew Fluet, Suresh
+ *    Jagannathan, and Stephen Weeks.
+ * Copyright (C) 1997-2000 NEC Research Institute.
+ *
+ * MLton is released under a BSD-style license.
+ * See the file MLton-LICENSE for details.
+ */
+
+pointer GC_arrayAllocate (GC_state s, 
+                          size_t ensureBytesFree, 
+                          GC_arrayLength numElements, 
+                          GC_header header);

Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/array.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/array.c	2005-10-30 14:38:45 UTC (rev 4125)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/array.c	2005-10-31 02:47:56 UTC (rev 4126)
@@ -6,19 +6,39 @@
  * See the file MLton-LICENSE for details.
  */
 
+/* getArrayLengthp (p)
+ *
+ * Returns a pointer to the length for the array pointed to by p.
+ */
+GC_arrayLength* getArrayLengthp (pointer a) {
+  return (GC_arrayLength*)(a 
+                           - GC_HEADER_SIZE 
+                           - GC_ARRAY_LENGTH_SIZE);
+}
+
+/* getArrayLength (p)
+ *
+ * Returns the length for the array pointed to by p.
+ */
+GC_arrayLength getArrayLength (pointer a) {
+  return *(getArrayLengthp (a));
+}
+
 /* getArrayCounterp (p)
  *
  * Returns a pointer to the counter for the array pointed to by p.
  */
-static inline GC_arrayCounter* getArrayCounterp (pointer a) {
-  return (GC_arrayCounter*)(a - GC_HEADER_SIZE 
-                            - GC_ARRAY_LENGTH_SIZE - GC_ARRAY_COUNTER_SIZE);
+GC_arrayCounter* getArrayCounterp (pointer a) {
+  return (GC_arrayCounter*)(a 
+                            - GC_HEADER_SIZE 
+                            - GC_ARRAY_LENGTH_SIZE 
+                            - GC_ARRAY_COUNTER_SIZE);
 }
 
 /* getArrayCounter (p)
  *
  * Returns the counter for the array pointed to by p.
  */
-static inline GC_arrayCounter getArrayCounter (pointer a) {
+GC_arrayCounter getArrayCounter (pointer a) {
   return *(getArrayCounterp (a));
 }

Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/array.h
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/array.h	2005-10-30 14:38:45 UTC (rev 4125)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/array.h	2005-10-31 02:47:56 UTC (rev 4126)
@@ -24,20 +24,11 @@
 #define FMTARRLEN "%"PRIxARRLEN
 typedef GC_arrayLength GC_arrayCounter;
 #define GC_ARRAY_COUNTER_SIZE GC_ARRAY_LENGTH_SIZE
+#define PRIxARRCTR PRIu32
+#define FMTARRCTR "%"PRIxARRCTR
 #define GC_ARRAY_HEADER_SIZE (GC_ARRAY_COUNTER_SIZE + GC_ARRAY_LENGTH_SIZE + GC_HEADER_SIZE)
 
-/* getArrayLengthp (p)
- *
- * Returns a pointer to the length for the array pointed to by p.
- */
-static inline GC_arrayLength* getArrayLengthp (pointer a) {
-  return (GC_arrayLength*)(a - GC_HEADER_SIZE - GC_ARRAY_LENGTH_SIZE);
-}
-
-/* getArrayLength (p)
- *
- * Returns the length for the array pointed to by p.
- */
-static inline GC_arrayLength getArrayLength (pointer a) {
-  return *(getArrayLengthp (a));
-}
+GC_arrayLength* getArrayLengthp (pointer a);
+GC_arrayLength getArrayLength (pointer a);
+GC_arrayCounter* getArrayCounterp (pointer a);
+GC_arrayCounter getArrayCounter (pointer a);

Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/atomic.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/atomic.c	2005-10-30 14:38:45 UTC (rev 4125)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/atomic.c	2005-10-31 02:47:56 UTC (rev 4126)
@@ -6,13 +6,13 @@
  * See the file MLton-LICENSE for details.
  */
 
-static inline void atomicBegin (GC_state s) {
+void atomicBegin (GC_state s) {
   s->atomicState++;
   if (0 == s->limit)
-    s->limit = s->limitPlusSlop - LIMIT_SLOP;
+    s->limit = s->limitPlusSlop - GC_HEAP_LIMIT_SLOP;
 }
 
-static inline void atomicEnd (GC_state s) {
+void atomicEnd (GC_state s) {
   s->atomicState--;
   if (0 == s->atomicState 
       and s->signalsInfo.signalIsPending)

Added: mlton/branches/on-20050822-x86_64-branch/runtime/gc/atomic.h
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/atomic.h	2005-10-30 14:38:45 UTC (rev 4125)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/atomic.h	2005-10-31 02:47:56 UTC (rev 4126)
@@ -0,0 +1,10 @@
+/* Copyright (C) 1999-2005 Henry Cejtin, Matthew Fluet, Suresh
+ *    Jagannathan, and Stephen Weeks.
+ * Copyright (C) 1997-2000 NEC Research Institute.
+ *
+ * MLton is released under a BSD-style license.
+ * See the file MLton-LICENSE for details.
+ */
+
+void atomicBegin (GC_state s);
+void atomicEnd (GC_state s);

Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/cheney-copy.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/cheney-copy.c	2005-10-30 14:38:45 UTC (rev 4125)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/cheney-copy.c	2005-10-31 02:47:56 UTC (rev 4126)
@@ -25,21 +25,21 @@
 };
 static struct forwardState forwardState;
 
-static inline bool pointerIsInToSpace (pointer p) {
+bool isPointerInToSpace (pointer p) {
   return (not (isPointer (p))
           or (forwardState.toStart <= p and p < forwardState.toLimit));
 }
 
-static inline bool objptrIsInToSpace (objptr op) {
+bool isObjptrInToSpace (objptr op) {
   pointer p;
 
   if (not (isObjptr (op)))
     return TRUE;
   p = objptrToPointer (op, forwardState.toStart);
-  return pointerIsInToSpace (p);
+  return isPointerInToSpace (p);
 }
 
-static void forwardObjptr (GC_state s, objptr *opp) {
+void forwardObjptr (GC_state s, objptr *opp) {
   objptr op;
   pointer p;
   GC_header header;
@@ -50,7 +50,7 @@
     fprintf (stderr,
              "forwardObjptr  opp = "FMTPTR"  op = "FMTOBJPTR"  p = "FMTPTR"\n",
              (uintptr_t)opp, op, (uintptr_t)p);
-  assert (objptrIsInFromSpace (s, *opp));
+  assert (isObjptrInFromSpace (s, *opp));
   header = getHeader (p);
   if (DEBUG_DETAILED and header == GC_FORWARDED)
     fprintf (stderr, "  already FORWARDED\n");
@@ -65,13 +65,12 @@
     /* Compute the space taken by the header and object body. */
     if ((NORMAL_TAG == tag) or (WEAK_TAG == tag)) { /* Fixed size object. */
       headerBytes = GC_NORMAL_HEADER_SIZE;
-      objectBytes = 
-        numNonObjptrsToBytes(numNonObjptrs, NORMAL_TAG)
-        + (numObjptrs * OBJPTR_SIZE);
+      objectBytes = sizeofNormalNoHeader (s, numNonObjptrs, numObjptrs);
       skip = 0;
     } else if (ARRAY_TAG == tag) {
       headerBytes = GC_ARRAY_HEADER_SIZE;
-      objectBytes = arraySizeNoHeader (s, p, numNonObjptrs, numObjptrs);
+      objectBytes = sizeofArrayNoHeader (s, getArrayLength (p), 
+                                         numNonObjptrs, numObjptrs);
       skip = 0;
     } else { /* Stack. */
       GC_stack stack;
@@ -80,14 +79,15 @@
       headerBytes = GC_STACK_HEADER_SIZE;
       stack = (GC_stack)p;
 
-      if (currentThreadStackObjptr(s) == op) {
+      if (getStackCurrentObjptr(s) == op) {
         /* Shrink stacks that don't use a lot of their reserved space;
          * but don't violate the stack invariant.
          */
         if (stack->used <= stack->reserved / 4) {
           size_t new = 
             alignStackReserved 
-            (s, max (stack->reserved / 2, stackMinimumReserved (s, stack)));
+            (s, max (stack->reserved / 2, 
+                     sizeofStackMinimumReserved (s, stack)));
           /* It's possible that new > stack->reserved if the stack
            * invariant is violated. In that case, we want to leave the
            * stack alone, because some other part of the gc will grow
@@ -129,7 +129,7 @@
                  (uintptr_t)w);
       if (isObjptr (w->objptr)
           and (not forwardState.amInMinorGC
-               or objptrIsInNursery (s, w->objptr))) {
+               or isObjptrInNursery (s, w->objptr))) {
         if (DEBUG_WEAK)
           fprintf (stderr, "linking\n");
         w->link = s->weaks;
@@ -148,10 +148,10 @@
                        s->alignment));
   }
   *opp = *(objptr*)p;
-  assert (objptrIsInToSpace (*opp));
+  assert (isObjptrInToSpace (*opp));
 }
 
-static inline void updateWeaks (GC_state s) {
+void updateWeaks (GC_state s) {
   pointer p;
   GC_weak w;
 
@@ -177,7 +177,7 @@
   s->weaks = NULL;
 }
 
-static inline void swapHeaps (GC_state s) {
+void swapHeaps (GC_state s) {
   struct GC_heap tempHeap;
   
   tempHeap = s->secondaryHeap;
@@ -186,7 +186,7 @@
   setCardMapAbsolute (s);
 }
 
-static void majorCheneyCopyGC (GC_state s) {
+void majorCheneyCopyGC (GC_state s) {
   struct rusage ru_start;
   pointer toStart;
 
@@ -236,7 +236,7 @@
 /*                 Minor Cheney Copying Collection                  */
 /* ---------------------------------------------------------------- */
 
-static inline void forwardObjptrIfInNursery (GC_state s, objptr *opp) {
+void forwardObjptrIfInNursery (GC_state s, objptr *opp) {
   objptr op;
   pointer p;
 
@@ -253,7 +253,7 @@
 }
 
 /* Walk through all the cards and forward all intergenerational pointers. */
-static void forwardInterGenerationalObjptrs (GC_state s) {
+void forwardInterGenerationalObjptrs (GC_state s) {
   GC_cardMapElem *cardMap;
   GC_crossMapElem *crossMap;
   pointer oldGenStart, oldGenEnd;
@@ -268,7 +268,7 @@
   /* Constants. */
   cardMap = s->generationalMaps.cardMap;
   crossMap = s->generationalMaps.crossMap;
-  maxCardIndex = sizeToCardIndex (align (s->heap.oldGenSize, CARD_SIZE));
+  maxCardIndex = sizeToCardMapIndex (align (s->heap.oldGenSize, CARD_SIZE));
   oldGenStart = s->heap.start;
   oldGenEnd = oldGenStart + s->heap.oldGenSize;
   /* Loop variables*/
@@ -284,7 +284,7 @@
   if (DEBUG_GENERATIONAL)
     fprintf (stderr, "checking card %zu  objectStart = "FMTPTR"\n",
              cardIndex, (uintptr_t)objectStart);
-  assert (objectStart < oldGenStart + cardIndexToSize (cardIndex + 1));
+  assert (objectStart < oldGenStart + cardMapIndexToSize (cardIndex + 1));
   if (cardMap[cardIndex]) {
     pointer lastObject;
     size_t size;
@@ -296,7 +296,7 @@
     lastObject = objectStart;
 skipObjects:
     assert (isAlignedFrontier (s, objectStart));
-    size = objectSize (s, objectData (s, objectStart));
+    size = sizeofObject (s, advanceToObjectData (s, objectStart));
     if (objectStart + size < cardStart) {
       objectStart += size;
       goto skipObjects;
@@ -318,8 +318,8 @@
     s->cumulativeStatistics.minorBytesScanned += objectStart - lastObject;
     if (objectStart == oldGenEnd)
       goto done;
-    cardIndex = sizeToCardIndex (objectStart - oldGenStart);
-    cardStart = oldGenStart + cardIndexToSize (cardIndex);
+    cardIndex = sizeToCardMapIndex (objectStart - oldGenStart);
+    cardStart = oldGenStart + cardMapIndexToSize (cardIndex);
     goto checkCard;
   } else {
     unless (CROSS_MAP_EMPTY == crossMap[cardIndex])
@@ -341,7 +341,7 @@
     fprintf (stderr, "Forwarding inter-generational pointers done.\n");
 }
 
-static void minorCheneyCopyGC (GC_state s) {
+void minorCheneyCopyGC (GC_state s) {
   size_t bytesAllocated;
   size_t bytesCopied;
   struct rusage ru_start;

Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/cheney-copy.h
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/cheney-copy.h	2005-10-30 14:38:45 UTC (rev 4125)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/cheney-copy.h	2005-10-31 02:47:56 UTC (rev 4126)
@@ -5,3 +5,13 @@
  * MLton is released under a BSD-style license.
  * See the file MLton-LICENSE for details.
  */
+
+bool pointerIsInToSpace (pointer p);
+bool objptrIsInToSpace (objptr op);
+void forwardObjptr (GC_state s, objptr *opp);
+void updateWeaks (GC_state s);
+void swapHeaps (GC_state s);
+void majorCheneyCopyGC (GC_state s);
+void forwardObjptrIfInNursery (GC_state s, objptr *opp);
+void forwardInterGenerationalObjptrs (GC_state s);
+void minorCheneyCopyGC (GC_state s);

Added: mlton/branches/on-20050822-x86_64-branch/runtime/gc/controls.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/controls.c	2005-10-30 14:38:45 UTC (rev 4125)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/controls.c	2005-10-31 02:47:56 UTC (rev 4126)
@@ -0,0 +1,11 @@
+/* Copyright (C) 1999-2005 Henry Cejtin, Matthew Fluet, Suresh
+ *    Jagannathan, and Stephen Weeks.
+ * Copyright (C) 1997-2000 NEC Research Institute.
+ *
+ * MLton is released under a BSD-style license.
+ * See the file MLton-LICENSE for details.
+ */
+
+bool detailedGCTime (GC_state s) {
+  return s->controls.summary;
+}

Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/controls.h
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/controls.h	2005-10-30 14:38:45 UTC (rev 4125)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/controls.h	2005-10-31 02:47:56 UTC (rev 4126)
@@ -15,3 +15,5 @@
   size_t oldGenArraySize; /* Arrays larger are allocated in old gen, if possible. */
   bool summary; /* Print a summary of gc info when program exits. */
 };
+
+bool detailedGCTime (GC_state s);

Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/copy-thread.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/copy-thread.c	2005-10-30 14:38:45 UTC (rev 4125)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/copy-thread.c	2005-10-31 02:47:56 UTC (rev 4126)
@@ -6,25 +6,25 @@
  * See the file MLton-LICENSE for details.
  */
 
-static GC_thread newThread (GC_state s, size_t stackSize) {
+GC_thread newThread (GC_state s, size_t reserved) {
   GC_stack stack;
   GC_thread thread;
 
-  ensureFree (s, stackSizeTotalAligned (s, stackSize) + threadSize (s));
-  stack = newStack (s, stackSize, FALSE);
+  ensureFree (s, sizeofStackWithHeaderAligned (s, reserved) + sizeofThread (s));
+  stack = newStack (s, reserved, FALSE);
   thread = (GC_thread) newObject (s, GC_THREAD_HEADER, 
-                                  threadSize (s), 
+                                  sizeofThread (s), 
                                   FALSE);
   thread->bytesNeeded = 0;
   thread->exnStack = BOGUS_EXN_STACK;
   thread->stack = pointerToObjptr((pointer)stack, s->heap.start);
   if (DEBUG_THREADS)
     fprintf (stderr, FMTPTR" = newThreadOfSize (%zu)\n",
-             (uintptr_t)thread, stackSize);;
+             (uintptr_t)thread, reserved);;
   return thread;
 }
 
-static GC_thread copyThread (GC_state s, GC_thread from, size_t size) {
+GC_thread copyThread (GC_state s, GC_thread from, size_t size) {
   GC_thread to;
 
   if (DEBUG_THREADS)
@@ -40,7 +40,7 @@
     fprintf (stderr, FMTPTR" = copyThread ("FMTPTR")\n",
              (uintptr_t)to, (uintptr_t)from);
   }
-  stackCopy (s, 
+  copyStack (s, 
              (GC_stack)(objptrToPointer(from->stack, s->heap.start)), 
              (GC_stack)(objptrToPointer(to->stack, s->heap.start)));
   to->bytesNeeded = from->bytesNeeded;

Added: mlton/branches/on-20050822-x86_64-branch/runtime/gc/copy-thread.h
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/copy-thread.h	2005-10-30 14:38:45 UTC (rev 4125)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/copy-thread.h	2005-10-31 02:47:56 UTC (rev 4126)
@@ -0,0 +1,12 @@
+/* Copyright (C) 1999-2005 Henry Cejtin, Matthew Fluet, Suresh
+ *    Jagannathan, and Stephen Weeks.
+ * Copyright (C) 1997-2000 NEC Research Institute.
+ *
+ * MLton is released under a BSD-style license.
+ * See the file MLton-LICENSE for details.
+ */
+
+GC_thread newThread (GC_state s, size_t stackSize);
+GC_thread copyThread (GC_state s, GC_thread from, size_t size);
+void GC_copyCurrentThread (GC_state s);
+pointer GC_copyThread (GC_state s, pointer p);

Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/current.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/current.c	2005-10-30 14:38:45 UTC (rev 4125)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/current.c	2005-10-31 02:47:56 UTC (rev 4126)
@@ -6,40 +6,40 @@
  * See the file MLton-LICENSE for details.
  */
 
-static inline objptr currentThreadObjptr (GC_state s) {
+objptr getThreadCurrentObjptr (GC_state s) {
   return s->currentThread;
 }
 
-static inline GC_thread currentThread (GC_state s) {
-  pointer p = objptrToPointer(currentThreadObjptr(s), s->heap.start);
+GC_thread getThreadCurrent (GC_state s) {
+  pointer p = objptrToPointer(getThreadCurrentObjptr(s), s->heap.start);
   return (GC_thread)p;
 }
 
-static inline objptr currentThreadStackObjptr (GC_state s) {
-  GC_thread ct = currentThread (s);
-  return ct->stack;
+objptr getStackCurrentObjptr (GC_state s) {
+  GC_thread thread = getThreadCurrent(s);
+  return thread->stack;
 }
 
-static inline GC_stack currentThreadStack (GC_state s) {
-  pointer p = objptrToPointer(currentThreadStackObjptr(s), s->heap.start);
+GC_stack getStackCurrent (GC_state s) {
+  pointer p = objptrToPointer(getStackCurrentObjptr(s), s->heap.start);
   return (GC_stack)p;
 }
 
-static inline size_t currentStackUsed (GC_state s) {
+size_t sizeofStackCurrentUsed (GC_state s) {
   return s->stackTop - s->stackBottom;
 }
 
 
 
-static void setCurrentStack (GC_state s) {
+void setThreadAndStackCurrent (GC_state s) {
   GC_thread thread;
   GC_stack stack;
   
-  thread = currentThread (s);
+  thread = getThreadCurrent (s);
   s->exnStack = thread->exnStack;
-  stack = currentThreadStack (s);
-  s->stackBottom = stackBottom (s, stack);
-  s->stackTop = stackTop (s, stack);
-  s->stackLimit = stackLimit (s, stack);
+  stack = getStackCurrent (s);
+  s->stackBottom = getStackBottom (s, stack);
+  s->stackTop = getStackTop (s, stack);
+  s->stackLimit = getStackLimit (s, stack);
   markCard (s, (pointer)stack);
 }

Added: mlton/branches/on-20050822-x86_64-branch/runtime/gc/current.h
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/current.h	2005-10-30 14:38:45 UTC (rev 4125)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/current.h	2005-10-31 02:47:56 UTC (rev 4126)
@@ -0,0 +1,15 @@
+/* Copyright (C) 1999-2005 Henry Cejtin, Matthew Fluet, Suresh
+ *    Jagannathan, and Stephen Weeks.
+ * Copyright (C) 1997-2000 NEC Research Institute.
+ *
+ * MLton is released under a BSD-style license.
+ * See the file MLton-LICENSE for details.
+ */
+
+objptr getThreadCurrentObjptr (GC_state s);
+GC_thread getThreadCurrent (GC_state s);
+objptr getStackCurrentObjptr (GC_state s);
+GC_stack getStackCurrent (GC_state s);
+size_t sizeofStackCurrentUsed (GC_state s);
+
+void setThreadAndStackCurrent (GC_state s);

Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/dfs-mark.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/dfs-mark.c	2005-10-30 14:38:45 UTC (rev 4125)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/dfs-mark.c	2005-10-31 02:47:56 UTC (rev 4126)
@@ -10,16 +10,11 @@
 /*                       Depth-first Marking                        */
 /* ---------------------------------------------------------------- */
 
-typedef enum {
-  MARK_MODE,
-  UNMARK_MODE,
-} GC_markMode;
-
-static inline bool isMarked (pointer p) {
+bool isMarked (pointer p) {
   return MARK_MASK & getHeader (p);
 }
 
-static bool isMarkedMode (GC_markMode m, pointer p) {
+bool isMarkedMode (GC_markMode m, pointer p) {
   switch (m) {
   case MARK_MODE:
     return isMarked (p);
@@ -30,11 +25,9 @@
   }
 }
 
-#if ASSERT
-static inline pointer arrayIndexAtPointer (GC_state s,
-                                           pointer a,
-                                           GC_arrayCounter arrayIndex,
-                                           uint32_t pointerIndex) {
+pointer arrayIndexAtPointer (GC_state s, pointer a,
+                             GC_arrayCounter arrayIndex,
+                             uint32_t pointerIndex) {
   GC_header header;
   uint16_t numNonObjptrs;
   uint16_t numObjptrs;
@@ -45,7 +38,7 @@
   assert (tag == ARRAY_TAG);
 
   size_t nonObjptrBytesPerElement =
-    numNonObjptrsToBytes(numNonObjptrs, ARRAY_TAG);
+    sizeofNumNonObjptrs (ARRAY_TAG, numNonObjptrs);
   size_t bytesPerElement =
     nonObjptrBytesPerElement
     + (numObjptrs * OBJPTR_SIZE);
@@ -55,7 +48,6 @@
     + nonObjptrBytesPerElement
     + pointerIndex * OBJPTR_SIZE;
 }
-#endif
 
 /* dfsMark (s, r, m, shc) 
  *
@@ -87,7 +79,7 @@
   GC_arrayCounter arrayIndex;
   pointer top; /* The top of the next stack frame to mark. */
   GC_returnAddress returnAddress; 
-  GC_frameLayout *frameLayout;
+  GC_frameLayout frameLayout;
   GC_frameOffsets frameOffsets;
 
   if (isMarkedMode (mode, root))
@@ -150,7 +142,7 @@
   if (NORMAL_TAG == tag) {
     size += 
       GC_NORMAL_HEADER_SIZE 
-      + numNonObjptrsToBytes (numNonObjptrs, tag) 
+      + sizeofNumNonObjptrs (tag, numNonObjptrs) 
       + (numObjptrs * OBJPTR_SIZE);
     if (0 == numObjptrs) {
       /* There is nothing to mark. */
@@ -159,7 +151,7 @@
         cur = hashCons (s, cur, TRUE);
       goto ret;
     }
-    todo = cur + numNonObjptrsToBytes (numNonObjptrs, NORMAL_TAG);
+    todo = cur + sizeofNumNonObjptrs (NORMAL_TAG, numNonObjptrs);
     index = 0;
 markInNormal:
     if (DEBUG_MARK_COMPACT)
@@ -200,7 +192,7 @@
      */
     size += 
       GC_ARRAY_HEADER_SIZE
-      + arraySizeNoHeader (s, cur, numNonObjptrs, numObjptrs);
+      + sizeofArrayNoHeader (s, getArrayLength (cur), numNonObjptrs, numObjptrs);
     if (0 == numObjptrs or 0 == getArrayLength (cur)) {
       /* There is nothing to mark. */
 arrayDone:
@@ -215,7 +207,7 @@
     assert (arrayIndex < getArrayLength (cur));
     index = 0;
     /* Skip to the first pointer. */
-    todo += numNonObjptrsToBytes (numNonObjptrs, ARRAY_TAG);
+    todo += sizeofNumNonObjptrs (ARRAY_TAG, numNonObjptrs);
 markInArray:
     if (DEBUG_MARK_COMPACT)
       fprintf (stderr, "markInArray arrayIndex = %"PRIu32" index = %"PRIu32"\n",
@@ -257,17 +249,17 @@
     size += 
       GC_STACK_HEADER_SIZE
       + sizeof (struct GC_stack) + ((GC_stack)cur)->reserved;
-    top = stackTop (s, (GC_stack)cur);
+    top = getStackTop (s, (GC_stack)cur);
     assert (((GC_stack)cur)->used <= ((GC_stack)cur)->reserved);
 markInStack:
     /* Invariant: top points just past the return address of the frame
      * to be marked.
      */
-    assert (stackBottom (s, (GC_stack)cur) <= top);
+    assert (getStackBottom (s, (GC_stack)cur) <= top);
     if (DEBUG_MARK_COMPACT)
       fprintf (stderr, "markInStack  top = %zu\n",
-               (size_t)(top - stackBottom (s, (GC_stack)cur)));
-    if (top == stackBottom (s, (GC_stack)(cur)))
+               (size_t)(top - getStackBottom (s, (GC_stack)cur)));
+    if (top == getStackBottom (s, (GC_stack)(cur)))
       goto ret;
     index = 0;
     returnAddress = *(GC_returnAddress*) (top - GC_RETURNADDRESS_SIZE);
@@ -323,7 +315,7 @@
    */
   assert (WEAK_TAG != tag);
   if (NORMAL_TAG == tag) {
-    todo = cur + numNonObjptrsToBytes (numNonObjptrs, tag);
+    todo = cur + sizeofNumNonObjptrs (tag, numNonObjptrs);
     index = (header & COUNTER_MASK) >> COUNTER_SHIFT;
     todo += index * OBJPTR_SIZE;
     // prev = *(pointer*)todo;
@@ -333,10 +325,10 @@
     goto markNextInNormal;
   } else if (ARRAY_TAG == tag) {
     arrayIndex = getArrayCounter (cur);
-    todo = cur + arrayIndex * (numNonObjptrsToBytes (numNonObjptrs, ARRAY_TAG)
+    todo = cur + arrayIndex * (sizeofNumNonObjptrs (ARRAY_TAG, numNonObjptrs)
                                + (numObjptrs * OBJPTR_SIZE));
     index = (header & COUNTER_MASK) >> COUNTER_SHIFT;
-    todo += numNonObjptrsToBytes (numNonObjptrs, ARRAY_TAG) + index * OBJPTR_SIZE;
+    todo += sizeofNumNonObjptrs (ARRAY_TAG, numNonObjptrs) + index * OBJPTR_SIZE;
     // prev = *(pointer*)todo;
     prev = fetchObjptrToPointer (todo, s->heap.start);
     // *(pointer*)todo = next;
@@ -360,3 +352,24 @@
   }
   assert (FALSE);
 }
+
+void dfsMarkTrue (GC_state s, objptr *opp) {
+  pointer p;
+
+  p = objptrToPointer (*opp, s->heap.start);
+  dfsMark (s, p, MARK_MODE, TRUE);
+}
+
+void dfsMarkFalse (GC_state s, objptr *opp) {
+  pointer p;
+
+  p = objptrToPointer (*opp, s->heap.start);
+  dfsMark (s, p, MARK_MODE, FALSE);
+}
+
+void dfsUnmark (GC_state s, objptr *opp) {
+  pointer p;
+
+  p = objptrToPointer (*opp, s->heap.start);
+  dfsMark (s, p, UNMARK_MODE, FALSE);
+}

Added: mlton/branches/on-20050822-x86_64-branch/runtime/gc/dfs-mark.h
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/dfs-mark.h	2005-10-30 14:38:45 UTC (rev 4125)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/dfs-mark.h	2005-10-31 02:47:56 UTC (rev 4126)
@@ -0,0 +1,24 @@
+/* Copyright (C) 1999-2005 Henry Cejtin, Matthew Fluet, Suresh
+ *    Jagannathan, and Stephen Weeks.
+ * Copyright (C) 1997-2000 NEC Research Institute.
+ *
+ * MLton is released under a BSD-style license.
+ * See the file MLton-LICENSE for details.
+ */
+
+typedef enum {
+  MARK_MODE,
+  UNMARK_MODE,
+} GC_markMode;
+
+bool isMarked (pointer p);
+bool isMarkedMode (GC_markMode m, pointer p);
+pointer arrayIndexAtPointer (GC_state s,
+                             pointer a,
+                             GC_arrayCounter arrayIndex,
+                             uint32_t pointerIndex);
+size_t dfsMark (GC_state s, pointer root,
+                GC_markMode mode, bool shouldHashCons);
+void dfsMarkTrue (GC_state s, objptr *opp);
+void dfsMarkFalse (GC_state s, objptr *opp);
+void dfsUnmark (GC_state s, objptr *opp);

Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/done.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/done.c	2005-10-30 14:38:45 UTC (rev 4125)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/done.c	2005-10-31 02:47:56 UTC (rev 4126)
@@ -87,6 +87,6 @@
     fprintf (out, "minor skipped: %s bytes\n", 
              uintmaxToCommaString (s->cumulativeStatistics.minorBytesSkipped));
   }
-  heapRelease (s, &s->heap);
-  heapRelease (s, &s->secondaryHeap);
+  releaseHeap (s, &s->heap);
+  releaseHeap (s, &s->secondaryHeap);
 }

Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/enter_leave.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/enter_leave.c	2005-10-30 14:38:45 UTC (rev 4125)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/enter_leave.c	2005-10-31 02:47:56 UTC (rev 4126)
@@ -11,13 +11,12 @@
  * that the function is run in a critical section and check the GC
  * invariant.
  */
-static void enter (GC_state s) {
-
+void enter (GC_state s) {
   if (DEBUG)
     fprintf (stderr, "enter\n");
   /* used needs to be set because the mutator has changed s->stackTop. */
-  currentThreadStack(s)->used = currentStackUsed (s);
-  currentThread(s)->exnStack = s->exnStack;
+  getStackCurrent(s)->used = sizeofStackCurrentUsed (s);
+  getThreadCurrent(s)->exnStack = s->exnStack;
   if (DEBUG) 
     displayGCState (s, stderr);
   atomicBegin (s);
@@ -26,7 +25,7 @@
     fprintf (stderr, "enter ok\n");
 }
 
-static void leave (GC_state s) {
+void leave (GC_state s) {
   if (DEBUG)
     fprintf (stderr, "leave\n");
   /* The mutator frontier invariant may not hold

Added: mlton/branches/on-20050822-x86_64-branch/runtime/gc/enter_leave.h
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/enter_leave.h	2005-10-30 14:38:45 UTC (rev 4125)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/enter_leave.h	2005-10-31 02:47:56 UTC (rev 4126)
@@ -0,0 +1,10 @@
+/* Copyright (C) 1999-2005 Henry Cejtin, Matthew Fluet, Suresh
+ *    Jagannathan, and Stephen Weeks.
+ * Copyright (C) 1997-2000 NEC Research Institute.
+ *
+ * MLton is released under a BSD-style license.
+ * See the file MLton-LICENSE for details.
+ */
+
+void enter (GC_state s);
+void leave (GC_state s);

Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/foreach.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/foreach.c	2005-10-30 14:38:45 UTC (rev 4125)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/foreach.c	2005-10-31 02:47:56 UTC (rev 4126)
@@ -6,10 +6,7 @@
  * See the file MLton-LICENSE for details.
  */
 
-typedef void (*GC_foreachObjptrFun) (GC_state s, objptr *opp);
-
-static inline void maybeCall (GC_foreachObjptrFun f, 
-                              GC_state s, objptr *opp) {
+void maybeCall (GC_state s, GC_foreachObjptrFun f, objptr *opp) {
   if (isObjptr (*opp))
     f (s, opp);
 }
@@ -18,19 +15,18 @@
  * 
  * Apply f to each global object pointer into the heap. 
  */
-static inline void foreachGlobalObjptr (GC_state s, 
-                                        GC_foreachObjptrFun f) {
+void foreachGlobalObjptr (GC_state s, GC_foreachObjptrFun f) {
   for (unsigned int i = 0; i < s->globalsLength; ++i) {
     if (DEBUG_DETAILED)
       fprintf (stderr, "foreachGlobal %u\n", i);
-    maybeCall (f, s, &s->globals [i]);
+    maybeCall (s, f, &s->globals [i]);
   }
   if (DEBUG_DETAILED)
     fprintf (stderr, "foreachGlobal threads\n");
-  maybeCall (f, s, &s->callFromCHandlerThread);
-  maybeCall (f, s, &s->currentThread);
-  maybeCall (f, s, &s->savedThread);
-  maybeCall (f, s, &s->signalHandlerThread);
+  maybeCall (s, f, &s->callFromCHandlerThread);
+  maybeCall (s, f, &s->currentThread);
+  maybeCall (s, f, &s->savedThread);
+  maybeCall (s, f, &s->signalHandlerThread);
 }
 
 
@@ -41,10 +37,8 @@
  *
  * If skipWeaks, then the object pointer in weak objects is skipped.
  */
-static inline pointer foreachObjptrInObject (GC_state s, 
-                                             pointer p,
-                                             bool skipWeaks,
-                                             GC_foreachObjptrFun f) {
+pointer foreachObjptrInObject (GC_state s, pointer p,
+                               bool skipWeaks, GC_foreachObjptrFun f) {
   GC_header header;
   uint16_t numNonObjptrs;
   uint16_t numObjptrs;
@@ -62,7 +56,7 @@
              (uintptr_t)p, header, objectTypeTagToString (tag), 
              numNonObjptrs, numObjptrs);
   if (NORMAL_TAG == tag) {
-    p += numNonObjptrsToBytes(numNonObjptrs, NORMAL_TAG);
+    p += sizeofNumNonObjptrs (NORMAL_TAG, numNonObjptrs);
     pointer max = p + (numObjptrs * OBJPTR_SIZE);
     /* Apply f to all internal pointers. */
     for ( ; p < max; p += OBJPTR_SIZE) {
@@ -70,12 +64,12 @@
         fprintf (stderr, 
                  "  p = "FMTPTR"  *p = "FMTOBJPTR"\n",
                  (uintptr_t)p, *(objptr*)p);
-      maybeCall (f, s, (objptr*)p);
+      maybeCall (s, f, (objptr*)p);
     }
   } else if (WEAK_TAG == tag) {
-    p += numNonObjptrsToBytes(numNonObjptrs, NORMAL_TAG);
+    p += sizeofNumNonObjptrs (NORMAL_TAG, numNonObjptrs);
     if (not skipWeaks and 1 == numObjptrs) {
-      maybeCall (f, s, (objptr*)p);
+      maybeCall (s, f, (objptr*)p);
       p += OBJPTR_SIZE;
     }
   } else if (ARRAY_TAG == tag) {
@@ -86,7 +80,7 @@
     
     numElements = getArrayLength (p);
     bytesPerElement = 
-      numNonObjptrsToBytes(numNonObjptrs, ARRAY_TAG) 
+      sizeofNumNonObjptrs (ARRAY_TAG, numNonObjptrs) 
       + (numObjptrs * OBJPTR_SIZE);
     dataBytes = numElements * bytesPerElement;
     /* Must check 0 == dataBytes before 0 == numPointers to correctly
@@ -103,13 +97,13 @@
       if (0 == numNonObjptrs)
         /* Array with only pointers. */
         for ( ; p < last; p += OBJPTR_SIZE)
-          maybeCall (f, s, (objptr*)p);
+          maybeCall (s, f, (objptr*)p);
       else {
         /* Array with a mix of pointers and non-pointers. */
         size_t nonObjptrBytes;
         size_t objptrBytes;
         
-        nonObjptrBytes = numNonObjptrsToBytes(numNonObjptrs, ARRAY_TAG);
+        nonObjptrBytes = sizeofNumNonObjptrs (ARRAY_TAG, numNonObjptrs);
         objptrBytes = numObjptrs * OBJPTR_SIZE;
 
         /* For each array element. */
@@ -121,7 +115,7 @@
           next = p + objptrBytes;
           /* For each internal pointer. */
           for ( ; p < next; p += OBJPTR_SIZE) 
-            maybeCall (f, s, (objptr*)p);
+            maybeCall (s, f, (objptr*)p);
         }
       }
       assert (p == last);
@@ -133,13 +127,13 @@
     pointer top, bottom; 
     unsigned int i;
     GC_returnAddress returnAddress; 
-    GC_frameLayout *frameLayout;
+    GC_frameLayout frameLayout;
     GC_frameOffsets frameOffsets;
 
     assert (STACK_TAG == tag);
     stack = (GC_stack)p;
-    bottom = stackBottom (s, stack); 
-    top = stackTop (s, stack);
+    bottom = getStackBottom (s, stack); 
+    top = getStackTop (s, stack);
     if (DEBUG) {
       fprintf (stderr, "  bottom = "FMTPTR"  top = "FMTPTR"\n",
                (uintptr_t)bottom, (uintptr_t)top);
@@ -159,7 +153,7 @@
         if (DEBUG)
           fprintf(stderr, "  offset %"PRIx16"  address "FMTOBJPTR"\n",
                   frameOffsets[i + 1], *(objptr*)(top + frameOffsets[i + 1]));
-        maybeCall(f, s, (objptr*)(top + frameOffsets[i + 1]));
+        maybeCall (s, f, (objptr*)(top + frameOffsets[i + 1]));
       }
     }
     assert(top == bottom);
@@ -180,11 +174,8 @@
  * If skipWeaks, then the object pointer in weak objects is skipped.
  */
 
-static inline pointer foreachObjptrInRange (GC_state s, 
-                                            pointer front, 
-                                            pointer *back,
-                                            bool skipWeaks,
-                                            GC_foreachObjptrFun f) {
+pointer foreachObjptrInRange (GC_state s, pointer front, pointer *back,
+                              bool skipWeaks, GC_foreachObjptrFun f) {
   pointer b;
 
   assert (isAlignedFrontier (s, front));
@@ -201,7 +192,7 @@
         fprintf (stderr, 
                  "  front = "FMTPTR"  *back = "FMTPTR"\n",
                  (uintptr_t)front, (uintptr_t)(*back));
-      front = foreachObjptrInObject (s, objectData (s, front), skipWeaks, f);
+      front = foreachObjptrInObject (s, advanceToObjectData (s, front), skipWeaks, f);
     }
     b = *back;
   }
@@ -209,19 +200,17 @@
 }
 
 
-typedef void (*GC_foreachStackFrameFun) (GC_state s, GC_frameIndex i);
-
 /* Apply f to the frame index of each frame in the current thread's stack. */
 void foreachStackFrame (GC_state s, GC_foreachStackFrameFun f) {
   pointer bottom;
   GC_frameIndex index;
-  GC_frameLayout *layout;
+  GC_frameLayout layout;
   GC_returnAddress returnAddress;
   pointer top;
 
   if (DEBUG_PROFILE)
     fprintf (stderr, "foreachStackFrame\n");
-  bottom = stackBottom (s, currentThreadStack(s));
+  bottom = getStackBottom (s, getStackCurrent(s));
   if (DEBUG_PROFILE)
     fprintf (stderr, "  bottom = "FMTPTR"  top = "FMTPTR".\n",
              (uintptr_t)bottom, (uintptr_t)s->stackTop);

Added: mlton/branches/on-20050822-x86_64-branch/runtime/gc/foreach.h
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/foreach.h	2005-10-30 14:38:45 UTC (rev 4125)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/foreach.h	2005-10-31 02:47:56 UTC (rev 4126)
@@ -0,0 +1,47 @@
+/* Copyright (C) 1999-2005 Henry Cejtin, Matthew Fluet, Suresh
+ *    Jagannathan, and Stephen Weeks.
+ * Copyright (C) 1997-2000 NEC Research Institute.
+ *
+ * MLton is released under a BSD-style license.
+ * See the file MLton-LICENSE for details.
+ */
+
+typedef void (*GC_foreachObjptrFun) (GC_state s, objptr *opp);
+
+void maybeCall (GC_state s, GC_foreachObjptrFun f, objptr *opp);
+/* foreachGlobalObjptr (s, f)
+ * 
+ * Apply f to each global object pointer into the heap. 
+ */
+void foreachGlobalObjptr (GC_state s, GC_foreachObjptrFun f);
+/* foreachObjptrInObject (s, p, skipWeaks, f) 
+ * 
+ * Applies f to each object pointer in the object pointed to by p.
+ * Returns pointer to the end of object, i.e. just past object.
+ *
+ * If skipWeaks, then the object pointer in weak objects is skipped.
+ */
+pointer foreachObjptrInObject (GC_state s, pointer p,
+                               bool skipWeaks, GC_foreachObjptrFun f);
+/* foreachObjptrInRange (s, front, back, skipWeaks, f)
+ *
+ * Apply f to each pointer between front and *back, which should be a
+ * contiguous sequence of objects, where front points at the beginning
+ * of the first object and *back points just past the end of the last
+ * object.  f may increase *back (for example, this is done by
+ * forward).  foreachObjptrInRange returns a pointer to the end of
+ * the last object it visits.
+ *
+ * If skipWeaks, then the object pointer in weak objects is skipped.
+ */
+pointer foreachObjptrInRange (GC_state s, pointer front, pointer *back,
+                              bool skipWeaks, GC_foreachObjptrFun f);
+
+
+typedef void (*GC_foreachStackFrameFun) (GC_state s, GC_frameIndex i);
+
+/* foreachStackFrame (s, f);
+ *
+ * Apply f to the frame index of each frame in the current stack.
+ */
+void foreachStackFrame (GC_state s, GC_foreachStackFrameFun f);

Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/frame.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/frame.c	2005-10-30 14:38:45 UTC (rev 4125)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/frame.c	2005-10-31 02:47:56 UTC (rev 4126)
@@ -6,8 +6,7 @@
  * See the file MLton-LICENSE for details.
  */
 
-static inline GC_frameIndex
-getFrameIndexFromReturnAddress (GC_state s, GC_returnAddress ra) {
+GC_frameIndex getFrameIndexFromReturnAddress (GC_state s, GC_returnAddress ra) {
   GC_frameIndex res;
 
   res = s->returnAddressToFrameIndex (ra);
@@ -17,14 +16,11 @@
   return res;
 }
 
-static inline GC_frameLayout * 
-getFrameLayoutFromFrameIndex (GC_state s, GC_frameIndex index) {
-  GC_frameLayout *layout;
+GC_frameLayout getFrameLayoutFromFrameIndex (GC_state s, GC_frameIndex index) {
+  GC_frameLayout layout;
 
   if (DEBUG_DETAILED)
-    fprintf (stderr, 
-             "index = "FMTFI
-             "  frameLayoutsLength = %"PRIu32"\n",
+    fprintf (stderr, "index = "FMTFI"  frameLayoutsLength = %"PRIu32"\n",
             index, s->frameLayoutsLength);
   assert (index < s->frameLayoutsLength);
   layout = &(s->frameLayouts[index]);
@@ -32,9 +28,8 @@
   return layout;
 }
 
-static inline GC_frameLayout * 
-getFrameLayoutFromReturnAddress (GC_state s, GC_returnAddress ra) {
-  GC_frameLayout *layout;
+GC_frameLayout getFrameLayoutFromReturnAddress (GC_state s, GC_returnAddress ra) {
+  GC_frameLayout layout;
   GC_frameIndex index;
   
   index = getFrameIndexFromReturnAddress (s, ra);

Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/frame.h
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/frame.h	2005-10-30 14:38:45 UTC (rev 4125)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/frame.h	2005-10-31 02:47:56 UTC (rev 4126)
@@ -34,9 +34,9 @@
 
 typedef struct GC_frameLayout {
   GC_frameKind kind;
+  GC_frameOffsets offsets;
   uint16_t size;
-  GC_frameOffsets offsets;
-} GC_frameLayout;
+} *GC_frameLayout;
 typedef uint32_t GC_frameIndex;
 #define PRIFI PRIu32
 #define FMTFI "%"PRIFI
@@ -44,3 +44,7 @@
 typedef uintptr_t GC_returnAddress;
 #define GC_RETURNADDRESS_SIZE sizeof(GC_returnAddress)
 #define FMTRA "0x%016"PRIxPTR
+
+GC_frameIndex getFrameIndexFromReturnAddress (GC_state s, GC_returnAddress ra);
+GC_frameLayout getFrameLayoutFromFrameIndex (GC_state s, GC_frameIndex index);
+GC_frameLayout getFrameLayoutFromReturnAddress (GC_state s, GC_returnAddress ra);

Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/garbage-collection.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/garbage-collection.c	2005-10-30 14:38:45 UTC (rev 4125)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/garbage-collection.c	2005-10-31 02:47:56 UTC (rev 4126)
@@ -6,11 +6,11 @@
  * See the file MLton-LICENSE for details.
  */
 
-static void minorGC (GC_state s) {
+void minorGC (GC_state s) {
   minorCheneyCopyGC (s);
 }
 
-static void majorGC (GC_state s, size_t bytesRequested, bool mayResize) {
+void majorGC (GC_state s, size_t bytesRequested, bool mayResize) {
   uintmax_t numGCs;
   size_t desiredSize;
 
@@ -23,12 +23,12 @@
            < s->ratios.hashCons))
     s->hashConsDuringGC = TRUE;
   desiredSize = 
-    heapDesiredSize (s, s->lastMajorStatistics.bytesLive + bytesRequested, 0);
+    sizeofHeapDesired (s, s->lastMajorStatistics.bytesLive + bytesRequested, 0);
   if ((not FORCE_MARK_COMPACT)
       and not s->hashConsDuringGC // only markCompact can hash cons
       and s->heap.size < s->sysvals.ram
-      and (not heapIsInit (&s->secondaryHeap)
-           or secondaryHeapCreate (s, desiredSize)))
+      and (not isHeapInit (&s->secondaryHeap)
+           or createHeapSecondary (s, desiredSize)))
     majorCheneyCopyGC (s);
   else
     majorMarkCompactGC (s);
@@ -36,17 +36,18 @@
   s->lastMajorStatistics.bytesLive = s->heap.oldGenSize;
   if (s->lastMajorStatistics.bytesLive > s->cumulativeStatistics.maxBytesLive)
     s->cumulativeStatistics.maxBytesLive = s->lastMajorStatistics.bytesLive;
-  /* Notice that the s->bytesLive below is different than the s->bytesLive
-   * used as an argument to heapAllocateSecondSemi above.  Above, it was 
-   * an estimate.  Here, it is exactly how much was live after the GC.
+  /* Notice that the s->bytesLive below is different than the
+   * s->bytesLive used as an argument to createHeapSecondary above.
+   * Above, it was an estimate.  Here, it is exactly how much was live
+   * after the GC.
    */
   if (mayResize)
-    heapResize (s, s->lastMajorStatistics.bytesLive + bytesRequested);
-  secondaryHeapResize (s);
+    resizeHeap (s, s->lastMajorStatistics.bytesLive + bytesRequested);
+  resizeHeapSecondary (s);
   assert (s->heap.oldGenSize + bytesRequested <= s->heap.size);
 }
 
-static inline void enterGC (GC_state s) {
+void enterGC (GC_state s) {
   if (s->profiling.isOn) {
     /* We don't need to profileEnter for count profiling because it
      * has already bumped the counter.  If we did allow the bump, then
@@ -59,7 +60,7 @@
   s->amInGC = TRUE;
 }
 
-static inline void leaveGC (GC_state s) {
+void leaveGC (GC_state s) {
   if (s->profiling.isOn) {
     if (s->profiling.stack
         and not (PROFILE_COUNT == s->profiling.kind))
@@ -68,7 +69,7 @@
   s->amInGC = FALSE;
 }
 
-static inline bool needGCTime (GC_state s) {
+bool needGCTime (GC_state s) {
   return 
     DEBUG 
     or s->controls.summary 
@@ -76,11 +77,11 @@
     or s->rusageIsEnabled;
 }
 
-static void doGC (GC_state s, 
-                  size_t oldGenBytesRequested,
-                  size_t nurseryBytesRequested, 
-                  bool forceMajor,
-                  bool mayResize) {
+void doGC (GC_state s, 
+           size_t oldGenBytesRequested,
+           size_t nurseryBytesRequested, 
+           bool forceMajor,
+           bool mayResize) {
   uintmax_t gcTime;
   bool stackTopOk;
   size_t stackBytesRequested;
@@ -98,7 +99,9 @@
   minorGC (s);
   stackTopOk = mutatorStackInvariant (s);
   stackBytesRequested = 
-    stackTopOk ? 0 : stackSizeTotalAligned (s, stackGrowSize (s));
+    stackTopOk 
+    ? 0 
+    : sizeofStackWithHeaderAligned (s, sizeofStackGrow (s, getStackCurrent (s)));
   totalBytesRequested = 
     oldGenBytesRequested 
     + nurseryBytesRequested
@@ -106,13 +109,13 @@
   if (forceMajor 
       or totalBytesRequested > s->heap.size - s->heap.oldGenSize)
     majorGC (s, totalBytesRequested, mayResize);
-  heapSetNursery (s, oldGenBytesRequested + stackBytesRequested, 
+  setHeapNursery (s, oldGenBytesRequested + stackBytesRequested, 
                   nurseryBytesRequested);
-  assert (heapHasBytesFree (s, oldGenBytesRequested + stackBytesRequested,
+  assert (hasHeapBytesFree (s, oldGenBytesRequested + stackBytesRequested,
                             nurseryBytesRequested));
   unless (stackTopOk)
-    stackGrow (s);
-  setCurrentStack (s);
+    growStack (s);
+  setThreadAndStackCurrent (s);
   if (needGCTime (s)) {
     gcTime = stopTiming (&ru_start, &s->cumulativeStatistics.ru_gc);
     s->cumulativeStatistics.maxPause = 
@@ -138,17 +141,17 @@
   }
   if (DEBUG) 
     displayGCState (s, stderr);
-  assert (heapHasBytesFree (s, oldGenBytesRequested, nurseryBytesRequested));
+  assert (hasHeapBytesFree (s, oldGenBytesRequested, nurseryBytesRequested));
   assert (invariant (s));
   leaveGC (s);
 }
 
-static inline void ensureMutatorInvariant (GC_state s, bool force) {
+void ensureMutatorInvariant (GC_state s, bool force) {
   if (force
       or not (mutatorFrontierInvariant(s))
       or not (mutatorStackInvariant(s))) {
     /* This GC will grow the stack, if necessary. */
-    doGC (s, 0, currentThread(s)->bytesNeeded, force, TRUE);
+    doGC (s, 0, getThreadCurrent(s)->bytesNeeded, force, TRUE);
   }
   assert (mutatorFrontierInvariant(s));
   assert (mutatorStackInvariant(s));
@@ -157,14 +160,14 @@
 /* ensureFree (s, b) ensures that upon return
  *      b <= s->limitPlusSlop - s->frontier
  */
-static inline void ensureFree (GC_state s, size_t bytesRequested) {
+void ensureFree (GC_state s, size_t bytesRequested) {
   assert (s->frontier <= s->limitPlusSlop);
   if (bytesRequested > (size_t)(s->limitPlusSlop - s->frontier))
     doGC (s, 0, bytesRequested, FALSE, TRUE);
   assert (bytesRequested <= (size_t)(s->limitPlusSlop - s->frontier));
 }
 
-static void switchToThread (GC_state s, objptr op) {
+void switchToThread (GC_state s, objptr op) {
   if (DEBUG_THREADS) {
     GC_thread thread;
     GC_stack stack;
@@ -176,7 +179,7 @@
              op, stack->used, stack->reserved);
   }
   s->currentThread = op;
-  setCurrentStack (s);
+  setThreadAndStackCurrent (s);
 }
 
 /* GC_startHandler does not do an enter()/leave(), even though it is
@@ -214,7 +217,7 @@
   s->signalsInfo.amInSignalHandler = FALSE;     
 }
 
-static inline void maybeSwitchToHandler (GC_state s) {
+void maybeSwitchToHandler (GC_state s) {
   if (s->atomicState == 1 
       and s->signalsInfo.signalIsPending) {
     GC_startHandler (s);
@@ -222,48 +225,49 @@
   }
 }
 
-/* void GC_switchToThread (GC_state s, GC_thread t, uint ensureBytesFree) { */
-/*         if (DEBUG_THREADS) */
-/*                 fprintf (stderr, "GC_switchToThread (0x%08x, %u)\n", (uint)t, ensureBytesFree); */
-/*         if (FALSE) { */
-/*                 /\* This branch is slower than the else branch, especially  */
-/*                  * when debugging is turned on, because it does an invariant */
-/*                  * check on every thread switch. */
-/*                  * So, we'll stick with the else branch for now. */
-/*                  *\/ */
-/*                 enter (s); */
-/*                 s->currentThread->bytesNeeded = ensureBytesFree; */
-/*                 switchToThread (s, t); */
-/*                 s->canHandle--; */
-/*                 maybeSwitchToHandler (s); */
-/*                 ensureMutatorInvariant (s, FALSE); */
-/*                 assert (mutatorFrontierInvariant(s)); */
-/*                 assert (mutatorStackInvariant(s)); */
-/*                 leave (s); */
-/*         } else { */
-/*                 /\* BEGIN: enter(s); *\/ */
-/*                 s->currentThread->stack->used = currentStackUsed (s); */
-/*                 s->currentThread->exnStack = s->exnStack; */
-/*                 atomicBegin (s); */
-/*                 /\* END: enter(s); *\/ */
-/*                 s->currentThread->bytesNeeded = ensureBytesFree; */
-/*                 switchToThread (s, t); */
-/*                 s->canHandle--; */
-/*                 maybeSwitchToHandler (s); */
-/*                 /\* BEGIN: ensureMutatorInvariant *\/ */
-/*                 if (not (mutatorFrontierInvariant(s)) */
-/*                         or not (mutatorStackInvariant(s))) { */
-/*                         /\* This GC will grow the stack, if necessary. *\/ */
-/*                         doGC (s, 0, s->currentThread->bytesNeeded, FALSE, TRUE); */
-/*                 }  */
-/*                 /\* END: ensureMutatorInvariant *\/ */
-/*                 /\* BEGIN: leave(s); *\/ */
-/*                 atomicEnd (s); */
-/*                 /\* END: leave(s); *\/ */
-/*         } */
-/*         assert (mutatorFrontierInvariant(s)); */
-/*         assert (mutatorStackInvariant(s)); */
-/* } */
+void GC_switchToThread (GC_state s, GC_thread t, size_t ensureBytesFree) {
+  if (DEBUG_THREADS)
+    fprintf (stderr, "GC_switchToThread ("FMTPTR", %zu)\n", 
+             (uintptr_t)t, ensureBytesFree);
+  if (FALSE) {
+    /* This branch is slower than the else branch, especially
+     * when debugging is turned on, because it does an invariant
+     * check on every thread switch.
+     * So, we'll stick with the else branch for now.
+     */
+    enter (s);
+    getThreadCurrent(s)->bytesNeeded = ensureBytesFree;
+    switchToThread (s, pointerToObjptr((pointer)t, s->heap.start));
+    s->atomicState--;
+    maybeSwitchToHandler (s);
+    ensureMutatorInvariant (s, FALSE);
+    assert (mutatorFrontierInvariant(s));
+    assert (mutatorStackInvariant(s));
+    leave (s);
+  } else {
+    /* BEGIN: enter(s); */
+    getStackCurrent(s)->used = sizeofStackCurrentUsed (s);
+    getThreadCurrent(s)->exnStack = s->exnStack;
+    atomicBegin (s);
+    /* END: enter(s); */
+    getThreadCurrent(s)->bytesNeeded = ensureBytesFree;
+    switchToThread (s, pointerToObjptr((pointer)t, s->heap.start));
+    s->atomicState--;
+    maybeSwitchToHandler (s);
+    /* BEGIN: ensureMutatorInvariant */
+    if (not (mutatorFrontierInvariant(s))
+        or not (mutatorStackInvariant(s))) {
+      /* This GC will grow the stack, if necessary. */
+      doGC (s, 0, getThreadCurrent(s)->bytesNeeded, FALSE, TRUE);
+    }
+    /* END: ensureMutatorInvariant */
+    /* BEGIN: leave(s); */
+    atomicEnd (s);
+    /* END: leave(s); */
+  }
+  assert (mutatorFrontierInvariant(s));
+  assert (mutatorStackInvariant(s));
+}
 
 void GC_gc (GC_state s, size_t bytesRequested, bool force,
             char *file, int line) {
@@ -271,11 +275,11 @@
     fprintf (stderr, "%s %d: GC_gc\n", file, line);
   enter (s);
   /* When the mutator requests zero bytes, it may actually need as
-   * much as LIMIT_SLOP.
+   * much as GC_HEAP_LIMIT_SLOP.
    */
   if (0 == bytesRequested)
-    bytesRequested = LIMIT_SLOP;
-  currentThread(s)->bytesNeeded = bytesRequested;
+    bytesRequested = GC_HEAP_LIMIT_SLOP;
+  getThreadCurrent(s)->bytesNeeded = bytesRequested;
   maybeSwitchToHandler (s);
   ensureMutatorInvariant (s, force);
   assert (mutatorFrontierInvariant(s));

Added: mlton/branches/on-20050822-x86_64-branch/runtime/gc/garbage-collection.h
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/garbage-collection.h	2005-10-30 14:38:45 UTC (rev 4125)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/garbage-collection.h	2005-10-31 02:47:56 UTC (rev 4126)
@@ -0,0 +1,27 @@
+/* Copyright (C) 1999-2005 Henry Cejtin, Matthew Fluet, Suresh
+ *    Jagannathan, and Stephen Weeks.
+ * Copyright (C) 1997-2000 NEC Research Institute.
+ *
+ * MLton is released under a BSD-style license.
+ * See the file MLton-LICENSE for details.
+ */
+
+void minorGC (GC_state s);
+void majorGC (GC_state s, size_t bytesRequested, bool mayResize);
+void enterGC (GC_state s);
+void leaveGC (GC_state s);
+bool needGCTime (GC_state s);
+void doGC (GC_state s, 
+           size_t oldGenBytesRequested,
+           size_t nurseryBytesRequested, 
+           bool forceMajor,
+           bool mayResize);
+void ensureMutatorInvariant (GC_state s, bool force);
+void ensureFree (GC_state s, size_t bytesRequested);
+void switchToThread (GC_state s, objptr op);
+void GC_startHandler (GC_state s);
+void GC_finishHandler (GC_state s);
+void maybeSwitchToHandler (GC_state s);
+void GC_switchToThread (GC_state s, GC_thread t, size_t ensureBytesFree);
+void GC_gc (GC_state s, size_t bytesRequested, bool force,
+            char *file, int line);

Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/gc_prefix.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/gc_prefix.c	2005-10-30 14:38:45 UTC (rev 4125)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/gc_prefix.c	2005-10-31 02:47:56 UTC (rev 4126)
@@ -1,6 +1,5 @@
-#include "gc.h"
+#include "libgc.h"
 
 static inline size_t meg (size_t n) {
   return n / (1024ul * 1024ul);
 }
-

Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/gc_state.h
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/gc_state.h	2005-10-30 14:38:45 UTC (rev 4125)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/gc_state.h	2005-10-31 02:47:56 UTC (rev 4126)
@@ -19,7 +19,7 @@
   struct GC_cumulativeStatistics cumulativeStatistics;
   objptr currentThread; /* Currently executing thread (in heap). */
   uint32_t exnStack;
-  GC_frameLayout *frameLayouts; /* Array of frame layouts. */
+  GC_frameLayout frameLayouts; /* Array of frame layouts. */
   uint32_t frameLayoutsLength; /* Cardinality of frameLayouts array. */
   pointer frontier; /* heap.start <= frontier < limit */
   struct GC_generationalMaps generationalMaps;
@@ -30,14 +30,14 @@
   struct GC_intInfInit *intInfInits;
   uint32_t intInfInitsLength;
   struct GC_lastMajorStatistics lastMajorStatistics;
-  pointer limit; /* limit = heap.start + heap.totalBytes */
-  pointer limitPlusSlop; /* limit + LIMIT_SLOP */
+  pointer limit; /* limit = heap.start + heap.size */
+  pointer limitPlusSlop; /* limit + GC_HEAP_LIMIT_SLOP */
   void (*loadGlobals)(int fd); /* loads the globals from the fd. */
   uint32_t magic; /* The magic number for this executable. */
   uint32_t maxFrameSize;
   /*Bool*/bool mutatorMarksCards;
   GC_objectHashTable objectHashTable;
-  GC_objectType *objectTypes; /* Array of object types. */
+  GC_objectType objectTypes; /* Array of object types. */
   uint32_t objectTypesLength; /* Cardinality of objectTypes array. */
   struct GC_profiling profiling;
   uint32_t (*returnAddressToFrameIndex) (GC_returnAddress ra);
@@ -59,3 +59,5 @@
   uint32_t vectorInitsLength;
   GC_weak weaks; /* Linked list of (live) weak pointers */
 };
+
+void displayGCState (GC_state s, FILE *stream);

Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/generational.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/generational.c	2005-10-30 14:38:45 UTC (rev 4125)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/generational.c	2005-10-31 02:47:56 UTC (rev 4126)
@@ -6,8 +6,6 @@
  * See the file MLton-LICENSE for details.
  */
 
-#define CROSS_MAP_EMPTY ((GC_crossMapElem)255)
-
 void displayGenerationalMaps (__attribute__ ((unused)) GC_state s,
                               struct GC_generationalMaps *generational,
                               FILE *stream) {
@@ -25,56 +23,78 @@
           generational->crossMapLength,
           generational->crossMapValidSize);
   if (DEBUG_GENERATIONAL and DEBUG_DETAILED) {
-    unsigned int i;
+    GC_crossMapIndex i;
 
     fprintf (stderr, "crossMap trues\n");
-    for (i = 0; i < generational->crossMapLength; ++i)
+    for (i = 0; i < generational->crossMapLength; i++)
       unless (CROSS_MAP_EMPTY == generational->crossMap[i])
-        fprintf (stderr, "\t%u\n", i);
+        fprintf (stderr, "\t"FMTCMI"\n", i);
     fprintf (stderr, "\n");
   }               
 }
 
-
-static inline uintptr_t pointerToCardIndex (pointer p) {
-  return (uintptr_t)p >> CARD_SIZE_LOG2;
+GC_cardMapIndex pointerToCardMapIndexAbsolute (pointer p) {
+  return (GC_cardMapIndex)p >> CARD_SIZE_LOG2;
 }
-static inline size_t sizeToCardIndex (size_t n) {
-  return n >> CARD_SIZE_LOG2;
+GC_cardMapIndex sizeToCardMapIndex (size_t z) {
+  return (GC_cardMapIndex)z >> CARD_SIZE_LOG2;
 }
-static inline size_t cardIndexToSize (size_t n) {
-  return n << CARD_SIZE_LOG2;
+size_t cardMapIndexToSize (GC_cardMapIndex i) {
+  return (size_t)i << CARD_SIZE_LOG2;
 }
-
-static inline pointer pointerToCardMapAddr (GC_state s, pointer p) {
+pointer pointerToCardMapAddr (GC_state s, pointer p) {
   pointer res;
   
-  res = &s->generationalMaps.cardMapAbsolute [pointerToCardIndex (p)];
+  res = &s->generationalMaps.cardMapAbsolute[pointerToCardMapIndexAbsolute (p)];
   if (DEBUG_CARD_MARKING)
     fprintf (stderr, "pointerToCardMapAddr ("FMTPTR") = "FMTPTR"\n",
              (uintptr_t)p, (uintptr_t)res);
   return res;
 }
 
-static inline bool cardIsMarked (GC_state s, pointer p) {
+bool isCardMarked (GC_state s, pointer p) {
   return (*pointerToCardMapAddr (s, p) != 0x0);
 }
 
-static inline void markCard (GC_state s, pointer p) {
+void markCard (GC_state s, pointer p) {
   if (DEBUG_CARD_MARKING)
     fprintf (stderr, "markCard ("FMTPTR")\n", (uintptr_t)p);
   if (s->mutatorMarksCards)
-    *pointerToCardMapAddr (s, p) = 0x1;
+    *(pointerToCardMapAddr (s, p)) = 0x1;
 }
 
-static inline void clearCardMap (GC_state s) {
+void setCardMapAbsolute (GC_state s) {
+  unless (s->mutatorMarksCards)
+    return;
+  /* It's OK if the subtraction below underflows because all the
+   * subsequent additions to mark the cards will overflow and put us
+   * in the right place.
+   */
+  s->generationalMaps.cardMapAbsolute = 
+    pointerToCardMapAddr (s, s->heap.start);
+  if (DEBUG_CARD_MARKING)
+    fprintf (stderr, "setCardMapAbsolute = "FMTPTR"\n",
+             (uintptr_t)s->generationalMaps.cardMapAbsolute);
+}
+
+pointer getCrossMapCardStart (GC_state s, pointer p) {
+  /* The p - 1 is so that a pointer to the beginning of a card falls
+   * into the index for the previous crossMap entry.
+   */
+  return 
+    (p == s->heap.start)
+    ? s->heap.start
+    : (p - 1) - ((uintptr_t)(p - 1) % CARD_SIZE);
+}
+
+void clearCardMap (GC_state s) {
   if (DEBUG_GENERATIONAL and DEBUG_DETAILED)
     fprintf (stderr, "clearCardMap ()\n");
   memset (s->generationalMaps.cardMap, 0, 
           s->generationalMaps.cardMapLength * CARD_MAP_ELEM_SIZE);
 }
 
-static inline void clearCrossMap (GC_state s) {
+void clearCrossMap (GC_state s) {
   if (DEBUG_GENERATIONAL and DEBUG_DETAILED)
     fprintf (stderr, "clearCrossMap ()\n");
   s->generationalMaps.crossMapValidSize = 0;
@@ -82,21 +102,7 @@
           s->generationalMaps.crossMapLength * CROSS_MAP_ELEM_SIZE);
 }
 
-static inline void setCardMapAbsolute (GC_state s) {
-  unless (s->mutatorMarksCards)
-    return;
-  /* It's OK if the subtraction below underflows because all the
-   * subsequent additions to mark the cards will overflow and put us
-   * in the right place.
-   */
-  s->generationalMaps.cardMapAbsolute = 
-    pointerToCardMapAddr (s, s->heap.start);
-  if (DEBUG_CARD_MARKING)
-    fprintf (stderr, "cardMapAbsolute = "FMTPTR"\n",
-             (uintptr_t)s->generationalMaps.cardMapAbsolute);
-}
-
-static inline void createCardMapAndCrossMap (GC_state s) {
+void createCardMapAndCrossMap (GC_state s) {
   unless (s->mutatorMarksCards) {
     s->generationalMaps.cardMapLength = 0;
     s->generationalMaps.cardMap = NULL;
@@ -107,18 +113,20 @@
   }
   assert (isAligned (s->heap.size, CARD_SIZE));
 
-  size_t cardMapLength, cardMapSize;
-  size_t crossMapLength, crossMapSize;
+  GC_cardMapIndex cardMapLength;
+  size_t cardMapSize;
+  GC_crossMapIndex crossMapLength;
+  size_t crossMapSize;
   size_t totalMapSize;
 
-  cardMapLength = sizeToCardIndex (s->heap.size);
+  cardMapLength = sizeToCardMapIndex (s->heap.size);
   cardMapSize = align (cardMapLength * CARD_MAP_ELEM_SIZE, s->sysvals.pageSize);
-  cardMapLength = cardMapSize / CARD_MAP_ELEM_SIZE;
+  cardMapLength = (GC_cardMapIndex)(cardMapSize / CARD_MAP_ELEM_SIZE);
   s->generationalMaps.cardMapLength = cardMapLength;
 
-  crossMapLength = sizeToCardIndex (s->heap.size);
+  crossMapLength = sizeToCardMapIndex (s->heap.size);
   crossMapSize = align (crossMapLength * CROSS_MAP_ELEM_SIZE, s->sysvals.pageSize);
-  crossMapLength = crossMapSize / CROSS_MAP_ELEM_SIZE;
+  crossMapLength = (GC_crossMapIndex)(crossMapSize / CROSS_MAP_ELEM_SIZE);
   s->generationalMaps.crossMapLength = crossMapLength;
 
   totalMapSize = cardMapSize + crossMapSize;
@@ -138,35 +146,46 @@
   clearCrossMap (s);
 }
 
-#if ASSERT
-
-static inline pointer crossMapCardStart (GC_state s, pointer p) {
-  /* The p - 1 is so that a pointer to the beginning of a card falls
-   * into the index for the previous crossMap entry.
-   */
-  return (p == s->heap.start)
-    ? s->heap.start
-    : (p - 1) - ((uintptr_t)(p - 1) % CARD_SIZE);
+void resizeCardMapAndCrossMap (GC_state s) {
+  if (s->mutatorMarksCards
+      and (s->generationalMaps.cardMapLength * CARD_MAP_ELEM_SIZE)
+          != align (sizeToCardMapIndex (s->heap.size), s->sysvals.pageSize)) {
+    GC_cardMapElem *oldCardMap;
+    size_t oldCardMapSize;
+    GC_crossMapElem *oldCrossMap;
+    size_t oldCrossMapSize;
+    
+    oldCardMap = s->generationalMaps.cardMap;
+    oldCardMapSize = s->generationalMaps.cardMapLength * CARD_MAP_ELEM_SIZE;
+    oldCrossMap = s->generationalMaps.crossMap;
+    oldCrossMapSize = s->generationalMaps.crossMapLength * CROSS_MAP_ELEM_SIZE;
+    createCardMapAndCrossMap (s);
+    GC_memcpy ((pointer)oldCrossMap, (pointer)s->generationalMaps.crossMap,
+               min (s->generationalMaps.crossMapLength * CROSS_MAP_ELEM_SIZE, 
+                    oldCrossMapSize));
+    if (DEBUG_MEM)
+      fprintf (stderr, "Releasing card/cross map.\n");
+    GC_munmap (oldCardMap, oldCardMapSize + oldCrossMapSize);
+  }
 }
 
-/* crossMapIsOK is a slower, but easier to understand, way of
+/* isCrossMapOk is a slower, but easier to understand, way of
  * computing the crossMap.  updateCrossMap (below) incrementally
  * updates the crossMap, checking only the part of the old generation
- * that it hasn't seen before.  crossMapIsOK simply walks through the
+ * that it hasn't seen before.  isCrossMapOk simply walks through the
  * entire old generation.  It is useful to check that the incremental
  * update is working correctly.
  */
-
-static inline bool crossMapIsOK (GC_state s) {
+bool isCrossMapOK (GC_state s) {
   static GC_crossMapElem *map;
   size_t mapSize;
 
   pointer front, back;
-  size_t cardIndex;
+  GC_cardMapIndex cardIndex;
   pointer cardStart;
   
   if (DEBUG)
-    fprintf (stderr, "crossMapIsOK ()\n");
+    fprintf (stderr, "isCrossMapOk ()\n");
   mapSize = s->generationalMaps.crossMapLength * CROSS_MAP_ELEM_SIZE;
   map = GC_mmapAnon_safe (NULL, mapSize);
   memset (map, CROSS_MAP_EMPTY, mapSize);
@@ -175,11 +194,11 @@
   front = alignFrontier (s, s->heap.start);
 loopObjects:
   assert (front <= back);
-  cardStart = crossMapCardStart (s, front);
-  cardIndex = sizeToCardIndex (cardStart - s->heap.start);
+  cardStart = getCrossMapCardStart (s, front);
+  cardIndex = sizeToCardMapIndex (cardStart - s->heap.start);
   map[cardIndex] = (front - cardStart);
   if (front < back) {
-    front += objectSize (s, objectData (s, front));
+    front += sizeofObject (s, advanceToObjectData (s, front));
     goto loopObjects;
   }
   for (size_t i = 0; i < cardIndex; ++i)
@@ -188,10 +207,8 @@
   return TRUE;
 }
 
-#endif /* ASSERT */
-
-static inline void updateCrossMap (GC_state s) {
-  size_t cardIndex;
+void updateCrossMap (GC_state s) {
+  GC_cardMapIndex cardIndex;
   pointer cardStart, cardEnd;
 
   pointer nextObject, objectStart;
@@ -205,14 +222,14 @@
     cardIndex = 0;
     objectStart = alignFrontier (s, objectStart);
   } else
-    cardIndex = sizeToCardIndex (objectStart - 1 - s->heap.start);
-  cardStart = s->heap.start + cardIndexToSize (cardIndex);
+    cardIndex = sizeToCardMapIndex (objectStart - 1 - s->heap.start);
+  cardStart = s->heap.start + cardMapIndexToSize (cardIndex);
   cardEnd = cardStart + CARD_SIZE;
 loopObjects:
   assert (objectStart < oldGenEnd);
   assert ((objectStart == s->heap.start or cardStart < objectStart)
           and objectStart <= cardEnd);
-  nextObject = objectStart + objectSize (s, objectData (s, objectStart));
+  nextObject = objectStart + sizeofObject (s, advanceToObjectData (s, objectStart));
   if (nextObject > cardEnd) {
     /* We're about to move to a new card, so we are looking at the
      * last object boundary in the current card.  
@@ -226,8 +243,8 @@
       fprintf (stderr, "crossMap[%zu] = %zu\n",
                cardIndex, offset);
     s->generationalMaps.crossMap[cardIndex] = (GC_crossMapElem)offset;
-    cardIndex = sizeToCardIndex (nextObject - 1 - s->heap.start);
-    cardStart = s->heap.start + cardIndexToSize (cardIndex);
+    cardIndex = sizeToCardMapIndex (nextObject - 1 - s->heap.start);
+    cardStart = s->heap.start + cardMapIndexToSize (cardIndex);
     cardEnd = cardStart + CARD_SIZE;
   }
   objectStart = nextObject;
@@ -238,28 +255,5 @@
   s->generationalMaps.crossMapValidSize = s->heap.oldGenSize;
 done:
   assert (s->generationalMaps.crossMapValidSize == s->heap.oldGenSize);
-  assert (crossMapIsOK (s));
+  assert (isCrossMapOk (s));
 }
-
-static inline void resizeCardMapAndCrossMap (GC_state s) {
-  if (s->mutatorMarksCards
-      and (s->generationalMaps.cardMapLength * CARD_MAP_ELEM_SIZE)
-          != align (sizeToCardIndex (s->heap.size), s->sysvals.pageSize)) {
-    GC_cardMapElem *oldCardMap;
-    size_t oldCardMapSize;
-    GC_crossMapElem *oldCrossMap;
-    size_t oldCrossMapSize;
-    
-    oldCardMap = s->generationalMaps.cardMap;
-    oldCardMapSize = s->generationalMaps.cardMapLength * CARD_MAP_ELEM_SIZE;
-    oldCrossMap = s->generationalMaps.crossMap;
-    oldCrossMapSize = s->generationalMaps.crossMapLength * CROSS_MAP_ELEM_SIZE;
-    createCardMapAndCrossMap (s);
-    GC_memcpy ((pointer)oldCrossMap, (pointer)s->generationalMaps.crossMap,
-               min (s->generationalMaps.crossMapLength * CROSS_MAP_ELEM_SIZE, 
-                    oldCrossMapSize));
-    if (DEBUG_MEM)
-      fprintf (stderr, "Releasing card/cross map.\n");
-    GC_munmap (oldCardMap, oldCardMapSize + oldCrossMapSize);
-  }
-}

Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/generational.h
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/generational.h	2005-10-30 14:38:45 UTC (rev 4125)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/generational.h	2005-10-31 02:47:56 UTC (rev 4126)
@@ -12,8 +12,12 @@
 
 typedef uint8_t GC_cardMapElem;
 typedef uint8_t GC_crossMapElem;
+typedef size_t GC_cardMapIndex;
+typedef size_t GC_crossMapIndex;
 #define CARD_MAP_ELEM_SIZE sizeof(GC_cardMapElem)
 #define CROSS_MAP_ELEM_SIZE sizeof(GC_crossMapElem)
+#define CROSS_MAP_EMPTY ((GC_crossMapElem)255)
+#define FMTCMI "%zu"
 
 struct GC_generationalMaps {
   /* cardMap is an array with cardinality equal to the size of the
@@ -25,7 +29,7 @@
    */
   GC_cardMapElem *cardMap;
   GC_cardMapElem *cardMapAbsolute;
-  size_t cardMapLength;
+  GC_cardMapIndex cardMapLength;
   /* crossMap is an array with cardinality equal to the size of the
    * heap divided by card size.  Each element in the array is
    * interpreted as a byte offset; the offset indicates the start of
@@ -33,9 +37,32 @@
    * card.
    */
   GC_crossMapElem *crossMap;
-  size_t crossMapLength;
+  GC_crossMapIndex crossMapLength;
   /* crossMapValidSize the size of the prefix of the old generation
    * for which the crossMap is valid.
    */
   size_t crossMapValidSize;
 };
+
+void displayGenerationalMaps (GC_state s,
+                              struct GC_generationalMaps *generational,
+                              FILE *stream);
+
+GC_cardMapIndex pointerToCardMapIndexAbsolute (pointer p);
+GC_cardMapIndex sizeToCardMapIndex (size_t z);
+size_t cardMapIndexToSize (GC_cardMapIndex i);
+pointer pointerToCardMapAddr (GC_state s, pointer p);
+
+bool isCardMarked (GC_state s, pointer p);
+void markCard (GC_state s, pointer p);
+
+void setCardMapAbsolute (GC_state s);
+pointer getCrossMapCardStart (GC_state s, pointer p);
+
+void clearCardMap (GC_state s);
+void clearCrossMap (GC_state s);
+void createCardMapAndCrossMap (GC_state s);
+void resizeCardMapAndCrossMap (GC_state s);
+
+bool isCrossMapOk (GC_state s);
+void updateCrossMap (GC_state s);

Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/hash-cons.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/hash-cons.c	2005-10-30 14:38:45 UTC (rev 4125)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/hash-cons.c	2005-10-31 02:47:56 UTC (rev 4126)
@@ -25,7 +25,7 @@
  *   we ensure by making it odd and keeping the table size as a power of 2.
  */
 
-static GC_objectHashTable newHashTable (GC_state s) {
+GC_objectHashTable newHashTable (GC_state s) {
   uint32_t elementsLengthMax;
   pointer regionStart;
   pointer regionEnd;
@@ -33,7 +33,7 @@
   
   t = (GC_objectHashTable)(malloc_safe (sizeof(*t)));
   // Try to use space in the heap for the elements.
-  if (not (heapIsInit (&s->secondaryHeap))) {
+  if (not (isHeapInit (&s->secondaryHeap))) {
     if (DEBUG_SHARE)
       fprintf (stderr, "using secondaryHeap\n");
     regionStart = s->secondaryHeap.start;
@@ -87,17 +87,17 @@
   return t;
 }
 
-static void destroyHashTable (GC_objectHashTable t) {
+void destroyHashTable (GC_objectHashTable t) {
   unless (t->elementsIsInHeap)
     free (t->elements);
   free (t);
 }
 
-static inline pointer 
-tableInsert (__attribute__ ((unused)) GC_state s, 
-             GC_objectHashTable t, 
-             GC_hash hash, pointer object,
-             bool mightBeThere, GC_header header, GC_objectTypeTag tag, pointer max) {
+pointer tableInsert (__attribute__ ((unused)) GC_state s, 
+                     GC_objectHashTable t, 
+                     GC_hash hash, pointer object,
+                     bool mightBeThere, 
+                     GC_header header, GC_objectTypeTag tag, pointer max) {
   static bool init = FALSE;
   static uint64_t mult; // magic multiplier for hashing
   static uint32_t maxNumProbes = 0;
@@ -176,7 +176,7 @@
   return e->object;
 }
 
-static void maybeGrowTable (GC_state s, GC_objectHashTable t) {
+void maybeGrowTable (GC_state s, GC_objectHashTable t) {
   GC_objectHashElement oldElement;
   struct GC_objectHashElement *oldElements;
   uint32_t oldElementsLengthMax;
@@ -218,7 +218,7 @@
     fprintf (stderr, "done growing table\n");
 }
 
-static pointer hashCons (GC_state s, pointer object, bool countBytesHashConsed) {
+pointer hashCons (GC_state s, pointer object, bool countBytesHashConsed) {
   GC_objectHashTable t;
   GC_header header;
   uint16_t numNonObjptrs;
@@ -244,9 +244,9 @@
   max = 
     object
     + (ARRAY_TAG == tag
-       ? arraySizeNoHeader (s, object,
-                            numNonObjptrs, numObjptrs)
-       : (numNonObjptrsToBytes (numNonObjptrs, NORMAL_TAG)
+       ? (sizeofArrayNoHeader (s, getArrayLength (object),
+                               numNonObjptrs, numObjptrs))
+       : (sizeofNumNonObjptrs (NORMAL_TAG, numNonObjptrs)
           + (numObjptrs * OBJPTR_SIZE)));
   // Compute the hash.
   hash = (GC_hash)header;
@@ -272,9 +272,9 @@
   return res;
 }
 
-static inline void maybeSharePointer (GC_state s,
-                                      pointer *pp,
-                                      bool shouldHashCons) {
+void maybeSharePointer (GC_state s,
+                        pointer *pp,
+                        bool shouldHashCons) {
   unless (shouldHashCons)
     return;
   if (DEBUG_SHARE)
@@ -283,9 +283,9 @@
   *pp = hashCons (s, *pp, FALSE);
 }
 
-static inline void maybeShareObjptr (GC_state s,
-                                     objptr *opp,
-                                     bool shouldHashCons) {
+void maybeShareObjptr (GC_state s,
+                       objptr *opp,
+                       bool shouldHashCons) {
   pointer p;
   
   unless (shouldHashCons)
@@ -298,7 +298,7 @@
   *opp = pointerToObjptr (p, s->heap.start);
 }
 
-static void bytesHashConsedMessage (GC_state s, uintmax_t total) {
+void bytesHashConsedMessage (GC_state s, uintmax_t total) {
   fprintf (stderr, "%"PRIuMAX" bytes hash consed (%.1f%%).\n",
            /*ullongToCommaString*/(s->cumulativeStatistics.bytesHashConsed),
            (100.0 

Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/hash-cons.h
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/hash-cons.h	2005-10-30 14:38:45 UTC (rev 4125)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/hash-cons.h	2005-10-31 02:47:56 UTC (rev 4126)
@@ -29,8 +29,14 @@
   bool mayInsert;
 } *GC_objectHashTable;
 
-/*
-void maybeShareObjptr (GC_state s,
-                       objptr *opp,
-                       bool shouldHashCons);
-*/
+GC_objectHashTable newHashTable (GC_state s);
+void destroyHashTable (GC_objectHashTable t);
+pointer tableInsert (GC_state s, GC_objectHashTable t, 
+                     GC_hash hash, pointer object,
+                     bool mightBeThere, 
+                     GC_header header, GC_objectTypeTag tag, pointer max);
+void maybeGrowTable (GC_state s, GC_objectHashTable t);
+pointer hashCons (GC_state s, pointer object, bool countBytesHashConsed);
+void maybeSharePointer (GC_state s, pointer *pp, bool shouldHashCons);
+void maybeShareObjptr (GC_state s, objptr *opp, bool shouldHashCons);
+void bytesHashConsedMessage (GC_state s, uintmax_t total);

Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/heap.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/heap.c	2005-10-30 14:38:45 UTC (rev 4125)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/heap.c	2005-10-31 02:47:56 UTC (rev 4126)
@@ -11,23 +11,102 @@
   fprintf(stream,
           "\t\tnursery ="FMTPTR"\n"
           "\t\toldGenSize = %zu\n"
-          "\t\tstart = "FMTPTR"\n"
-          "\t\tsize = %zu\n",
+          "\t\tsize = %zu\n"
+          "\t\tstart = "FMTPTR"\n",
           (uintptr_t)heap->nursery,
           heap->oldGenSize,
-          (uintptr_t)heap->start,
-          heap->size);
+          heap->size,
+          (uintptr_t)heap->start);
 }
 
 
-static inline void heapInit (GC_heap h) {
+void initHeap (__attribute__ ((unused)) GC_state s,
+               GC_heap h) {
+  h->nursery = NULL;
+  h->oldGenSize = 0;
+  h->size = 0;
   h->start = NULL;
-  h->size = 0;
-  h->oldGenSize = 0;
-  h->nursery = NULL;
 }
 
-static void heapRelease (GC_state s, GC_heap h) {
+/* sizeofHeapDesired (s, l, cs) 
+ *
+ * returns the desired heap size for a heap with l bytes live, given
+ * that the current heap size is cs.
+ */
+size_t sizeofHeapDesired (GC_state s, size_t live, size_t currentSize) {
+  size_t res;
+  float ratio;
+
+  ratio = (float)s->sysvals.ram / (float)live;
+  if (ratio >= s->ratios.live + s->ratios.grow) {
+    /* Cheney copying fits in RAM with desired ratios.live. */
+    res = live * s->ratios.live;
+    /* If the heap is currently close in size to what we want, leave
+     * it alone.  Favor growing over shrinking.
+     */
+    unless (1.1 * currentSize <= res
+            or res <= .5 * currentSize)
+      res = currentSize;
+  } else if (s->ratios.grow >= s->ratios.copy
+             and ratio >= 2 * s->ratios.copy) {
+    /* Split RAM in half.  Round down by pageSize so that the total
+     * amount of space taken isn't greater than RAM once rounding
+     * happens.  This is so resizeHeap2 doesn't get confused and free
+     * a semispace in a misguided attempt to avoid paging.
+     */
+    res = alignDown (s->sysvals.ram / 2, s->sysvals.pageSize);
+  } else if (ratio >= s->ratios.copy + s->ratios.grow) {
+    /* Cheney copying fits in RAM. */
+    res = s->sysvals.ram - s->ratios.grow * live;
+    /* If the heap isn't too much smaller than what we want, leave it
+     * alone.  On the other hand, if it is bigger we want to leave res
+     * as is so that the heap is shrunk, to try to avoid paging.
+     */
+    if (currentSize <= res 
+        and res <= 1.1 * currentSize)
+      res = currentSize;
+  } else if (ratio >= s->ratios.markCompact) {
+    /* Mark compact fits in RAM.  It doesn't matter what the current
+     * size is.  If the heap is currently smaller, we are using
+     * copying and should switch to mark-compact.  If the heap is
+     * currently bigger, we want to shrink back to RAM to avoid
+     * paging.
+     */
+    res = s->sysvals.ram;
+  } else { /* Required live ratio. */
+    res = live * s->ratios.markCompact;
+    /* If the current heap is bigger than res, then shrinking always
+     * sounds like a good idea.  However, depending on what pages the
+     * VM keeps around, growing could be very expensive, if it
+     * involves paging the entire heap.  Hopefully the copy loop in
+     * growHeap will make the right thing happen.
+     */ 
+  }
+  if (s->controls.fixedHeap > 0) {
+    if (res > s->controls.fixedHeap / 2)
+      res = s->controls.fixedHeap;
+    else
+      res = s->controls.fixedHeap / 2;
+    if (res < live)
+      die ("Out of memory with fixed heap size %zu.",
+           /*uintToCommaString*/(s->controls.fixedHeap));
+  } else if (s->controls.maxHeap > 0) {
+    if (res > s->controls.maxHeap)
+      res = s->controls.maxHeap;
+    if (res < live)
+      die ("Out of memory with max heap size %zu.",
+           /*uintToCommaString*/(s->controls.maxHeap));
+  }
+  if (DEBUG_RESIZING)
+    fprintf (stderr, "%zu = sizeofHeapDesired (%zu, %zu)\n",
+             /*uintToCommaString*/(res),
+             /*uintToCommaString*/(live),
+             /*uintToCommaString*/(currentSize));
+  assert (res >= live);
+  return res;
+}
+
+void releaseHeap (GC_state s, GC_heap h) {
   if (NULL == h->start)
     return;
   if (DEBUG or s->controls.messages)
@@ -35,13 +114,13 @@
              (uintptr_t)h->start,
              /*uintToCommaString*/(h->size));
   GC_release (h->start, h->size);
-  heapInit (h);
+  initHeap (s, h);
 }
 
-static void heapShrink (GC_state s, GC_heap h, size_t keep) {
+void shrinkHeap (GC_state s, GC_heap h, size_t keep) {
   assert (keep <= h->size);
   if (0 == keep) {
-    heapRelease (s, h);
+    releaseHeap (s, h);
     return;
   }
   keep = align (keep, s->sysvals.pageSize);
@@ -57,7 +136,7 @@
   }
 }
 
-/* heapCreate (s, h, desiredSize, minSize) 
+/* createHeap (s, h, desiredSize, minSize) 
  * 
  * allocates a heap of the size necessary to work with desiredSize
  * live data, and ensures that at least minSize is available.  It
@@ -65,16 +144,16 @@
  * if it is unable.  If a reasonable size to space is already there,
  * then heapCreate leaves it.
  */
-static bool heapCreate (GC_state s, GC_heap h, 
-                        size_t desiredSize, 
-                        size_t minSize) {
+bool createHeap (GC_state s, GC_heap h, 
+                 size_t desiredSize, 
+                 size_t minSize) {
   size_t backoff;
 
   if (DEBUG_MEM)
-    fprintf (stderr, "heapCreate  desired size = %zu  min size = %zu\n",
+    fprintf (stderr, "createHeap  desired size = %zu  min size = %zu\n",
              /*uintToCommaString*/(desiredSize),
              /*uintToCommaString*/(minSize));
-  assert (heapIsInit (h));
+  assert (isHeapInit (h));
   if (desiredSize < minSize)
     desiredSize = minSize;
   desiredSize = align (desiredSize, s->sysvals.pageSize);
@@ -88,7 +167,7 @@
    * to fail.  This is important for large heaps.
    */
   for (h->size = desiredSize; h->size >= minSize; h->size -= backoff) {
-    const size_t highAddress = ((size_t)0xf8) << ((POINTER_SIZE - 1) * 8);
+    const size_t highAddress = ((size_t)0xf8) << ((POINTER_SIZE - 1) * CHAR_BIT);
     const size_t step = (size_t)0x08000000;
     const size_t count = highAddress / step;
 
@@ -127,22 +206,22 @@
   return FALSE;
 }
 
-/* secondaryHeapCreate (s, desiredSize)
+/* createHeapSecondary (s, desiredSize)
  */
-static bool secondaryHeapCreate (GC_state s, size_t desiredSize) {
+bool createHeapSecondary (GC_state s, size_t desiredSize) {
   if ((s->controls.fixedHeap > 0 
        and s->heap.size + desiredSize > s->controls.fixedHeap)
       or (s->controls.maxHeap > 0 
           and s->heap.size + desiredSize > s->controls.maxHeap))
     return FALSE;
-  return heapCreate (s, &s->secondaryHeap, desiredSize, s->heap.oldGenSize);
+  return createHeap (s, &s->secondaryHeap, desiredSize, s->heap.oldGenSize);
 }
 
-/* heapRemap (s, h, desiredSize, minSize)
+/* remapHeap (s, h, desiredSize, minSize)
  */
-static bool heapRemap (GC_state s, GC_heap h, 
-                       size_t desiredSize, 
-                       size_t minSize) {
+bool remapHeap (GC_state s, GC_heap h, 
+                size_t desiredSize, 
+                size_t minSize) {
   size_t backoff;
   size_t size;
 
@@ -176,9 +255,9 @@
   COPY_CHUNK_SIZE = 0x2000000, /* 32M */
 };
 
-/* heapGrow (s, desiredSize, minSize)
+/* growHeap (s, desiredSize, minSize)
  */
-static void heapGrow (GC_state s, size_t desiredSize, size_t minSize) {
+void growHeap (GC_state s, size_t desiredSize, size_t minSize) {
   GC_heap curHeapp;
   struct GC_heap newHeap;
 
@@ -195,12 +274,12 @@
   orig = curHeapp->start;
   size = curHeapp->oldGenSize;
   assert (size <= s->heap.size);
-  if (heapRemap (s, curHeapp, desiredSize, minSize))
+  if (remapHeap (s, curHeapp, desiredSize, minSize))
     goto done;
-  heapShrink (s, curHeapp, size);
-  heapInit (&newHeap);
+  shrinkHeap (s, curHeapp, size);
+  initHeap (s, &newHeap);
   /* Allocate a space of the desired size. */
-  if (heapCreate (s, &newHeap, desiredSize, minSize)) {
+  if (createHeap (s, &newHeap, desiredSize, minSize)) {
     pointer from;
     pointer to;
     size_t remaining;
@@ -219,10 +298,10 @@
       from -= COPY_CHUNK_SIZE;
       to -= COPY_CHUNK_SIZE;
       GC_memcpy (from, to, COPY_CHUNK_SIZE);
-      heapShrink (s, curHeapp, remaining);
+      shrinkHeap (s, curHeapp, remaining);
       goto copy;
     }
-    heapRelease (s, curHeapp);
+    releaseHeap (s, curHeapp);
     *curHeapp = newHeap;
   } else {
     /* Write the heap to a file and try again. */
@@ -250,8 +329,8 @@
     fd = open_safe (template, O_WRONLY, 0);
     write_safe (fd, orig, size);
     close_safe (fd);
-    heapRelease (s, curHeapp);
-    if (heapCreate (s, curHeapp, desiredSize, minSize)) {
+    releaseHeap (s, curHeapp);
+    if (createHeap (s, curHeapp, desiredSize, minSize)) {
       fd = open_safe (template, O_RDONLY, 0);
       read_safe (fd, curHeapp->start, size);
       close_safe (fd);
@@ -271,99 +350,67 @@
   }
 }
 
-/* heapDesiredSize (s, l, cs) 
- *
- * returns the desired heap size for a heap with l bytes live, given
- * that the current heap size is cs.
+/* resizeHeap (s, minSize)
  */
-static size_t heapDesiredSize (GC_state s, size_t live, size_t currentSize) {
-  size_t res;
-  float ratio;
+void resizeHeap (GC_state s, size_t minSize) {
+  size_t desiredSize;
 
-  ratio = (float)s->sysvals.ram / (float)live;
-  if (ratio >= s->ratios.live + s->ratios.grow) {
-    /* Cheney copying fits in RAM with desired ratios.live. */
-    res = live * s->ratios.live;
-    /* If the heap is currently close in size to what we want, leave
-     * it alone.  Favor growing over shrinking.
-     */
-    unless (1.1 * currentSize <= res
-            or res <= .5 * currentSize)
-      res = currentSize;
-  } else if (s->ratios.grow >= s->ratios.copy
-             and ratio >= 2 * s->ratios.copy) {
-    /* Split RAM in half.  Round down by pageSize so that the total
-     * amount of space taken isn't greater than RAM once rounding
-     * happens.  This is so resizeHeap2 doesn't get confused and free
-     * a semispace in a misguided attempt to avoid paging.
-     */
-    res = alignDown (s->sysvals.ram / 2, s->sysvals.pageSize);
-  } else if (ratio >= s->ratios.copy + s->ratios.grow) {
-    /* Cheney copying fits in RAM. */
-    res = s->sysvals.ram - s->ratios.grow * live;
-    /* If the heap isn't too much smaller than what we want, leave it
-     * alone.  On the other hand, if it is bigger we want to leave res
-     * as is so that the heap is shrunk, to try to avoid paging.
-     */
-    if (currentSize <= res 
-        and res <= 1.1 * currentSize)
-      res = currentSize;
-  } else if (ratio >= s->ratios.markCompact) {
-    /* Mark compact fits in RAM.  It doesn't matter what the current
-     * size is.  If the heap is currently smaller, we are using
-     * copying and should switch to mark-compact.  If the heap is
-     * currently bigger, we want to shrink back to RAM to avoid
-     * paging.
-     */
-    res = s->sysvals.ram;
-  } else { /* Required live ratio. */
-    res = live * s->ratios.markCompact;
-    /* If the current heap is bigger than res, the shrinking always
-     * sounds like a good idea.  However, depending on what pages the
-     * VM keeps around, growing could be very expensive, if it
-     * involves paging the entire heap.  Hopefully the copy loop in
-     * growFromSpace will make the right thing happen.
-     */ 
+  if (DEBUG_RESIZING)
+    fprintf (stderr, "resizeHeap  minSize = %zu  size = %zu\n",
+             /*ullongToCommaString*/(minSize), 
+             /*uintToCommaString*/(s->heap.size));
+  desiredSize = sizeofHeapDesired (s, minSize, s->heap.size);
+  assert (minSize <= desiredSize);
+  if (desiredSize <= s->heap.size)
+    shrinkHeap (s, &s->heap, desiredSize);
+  else {
+    releaseHeap (s, &s->secondaryHeap);
+    growHeap (s, desiredSize, minSize);
   }
-  if (s->controls.fixedHeap > 0) {
-    if (res > s->controls.fixedHeap / 2)
-      res = s->controls.fixedHeap;
-    else
-      res = s->controls.fixedHeap / 2;
-    if (res < live)
-      die ("Out of memory with fixed heap size %zu.",
-           /*uintToCommaString*/(s->controls.fixedHeap));
-  } else if (s->controls.maxHeap > 0) {
-    if (res > s->controls.maxHeap)
-      res = s->controls.maxHeap;
-    if (res < live)
-      die ("Out of memory with max heap size %zu.",
-           /*uintToCommaString*/(s->controls.maxHeap));
-  }
+  resizeCardMapAndCrossMap (s);
+  assert (s->heap.size >= minSize);
+}
+
+/* resizeHeapSecondary (s)
+ */
+void resizeHeapSecondary (GC_state s) {
+  size_t primarySize;
+  size_t secondarySize;
+
+  primarySize = s->heap.size;
+  secondarySize = s->secondaryHeap.size;
   if (DEBUG_RESIZING)
-    fprintf (stderr, "%zu = heapDesiredSize (%zu, %zu)\n",
-             /*uintToCommaString*/(res),
-             /*uintToCommaString*/(live),
-             /*uintToCommaString*/(currentSize));
-  assert (res >= live);
-  return res;
+    fprintf (stderr, "secondaryHeapResize\n");
+  if (0 == secondarySize)
+    return;
+  if (2 * primarySize > s->sysvals.ram)
+    /* Holding on to heap2 might cause paging.  So don't. */
+    releaseHeap (s, &s->secondaryHeap);
+  else if (secondarySize < primarySize) {
+    unless (remapHeap (s, &s->secondaryHeap, primarySize, primarySize))
+      releaseHeap (s, &s->secondaryHeap);
+  } else if (secondarySize > primarySize)
+    shrinkHeap (s, &s->secondaryHeap, primarySize);
+  assert (0 == s->secondaryHeap.size 
+          or s->heap.size == s->secondaryHeap.size);
 }
 
-static void heapSetNursery (GC_state s, 
-                            size_t oldGenBytesRequested,
-                            size_t nurseryBytesRequested) {
+
+void setHeapNursery (GC_state s, 
+                     size_t oldGenBytesRequested,
+                     size_t nurseryBytesRequested) {
   GC_heap h;
   size_t nurserySize;
 
   if (DEBUG_DETAILED)
-    fprintf (stderr, "heapSetNursery(%zu, %zu)\n",
+    fprintf (stderr, "setHeapNursery(%zu, %zu)\n",
              /*uintToCommaString*/(oldGenBytesRequested),
              /*uintToCommaString*/(nurseryBytesRequested));
   h = &s->heap;
   assert (isAlignedFrontier (s, h->start + h->oldGenSize + oldGenBytesRequested));
   nurserySize = h->size - h->oldGenSize - oldGenBytesRequested;
   s->limitPlusSlop = h->start + h->size;
-  s->limit = s->limitPlusSlop - LIMIT_SLOP;
+  s->limit = s->limitPlusSlop - GC_HEAP_LIMIT_SLOP;
   assert (isAligned (nurserySize, POINTER_SIZE));
   if (/* The mutator marks cards. */
       s->mutatorMarksCards
@@ -412,50 +459,5 @@
   s->frontier = s->heap.nursery;
   assert (nurseryBytesRequested <= (size_t)(s->limitPlusSlop - s->frontier));
   assert (isAlignedFrontier (s, s->heap.nursery));
-  assert (heapHasBytesFree (s, oldGenBytesRequested, nurseryBytesRequested));
+  assert (hasHeapBytesFree (s, oldGenBytesRequested, nurseryBytesRequested));
 }
-
-/* heapResize (s, minSize)
- */
-static void heapResize (GC_state s, size_t minSize) {
-  size_t desiredSize;
-
-  if (DEBUG_RESIZING)
-    fprintf (stderr, "heapResize  minSize = %zu  size = %zu\n",
-             /*ullongToCommaString*/(minSize), 
-             /*uintToCommaString*/(s->heap.size));
-  desiredSize = heapDesiredSize (s, minSize, s->heap.size);
-  assert (minSize <= desiredSize);
-  if (desiredSize <= s->heap.size)
-    heapShrink (s, &s->heap, desiredSize);
-  else {
-    heapRelease (s, &s->secondaryHeap);
-    heapGrow (s, desiredSize, minSize);
-  }
-  resizeCardMapAndCrossMap (s);
-  assert (s->heap.size >= minSize);
-}
-
-/* secondaryHeapResize (s)
- */
-static void secondaryHeapResize (GC_state s) {
-  size_t primarySize;
-  size_t secondarySize;
-
-  primarySize = s->heap.size;
-  secondarySize = s->secondaryHeap.size;
-  if (DEBUG_RESIZING)
-    fprintf (stderr, "secondaryHeapResize\n");
-  if (0 == secondarySize)
-    return;
-  if (2 * primarySize > s->sysvals.ram)
-    /* Holding on to heap2 might cause paging.  So don't. */
-    heapRelease (s, &s->secondaryHeap);
-  else if (secondarySize < primarySize) {
-    unless (heapRemap (s, &s->secondaryHeap, primarySize, primarySize))
-      heapRelease (s, &s->secondaryHeap);
-  } else if (secondarySize > primarySize)
-    heapShrink (s, &s->secondaryHeap, primarySize);
-  assert (0 == s->secondaryHeap.size 
-          or s->heap.size == s->secondaryHeap.size);
-}

Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/heap.h
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/heap.h	2005-10-30 14:38:45 UTC (rev 4125)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/heap.h	2005-10-31 02:47:56 UTC (rev 4126)
@@ -10,18 +10,48 @@
  * All ML objects (including ML execution stacks) are allocated in a
  * contiguous heap.  The heap has the following general layout:
  * 
- *  ---------------------------------------------------
- *  |    old generation    |              |  nursery  |
- *  ---------------------------------------------------
- *  ^                                     ^
- *  start                                 nursery
+ *  ----------------------------------------------------
+ *  |    old generation    |               |  nursery  |
+ *  ----------------------------------------------------
+ *  |------oldGenSize------|
+ *  |-----------------------size-----------------------|
+ *  ^                                      ^
+ *  start                                  nursery
 */
 
 typedef struct GC_heap {
-  pointer start; /* start of heap (and old generation) */
-  size_t size; /* size of heap */
   size_t oldGenSize; /* size of old generation */
   pointer nursery; /* start of nursery */
+  size_t size; /* size of heap */
+  pointer start; /* start of heap (and old generation) */
 } *GC_heap;
 
-#define LIMIT_SLOP 512
+#define GC_HEAP_LIMIT_SLOP 512
+
+bool isPointerInHeap (GC_state s, pointer p);
+bool isPointerInOldGen (GC_state s, pointer p);
+bool isPointerInNursery (GC_state s, pointer p);
+bool isPointerInFromSpace (GC_state s, pointer p);
+bool isObjptrInHeap (GC_state s, objptr op);
+bool isObjptrInOldGen (GC_state s, objptr op);
+bool isObjptrInNursery (GC_state s, objptr op);
+bool isObjptrInFromSpace (GC_state s, objptr op);
+bool hasHeapBytesFree (GC_state s, size_t oldGen, size_t nursery);
+bool isHeapInit (GC_heap h);
+
+void displayHeap (GC_state s, GC_heap heap, FILE *stream);
+void initHeap (GC_state s, GC_heap h);
+size_t sizeofHeapDesired (GC_state s, size_t live, size_t currentSize);
+
+void releaseHeap (GC_state s, GC_heap h);
+void shrinkHeap (GC_state s, GC_heap h, size_t keep);
+bool createHeap (GC_state s, GC_heap h, size_t desiredSize, size_t minSize);
+bool createHeapSecondary (GC_state s, size_t desiredSize);
+bool remapHeap (GC_state s, GC_heap h, size_t desiredSize, size_t minSize);
+void growHeap (GC_state s, size_t desiredSize, size_t minSize);
+void resizeHeap (GC_state s, size_t minSize);
+void resizeHeapSecondary (GC_state s);
+
+void setHeapNursery (GC_state s, 
+                     size_t oldGenBytesRequested, 
+                     size_t nurseryBytesRequested);

Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/heap_predicates.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/heap_predicates.c	2005-10-30 14:38:45 UTC (rev 4125)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/heap_predicates.c	2005-10-31 02:47:56 UTC (rev 4126)
@@ -5,57 +5,58 @@
  * See the file MLton-LICENSE for details.
  */
 
-static inline bool pointerIsInHeap (GC_state s, pointer p) {
+bool isPointerInHeap (GC_state s, pointer p) {
   return (not (isPointer (p))
           or (s->heap.start <= p 
               and p < s->frontier));
 }
 
-static inline bool objptrIsInHeap (GC_state s, objptr op) {
-  pointer p;
-  if (not (isObjptr(op)))
-    return TRUE;
-  p = objptrToPointer (op, s->heap.start);
-  return pointerIsInHeap (s, p);
-}
-
-static inline bool pointerIsInOldGen (GC_state s, pointer p) {
+bool isPointerInOldGen (GC_state s, pointer p) {
   return (not (isPointer (p))
           or (s->heap.start <= p 
               and p < s->heap.start + s->heap.oldGenSize));
 }
 
-static inline bool objptrIsInOldGen (GC_state s, objptr op) {
+bool isPointerInNursery (GC_state s, pointer p) {
+  return (not (isPointer (p))
+          or (s->heap.nursery <= p and p < s->frontier));
+}
+
+bool isPointerInFromSpace (GC_state s, pointer p) {
+  return (isPointerInOldGen (s, p) 
+          or isPointerInNursery (s, p));
+}
+
+bool isObjptrInHeap (GC_state s, objptr op) {
   pointer p;
   if (not (isObjptr(op)))
     return TRUE;
   p = objptrToPointer (op, s->heap.start);
-  return pointerIsInOldGen (s, p);
+  return isPointerInHeap (s, p);
 }
 
-static inline bool pointerIsInNursery (GC_state s, pointer p) {
-  return (not (isPointer (p))
-          or (s->heap.nursery <= p and p < s->frontier));
+bool isObjptrInOldGen (GC_state s, objptr op) {
+  pointer p;
+  if (not (isObjptr(op)))
+    return TRUE;
+  p = objptrToPointer (op, s->heap.start);
+  return isPointerInOldGen (s, p);
 }
 
-static inline bool objptrIsInNursery (GC_state s, objptr op) {
+bool isObjptrInNursery (GC_state s, objptr op) {
   pointer p;
   if (not (isObjptr(op)))
     return TRUE;
   p = objptrToPointer (op, s->heap.start);
-  return pointerIsInNursery (s, p);
+  return isPointerInNursery (s, p);
 }
 
-static inline bool pointerIsInFromSpace (GC_state s, pointer p) {
-  return (pointerIsInOldGen (s, p) or pointerIsInNursery (s, p));
+bool isObjptrInFromSpace (GC_state s, objptr op) {
+  return (isObjptrInOldGen (s, op) 
+          or isObjptrInNursery (s, op));
 }
 
-static inline bool objptrIsInFromSpace (GC_state s, objptr op) {
-  return (objptrIsInOldGen (s, op) or objptrIsInNursery (s, op));
-}
-
-#if ASSERT
-static bool heapHasBytesFree (GC_state s, size_t oldGen, size_t nursery) {
+bool hasHeapBytesFree (GC_state s, size_t oldGen, size_t nursery) {
   size_t total;
   bool res;
 
@@ -72,8 +73,7 @@
              /*uintToCommaString*/(nursery));
   return res;
 }
-#endif
 
-static inline bool heapIsInit (GC_heap h) {
-  return 0 == h->size;
+bool isHeapInit (GC_heap h) {
+  return (0 == h->size);
 }

Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/init.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/init.c	2005-10-30 14:38:45 UTC (rev 4125)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/init.c	2005-10-31 02:47:56 UTC (rev 4126)
@@ -84,7 +84,7 @@
   s->lastMajorStatistics.bytesLive = 0;
   for (i = 0; i < s->intInfInitsLength; ++i) {
     numBytes = 
-      WORD_SIZE // for the sign
+      sizeof(uint32_t) // for the sign
       + strlen (s->intInfInits[i].mlstr);
     s->lastMajorStatistics.bytesLive +=
       align (GC_ARRAY_HEADER_SIZE + numBytes,
@@ -172,7 +172,7 @@
     s->globals[inits->globalIndex] = pointerToObjptr((pointer)(&bp->isneg), s->heap.start);
     bp->counter = 0;
     bp->length = alen + 1;
-    bp->header = objectHeader (WORD32_VECTOR_TYPE_INDEX);
+    bp->header = buildHeaderFromTypeIndex (WORD32_VECTOR_TYPE_INDEX);
     bp->isneg = neg;
     frontier = alignFrontier (s, (pointer)&bp->limbs[alen]);
   }
@@ -222,7 +222,7 @@
       die ("unknown bytes per element in vectorInit: %zu",
            bytesPerElement);
     }
-    *((GC_header*)(frontier)) = objectHeader (typeIndex);
+    *((GC_header*)(frontier)) = buildHeaderFromTypeIndex (typeIndex);
     frontier = frontier + GC_HEADER_SIZE;
     s->globals[inits[i].globalIndex] = pointerToObjptr(frontier, s->heap.start);
     if (DEBUG_DETAILED)
@@ -248,8 +248,8 @@
   for (i = 0; i < s->globalsLength; ++i)
     s->globals[i] = BOGUS_OBJPTR;
   setInitialBytesLive (s);
-  heapCreate (s, &s->heap, 
-              heapDesiredSize (s, s->lastMajorStatistics.bytesLive, 0),
+  createHeap (s, &s->heap, 
+              sizeofHeapDesired (s, s->lastMajorStatistics.bytesLive, 0),
               s->lastMajorStatistics.bytesLive);
   createCardMapAndCrossMap (s);
   start = alignFrontier (s, s->heap.start);
@@ -258,8 +258,8 @@
   initVectors (s);
   assert ((size_t)(s->frontier - start) <= s->lastMajorStatistics.bytesLive);
   s->heap.oldGenSize = s->frontier - s->heap.start;
-  heapSetNursery (s, 0, 0);
-  thread = newThread (s, initialStackSize (s));
+  setHeapNursery (s, 0, 0);
+  thread = newThread (s, sizeofStackInitial (s));
   switchToThread (s, pointerToObjptr((pointer)thread, s->heap.start));
 }
 
@@ -397,7 +397,7 @@
 
 int GC_init (GC_state s, int argc, char **argv) {
   char *worldFile;
-  int i;
+  int res;
 
   assert (isAligned (sizeof (struct GC_stack), s->alignment));
   assert (isAligned (GC_NORMAL_HEADER_SIZE + sizeof (struct GC_thread),
@@ -439,7 +439,7 @@
   rusageZero (&s->cumulativeStatistics.ru_gcMinor);
   s->currentThread = BOGUS_OBJPTR;
   s->hashConsDuringGC = FALSE;
-  heapInit (&s->heap);
+  initHeap (s, &s->heap);
   s->lastMajorStatistics.bytesLive = 0;
   s->lastMajorStatistics.kind = GC_COPYING;
   s->lastMajorStatistics.numMinorGCs = 0;
@@ -455,7 +455,7 @@
   s->ratios.threadShrink = 0.5;
   s->rusageIsEnabled = FALSE;
   s->savedThread = BOGUS_OBJPTR;
-  heapInit (&s->secondaryHeap);
+  initHeap (s, &s->secondaryHeap);
   s->signalHandlerThread = BOGUS_OBJPTR;
   s->signalsInfo.amInSignalHandler = FALSE;
   s->signalsInfo.gcSignalHandled = FALSE;
@@ -475,7 +475,7 @@
   unless (isAligned (s->sysvals.pageSize, CARD_SIZE))
     die ("Page size must be a multiple of card size.");
   processAtMLton (s, s->atMLtonsLength, s->atMLtons, &worldFile);
-  i = processAtMLton (s, argc, argv, &worldFile);
+  res = processAtMLton (s, argc, argv, &worldFile);
   if (s->controls.fixedHeap > 0 and s->controls.maxHeap > 0)
     die ("Cannot use both fixed-heap and max-heap.\n");
   unless (ratiosOk (s->ratios))
@@ -485,7 +485,7 @@
    * we are using mark-compact by comparing heap size to ram size.  If
    * we didn't round, the size might be slightly off.
    */
-  s->sysvals.ram = align (s->ratios.ramSlop * s->sysvals.totalRam, s->sysvals.pageSize);
+  s->sysvals.ram = align ((size_t)(s->ratios.ramSlop * s->sysvals.totalRam), s->sysvals.pageSize);
   if (DEBUG or DEBUG_RESIZING or s->controls.messages)
     fprintf (stderr, "total RAM = %zu  RAM = %zu\n",
              /*uintToCommaString*/(s->sysvals.totalRam),
@@ -532,13 +532,13 @@
      */
     assert (mutatorInvariant (s, TRUE, FALSE));
   } else {
-    loadWorld (s, worldFile);
+    loadWorldFromFileName (s, worldFile);
     if (s->profiling.isOn and s->profiling.stack)
       foreachStackFrame (s, enterFrame);
     assert (mutatorInvariant (s, TRUE, TRUE));
   }
   s->amInGC = FALSE;
-  return i;
+  return res;
 }
 
 /* extern char **environ; /\* for Posix_ProcEnv_environ *\/ */

Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/invariant.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/invariant.c	2005-10-30 14:38:45 UTC (rev 4125)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/invariant.c	2005-10-31 02:47:56 UTC (rev 4126)
@@ -6,23 +6,21 @@
  * See the file MLton-LICENSE for details.
  */
 
-#if ASSERT
-
-static inline void assertObjptrIsInFromSpace (GC_state s, objptr *opp) {
-  unless (objptrIsInFromSpace (s, *opp))
-    die ("gc.c: assertObjptrIsInFromSpace "
+void assertIsObjptrInFromSpace (GC_state s, objptr *opp) {
+  unless (isObjptrInFromSpace (s, *opp))
+    die ("gc.c: assertIsObjptrInFromSpace "
          "opp = "FMTPTR"  "
          "*opp = "FMTOBJPTR"\n",
          (uintptr_t)opp, *opp);
 }
 
-static bool invariant (GC_state s) {
+bool invariant (GC_state s) {
   if (DEBUG)
     fprintf (stderr, "invariant\n");
   assert (ratiosOk (s->ratios));
   /* Frame layouts */
   for (unsigned int i = 0; i < s->frameLayoutsLength; ++i) {
-    GC_frameLayout *layout;
+    GC_frameLayout layout;
     
     layout = &(s->frameLayouts[i]);
     if (layout->size > 0) {
@@ -36,9 +34,9 @@
   if (s->mutatorMarksCards) {
     assert (s->generationalMaps.cardMap == 
             &(s->generationalMaps.cardMapAbsolute
-              [pointerToCardIndex(s->heap.start)]));
+              [pointerToCardMapIndexAbsolute(s->heap.start)]));
     assert (&(s->generationalMaps.cardMapAbsolute
-              [pointerToCardIndex(s->heap.start + s->heap.size - 1)])
+              [pointerToCardMapIndexAbsolute(s->heap.start + s->heap.size - 1)])
             < (s->generationalMaps.cardMap 
                + (s->generationalMaps.cardMapLength * CARD_MAP_ELEM_SIZE)));
   }
@@ -51,8 +49,8 @@
   unless (0 == s->heap.size) {
     assert (s->heap.nursery <= s->frontier);
     assert (s->frontier <= s->limitPlusSlop);
-    assert (s->limit == s->limitPlusSlop - LIMIT_SLOP);
-    assert (heapHasBytesFree (s, 0, 0));
+    assert (s->limit == s->limitPlusSlop - GC_HEAP_LIMIT_SLOP);
+    assert (hasHeapBytesFree (s, 0, 0));
   }
   assert (s->secondaryHeap.start == NULL 
           or s->heap.size == s->secondaryHeap.size);
@@ -68,32 +66,32 @@
   foreachObjptrInRange (s, s->heap.nursery, &s->frontier, 
                         FALSE, assertObjptrIsInFromSpace);
   /* Current thread. */
-  GC_stack stack = currentThreadStack(s);
+  GC_stack stack = getStackCurrent(s);
   assert (isAlignedStackReserved (s, stack->reserved));
-  assert (s->stackBottom == stackBottom (s, stack));
-  assert (s->stackTop == stackTop (s, stack));
-  assert (s->stackLimit == stackLimit (s, stack));
+  assert (s->stackBottom == getStackBottom (s, stack));
+  assert (s->stackTop == getStackTop (s, stack));
+  assert (s->stackLimit == getStackLimit (s, stack));
   assert (s->stackBottom <= s->stackTop);
-  assert (stack->used == currentStackUsed (s));
+  assert (stack->used == sizeofStackCurrentUsed (s));
   assert (stack->used <= stack->reserved);
   if (DEBUG)
     fprintf (stderr, "invariant passed\n");
   return TRUE;
 }
 
-#endif /* #if ASSERT */
-
-static bool mutatorFrontierInvariant (GC_state s) {
-  GC_thread ct = currentThread(s);
-  return (ct->bytesNeeded <= (size_t)(s->limitPlusSlop - s->frontier));
+bool mutatorFrontierInvariant (GC_state s) {
+  GC_thread thread = getThreadCurrent(s);
+  return (thread->bytesNeeded 
+          <= (size_t)(s->limitPlusSlop - s->frontier));
 }
 
-static bool mutatorStackInvariant (GC_state s) {
-  GC_stack sk = currentThreadStack(s);
-  return (stackTop (s, sk) <= stackLimit (s, sk) + topFrameSize (s, sk));
+bool mutatorStackInvariant (GC_state s) {
+  GC_stack stack = getStackCurrent(s);
+  return (getStackTop (s, stack) 
+          <= getStackLimit (s, stack) + getStackTopFrameSize (s, stack));
 }
 
-static bool mutatorInvariant (GC_state s, bool frontier, bool stack) {
+bool mutatorInvariant (GC_state s, bool frontier, bool stack) {
   if (DEBUG)
     displayGCState (s, stderr);
   if (frontier)

Added: mlton/branches/on-20050822-x86_64-branch/runtime/gc/invariant.h
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/invariant.h	2005-10-30 14:38:45 UTC (rev 4125)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/invariant.h	2005-10-31 02:47:56 UTC (rev 4126)
@@ -0,0 +1,13 @@
+/* Copyright (C) 1999-2005 Henry Cejtin, Matthew Fluet, Suresh
+ *    Jagannathan, and Stephen Weeks.
+ * Copyright (C) 1997-2000 NEC Research Institute.
+ *
+ * MLton is released under a BSD-style license.
+ * See the file MLton-LICENSE for details.
+ */
+
+void assertObjptrIsInFromSpace (GC_state s, objptr *opp);
+bool invariant (GC_state s);
+bool mutatorFrontierInvariant (GC_state s);
+bool mutatorStackInvariant (GC_state s);
+bool mutatorInvariant (GC_state s, bool frontier, bool stack);

Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/mark-compact.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/mark-compact.c	2005-10-30 14:38:45 UTC (rev 4125)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/mark-compact.c	2005-10-31 02:47:56 UTC (rev 4126)
@@ -10,30 +10,9 @@
 /*                 Jonkers Mark-compact Collection                  */
 /* ---------------------------------------------------------------- */
 
-static inline void dfsMarkTrue (GC_state s, objptr *opp) {
-  pointer p;
-
-  p = objptrToPointer (*opp, s->heap.start);
-  dfsMark (s, p, MARK_MODE, TRUE);
-}
-
-static inline void dfsMarkFalse (GC_state s, objptr *opp) {
-  pointer p;
-
-  p = objptrToPointer (*opp, s->heap.start);
-  dfsMark (s, p, MARK_MODE, FALSE);
-}
-
-static inline void dfsUnmark (GC_state s, objptr *opp) {
-  pointer p;
-
-  p = objptrToPointer (*opp, s->heap.start);
-  dfsMark (s, p, UNMARK_MODE, FALSE);
-}
-
 /* An object pointer might be larger than a header.
  */ 
-static inline void threadInternalCopy (pointer dst, pointer src) {
+void threadInternalCopy (pointer dst, pointer src) {
   size_t count = (OBJPTR_SIZE - GC_HEADER_SIZE) / GC_HEADER_SIZE;
   src = src + GC_HEADER_SIZE * count;
 
@@ -44,7 +23,7 @@
   }
 }
 
-static inline void threadInternalObjptr (GC_state s, objptr *opp) {
+void threadInternalObjptr (GC_state s, objptr *opp) {
   objptr opop;
   pointer p;
   GC_header *headerp;
@@ -63,7 +42,7 @@
 /* If p is weak, the object pointer was valid, and points to an unmarked object,
  * then clear the object pointer.
  */
-static inline void maybeClearWeak (GC_state s, pointer p) {
+void maybeClearWeak (GC_state s, pointer p) {
   GC_header header;
   GC_header *headerp;
   uint16_t numNonObjptrs, numObjptrs;
@@ -91,7 +70,7 @@
   }
 }
 
-static void updateForwardPointers (GC_state s) {
+void updateForwardPointers (GC_state s) {
   pointer back;
   pointer endOfLastMarked;
   pointer front;
@@ -113,15 +92,9 @@
              (uintptr_t)front, (uintptr_t)back);
   if (front == back)
     goto done;
-  headerp = (GC_header*)front;
+  p = advanceToObjectData (s, front);
+  headerp = getHeaderp (p);
   header = *headerp;
-  if (0 == header) {
-    /* We're looking at an array.  Move to the header. */
-    p = front + GC_ARRAY_HEADER_SIZE;
-    headerp = (GC_header*)(p - GC_HEADER_SIZE);
-    header = *headerp;
-  } else
-    p = front + GC_HEADER_SIZE;
   if (1 == (1 & header)) {
     /* It's a header */
     if (MARK_MASK & header) {
@@ -130,12 +103,12 @@
        */
 thread:
       maybeClearWeak (s, p);
-      size = objectSize (s, p);
+      size = sizeofObject (s, p);
       if (DEBUG_MARK_COMPACT)
         fprintf (stderr, "threading "FMTPTR" of size %zu\n",
                  (uintptr_t)p, size);
       if ((size_t)(front - endOfLastMarked) >= GC_ARRAY_HEADER_SIZE + OBJPTR_SIZE) {
-        /* Compress all of the unmarked into one string.  We require
+        /* Compress all of the unmarked into one vector.  We require
          * (GC_ARRAY_HEADER_SIZE + OBJPTR_SIZE) space to be available
          * because that is the smallest possible array.  You cannot
          * use GC_ARRAY_HEADER_SIZE because even zero-length arrays
@@ -152,7 +125,7 @@
         endOfLastMarked = endOfLastMarked + GC_ARRAY_COUNTER_SIZE;
         *((GC_arrayLength*)(endOfLastMarked)) = ((size_t)(front - endOfLastMarked)) - GC_ARRAY_HEADER_SIZE;
         endOfLastMarked = endOfLastMarked + GC_ARRAY_LENGTH_SIZE;
-        *((GC_header*)(endOfLastMarked)) = GC_STRING_HEADER;
+        *((GC_header*)(endOfLastMarked)) = GC_WORD8_VECTOR_HEADER;
       }
       front += size;
       endOfLastMarked = front;
@@ -160,7 +133,7 @@
       goto updateObject;
     } else {
       /* It's not marked. */
-      size = objectSize (s, p);
+      size = sizeofObject (s, p);
       gap += size;
       front += size;
       goto updateObject;
@@ -195,7 +168,7 @@
   return;
 }
 
-static void updateBackwardPointersAndSlide (GC_state s) {
+void updateBackwardPointersAndSlide (GC_state s) {
   pointer back;
   pointer front;
   size_t gap;
@@ -215,15 +188,9 @@
              (uintptr_t)front, (uintptr_t)back);
   if (front == back)
     goto done;
-  headerp = (GC_header*)front;
+  p = advanceToObjectData (s, front);
+  headerp = getHeaderp (p);
   header = *headerp;
-  if (0 == header) {
-    /* We're looking at an array.  Move to the header. */
-    p = front + GC_ARRAY_HEADER_SIZE;
-    headerp = (GC_header*)(p - GC_HEADER_SIZE);
-    header = *headerp;
-  } else
-    p = front + GC_HEADER_SIZE;
   if (1 == (1 & header)) {
     /* It's a header */
     if (MARK_MASK & header) {
@@ -231,7 +198,7 @@
        * Unmark it.
        */
 unmark:
-      size = objectSize (s, p);
+      size = sizeofObject (s, p);
       /* unmark */
       if (DEBUG_MARK_COMPACT)
         fprintf (stderr, "unmarking "FMTPTR" of size %zu\n",
@@ -246,7 +213,7 @@
       goto updateObject;
     } else {
       /* It's not marked. */
-      size = objectSize (s, p);
+      size = sizeofObject (s, p);
       if (DEBUG_MARK_COMPACT)
         fprintf (stderr, "skipping "FMTPTR" of size %zu\n",
                  (uintptr_t)p, size);
@@ -287,7 +254,7 @@
   return;
 }
 
-static void majorMarkCompactGC (GC_state s) {
+void majorMarkCompactGC (GC_state s) {
   struct rusage ru_start;
 
   if (detailedGCTime (s))

Added: mlton/branches/on-20050822-x86_64-branch/runtime/gc/mark-compact.h
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/mark-compact.h	2005-10-30 14:38:45 UTC (rev 4125)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/mark-compact.h	2005-10-31 02:47:56 UTC (rev 4126)
@@ -0,0 +1,14 @@
+/* Copyright (C) 1999-2005 Henry Cejtin, Matthew Fluet, Suresh
+ *    Jagannathan, and Stephen Weeks.
+ * Copyright (C) 1997-2000 NEC Research Institute.
+ *
+ * MLton is released under a BSD-style license.
+ * See the file MLton-LICENSE for details.
+ */
+
+void threadInternalCopy (pointer dst, pointer src);
+void threadInternalObjptr (GC_state s, objptr *opp);
+void maybeClearWeak (GC_state s, pointer p);
+void updateForwardPointers (GC_state s);
+void updateBackwardPointersAndSlide (GC_state s);
+void majorMarkCompactGC (GC_state s);

Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/model.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/model.c	2005-10-30 14:38:45 UTC (rev 4125)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/model.c	2005-10-31 02:47:56 UTC (rev 4126)
@@ -5,7 +5,7 @@
  * See the file MLton-LICENSE for details.
  */
 
-static inline pointer objptrToPointer (objptr O, pointer B) {
+pointer objptrToPointer (objptr O, pointer B) {
   uintptr_t O_ = (uintptr_t)O;
   uintptr_t B_;
   unsigned int S_ = GC_MODEL_SHIFT;
@@ -26,7 +26,7 @@
   return P;
 }
 
-static inline objptr pointerToObjptr (pointer P, pointer B) {
+objptr pointerToObjptr (pointer P, pointer B) {
   uintptr_t P_ = (uintptr_t)P;
   uintptr_t B_;
   unsigned int S_ = GC_MODEL_SHIFT;
@@ -56,12 +56,9 @@
  * runtime in a manner which is agnostic to the actual objptr
  * representation.
  */
-static inline pointer fetchObjptrToPointer (pointer OP, pointer B) {
+pointer fetchObjptrToPointer (pointer OP, pointer B) {
   return objptrToPointer (*((objptr*)OP), B);
 }
-static inline void storeObjptrFromPointer (pointer OP, pointer P, pointer B) {
+void storeObjptrFromPointer (pointer OP, pointer P, pointer B) {
   *((objptr*)OP) = pointerToObjptr (P, B);
 }
-static inline size_t objptrSize (void) {
-  return OBJPTR_SIZE;
-}

Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/model.h
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/model.h	2005-10-30 14:38:45 UTC (rev 4125)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/model.h	2005-10-31 02:47:56 UTC (rev 4126)
@@ -221,3 +221,9 @@
 #else
 #error gc model does not admit bogus object pointer
 #endif
+
+bool isObjptr (objptr p);
+pointer objptrToPointer (objptr O, pointer B);
+objptr pointerToObjptr (pointer P, pointer B);
+pointer fetchObjptrToPointer (pointer OP, pointer B);
+void storeObjptrFromPointer (pointer OP, pointer P, pointer B);

Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/model_predicates.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/model_predicates.c	2005-10-30 14:38:45 UTC (rev 4125)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/model_predicates.c	2005-10-31 02:47:56 UTC (rev 4126)
@@ -6,7 +6,7 @@
  */
 
 /* isObjptr returns true if p looks like an object pointer. */
-static inline bool isObjptr (objptr p) {
+bool isObjptr (objptr p) {
   if GC_MODEL_NONOBJPTR {
     unsigned int shift = GC_MODEL_MINALIGN_SHIFT - GC_MODEL_SHIFT;
     objptr mask = ~((~((objptr)0)) << shift);
@@ -15,3 +15,4 @@
     return TRUE;
   }
 }
+

Copied: mlton/branches/on-20050822-x86_64-branch/runtime/gc/new-object.c (from rev 4120, mlton/branches/on-20050822-x86_64-branch/runtime/gc/new_object.c)
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/new_object.c	2005-10-26 00:53:09 UTC (rev 4120)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/new-object.c	2005-10-31 02:47:56 UTC (rev 4126)
@@ -0,0 +1,82 @@
+/* Copyright (C) 1999-2005 Henry Cejtin, Matthew Fluet, Suresh
+ *    Jagannathan, and Stephen Weeks.
+ * Copyright (C) 1997-2000 NEC Research Institute.
+ *
+ * MLton is released under a BSD-style license.
+ * See the file MLton-LICENSE for details.
+ */
+
+/* newObject (s, header, bytesRequested, allocInOldGen)
+ *
+ * Allocate a new object in the heap.
+ * bytesRequested includes the size of the header.
+ */
+pointer newObject (GC_state s,
+                   GC_header header,
+                   size_t bytesRequested,
+                   bool allocInOldGen) {
+  pointer frontier;
+  pointer result;
+
+  assert (isAligned (bytesRequested, s->alignment));
+  assert (allocInOldGen
+          ? hasHeapBytesFree (s, bytesRequested, 0)
+          : hasHeapBytesFree (s, 0, bytesRequested));
+  if (allocInOldGen) {
+    frontier = s->heap.start + s->heap.oldGenSize;
+    s->heap.oldGenSize += bytesRequested;
+    s->cumulativeStatistics.bytesAllocated += bytesRequested;
+  } else {
+    if (DEBUG_DETAILED)
+      fprintf (stderr, "frontier changed from "FMTPTR" to "FMTPTR"\n",
+               (uintptr_t)s->frontier, 
+               (uintptr_t)(s->frontier + bytesRequested));
+    frontier = s->frontier;
+    s->frontier += bytesRequested;
+  }
+  GC_profileAllocInc (s, bytesRequested);
+  *(GC_header*)(frontier) = header;
+  result = frontier + GC_NORMAL_HEADER_SIZE;
+  if (DEBUG)
+    fprintf (stderr, FMTPTR " = newObject ("FMTHDR", %zu, %s)\n",
+             (uintptr_t)result,
+             header, 
+             bytesRequested,
+             boolToString (allocInOldGen));
+  return result;
+}
+
+GC_stack newStack (GC_state s, 
+                   size_t reserved, 
+                   bool allocInOldGen) {
+  GC_stack stack;
+
+  reserved = alignStackReserved (s, reserved);
+  if (reserved > s->cumulativeStatistics.maxStackSizeSeen)
+    s->cumulativeStatistics.maxStackSizeSeen = reserved;
+  stack = (GC_stack) newObject (s, GC_STACK_HEADER, 
+                                sizeofStackWithHeaderAligned (s, reserved),
+                                allocInOldGen);
+  stack->reserved = reserved;
+  stack->used = 0;
+  if (DEBUG_STACKS)
+    fprintf (stderr, FMTPTR " = newStack (%zu)\n", 
+             (uintptr_t)stack, 
+             reserved);
+  return stack;
+}
+
+void growStack (GC_state s) {
+  size_t size;
+  GC_stack stack;
+
+  size = sizeofStackGrow (s, getStackCurrent(s));
+  if (DEBUG_STACKS or s->controls.messages)
+    fprintf (stderr, "Growing stack to size %zu.\n",
+             /*uintToCommaString*/(sizeofStackWithHeaderAligned (s, size)));
+  assert (hasHeapBytesFree (s, sizeofStackWithHeaderAligned (s, size), 0));
+  stack = newStack (s, size, TRUE);
+  copyStack (s, getStackCurrent(s), stack);
+  getThreadCurrent(s)->stack = pointerToObjptr ((pointer)stack, s->heap.start);
+  markCard (s, objptrToPointer (getThreadCurrentObjptr(s), s->heap.start));
+}

Added: mlton/branches/on-20050822-x86_64-branch/runtime/gc/new-object.h
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/new-object.h	2005-10-30 14:38:45 UTC (rev 4125)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/new-object.h	2005-10-31 02:47:56 UTC (rev 4126)
@@ -0,0 +1,12 @@
+/* Copyright (C) 1999-2005 Henry Cejtin, Matthew Fluet, Suresh
+ *    Jagannathan, and Stephen Weeks.
+ * Copyright (C) 1997-2000 NEC Research Institute.
+ *
+ * MLton is released under a BSD-style license.
+ * See the file MLton-LICENSE for details.
+ */
+
+pointer newObject (GC_state s, GC_header header, 
+                   size_t bytesRequested, bool allocInOldGen);
+GC_stack newStack (GC_state s, size_t reserved, bool allocInOldGen);
+void growStack (GC_state s);

Deleted: mlton/branches/on-20050822-x86_64-branch/runtime/gc/new_object.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/new_object.c	2005-10-30 14:38:45 UTC (rev 4125)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/new_object.c	2005-10-31 02:47:56 UTC (rev 4126)
@@ -1,87 +0,0 @@
-/* Copyright (C) 1999-2005 Henry Cejtin, Matthew Fluet, Suresh
- *    Jagannathan, and Stephen Weeks.
- * Copyright (C) 1997-2000 NEC Research Institute.
- *
- * MLton is released under a BSD-style license.
- * See the file MLton-LICENSE for details.
- */
-
-/* newObject (s, header, bytesRequested, allocInOldGen)
- *
- * Allocate a new object in the heap.
- * bytesRequested includes the size of the header.
- */
-static pointer newObject (GC_state s,
-                          GC_header header,
-                          size_t bytesRequested,
-                          bool allocInOldGen) {
-  pointer frontier;
-  pointer result;
-
-  assert (isAligned (bytesRequested, s->alignment));
-  assert (allocInOldGen
-          ? heapHasBytesFree (s, bytesRequested, 0)
-          : heapHasBytesFree (s, 0, bytesRequested));
-  if (allocInOldGen) {
-    frontier = s->heap.start + s->heap.oldGenSize;
-    s->heap.oldGenSize += bytesRequested;
-    s->cumulativeStatistics.bytesAllocated += bytesRequested;
-  } else {
-    if (DEBUG_DETAILED)
-      fprintf (stderr, "frontier changed from "FMTPTR" to "FMTPTR"\n",
-               (uintptr_t)s->frontier, 
-               (uintptr_t)(s->frontier + bytesRequested));
-    frontier = s->frontier;
-    s->frontier += bytesRequested;
-  }
-  GC_profileAllocInc (s, bytesRequested);
-  *(GC_header*)(frontier) = header;
-  result = frontier + GC_NORMAL_HEADER_SIZE;
-  if (DEBUG)
-    fprintf (stderr, FMTPTR " = newObject ("FMTHDR", %zu, %s)\n",
-             (uintptr_t)result,
-             header, 
-             bytesRequested,
-             boolToString (allocInOldGen));
-  return result;
-}
-
-static GC_stack newStack (GC_state s, 
-                          size_t reserved, 
-                          bool allocInOldGen) {
-  GC_stack stack;
-
-  reserved = alignStackReserved (s, reserved);
-  if (reserved > s->cumulativeStatistics.maxStackSizeSeen)
-    s->cumulativeStatistics.maxStackSizeSeen = reserved;
-  stack = (GC_stack) newObject (s, GC_STACK_HEADER, 
-                                stackSizeTotalAligned (s, reserved),
-                                allocInOldGen);
-  stack->reserved = reserved;
-  stack->used = 0;
-  if (DEBUG_STACKS)
-    fprintf (stderr, FMTPTR " = newStack (%zu)\n", 
-             (uintptr_t)stack, 
-             reserved);
-  return stack;
-}
-
-static inline size_t stackGrowSize (GC_state s) {
-  return max (2 * currentThreadStack(s)->reserved,
-              stackMinimumReserved (s, currentThreadStack(s)));
-}
-
-static void stackGrow (GC_state s) {
-  size_t size;
-  GC_stack stack;
-
-  size = stackGrowSize (s);
-  if (DEBUG_STACKS or s->controls.messages)
-    fprintf (stderr, "Growing stack to size %zu.\n",
-             /*uintToCommaString*/(stackSizeTotalAligned (s, size)));
-  assert (heapHasBytesFree (s, stackSizeTotalAligned (s, size), 0));
-  stack = newStack (s, size, TRUE);
-  stackCopy (s, currentThreadStack(s), stack);
-  currentThread(s)->stack = pointerToObjptr ((pointer)stack, s->heap.start);
-  markCard (s, objptrToPointer (currentThreadObjptr(s), s->heap.start));
-}

Copied: mlton/branches/on-20050822-x86_64-branch/runtime/gc/object-size.c (from rev 4120, mlton/branches/on-20050822-x86_64-branch/runtime/gc/object_size.c)
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/object_size.c	2005-10-26 00:53:09 UTC (rev 4120)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/object-size.c	2005-10-31 02:47:56 UTC (rev 4126)
@@ -0,0 +1,92 @@
+/* Copyright (C) 1999-2005 Henry Cejtin, Matthew Fluet, Suresh
+ *    Jagannathan, and Stephen Weeks.
+ * Copyright (C) 1997-2000 NEC Research Institute.
+ *
+ * MLton is released under a BSD-style license.
+ * See the file MLton-LICENSE for details.
+ */
+
+size_t sizeofNumNonObjptrs (GC_objectTypeTag tag, uint16_t numNonObjptrs) {
+  switch (tag) {
+  case ARRAY_TAG:
+    return (size_t)(numNonObjptrs);
+  case NORMAL_TAG:
+    return (size_t)(numNonObjptrs) * 4;
+  case WEAK_TAG:
+    return (size_t)(numNonObjptrs) * 4;
+  default:
+    die ("bad GC_objectTypeTag %u", tag);
+  }
+}
+
+size_t sizeofNormalNoHeader (__attribute__ ((unused)) GC_state s,
+                             uint16_t numNonObjptrs,
+                             uint16_t numObjptrs) {
+  size_t result;
+
+  result = 
+    sizeofNumNonObjptrs (NORMAL_TAG, numNonObjptrs)
+    + (numObjptrs * OBJPTR_SIZE);
+  return result;
+}
+
+size_t sizeofArrayNoHeader (GC_state s, 
+                            GC_arrayLength numElements,
+                            uint16_t numNonObjptrs, uint16_t numObjptrs) {
+  size_t bytesPerElement;
+  size_t result;
+        
+  bytesPerElement = 
+    sizeofNumNonObjptrs (ARRAY_TAG, numNonObjptrs) 
+    + (numObjptrs * OBJPTR_SIZE);
+  result = numElements * bytesPerElement;
+  /* Empty arrays have OBJPTR_SIZE bytes for the forwarding pointer. */
+  if (0 == result) 
+    result = OBJPTR_SIZE;
+  return pad (s, result, GC_ARRAY_HEADER_SIZE);
+}
+
+size_t sizeofWeakNoHeader (__attribute__ ((unused)) GC_state s,
+                           uint16_t numNonObjptrs,
+                           uint16_t numObjptrs) {
+  size_t result;
+
+  result = 
+    sizeofNumNonObjptrs (WEAK_TAG, numNonObjptrs)
+    + (numObjptrs * OBJPTR_SIZE);
+  return result;
+}
+
+size_t sizeofStackNoHeader (__attribute__ ((unused)) GC_state s,
+                            GC_stack stack) {
+  size_t result;
+
+  result = sizeof (struct GC_stack) + stack->reserved;
+  return result;
+}
+
+size_t sizeofObject (GC_state s, pointer p) {
+  size_t headerBytes, objectBytes;
+  GC_header header;
+  GC_objectTypeTag tag;
+  uint16_t numNonObjptrs, numObjptrs;
+  
+  header = getHeader (p);
+  splitHeader (s, header, &tag, NULL, &numNonObjptrs, &numObjptrs);
+  if (NORMAL_TAG == tag) { 
+    headerBytes = GC_NORMAL_HEADER_SIZE;
+    objectBytes = sizeofNormalNoHeader (s, numNonObjptrs, numObjptrs);
+  } else if (ARRAY_TAG == tag) {
+    headerBytes = GC_ARRAY_HEADER_SIZE;
+    objectBytes = sizeofArrayNoHeader (s, getArrayLength (p), 
+                                       numNonObjptrs, numObjptrs);
+  } else if (WEAK_TAG == tag) {
+    headerBytes = GC_NORMAL_HEADER_SIZE;
+    objectBytes = sizeofWeakNoHeader (s, numNonObjptrs, numObjptrs);
+  } else { /* Stack. */
+    assert (STACK_TAG == tag);
+    headerBytes = GC_STACK_HEADER_SIZE;
+    objectBytes = sizeofStackNoHeader (s, (GC_stack)p);
+  }
+  return headerBytes + objectBytes;
+}

Added: mlton/branches/on-20050822-x86_64-branch/runtime/gc/object-size.h
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/object-size.h	2005-10-30 14:38:45 UTC (rev 4125)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/object-size.h	2005-10-31 02:47:56 UTC (rev 4126)
@@ -0,0 +1,19 @@
+/* Copyright (C) 1999-2005 Henry Cejtin, Matthew Fluet, Suresh
+ *    Jagannathan, and Stephen Weeks.
+ * Copyright (C) 1997-2000 NEC Research Institute.
+ *
+ * MLton is released under a BSD-style license.
+ * See the file MLton-LICENSE for details.
+ */
+
+size_t sizeofNumNonObjptrs (GC_objectTypeTag tag, 
+                            uint16_t numNonObjptrs);
+size_t sizeofNormalNoHeader (GC_state s, 
+                             uint16_t numNonObjptrs, uint16_t numObjptrs);
+size_t sizeofArrayNoHeader (GC_state s, GC_arrayLength numElements, 
+                            uint16_t numNonObjptrs, uint16_t numObjptrs);
+size_t sizeofWeakNoHeader (GC_state s, 
+                           uint16_t numNonObjptrs, uint16_t numObjptrs);
+size_t sizeofStackNoHeader (GC_state s, GC_stack stack);
+
+size_t sizeofObject (GC_state s, pointer p);

Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/object.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/object.c	2005-10-30 14:38:45 UTC (rev 4125)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/object.c	2005-10-31 02:47:56 UTC (rev 4126)
@@ -6,7 +6,7 @@
  * See the file MLton-LICENSE for details.
  */
 
-static char* objectTypeTagToString (GC_objectTypeTag tag) {
+const char* objectTypeTagToString (GC_objectTypeTag tag) {
   switch (tag) {
   case ARRAY_TAG:
     return "ARRAY";
@@ -17,29 +17,40 @@
   case WEAK_TAG:
     return "WEAK";
   default:
-    die ("bad tag %u", tag);
+    die ("bad GC_objectTypeTag %u", tag);
   }
 }
 
+/* getHeaderp (p)
+ *
+ * Returns a pointer to the header for the object pointed to by p.
+ */
+GC_header* getHeaderp (pointer p) {
+  return (GC_header*)(p 
+                      - GC_HEADER_SIZE);
+}
+
+/* getHeader (p) 
+ *
+ * Returns the header for the object pointed to by p. 
+ */
+GC_header getHeader (pointer p) {
+  return *(getHeaderp(p));
+}
+
 /*
  * Build the header for an object, given the index to its type info.
  */
-static inline GC_header objectHeader (uint32_t t) {
-        assert (t < TWOPOWER (TYPE_INDEX_BITS));
-        return 1 | (t << 1);
+GC_header buildHeaderFromTypeIndex (uint32_t t) {
+  assert (t < TWOPOWER (TYPE_INDEX_BITS));
+  return 1 | (t << 1);
 }
 
-#define GC_STACK_HEADER objectHeader (STACK_TYPE_INDEX)
-#define GC_STRING_HEADER objectHeader (STRING_TYPE_INDEX)
-#define GC_THREAD_HEADER objectHeader (THREAD_TYPE_INDEX)
-#define GC_WEAK_GONE_HEADER objectHeader (WEAK_GONE_TYPE_INDEX)
-#define GC_WORD8_VECTOR_HEADER objectHeader (WORD8_TYPE_INDEX)
-
-static inline void splitHeader(GC_state s, GC_header header,
-                               GC_objectTypeTag *tagRet, bool *hasIdentityRet,
-                               uint16_t *numNonObjptrsRet, uint16_t *numObjptrsRet) {
+void splitHeader(GC_state s, GC_header header,
+                 GC_objectTypeTag *tagRet, bool *hasIdentityRet,
+                 uint16_t *numNonObjptrsRet, uint16_t *numObjptrsRet) {
   unsigned int objectTypeIndex; 
-  GC_objectType *objectType; 
+  GC_objectType objectType; 
   GC_objectTypeTag tag;
   bool hasIdentity;
   uint16_t numNonObjptrs, numObjptrs;
@@ -57,11 +68,13 @@
     fprintf (stderr, 
              "splitHeader ("FMTHDR")" 
              "  tag = %s" 
-             "  hasIdentity = %u" 
+             "  hasIdentity = %s" 
              "  numNonObjptrs = %"PRIu16 
              "  numObjptrs = %"PRIu16"\n", 
              header, 
-             objectTypeTagToString(tag), hasIdentity, numNonObjptrs, numObjptrs); 
+             objectTypeTagToString(tag), 
+             boolToString(hasIdentity), 
+             numNonObjptrs, numObjptrs); 
 
   if (tagRet != NULL)
     *tagRet = tag;
@@ -73,12 +86,12 @@
     *numObjptrsRet = numObjptrs;
 }
 
-/* objectData (s, p)
+/* advanceToObjectData (s, p)
  *
- * If p points at the beginning of an object, then objectData returns
- * a pointer to the start of the object data.
+ * If p points at the beginning of an object, then advanceToObjectData
+ * returns a pointer to the start of the object data.
  */
-static inline pointer objectData (GC_state s, pointer p) {
+pointer advanceToObjectData (GC_state s, pointer p) {
   GC_header header;
   pointer res;
 

Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/object.h
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/object.h	2005-10-30 14:38:45 UTC (rev 4125)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/object.h	2005-10-31 02:47:56 UTC (rev 4126)
@@ -17,6 +17,8 @@
   WEAK_TAG,
 } GC_objectTypeTag;
 
+const char* objectTypeTagToString (GC_objectTypeTag tag);
+
 /*
  * Each object has a header, which immediately precedes the object data.
  * A header has the following bit layout:
@@ -42,22 +44,10 @@
 #define MARK_MASK          0x80000000
 #define MARK_SHIFT         31
 
-/* getHeaderp (p)
- *
- * Returns a pointer to the header for the object pointed to by p.
- */
-static inline GC_header* getHeaderp (pointer p) {
-  return (GC_header*)(p - GC_HEADER_SIZE);
-}
+GC_header* getHeaderp (pointer p);
+GC_header getHeader (pointer p);
+GC_header buildHeaderFromTypeIndex (uint32_t t);
 
-/* getHeader (p) 
- *
- * Returns the header for the object pointed to by p. 
- */
-static inline GC_header getHeader (pointer p) {
-  return *(getHeaderp(p));
-}
-
 /*
  * Normal objects have the following layout:
  *
@@ -108,7 +98,7 @@
   bool hasIdentity;
   uint16_t numNonObjptrs;
   uint16_t numObjptrs;
-} GC_objectType;
+} *GC_objectType;
 enum {
   /* The type indices here must agree with those in backend/rep-type.fun. */
   STACK_TYPE_INDEX =         0,
@@ -119,3 +109,15 @@
   WORD32_VECTOR_TYPE_INDEX = 4,
   WORD16_VECTOR_TYPE_INDEX = 5,
 };
+
+#define GC_STACK_HEADER buildHeaderFromTypeIndex (STACK_TYPE_INDEX)
+#define GC_THREAD_HEADER buildHeaderFromTypeIndex (THREAD_TYPE_INDEX)
+#define GC_WEAK_GONE_HEADER buildHeaderFromTypeIndex (WEAK_GONE_TYPE_INDEX)
+#define GC_WORD8_VECTOR_HEADER buildHeaderFromTypeIndex (WORD8_VECTOR_TYPE_INDEX)
+#define GC_WORD16_VECTOR_HEADER buildHeaderFromTypeIndex (WORD16_VECTOR_TYPE_INDEX)
+#define GC_WORD32_VECTOR_HEADER buildHeaderFromTypeIndex (WORD32_VECTOR_TYPE_INDEX)
+
+void splitHeader (GC_state s, GC_header header,
+                  GC_objectTypeTag *tagRet, bool *hasIdentityRet,
+                  uint16_t *numNonObjptrsRet, uint16_t *numObjptrsRet);
+pointer advanceToObjectData (GC_state s, pointer p);

Deleted: mlton/branches/on-20050822-x86_64-branch/runtime/gc/object_size.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/object_size.c	2005-10-30 14:38:45 UTC (rev 4125)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/object_size.c	2005-10-31 02:47:56 UTC (rev 4126)
@@ -1,95 +0,0 @@
-/* Copyright (C) 1999-2005 Henry Cejtin, Matthew Fluet, Suresh
- *    Jagannathan, and Stephen Weeks.
- * Copyright (C) 1997-2000 NEC Research Institute.
- *
- * MLton is released under a BSD-style license.
- * See the file MLton-LICENSE for details.
- */
-
-static inline size_t numNonObjptrsToBytes (uint16_t numNonObjptrs, 
-                                           GC_objectTypeTag tag) {
-  switch (tag) {
-  case ARRAY_TAG:
-    return (size_t)(numNonObjptrs);
-  case NORMAL_TAG:
-    return (size_t)(numNonObjptrs) * 4;
-  case WEAK_TAG:
-    return (size_t)(numNonObjptrs) * 4;
-  default:
-    die ("bad tag %u", tag);
-  }
-}
-
-static inline size_t normalSizeNoHeader (__attribute__ ((unused)) GC_state s,
-                                         uint16_t numNonObjptrs,
-                                         uint16_t numObjptrs) {
-  size_t result;
-
-  result = 
-    numNonObjptrsToBytes (numNonObjptrs, NORMAL_TAG)
-    + (numObjptrs * OBJPTR_SIZE);
-  return result;
-}
-
-static inline size_t arraySizeNoHeader (GC_state s,
-                                        pointer p, 
-                                        uint16_t numNonObjptrs,
-                                        uint16_t numObjptrs) {
-  size_t bytesPerElement;
-  GC_arrayLength numElements;
-  size_t result;
-        
-  numElements = getArrayLength (p);
-  bytesPerElement = 
-    numNonObjptrsToBytes(numNonObjptrs, ARRAY_TAG) 
-    + (numObjptrs * OBJPTR_SIZE);
-  result = numElements * bytesPerElement;
-  /* Empty arrays have OBJPTR_SIZE bytes for the forwarding pointer. */
-  if (0 == result) 
-    result = OBJPTR_SIZE;
-  return pad (s, result, GC_ARRAY_HEADER_SIZE);
-}
-
-static inline size_t weakSizeNoHeader (__attribute__ ((unused)) GC_state s,
-                                       uint16_t numNonObjptrs,
-                                       uint16_t numObjptrs) {
-  size_t result;
-
-  result = 
-    numNonObjptrsToBytes (numNonObjptrs, WEAK_TAG)
-    + (numObjptrs * OBJPTR_SIZE);
-  return result;
-}
-
-static inline size_t stackSizeNoHeader (__attribute__ ((unused)) GC_state s,
-                                        pointer p) {
-  size_t result;
-
-  result = sizeof (struct GC_stack) + ((GC_stack)p)->reserved;
-  return result;
-}
-
-static inline size_t objectSize (GC_state s, pointer p) {
-  size_t headerBytes, objectBytes;
-  GC_header header;
-  GC_objectTypeTag tag;
-  uint16_t numNonObjptrs, numObjptrs;
-  
-  header = getHeader (p);
-  splitHeader (s, header, &tag, NULL, &numNonObjptrs, &numObjptrs);
-  if (NORMAL_TAG == tag) { 
-    headerBytes = GC_NORMAL_HEADER_SIZE;
-    objectBytes = normalSizeNoHeader (s, numNonObjptrs, numObjptrs);
-  } else if (ARRAY_TAG == tag) {
-    headerBytes = GC_ARRAY_HEADER_SIZE;
-    objectBytes = arraySizeNoHeader (s, p, numNonObjptrs, numObjptrs);
-  } else if (WEAK_TAG == tag) {
-    headerBytes = GC_NORMAL_HEADER_SIZE;
-    objectBytes = weakSizeNoHeader (s, numNonObjptrs, numObjptrs);
-  } else { /* Stack. */
-    assert (STACK_TAG == tag);
-    headerBytes = GC_STACK_HEADER_SIZE;
-    objectBytes = stackSizeNoHeader (s, p);
-  }
-  return headerBytes + objectBytes;
-}

Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/pack.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/pack.c	2005-10-30 14:38:45 UTC (rev 4125)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/pack.c	2005-10-31 02:47:56 UTC (rev 4126)
@@ -20,11 +20,11 @@
   doGC (s, 0, 0, TRUE, FALSE);
   keep = s->heap.oldGenSize * 1.1;
   if (keep <= s->heap.size) {
-    heapShrink (s, &s->heap, keep);
-    heapSetNursery (s, 0, 0);
-    setCurrentStack (s);
+    shrinkHeap (s, &s->heap, keep);
+    setHeapNursery (s, 0, 0);
+    setThreadAndStackCurrent (s);
   }
-  heapRelease (s, &s->secondaryHeap);
+  releaseHeap (s, &s->secondaryHeap);
   if (DEBUG or s->controls.messages)
     fprintf (stderr, "Packed heap to size %zu.\n",
              /*uintToCommaString*/(s->heap.size));
@@ -42,10 +42,10 @@
    */
   enterGC (s);
   minorGC (s);
-  heapResize (s, s->heap.oldGenSize);
-  secondaryHeapResize (s);
-  heapSetNursery (s, 0, 0);
-  setCurrentStack (s);
+  resizeHeap (s, s->heap.oldGenSize);
+  resizeHeapSecondary (s);
+  setHeapNursery (s, 0, 0);
+  setThreadAndStackCurrent (s);
   leaveGC (s);
   if (DEBUG or s->controls.messages)
     fprintf (stderr, "Unpacked heap to size %zu.\n",

Added: mlton/branches/on-20050822-x86_64-branch/runtime/gc/pack.h
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/pack.h	2005-10-30 14:38:45 UTC (rev 4125)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/pack.h	2005-10-31 02:47:56 UTC (rev 4126)
@@ -0,0 +1,10 @@
+/* Copyright (C) 1999-2005 Henry Cejtin, Matthew Fluet, Suresh
+ *    Jagannathan, and Stephen Weeks.
+ * Copyright (C) 1997-2000 NEC Research Institute.
+ *
+ * MLton is released under a BSD-style license.
+ * See the file MLton-LICENSE for details.
+ */
+
+void GC_pack (GC_state s);
+void GC_unpack (GC_state s);

Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/pointer.h
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/pointer.h	2005-10-30 14:38:45 UTC (rev 4125)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/pointer.h	2005-10-31 02:47:56 UTC (rev 4126)
@@ -11,4 +11,4 @@
 #define FMTPTR "0x%016"PRIxPTR
 #define BOGUS_POINTER (pointer)0x1
 
-#define WORD_SIZE POINTER_SIZE
+bool isPointer (pointer p);

Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/pointer_predicates.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/pointer_predicates.c	2005-10-30 14:38:45 UTC (rev 4125)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/pointer_predicates.c	2005-10-31 02:47:56 UTC (rev 4126)
@@ -7,7 +7,7 @@
  */
 
 /* isPointer returns true if p looks like a pointer. */
-static inline bool isPointer (pointer p) {
+bool isPointer (pointer p) {
   uintptr_t mask = ~((~((uintptr_t)0)) << GC_MODEL_MINALIGN_SHIFT);
   return (0 == ((uintptr_t)p & mask));
 }

Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/profiling.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/profiling.c	2005-10-30 14:38:45 UTC (rev 4125)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/profiling.c	2005-10-31 02:47:56 UTC (rev 4126)
@@ -44,7 +44,7 @@
 }
 
 static inline uint32_t topFrameSourceSeqIndex (GC_state s, GC_stack stack) {
-  return s->profiling.frameSources[topFrameIndex (s, stack)];
+  return s->profiling.frameSources[getStackTopFrameIndex (s, stack)];
 }
 
 uint32_t* GC_frameIndexSourceSeq (GC_state s, GC_frameIndex frameIndex) {
@@ -243,11 +243,11 @@
 }
 
 void GC_profileEnter (GC_state s) {
-  profileEnter (s, topFrameSourceSeqIndex (s, currentThreadStack (s)));
+  profileEnter (s, topFrameSourceSeqIndex (s, getStackCurrent (s)));
 }
 
 void GC_profileLeave (GC_state s) {
-  profileLeave (s, topFrameSourceSeqIndex (s, currentThreadStack (s)));
+  profileLeave (s, topFrameSourceSeqIndex (s, getStackCurrent (s)));
 }
 
 void GC_profileInc (GC_state s, size_t amount) {
@@ -256,7 +256,7 @@
   profileInc (s, amount,
               s->amInGC 
               ? SOURCE_SEQ_GC 
-              : topFrameSourceSeqIndex (s, currentThreadStack (s)));
+              : topFrameSourceSeqIndex (s, getStackCurrent (s)));
 }
 
 void GC_profileAllocInc (GC_state s, size_t amount) {
@@ -396,7 +396,7 @@
   if (s->amInGC)
     sourceSeqIndex = SOURCE_SEQ_GC;
   else {
-    frameIndex = topFrameIndex (s, currentThreadStack (s));
+    frameIndex = getStackTopFrameIndex (s, getStackCurrent (s));
     if (C_FRAME == s->frameLayouts[frameIndex].kind)
       sourceSeqIndex = s->profiling.frameSources[frameIndex];
     else {

Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/profiling.h
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/profiling.h	2005-10-30 14:38:45 UTC (rev 4125)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/profiling.h	2005-10-31 02:47:56 UTC (rev 4126)
@@ -59,8 +59,8 @@
    * ticks that occurred while the function was on top of the stack.
    */
   uintmax_t *countTop;
-  /* stack is an array that gives stack info for each function.  It is
-   * only used if profileStack.
+  /* stack is an array that gives stack info for each function.  
+   * It is only used if profileStack.
    */
   struct GC_profileStack *stack;
   /* The total number of mutator ticks. */

Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/ratios.h
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/ratios.h	2005-10-30 14:38:45 UTC (rev 4125)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/ratios.h	2005-10-31 02:47:56 UTC (rev 4126)
@@ -31,3 +31,6 @@
   float ramSlop;
   float threadShrink; 
 };
+
+bool ratiosOk (struct GC_ratios ratios);
+

Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/ratios_predicates.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/ratios_predicates.c	2005-10-30 14:38:45 UTC (rev 4125)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/ratios_predicates.c	2005-10-31 02:47:56 UTC (rev 4126)
@@ -6,7 +6,7 @@
  * See the file MLton-LICENSE for details.
  */
 
-static bool ratiosOk (struct GC_ratios ratios) {
+bool ratiosOk (struct GC_ratios ratios) {
   return 1.0 < ratios.grow
     and 1.0 < ratios.nursery
     and 1.0 < ratios.markCompact

Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/read_write.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/read_write.c	2005-10-30 14:38:45 UTC (rev 4125)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/read_write.c	2005-10-31 02:47:56 UTC (rev 4126)
@@ -71,28 +71,36 @@
   write_safe (fd, s, strlen(s));
 }
 
+#define BUF_SIZE 81
 static inline void writeUint32U (int fd, uint32_t u) {
-  char buf[(UINT32_MAX / 10) + 2];
+  static char buf[BUF_SIZE];
 
   sprintf (buf, "%"PRIu32, u);
   writeString (fd, buf);
 }
 
 static inline void writeUintmaxU (int fd, uintmax_t u) {
-  // char buf[(UINTMAX_MAX / 10) + 2];
-  char buf[20];
+  static char buf[BUF_SIZE];
 
   sprintf (buf, "%"PRIuMAX, u);
   writeString (fd, buf);
 }
 
 static inline void writeUint32X (int fd, uint32_t u) {
-  char buf[5 + (UINT32_MAX / 16) + 2];
+  static char buf[BUF_SIZE];
   
   sprintf (buf, "0x%08"PRIx32, u);
   writeString (fd, buf);
 }
 
+static inline void writeUintmaxX (int fd, uintmax_t u) {
+  static char buf[BUF_SIZE];
+  
+  sprintf (buf, "0x%08"PRIxMAX, u);
+  writeString (fd, buf);
+}
+
 static inline inline void writeNewline (int fd) {
   writeString (fd, "\n");
 }
+#undef BUF_SIZE

Added: mlton/branches/on-20050822-x86_64-branch/runtime/gc/read_write.h
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/read_write.h	2005-10-30 14:38:45 UTC (rev 4125)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/read_write.h	2005-10-31 02:47:56 UTC (rev 4126)
@@ -0,0 +1,26 @@
+/* Copyright (C) 1999-2005 Henry Cejtin, Matthew Fluet, Suresh
+ *    Jagannathan, and Stephen Weeks.
+ * Copyright (C) 1997-2000 NEC Research Institute.
+ *
+ * MLton is released under a BSD-style license.
+ * See the file MLton-LICENSE for details.
+ */
+
+char readChar (int fd);
+pointer readPointer (int fd);
+objptr readObjptr (int fd);
+size_t readSize (int fd);
+uint32_t readUint32 (int fd);
+uintptr_t readUintptr (int fd);
+void writeChar (int fd, char c);
+void writePointer (int fd, pointer p);
+void writeObjptr (int fd, objptr op);
+void writeSize (int fd, size_t z);
+void writeUint32 (int fd, uint32_t u);
+void writeUintptr (int fd, uintptr_t u);
+void writeString (int fd, char* s);
+void writeUint32U (int fd, uint32_t u);
+void writeUintmaxU (int fd, uintmax_t u);
+void writeUint32X (int fd, uint32_t u);
+void writeUintmaxX (int fd, uintmax_t u);
+void writeNewline (int fd);

Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/rusage.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/rusage.c	2005-10-30 14:38:45 UTC (rev 4125)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/rusage.c	2005-10-31 02:47:56 UTC (rev 4126)
@@ -6,13 +6,13 @@
  * See the file MLton-LICENSE for details.
  */
 
-static inline void rusageZero (struct rusage *ru) {
+void rusageZero (struct rusage *ru) {
   memset (ru, 0, sizeof (*ru));
 }
 
-static void rusagePlusMax (struct rusage *ru1,
-                           struct rusage *ru2,
-                           struct rusage *ru) {
+void rusagePlusMax (struct rusage *ru1,
+                    struct rusage *ru2,
+                    struct rusage *ru) {
   const int       million = 1000000;
   time_t          sec,
                   usec;
@@ -32,9 +32,9 @@
   ru->ru_stime.tv_usec = usec;
 }
 
-static void rusageMinusMax (struct rusage *ru1,
-                            struct rusage *ru2,
-                            struct rusage *ru) {
+void rusageMinusMax (struct rusage *ru1,
+                     struct rusage *ru2,
+                     struct rusage *ru) {
   const int       million = 1000000;
   time_t          sec,
                   usec;
@@ -54,7 +54,7 @@
   ru->ru_stime.tv_usec = usec;
 }
 
-static uintmax_t rusageTime (struct rusage *ru) {
+uintmax_t rusageTime (struct rusage *ru) {
   uintmax_t result;
 
   result = 0;
@@ -66,27 +66,22 @@
 }
 
 /* Return time as number of milliseconds. */
-static uintmax_t currentTime (void) {
+uintmax_t currentTime (void) {
   struct rusage ru;
   
   getrusage (RUSAGE_SELF, &ru);
   return rusageTime (&ru);
 }
 
-static inline void startTiming (struct rusage *ru_start) {
+void startTiming (struct rusage *ru_start) {
   getrusage (RUSAGE_SELF, ru_start);
 }
 
-static uintmax_t stopTiming (struct rusage *ru_start, struct rusage *ru_gc) {
+uintmax_t stopTiming (struct rusage *ru_start, struct rusage *ru_acc) {
   struct rusage ru_finish, ru_total;
 
   getrusage (RUSAGE_SELF, &ru_finish);
   rusageMinusMax (&ru_finish, ru_start, &ru_total);
-  rusagePlusMax (ru_gc, &ru_total, ru_gc);
+  rusagePlusMax (ru_acc, &ru_total, ru_acc);
   return rusageTime (&ru_total);
 }
-
-
-static inline bool detailedGCTime (GC_state s) {
-  return s->controls.summary;
-}

Added: mlton/branches/on-20050822-x86_64-branch/runtime/gc/rusage.h
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/rusage.h	2005-10-30 14:38:45 UTC (rev 4125)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/rusage.h	2005-10-31 02:47:56 UTC (rev 4126)
@@ -0,0 +1,19 @@
+/* Copyright (C) 1999-2005 Henry Cejtin, Matthew Fluet, Suresh
+ *    Jagannathan, and Stephen Weeks.
+ * Copyright (C) 1997-2000 NEC Research Institute.
+ *
+ * MLton is released under a BSD-style license.
+ * See the file MLton-LICENSE for details.
+ */
+
+void rusageZero (struct rusage *ru);
+void rusagePlusMax (struct rusage *ru1,
+                    struct rusage *ru2,
+                    struct rusage *ru);
+void rusageMinusMax (struct rusage *ru1,
+                     struct rusage *ru2,
+                     struct rusage *ru);
+uintmax_t rusageTime (struct rusage *ru);
+uintmax_t currentTime (void);
+void startTiming (struct rusage *ru_start);
+uintmax_t stopTiming (struct rusage *ru_start, struct rusage *ru_gc);

Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/safe.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/safe.c	2005-10-30 14:38:45 UTC (rev 4125)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/safe.c	2005-10-31 02:47:56 UTC (rev 4126)
@@ -16,6 +16,15 @@
   return res;
 }
 
+void close_safe (int fd) {
+  int res;
+
+  res = close (fd);
+  if (-1 == res)
+    diee ("close (%d) failed.\n", fd);
+  return;
+}
+
 void *malloc_safe (size_t size) {
   void *res;
   
@@ -43,58 +52,15 @@
   return res;
 }
 
-void close_safe (int fd) {
-  int res;
+void read_safe (int fd, void *buf, size_t size) {
+  ssize_t res;
 
-  res = close (fd);
-  if (-1 == res)
-    diee ("close (%d) failed.\n", fd);
-  return;
+  if (0 == size) return;
+  res = read (fd, buf, size);
+  if (res == -1 or (size_t)res != size)
+    diee ("read (_, _, _) failed.\n");
 }
 
-/*
-FILE *fopen_safe (char *fileName, char *mode) {
-  FILE *file;
-  
-  file = fopen (fileName, mode);
-  if (NULL == file)
-    diee ("fopen (%s) failed.\n", fileName);
-  return file;
-}
-
-void fwrite_safe (const void *data, size_t size, size_t count, FILE *stream) {
-  size_t bytes;
-  size_t res;
-
-  bytes = size * count;
-  if (0 == bytes) return;
-  res = fwrite (data, bytes, 1, stream);
-  if (1 != res)
-    diee ("fwrite (_, _, _, _) failed.\n");
-  return;
-}
-
-void fclose_safe (FILE *stream) {
-  int res;
-
-  res = fclose (stream);
-  if (-1 == res)
-    diee ("fclose (_) failed.\n");
-  return;
-}
-
-void fread_safe (void *data, size_t size, size_t count, FILE *stream) {
-  size_t bytes;
-  size_t res;
-
-  bytes = size * count;
-  res = fread (data, bytes, 1, stream);
-  if (1 != res)
-    diee ("fread (_, _, _, _) failed.\n");
-  return;
-}
-*/
-
 void unlink_safe (const char *pathname) {
   int res;
 
@@ -104,15 +70,6 @@
   return;
 }
 
-void read_safe (int fd, void *buf, size_t size) {
-  ssize_t res;
-
-  if (0 == size) return;
-  res = read (fd, buf, size);
-  if (res == -1 or (size_t)res != size)
-    diee ("read (_, _, _) failed.\n");
-}
-
 void write_safe (int fd, const void *buf, size_t size) {
   ssize_t res;
 

Added: mlton/branches/on-20050822-x86_64-branch/runtime/gc/safe.h
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/safe.h	2005-10-30 14:38:45 UTC (rev 4125)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/safe.h	2005-10-31 02:47:56 UTC (rev 4126)
@@ -0,0 +1,16 @@
+/* Copyright (C) 1999-2005 Henry Cejtin, Matthew Fluet, Suresh
+ *    Jagannathan, and Stephen Weeks.
+ * Copyright (C) 1997-2000 NEC Research Institute.
+ *
+ * MLton is released under a BSD-style license.
+ * See the file MLton-LICENSE for details.
+ */
+
+void *calloc_safe (size_t count, size_t size);
+void close_safe (int fd);
+void *malloc_safe (size_t size);
+int mkstemp_safe (char *template);
+int open_safe (const char *fileName, int flags, mode_t mode);
+void read_safe (int fd, void *buf, size_t size);
+void unlink_safe (const char *pathname);
+void write_safe (int fd, const void *buf, size_t size);

Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/share.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/share.c	2005-10-30 14:38:45 UTC (rev 4125)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/share.c	2005-10-31 02:47:56 UTC (rev 4126)
@@ -6,7 +6,7 @@
  * See the file MLton-LICENSE for details.
  */
 
-void GC_share (GC_state s, pointer object) {
+void share (GC_state s, pointer object) {
   size_t total;
   
   if (DEBUG_SHARE)

Added: mlton/branches/on-20050822-x86_64-branch/runtime/gc/share.h
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/share.h	2005-10-30 14:38:45 UTC (rev 4125)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/share.h	2005-10-31 02:47:56 UTC (rev 4126)
@@ -0,0 +1,9 @@
+/* Copyright (C) 1999-2005 Henry Cejtin, Matthew Fluet, Suresh
+ *    Jagannathan, and Stephen Weeks.
+ * Copyright (C) 1997-2000 NEC Research Institute.
+ *
+ * MLton is released under a BSD-style license.
+ * See the file MLton-LICENSE for details.
+ */
+
+void share (GC_state s, pointer object);

Added: mlton/branches/on-20050822-x86_64-branch/runtime/gc/size.h
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/size.h	2005-10-30 14:38:45 UTC (rev 4125)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/size.h	2005-10-31 02:47:56 UTC (rev 4126)
@@ -0,0 +1,9 @@
+/* Copyright (C) 1999-2005 Henry Cejtin, Matthew Fluet, Suresh
+ *    Jagannathan, and Stephen Weeks.
+ * Copyright (C) 1997-2000 NEC Research Institute.
+ *
+ * MLton is released under a BSD-style license.
+ * See the file MLton-LICENSE for details.
+ */
+
+size_t GC_size (GC_state s, pointer root);

Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/stack.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/stack.c	2005-10-30 14:38:45 UTC (rev 4125)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/stack.c	2005-10-31 02:47:56 UTC (rev 4126)
@@ -16,19 +16,19 @@
           stack->used);
 }
 
-/* stackSlop returns the amount of "slop" space needed between the top
- * of the stack and the end of the stack space.
+/* sizeofStackSlop returns the amount of "slop" space needed between
+ * the top of the stack and the end of the stack space.
  */
-static inline size_t stackSlop (GC_state s) {
+size_t sizeofStackSlop (GC_state s) {
   return (size_t)(2 * s->maxFrameSize);
 }
 
-static inline size_t initialStackSize (GC_state s) {
-  return stackSlop (s);
+size_t sizeofStackInitial (GC_state s) {
+  return sizeofStackSlop (s);
 }
 
 /* Pointer to the bottommost word in use on the stack. */
-static inline pointer stackBottom (GC_state s, GC_stack stack) {
+pointer getStackBottom (GC_state s, GC_stack stack) {
   pointer res;
   
   res = ((pointer)stack) + sizeof (struct GC_stack);
@@ -37,56 +37,80 @@
 }
 
 /* Pointer to the topmost word in use on the stack. */
-static inline pointer stackTop (GC_state s, GC_stack stack) {
-  return stackBottom (s, stack) + stack->used;
+pointer getStackTop (GC_state s, GC_stack stack) {
+  return getStackBottom (s, stack) + stack->used;
 }
 
 /* Pointer to the end of stack. */
-static inline pointer stackLimitPlusSlop (GC_state s, GC_stack stack) {
-  return stackBottom (s, stack) + stack->reserved;
+pointer getStackLimitPlusSlop (GC_state s, GC_stack stack) {
+  return getStackBottom (s, stack) + stack->reserved;
 }
 
 /* The maximum value which is valid for stackTop. */
-static inline pointer stackLimit (GC_state s, GC_stack stack) {
-  return stackLimitPlusSlop (s, stack) - stackSlop (s);
+pointer getStackLimit (GC_state s, GC_stack stack) {
+  return getStackLimitPlusSlop (s, stack) - sizeofStackSlop (s);
 }
 
 
-static inline GC_frameIndex topFrameIndex (GC_state s, GC_stack stack) {
+GC_frameIndex getStackTopFrameIndex (GC_state s, GC_stack stack) {
   GC_frameIndex res;
   
   res = 
     getFrameIndexFromReturnAddress 
-    (s, *(GC_returnAddress*)(stackTop (s, stack) - GC_RETURNADDRESS_SIZE));
-  if (DEBUG_PROFILE)
-    fprintf (stderr, "topFrameIndex = "FMTFI"\n", res);
+    (s, *((GC_returnAddress*)(getStackTop (s, stack) - GC_RETURNADDRESS_SIZE)));
   return res;
 }
 
-static inline GC_frameLayout * topFrameLayout (GC_state s, GC_stack stack) {
-  GC_frameLayout *layout;
+GC_frameLayout getStackTopFrameLayout (GC_state s, GC_stack stack) {
+  GC_frameLayout layout;
 
-  layout = getFrameLayoutFromFrameIndex (s, topFrameIndex (s, stack));
+  layout = getFrameLayoutFromFrameIndex (s, getStackTopFrameIndex (s, stack));
   return layout;
 }
 
-static inline uint16_t topFrameSize (GC_state s, GC_stack stack) {
-  GC_frameLayout *layout;
+uint16_t getStackTopFrameSize (GC_state s, GC_stack stack) {
+  GC_frameLayout layout;
   
-  assert (not (stackIsEmpty (stack)));
-  layout = topFrameLayout (s, stack);
+  assert (not (isStackEmpty (stack)));
+  layout = getStackTopFrameLayout (s, stack);
   return layout->size;
 }
 
-static inline size_t stackMinimumReserved (GC_state s, GC_stack stack) {
-  return stack->used + stackSlop (s) - topFrameSize(s, stack);
+size_t sizeofStackMinimumReserved (GC_state s, GC_stack stack) {
+  size_t res;
+
+  res =
+    stack->used 
+    + sizeofStackSlop (s) 
+    - getStackTopFrameSize(s, stack);
+  return res;
 }
 
-static inline void stackCopy (GC_state s, GC_stack from, GC_stack to) {
+size_t sizeofStackWithHeaderAligned (GC_state s, size_t reserved) {
+  size_t res;
+  
+  res = 
+    align (GC_STACK_HEADER_SIZE 
+           + sizeof (struct GC_stack) 
+           + reserved,
+           s->alignment);
+  if (DEBUG_STACKS)
+    fprintf (stderr, "%zu = sizeofStackTotalAligned (%zu)\n", res, reserved);
+  return res;
+}
+
+size_t sizeofStackGrow (GC_state s, GC_stack stack) {
+  size_t res;
+
+  res = max (2 * stack->reserved, sizeofStackMinimumReserved (s, stack));
+  return res;
+}
+
+void copyStack (GC_state s, GC_stack from, GC_stack to) {
   pointer fromBottom, toBottom;
 
-  fromBottom = stackBottom (s, from);
-  toBottom = stackBottom (s, to);
+  fromBottom = getStackBottom (s, from);
+  toBottom = getStackBottom (s, to);
   assert (from->used <= to->reserved);
   to->used = from->used;
   if (DEBUG_STACKS)
@@ -96,13 +120,3 @@
              from->used);
   GC_memcpy (fromBottom, toBottom, from->used);
 }
-
-static inline size_t stackSizeTotalAligned (GC_state s, size_t reserved) {
-  size_t res;
-  
-  res = align (GC_STACK_HEADER_SIZE + sizeof (struct GC_stack) + reserved,
-               s->alignment);
-  if (DEBUG_STACKS)
-    fprintf (stderr, "%zu = stackSizeTotalAligned (%zu)\n", res, reserved);
-  return res;
-}

Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/stack.h
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/stack.h	2005-10-30 14:38:45 UTC (rev 4125)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/stack.h	2005-10-31 02:47:56 UTC (rev 4126)
@@ -48,4 +48,23 @@
 } *GC_stack;
 
 #define GC_STACK_HEADER_SIZE GC_HEADER_SIZE
-#define GC_STACK_SIZE sizeof(struct GC_stack);
+
+bool isStackEmpty (GC_stack stack);
+void displayStack (GC_state s, GC_stack stack, FILE *stream);
+
+size_t sizeofStackSlop (GC_state s);
+size_t sizeofStackInitial (GC_state s);
+
+pointer getStackBottom (GC_state s, GC_stack stack);
+pointer getStackTop (GC_state s, GC_stack stack);
+pointer getStackLimitPlusSlop (GC_state s, GC_stack stack);
+pointer getStackLimit (GC_state s, GC_stack stack);
+GC_frameIndex getStackTopFrameIndex (GC_state s, GC_stack stack);
+GC_frameLayout getStackTopFrameLayout (GC_state s, GC_stack stack);
+uint16_t getStackTopFrameSize (GC_state s, GC_stack stack);
+
+size_t sizeofStackMinimumReserved (GC_state s, GC_stack stack);
+size_t sizeofStackWithHeaderAligned (GC_state s, size_t reserved);
+size_t sizeofStackGrow (GC_state s, GC_stack stack);
+
+void copyStack (GC_state s, GC_stack from, GC_stack to);

Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/stack_predicates.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/stack_predicates.c	2005-10-30 14:38:45 UTC (rev 4125)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/stack_predicates.c	2005-10-31 02:47:56 UTC (rev 4126)
@@ -6,6 +6,6 @@
  * See the file MLton-LICENSE for details.
  */
 
-static inline bool stackIsEmpty (GC_stack stack) {
+bool isStackEmpty (GC_stack stack) {
   return 0 == stack->used;
 }

Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/thread.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/thread.c	2005-10-30 14:38:45 UTC (rev 4125)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/thread.c	2005-10-31 02:47:56 UTC (rev 4126)
@@ -6,8 +6,6 @@
  * See the file MLton-LICENSE for details.
  */
 
-#define BOGUS_EXN_STACK 0xFFFFFFFF
-
 void displayThread (GC_state s,
                     GC_thread thread, 
                     FILE *stream) {
@@ -22,13 +20,13 @@
                 stream);
 }
 
-static inline size_t threadSize (GC_state s) {
+size_t sizeofThread (GC_state s) {
   size_t res;
 
   res = GC_NORMAL_HEADER_SIZE + sizeof (struct GC_thread);
   /* The following assert depends on struct GC_thread being the right
    * size.  Right now, it happens that res = 16, which is aligned mod
-   * 4 and mod 8, which is all that we need.  If the struct every
+   * 4 and mod 8, which is all that we need.  If the struct ever
    * changes (possible) or we need more alignment (doubtful), we may
    * need to put some padding at the beginning.
    */

Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/thread.h
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/thread.h	2005-10-30 14:38:45 UTC (rev 4125)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/thread.h	2005-10-31 02:47:56 UTC (rev 4126)
@@ -21,3 +21,8 @@
                        */
   objptr stack;       /* The stack for this thread. */
 } *GC_thread;
+
+#define BOGUS_EXN_STACK 0xFFFFFFFF
+
+void displayThread (GC_state s, GC_thread thread, FILE *stream);
+size_t sizeofThread (GC_state s);

Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/translate.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/translate.c	2005-10-30 14:38:45 UTC (rev 4125)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/translate.c	2005-10-31 02:47:56 UTC (rev 4126)
@@ -16,8 +16,8 @@
 };
 static struct translateState translateState;
 
-static void translateObjptr (__attribute__ ((unused)) GC_state s, 
-                             objptr *opp) {
+void translateObjptr (__attribute__ ((unused)) GC_state s, 
+                      objptr *opp) {
   pointer p;
 
   p = objptrToPointer (*opp, translateState.from);
@@ -27,7 +27,7 @@
 
 /* translateHeap (s, from, to, size)
  */
-static void translateHeap (GC_state s, pointer from, pointer to, size_t size) {
+void translateHeap (GC_state s, pointer from, pointer to, size_t size) {
   pointer limit;
 
   if (DEBUG or s->controls.messages)

Added: mlton/branches/on-20050822-x86_64-branch/runtime/gc/translate.h
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/translate.h	2005-10-30 14:38:45 UTC (rev 4125)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/translate.h	2005-10-31 02:47:56 UTC (rev 4126)
@@ -0,0 +1,10 @@
+/* Copyright (C) 1999-2005 Henry Cejtin, Matthew Fluet, Suresh
+ *    Jagannathan, and Stephen Weeks.
+ * Copyright (C) 1997-2000 NEC Research Institute.
+ *
+ * MLton is released under a BSD-style license.
+ * See the file MLton-LICENSE for details.
+ */
+
+void translateObjptr (GC_state s, objptr *opp);
+void translateHeap (GC_state s, pointer from, pointer to, size_t size);

Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/util.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/util.c	2005-10-30 14:38:45 UTC (rev 4125)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/util.c	2005-10-31 02:47:56 UTC (rev 4126)
@@ -6,10 +6,70 @@
  */
 
 const char* boolToString (bool b) {
-        return b ? "TRUE" : "FALSE";
+  return b ? "TRUE" : "FALSE";
 }
 
 #define BUF_SIZE 81
+char* intmaxToCommaString (intmax_t n) {
+  static char buf1[BUF_SIZE];
+  static char buf2[BUF_SIZE];
+  static char buf3[BUF_SIZE];
+  static char buf4[BUF_SIZE];
+  static char buf5[BUF_SIZE];
+  static char *bufs[] = {buf1, buf2, buf3, buf4, buf5};
+  static int bufIndex = 0;
+  static char *buf;
+  int i;
+  
+  buf = bufs[bufIndex++];
+  bufIndex %= 5;
+        
+  i = BUF_SIZE - 1;
+  buf[i--] = '\000';
+        
+  if (0 == n)
+    buf[i--] = '0';
+  else if (INTMAX_MIN == n) {
+    /* must treat INTMAX_MIN specially, because I negate stuff later */
+    switch (sizeof(intmax_t)) {
+    case 1:
+      strcpy (buf + 1, "-128");
+      break;
+    case 2:
+      strcpy (buf + 1, "-32,768");
+      break;
+    case 4:
+      strcpy (buf + 1, "-2,147,483,648");
+      break;
+    case 8:
+      strcpy (buf + 1, "-9,223,372,036,854,775,808");
+      break;
+    case 16:
+      strcpy (buf + 1, "-170,141,183,460,469,231,731,687,303,715,884,105,728");
+      break;
+    default:
+      die ("intmaxToCommaString: sizeof(intmax_t) = %zu", sizeof(intmax_t));
+      break;
+    }
+    i = 0;
+  } else {
+    intmax_t m;
+        
+    if (n > 0) 
+      m = n; 
+    else 
+      m = -n;
+        
+    while (m > 0) {
+      buf[i--] = m % 10 + '0';
+      m = m / 10;
+      if (i % 4 == 0 and m > 0) buf[i--] = ',';
+    }
+    if (n < 0) buf[i--] = '-';
+  }
+  return buf + i + 1;
+}
+
 char* uintmaxToCommaString (uintmax_t n) {
   static char buf1[BUF_SIZE];
   static char buf2[BUF_SIZE];
@@ -37,3 +97,4 @@
   }
   return buf + i + 1;
 }
+#undef BUF_SIZE

Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/util.h
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/util.h	2005-10-30 14:38:45 UTC (rev 4125)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/util.h	2005-10-31 02:47:56 UTC (rev 4126)
@@ -57,13 +57,10 @@
 #endif
 
 /* issue error message and exit */
-extern void die (char *fmt, ...)
-                        __attribute__ ((format(printf, 1, 2)))
-                        __attribute__ ((noreturn));
+extern void die (char *fmt, ...) 
+  __attribute__ ((format(printf, 1, 2)))
+  __attribute__ ((noreturn));
 /* issue error message and exit.  Also print strerror(errno). */
 extern void diee (char *fmt, ...)
-                        __attribute__ ((format(printf, 1, 2)))
-                        __attribute__ ((noreturn));
-
-#define HAS_SIGALTSTACK TRUE
-#define HAS_TIME_PROFILING TRUE
+  __attribute__ ((format(printf, 1, 2)))
+  __attribute__ ((noreturn));

Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/world.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/world.c	2005-10-30 14:38:45 UTC (rev 4125)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/world.c	2005-10-31 02:47:56 UTC (rev 4126)
@@ -6,14 +6,12 @@
  * See the file MLton-LICENSE for details.
  */
 
-static void loadWorld (GC_state s, char *fileName) {
-  int fd;
+void loadWorldFromFD (GC_state s, int fd) {
   uint32_t magic;
   pointer start;
         
   if (DEBUG_WORLD)
-    fprintf (stderr, "loadWorld (%s)\n", fileName);
-  fd = open_safe (fileName, O_RDONLY, 0); 
+    fprintf (stderr, "loadWorldFromFD (%d)\n", fd);
   until (readChar (fd) == '\000') ;
   magic = readUint32 (fd);
   unless (s->magic == magic)
@@ -21,32 +19,40 @@
   start = readPointer (fd);
   s->heap.oldGenSize = readSize (fd);
   s->atomicState = readUint32 (fd);
-  s->callFromCHandlerThread =  readObjptr (fd); 
+  s->callFromCHandlerThread = readObjptr (fd); 
   s->currentThread = readObjptr (fd); 
   s->signalHandlerThread = readObjptr (fd); 
-  heapCreate (s, &s->heap, 
-              heapDesiredSize (s, s->heap.oldGenSize, 0), 
+  createHeap (s, &s->heap, 
+              sizeofHeapDesired (s, s->heap.oldGenSize, 0), 
               s->heap.oldGenSize);
   createCardMapAndCrossMap (s); 
   read_safe (fd, s->heap.start, s->heap.oldGenSize);
   (*s->loadGlobals) (fd);
   // unless (EOF == fgetc (file))
   //  die ("Invalid world: junk at end of file.");
-  close_safe (fd); 
   /* translateHeap must occur after loading the heap and globals,
    * since it changes pointers in all of them.
    */
   translateHeap (s, start, s->heap.start, s->heap.oldGenSize);
-  heapSetNursery (s, 0, 0); 
-  setCurrentStack (s); 
+  setHeapNursery (s, 0, 0); 
+  setThreadAndStackCurrent (s); 
 }
 
-static void saveWorld (GC_state s, int fd) {
+void loadWorldFromFileName (GC_state s, char *fileName) {
+  int fd;
+        
+  if (DEBUG_WORLD)
+    fprintf (stderr, "loadWorldFromFileName (%s)\n", fileName);
+  fd = open_safe (fileName, O_RDONLY, 0); 
+  loadWorldFromFD (s, fd);
+  close_safe (fd); 
+}
+
+void saveWorldToFD (GC_state s, int fd) {
   char buf[80];
 
   if (DEBUG_WORLD)
-    fprintf (stderr, "GC_saveWorld (%d).\n", fd);
-  enter (s);
+    fprintf (stderr, "saveWorld (%d).\n", fd);
   /* Compact the heap. */
   doGC (s, 0, 0, TRUE, TRUE);
   sprintf (buf,
@@ -67,5 +73,10 @@
   writeObjptr (fd, s->signalHandlerThread);
   write_safe (fd, s->heap.start, s->heap.oldGenSize);
   (*s->saveGlobals) (fd);
+}
+
+void GC_saveWorldToFD (GC_state s, int fd) {
+  enter (s);
+  saveWorldToFD (s, fd);
   leave (s);
 }

Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/world.h
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/world.h	2005-10-30 14:38:45 UTC (rev 4125)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/world.h	2005-10-31 02:47:56 UTC (rev 4126)
@@ -6,6 +6,8 @@
  * See the file MLton-LICENSE for details.
  */
 
-static void loadWorld (GC_state s, char *fileName);
+void loadWorldFromFD (GC_state s, int fd);
+void loadWorldFromFileName (GC_state s, char *fileName);
+void saveWorldToFD (GC_state s, int fd);
+void GC_saveWorldToFD (GC_state s, int fd);
 
-static void saveWorld (GC_state s, int fd);