[MLton-commit] r6437

spoons at mlton.org spoons at mlton.org
Mon Mar 3 07:07:58 PST 2008


Use one GC_state structure per processor.

Generally replace "GC_state" with "GC_state *".  For internal
structures of GC_state (e.g. heap, statistics), use a pointer to
share these data across processors.  Use pthread_getspecific to
access the proper version of GC_state when necessary.

This commit is not precisely those changes needed to support
multiple GC_state structures, but it is the most boring changes
necessary to do so.  Subsequent commits will include more
interesting changes.  Furthermore, this commit will not compile
on its own: some later changes leaked into this commit in small
ways.  For example, some debugging messages use yet-undefined
multiprocessor-related functions. (It seemed to be too much
trouble to completely factor them out.)

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

U   mlton/branches/shared-heap-multicore/include/c-chunk.h
U   mlton/branches/shared-heap-multicore/include/main.h
U   mlton/branches/shared-heap-multicore/mlton/codegen/c-codegen/c-codegen.fun
U   mlton/branches/shared-heap-multicore/runtime/gc/call-stack.c
U   mlton/branches/shared-heap-multicore/runtime/gc/call-stack.h
U   mlton/branches/shared-heap-multicore/runtime/gc/cheney-copy.c
U   mlton/branches/shared-heap-multicore/runtime/gc/controls.c
U   mlton/branches/shared-heap-multicore/runtime/gc/copy-thread.c
U   mlton/branches/shared-heap-multicore/runtime/gc/current.c
U   mlton/branches/shared-heap-multicore/runtime/gc/dfs-mark.c
U   mlton/branches/shared-heap-multicore/runtime/gc/done.c
U   mlton/branches/shared-heap-multicore/runtime/gc/forward.c
U   mlton/branches/shared-heap-multicore/runtime/gc/garbage-collection.c
U   mlton/branches/shared-heap-multicore/runtime/gc/gc_state.c
U   mlton/branches/shared-heap-multicore/runtime/gc/gc_state.h
U   mlton/branches/shared-heap-multicore/runtime/gc/generational.c
U   mlton/branches/shared-heap-multicore/runtime/gc/handler.c
U   mlton/branches/shared-heap-multicore/runtime/gc/handler.h
U   mlton/branches/shared-heap-multicore/runtime/gc/hash-cons.c
U   mlton/branches/shared-heap-multicore/runtime/gc/heap.c
U   mlton/branches/shared-heap-multicore/runtime/gc/heap_predicates.c
U   mlton/branches/shared-heap-multicore/runtime/gc/init-world.c
U   mlton/branches/shared-heap-multicore/runtime/gc/init-world.h
U   mlton/branches/shared-heap-multicore/runtime/gc/init.c
U   mlton/branches/shared-heap-multicore/runtime/gc/init.h
U   mlton/branches/shared-heap-multicore/runtime/gc/int-inf.c
U   mlton/branches/shared-heap-multicore/runtime/gc/invariant.c
U   mlton/branches/shared-heap-multicore/runtime/gc/mark-compact.c
U   mlton/branches/shared-heap-multicore/runtime/gc/new-object.c
U   mlton/branches/shared-heap-multicore/runtime/gc/pack.c
U   mlton/branches/shared-heap-multicore/runtime/gc/pack.h
U   mlton/branches/shared-heap-multicore/runtime/gc/profiling.c
U   mlton/branches/shared-heap-multicore/runtime/gc/profiling.h
U   mlton/branches/shared-heap-multicore/runtime/gc/rusage.h
U   mlton/branches/shared-heap-multicore/runtime/gc/share.c
U   mlton/branches/shared-heap-multicore/runtime/gc/sources.c
U   mlton/branches/shared-heap-multicore/runtime/gc/sources.h
U   mlton/branches/shared-heap-multicore/runtime/gc/switch-thread.c
U   mlton/branches/shared-heap-multicore/runtime/gc/thread.c
U   mlton/branches/shared-heap-multicore/runtime/gc/translate.c
U   mlton/branches/shared-heap-multicore/runtime/gc/weak.c
U   mlton/branches/shared-heap-multicore/runtime/gc/world.c
U   mlton/branches/shared-heap-multicore/runtime/gc/world.h
U   mlton/branches/shared-heap-multicore/runtime/gc.c

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

Modified: mlton/branches/shared-heap-multicore/include/c-chunk.h
===================================================================
--- mlton/branches/shared-heap-multicore/include/c-chunk.h	2008-03-03 14:52:41 UTC (rev 6436)
+++ mlton/branches/shared-heap-multicore/include/c-chunk.h	2008-03-03 15:07:53 UTC (rev 6437)
@@ -30,7 +30,6 @@
 #define DEBUG_CCODEGEN FALSE
 #endif
 
-#define GCState ((Pointer)&gcState)
 #define ExnStack *(size_t*)(GCState + ExnStackOffset)
 #define FrontierMem *(Pointer*)(GCState + FrontierOffset)
 #define Frontier frontier

Modified: mlton/branches/shared-heap-multicore/include/main.h
===================================================================
--- mlton/branches/shared-heap-multicore/include/main.h	2008-03-03 14:52:41 UTC (rev 6436)
+++ mlton/branches/shared-heap-multicore/include/main.h	2008-03-03 15:07:53 UTC (rev 6437)
@@ -35,41 +35,79 @@
 
 Pointer gcStateAddress;
 
-#define Initialize(al, mg, mfs, mmc, pk, ps)                            \
-        gcStateAddress = &gcState;                                      \
-        gcState.alignment = al;                                         \
-        gcState.atMLtons = atMLtons;                                    \
-        gcState.atMLtonsLength = cardof(atMLtons);                      \
-        gcState.frameLayouts = frameLayouts;                            \
-        gcState.frameLayoutsLength = cardof(frameLayouts);              \
-        gcState.globals = globalObjptr;                                 \
-        gcState.globalsLength = cardof(globalObjptr);                   \
-        gcState.intInfInits = intInfInits;                              \
-        gcState.intInfInitsLength = cardof(intInfInits);                \
-        gcState.loadGlobals = loadGlobals;                              \
-        gcState.magic = mg;                                             \
-        gcState.maxFrameSize = mfs;                                     \
-        gcState.mutatorMarksCards = mmc;                                \
-        gcState.objectTypes = objectTypes;                              \
-        gcState.objectTypesLength = cardof(objectTypes);                \
-        gcState.returnAddressToFrameIndex = returnAddressToFrameIndex;  \
-        gcState.saveGlobals = saveGlobals;                              \
-        gcState.vectorInits = vectorInits;                              \
-        gcState.vectorInitsLength = cardof(vectorInits);                \
-        gcState.sourceMaps.frameSources = frameSources;                 \
-        gcState.sourceMaps.frameSourcesLength = cardof(frameSources);   \
-        gcState.sourceMaps.sourceLabels = sourceLabels;                 \
-        gcState.sourceMaps.sourceLabelsLength = cardof(sourceLabels);   \
-        gcState.sourceMaps.sourceNames = sourceNames;                   \
-        gcState.sourceMaps.sourceNamesLength = cardof(sourceNames);     \
-        gcState.sourceMaps.sourceSeqs = sourceSeqs;                     \
-        gcState.sourceMaps.sourceSeqsLength = cardof(sourceSeqs);       \
-        gcState.sourceMaps.sources = sources;                           \
-        gcState.sourceMaps.sourcesLength = cardof(sources);             \
-        gcState.profiling.kind = pk;                                    \
-        gcState.profiling.stack = ps;                                   \
-        MLton_init (argc, argv, &gcState);                              \
+#define Initialize(s, al, mg, mfs, mmc, pk, ps, gnr)              \
+        gcStateAddress = &s;                                      \
+        s.alignment = al;                                         \
+        s.atMLtons = atMLtons;                                    \
+        s.atMLtonsLength = cardof(atMLtons);                      \
+        s.frameLayouts = frameLayouts;                            \
+        s.frameLayoutsLength = cardof(frameLayouts);              \
+        s.globals = globalObjptr;                                 \
+        s.globalsLength = cardof(globalObjptr);                   \
+        s.intInfInits = intInfInits;                              \
+        s.intInfInitsLength = cardof(intInfInits);                \
+        s.loadGlobals = loadGlobals;                              \
+        s.magic = mg;                                             \
+        s.maxFrameSize = mfs;                                     \
+        s.mutatorMarksCards = mmc;                                \
+        s.objectTypes = objectTypes;                              \
+        s.objectTypesLength = cardof(objectTypes);                \
+        s.returnAddressToFrameIndex = returnAddressToFrameIndex;  \
+        s.saveGlobals = saveGlobals;                              \
+        s.vectorInits = vectorInits;                              \
+        s.vectorInitsLength = cardof(vectorInits);                \
+        s.sourceMaps.frameSources = frameSources;                 \
+        s.sourceMaps.frameSourcesLength = cardof(frameSources);   \
+        s.sourceMaps.sourceLabels = sourceLabels;                 \
+        s.sourceMaps.sourceLabelsLength = cardof(sourceLabels);   \
+        s.sourceMaps.sourceNames = sourceNames;                   \
+        s.sourceMaps.sourceNamesLength = cardof(sourceNames);     \
+        s.sourceMaps.sourceSeqs = sourceSeqs;                     \
+        s.sourceMaps.sourceSeqsLength = cardof(sourceSeqs);       \
+        s.sourceMaps.sources = sources;                           \
+        s.sourceMaps.sourcesLength = cardof(sources);             \
+        s.profiling.kind = pk;                                    \
+        s.profiling.stack = ps;                                   \
+        s.globalObjptrNonRoot = (Pointer *) malloc (gnr * sizeof (Pointer));  \
+        MLton_init (argc, argv, &s);                              \
 
 void MLton_callFromC ();
 
+void Duplicate (GC_state d, GC_state s) {
+  // Initialize
+  d->alignment = s->alignment;
+  d->atMLtons = s->atMLtons;
+  d->atMLtonsLength = s->atMLtonsLength;
+  d->frameLayouts = s->frameLayouts;
+  d->frameLayoutsLength = s->frameLayoutsLength;
+  d->globals = s->globals;
+  d->globalsLength = s->globalsLength;
+  d->intInfInits = s->intInfInits;
+  d->intInfInitsLength = s->intInfInitsLength;
+  d->loadGlobals = s->loadGlobals;
+  d->magic = s->magic;
+  d->maxFrameSize = s->maxFrameSize;
+  d->mutatorMarksCards = s->mutatorMarksCards;
+  d->objectTypes = s->objectTypes;
+  d->objectTypesLength = s->objectTypesLength;
+  d->returnAddressToFrameIndex = s->returnAddressToFrameIndex;
+  d->saveGlobals = s->saveGlobals;
+  d->vectorInits = s->vectorInits;
+  d->vectorInitsLength = s->vectorInitsLength;
+  d->sourceMaps.frameSources = s->sourceMaps.frameSources;
+  d->sourceMaps.frameSourcesLength = s->sourceMaps.frameSourcesLength;
+  d->sourceMaps.sourceLabels = s->sourceMaps.sourceLabels;
+  d->sourceMaps.sourceLabelsLength = s->sourceMaps.sourceLabelsLength;
+  d->sourceMaps.sourceNames = s->sourceMaps.sourceNames;
+  d->sourceMaps.sourceNamesLength = s->sourceMaps.sourceNamesLength;
+  d->sourceMaps.sourceSeqs = s->sourceMaps.sourceSeqs;
+  d->sourceMaps.sourceSeqsLength = s->sourceMaps.sourceSeqsLength;
+  d->sourceMaps.sources = s->sourceMaps.sources;
+  d->sourceMaps.sourcesLength = s->sourceMaps.sourcesLength;
+  d->profiling.kind = s->profiling.kind;
+  d->profiling.stack = s->profiling.stack;
+  d->globalObjptrNonRoot = s->globalObjptrNonRoot;
+  GC_duplicate (d, s);
+}
+
 #endif /* #ifndef _MAIN_H_ */

Modified: mlton/branches/shared-heap-multicore/mlton/codegen/c-codegen/c-codegen.fun
===================================================================
--- mlton/branches/shared-heap-multicore/mlton/codegen/c-codegen/c-codegen.fun	2008-03-03 14:52:41 UTC (rev 6436)
+++ mlton/branches/shared-heap-multicore/mlton/codegen/c-codegen/c-codegen.fun	2008-03-03 15:07:53 UTC (rev 6437)
@@ -107,7 +107,7 @@
       val bytes = int o Bytes.toInt
 
       fun string s =
-         let val quote = "\""
+         let val quote = "\"" (* " *)
          in concat [quote, String.escapeC s, quote]
          end
 
@@ -217,7 +217,7 @@
       (* gcState can't be static because stuff in mlton-lib.c refers to
        * it.
        *)
-      val _ = print (concat [prefix, "struct GC_state gcState;\n"])
+      val _ = print (concat [prefix, "struct GC_state * gcState;\n"])
       val _ =
          List.foreach
          (CType.all, fn t =>

Modified: mlton/branches/shared-heap-multicore/runtime/gc/call-stack.c
===================================================================
--- mlton/branches/shared-heap-multicore/runtime/gc/call-stack.c	2008-03-03 14:52:41 UTC (rev 6436)
+++ mlton/branches/shared-heap-multicore/runtime/gc/call-stack.c	2008-03-03 15:07:53 UTC (rev 6437)
@@ -11,12 +11,13 @@
   s->callStackState.numStackFrames++;
 }
 
-uint32_t GC_numStackFrames (GC_state s) {
+uint32_t GC_numStackFrames (__attribute__ ((unused)) GC_state *gs) {
+  GC_state s = pthread_getspecific (gcstate_key);
   s->callStackState.numStackFrames = 0;
   foreachStackFrame (s, numStackFramesAux);
   if (DEBUG_CALL_STACK)
-    fprintf (stderr, "%"PRIu32" = GC_numStackFrames\n", 
-             s->callStackState.numStackFrames);
+    fprintf (stderr, "%"PRIu32" = GC_numStackFrames [%d]\n", 
+             s->callStackState.numStackFrames, Proc_processorNumber (s));
   return s->callStackState.numStackFrames;
 }
 
@@ -27,20 +28,23 @@
   s->callStackState.numStackFrames++;
 }
 
-void GC_callStack (GC_state s, pointer p) {
+void GC_callStack (__attribute__ ((unused)) GC_state *gs, 
+                   pointer p) {
+  GC_state s = pthread_getspecific (gcstate_key);
   if (DEBUG_CALL_STACK)
-    fprintf (stderr, "GC_callStack\n");
+    fprintf (stderr, "GC_callStack [%d]\n", Proc_processorNumber (s));
   s->callStackState.numStackFrames = 0;
   s->callStackState.callStack = (uint32_t*)p;
   foreachStackFrame (s, callStackAux);
 }
 
-uint32_t* GC_frameIndexSourceSeq (GC_state s, GC_frameIndex frameIndex) {
+uint32_t* GC_frameIndexSourceSeq (__attribute__ ((unused)) GC_state *gs, 
+                                  GC_frameIndex frameIndex) {
   uint32_t *res;
-
+  GC_state s = pthread_getspecific (gcstate_key);
   res = s->sourceMaps.sourceSeqs[s->sourceMaps.frameSources[frameIndex]];
   if (DEBUG_CALL_STACK)
-    fprintf (stderr, FMTPTR" = GC_frameIndexSourceSeq ("FMTFI")\n",
-             (uintptr_t)res, frameIndex);
+    fprintf (stderr, FMTPTR" = GC_frameIndexSourceSeq ("FMTFI") [%d]\n",
+             (uintptr_t)res, frameIndex, Proc_processorNumber (s));
   return res;
 }

Modified: mlton/branches/shared-heap-multicore/runtime/gc/call-stack.h
===================================================================
--- mlton/branches/shared-heap-multicore/runtime/gc/call-stack.h	2008-03-03 14:52:41 UTC (rev 6436)
+++ mlton/branches/shared-heap-multicore/runtime/gc/call-stack.h	2008-03-03 15:07:53 UTC (rev 6437)
@@ -25,8 +25,8 @@
 
 #if (defined (MLTON_GC_INTERNAL_BASIS))
 
-uint32_t GC_numStackFrames (GC_state s);
-void GC_callStack (GC_state s, pointer p);
-uint32_t* GC_frameIndexSourceSeq (GC_state s, GC_frameIndex frameIndex);
+uint32_t GC_numStackFrames (GC_state *gs);
+void GC_callStack (GC_state *gs, pointer p);
+uint32_t* GC_frameIndexSourceSeq (GC_state *gs, GC_frameIndex frameIndex);
 
 #endif /* (defined (MLTON_GC_INTERNAL_BASIS)) */

Modified: mlton/branches/shared-heap-multicore/runtime/gc/cheney-copy.c
===================================================================
--- mlton/branches/shared-heap-multicore/runtime/gc/cheney-copy.c	2008-03-03 14:52:41 UTC (rev 6436)
+++ mlton/branches/shared-heap-multicore/runtime/gc/cheney-copy.c	2008-03-03 15:07:53 UTC (rev 6437)
@@ -19,7 +19,7 @@
 
     if (DEBUG_WEAK)
       fprintf (stderr, "updateWeaksForCheneyCopy  w = "FMTPTR"  ", (uintptr_t)w);
-    p = objptrToPointer (w->objptr, s->heap.start);
+    p = objptrToPointer (w->objptr, s->heap->start);
     if (GC_FORWARDED == getHeader (p)) {
       if (DEBUG_WEAK)
         fprintf (stderr, "forwarded from "FMTOBJPTR" to "FMTOBJPTR"\n",
@@ -50,42 +50,42 @@
   struct rusage ru_start;
   pointer toStart;
 
-  assert (s->secondaryHeap.size >= s->heap.oldGenSize);
+  assert (s->secondaryHeap->size >= s->heap->oldGenSize);
   if (detailedGCTime (s))
     startTiming (&ru_start);
-  s->cumulativeStatistics.numCopyingGCs++;
+  s->cumulativeStatistics->numCopyingGCs++;
   s->forwardState.amInMinorGC = FALSE;
-  s->forwardState.toStart = s->secondaryHeap.start;
-  s->forwardState.toLimit = s->secondaryHeap.start + s->secondaryHeap.size;
-  if (DEBUG or s->controls.messages) {
+  s->forwardState.toStart = s->secondaryHeap->start;
+  s->forwardState.toLimit = s->secondaryHeap->start + s->secondaryHeap->size;
+  if (DEBUG or s->controls->messages) {
     fprintf (stderr, "[GC: Major Cheney-copy; from heap at "FMTPTR" of size %s bytes,]\n",
-             (uintptr_t)(s->heap.start), 
-             uintmaxToCommaString(s->heap.size));
+             (uintptr_t)(s->heap->start), 
+             uintmaxToCommaString(s->heap->size));
     fprintf (stderr, "[GC:                    to heap at "FMTPTR" of size %s bytes.]\n",
-             (uintptr_t)(s->secondaryHeap.start), 
-             uintmaxToCommaString(s->secondaryHeap.size));
+             (uintptr_t)(s->secondaryHeap->start), 
+             uintmaxToCommaString(s->secondaryHeap->size));
   }
-  assert (s->secondaryHeap.start != (pointer)NULL);
+  assert (s->secondaryHeap->start != (pointer)NULL);
   /* The next assert ensures there is enough space for the copy to
    * succeed.  It does not assert 
-   *   (s->secondaryHeap.size >= s->heap.size) 
+   *   (s->secondaryHeap->size >= s->heap->size) 
    * because that is too strong.
    */
-  assert (s->secondaryHeap.size >= s->heap.oldGenSize);
-  toStart = alignFrontier (s, s->secondaryHeap.start);
+  assert (s->secondaryHeap->size >= s->heap->oldGenSize);
+  toStart = alignFrontier (s, s->secondaryHeap->start);
   s->forwardState.back = toStart;
   foreachGlobalObjptr (s, forwardObjptr);
   foreachObjptrInRange (s, toStart, &s->forwardState.back, forwardObjptr, TRUE);
   updateWeaksForCheneyCopy (s);
-  s->secondaryHeap.oldGenSize = s->forwardState.back - s->secondaryHeap.start;
-  bytesCopied = s->secondaryHeap.oldGenSize;
-  s->cumulativeStatistics.bytesCopied += bytesCopied;
+  s->secondaryHeap->oldGenSize = s->forwardState.back - s->secondaryHeap->start;
+  bytesCopied = s->secondaryHeap->oldGenSize;
+  s->cumulativeStatistics->bytesCopied += bytesCopied;
   swapHeapsForCheneyCopy (s);
   clearCrossMap (s);
-  s->lastMajorStatistics.kind = GC_COPYING;
+  s->lastMajorStatistics->kind = GC_COPYING;
   if (detailedGCTime (s))
-    stopTiming (&ru_start, &s->cumulativeStatistics.ru_gcCopy);
-  if (DEBUG or s->controls.messages)
+    stopTiming (&ru_start, &s->cumulativeStatistics->ru_gcCopy);
+  if (DEBUG or s->controls->messages)
     fprintf (stderr, "[GC: Major Cheney-copy done; %s bytes copied.]\n",
              uintmaxToCommaString(bytesCopied));
 }
@@ -118,15 +118,15 @@
     if (detailedGCTime (s))
       startTiming (&ru_start);
     s->forwardState.amInMinorGC = TRUE;
-    s->forwardState.toStart = s->heap.start + s->heap.oldGenSize;
-    if (DEBUG_GENERATIONAL or s->controls.messages)
+    s->forwardState.toStart = s->heap->start + s->heap->oldGenSize;
+    if (DEBUG_GENERATIONAL or s->controls->messages)
       fprintf (stderr, "[GC:                    to "FMTPTR".]\n",
                (uintptr_t)(s->forwardState.toStart));
     assert (isFrontierAligned (s, s->forwardState.toStart));
     s->forwardState.toLimit = s->forwardState.toStart + bytesAllocated;
     assert (invariantForGC (s));
-    s->cumulativeStatistics.numMinorGCs++;
-    s->lastMajorStatistics.numMinorGCs++;
+    s->cumulativeStatistics->numMinorGCs++;
+    s->lastMajorStatistics->numMinorGCs++;
     s->forwardState.back = s->forwardState.toStart;
     /* Forward all globals.  Would like to avoid doing this once all
      * the globals have been assigned.
@@ -137,11 +137,11 @@
                           forwardObjptrIfInNursery, TRUE);
     updateWeaksForCheneyCopy (s);
     bytesCopied = s->forwardState.back - s->forwardState.toStart;
-    s->cumulativeStatistics.bytesCopiedMinor += bytesCopied;
-    s->heap.oldGenSize += bytesCopied;
+    s->cumulativeStatistics->bytesCopiedMinor += bytesCopied;
+    s->heap->oldGenSize += bytesCopied;
     if (detailedGCTime (s))
-      stopTiming (&ru_start, &s->cumulativeStatistics.ru_gcMinor);
-    if (DEBUG_GENERATIONAL or s->controls.messages)
+      stopTiming (&ru_start, &s->cumulativeStatistics->ru_gcMinor);
+    if (DEBUG_GENERATIONAL or s->controls->messages)
       fprintf (stderr, "[GC: Minor Cheney-copy done; %s bytes copied.]\n",
                uintmaxToCommaString(bytesCopied));
   }

Modified: mlton/branches/shared-heap-multicore/runtime/gc/controls.c
===================================================================
--- mlton/branches/shared-heap-multicore/runtime/gc/controls.c	2008-03-03 14:52:41 UTC (rev 6436)
+++ mlton/branches/shared-heap-multicore/runtime/gc/controls.c	2008-03-03 15:07:53 UTC (rev 6437)
@@ -7,13 +7,13 @@
  */
 
 bool detailedGCTime (GC_state s) {
-  return s->controls.summary;
+  return s->controls->summary;
 }
 
 bool needGCTime (GC_state s) {
   return 
     DEBUG 
-    or s->controls.summary 
-    or s->controls.messages
-    or s->controls.rusageMeasureGC;
+    or s->controls->summary 
+    or s->controls->messages
+    or s->controls->rusageMeasureGC;
 }

Modified: mlton/branches/shared-heap-multicore/runtime/gc/copy-thread.c
===================================================================
--- mlton/branches/shared-heap-multicore/runtime/gc/copy-thread.c	2008-03-03 14:52:41 UTC (rev 6436)
+++ mlton/branches/shared-heap-multicore/runtime/gc/copy-thread.c	2008-03-03 15:07:53 UTC (rev 6437)
@@ -15,9 +15,9 @@
    * Hence we need to stash from where the GC can find it.
    */
   assert (s->savedThread == BOGUS_OBJPTR);
-  s->savedThread = pointerToObjptr((pointer)from - offsetofThread (s), s->heap.start);
+  s->savedThread = pointerToObjptr((pointer)from - offsetofThread (s), s->heap->start);
   to = newThread (s, size);
-  from = (GC_thread)(objptrToPointer(s->savedThread, s->heap.start) 
+  from = (GC_thread)(objptrToPointer(s->savedThread, s->heap->start) 
                      + offsetofThread (s));
   s->savedThread = BOGUS_OBJPTR;
   if (DEBUG_THREADS) {
@@ -25,8 +25,8 @@
              (uintptr_t)to, (uintptr_t)from);
   }
   copyStack (s, 
-             (GC_stack)(objptrToPointer(from->stack, s->heap.start)), 
-             (GC_stack)(objptrToPointer(to->stack, s->heap.start)));
+             (GC_stack)(objptrToPointer(from->stack, s->heap->start)), 
+             (GC_stack)(objptrToPointer(to->stack, s->heap->start)));
   to->bytesNeeded = from->bytesNeeded;
   to->exnStack = from->exnStack;
   return to;

Modified: mlton/branches/shared-heap-multicore/runtime/gc/current.c
===================================================================
--- mlton/branches/shared-heap-multicore/runtime/gc/current.c	2008-03-03 14:52:41 UTC (rev 6436)
+++ mlton/branches/shared-heap-multicore/runtime/gc/current.c	2008-03-03 15:07:53 UTC (rev 6437)
@@ -11,7 +11,7 @@
 }
 
 GC_thread getThreadCurrent (GC_state s) {
-  pointer p = objptrToPointer(getThreadCurrentObjptr(s), s->heap.start);
+  pointer p = objptrToPointer(getThreadCurrentObjptr(s), s->heap->start);
   return (GC_thread)(p + offsetofThread (s));
 }
 
@@ -21,6 +21,6 @@
 }
 
 GC_stack getStackCurrent (GC_state s) {
-  pointer p = objptrToPointer(getStackCurrentObjptr(s), s->heap.start);
+  pointer p = objptrToPointer(getStackCurrentObjptr(s), s->heap->start);
   return (GC_stack)p;
 }

Modified: mlton/branches/shared-heap-multicore/runtime/gc/dfs-mark.c
===================================================================
--- mlton/branches/shared-heap-multicore/runtime/gc/dfs-mark.c	2008-03-03 14:52:41 UTC (rev 6436)
+++ mlton/branches/shared-heap-multicore/runtime/gc/dfs-mark.c	2008-03-03 15:07:53 UTC (rev 6437)
@@ -87,11 +87,11 @@
   assert (nextHeaderp == getHeaderp (next));
   assert (nextHeader == getHeader (next));
   // assert (*(pointer*) todo == next);
-  assert (fetchObjptrToPointer (todo, s->heap.start) == next);
+  assert (fetchObjptrToPointer (todo, s->heap->start) == next);
   headerp = nextHeaderp;
   header = nextHeader;
   // *(pointer*)todo = prev;
-  storeObjptrFromPointer (todo, prev, s->heap.start);
+  storeObjptrFromPointer (todo, prev, s->heap->start);
   prev = cur;
   cur = next;
 mark:
@@ -134,7 +134,7 @@
       fprintf (stderr, "markInNormal  objptrIndex = %"PRIu32"\n", objptrIndex);
     assert (objptrIndex < numObjptrs);
     // next = *(pointer*)todo;
-    next = fetchObjptrToPointer (todo, s->heap.start);
+    next = fetchObjptrToPointer (todo, s->heap->start);
     if (not isPointer (next)) {
 markNextInNormal:
       assert (objptrIndex < numObjptrs);
@@ -193,7 +193,7 @@
     assert (objptrIndex < numObjptrs);
     assert (todo == indexArrayAtObjptrIndex (s, cur, arrayIndex, objptrIndex));
     // next = *(pointer*)todo;
-    next = fetchObjptrToPointer (todo, s->heap.start);
+    next = fetchObjptrToPointer (todo, s->heap->start);
     if (not (isPointer(next))) {
 markNextInArray:
       assert (arrayIndex < getArrayLength (cur));
@@ -251,7 +251,7 @@
     }
     todo = top - frameLayout->size + frameOffsets [objptrIndex + 1];
     // next = *(pointer*)todo;
-    next = fetchObjptrToPointer (todo, s->heap.start);
+    next = fetchObjptrToPointer (todo, s->heap->start);
     if (DEBUG_DFS_MARK)
       fprintf (stderr,
                "    offset %u  todo "FMTPTR"  next = "FMTPTR"\n",
@@ -298,9 +298,9 @@
     objptrIndex = (header & COUNTER_MASK) >> COUNTER_SHIFT;
     todo += objptrIndex * OBJPTR_SIZE;
     // prev = *(pointer*)todo;
-    prev = fetchObjptrToPointer (todo, s->heap.start);
+    prev = fetchObjptrToPointer (todo, s->heap->start);
     // *(pointer*)todo = next;
-    storeObjptrFromPointer (todo, next, s->heap.start);
+    storeObjptrFromPointer (todo, next, s->heap->start);
     if (shouldHashCons)
       markIntergenerationalPointer (s, (pointer*)todo);
     goto markNextInNormal;
@@ -310,9 +310,9 @@
     objptrIndex = (header & COUNTER_MASK) >> COUNTER_SHIFT;
     todo += bytesNonObjptrs + objptrIndex * OBJPTR_SIZE;
     // prev = *(pointer*)todo;
-    prev = fetchObjptrToPointer (todo, s->heap.start);
+    prev = fetchObjptrToPointer (todo, s->heap->start);
     // *(pointer*)todo = next;
-    storeObjptrFromPointer (todo, next, s->heap.start);
+    storeObjptrFromPointer (todo, next, s->heap->start);
     if (shouldHashCons)
       markIntergenerationalPointer (s, (pointer*)todo);
     goto markNextInArray;
@@ -326,9 +326,9 @@
     frameOffsets = frameLayout->offsets;
     todo = top - frameLayout->size + frameOffsets [objptrIndex + 1];
     // prev = *(pointer*)todo;
-    prev = fetchObjptrToPointer (todo, s->heap.start);
+    prev = fetchObjptrToPointer (todo, s->heap->start);
     // *(pointer*)todo = next;
-    storeObjptrFromPointer (todo, next, s->heap.start);
+    storeObjptrFromPointer (todo, next, s->heap->start);
     if (shouldHashCons)
       markIntergenerationalPointer (s, (pointer*)todo);
     objptrIndex++;
@@ -340,20 +340,20 @@
 void dfsMarkWithHashCons (GC_state s, objptr *opp) {
   pointer p;
 
-  p = objptrToPointer (*opp, s->heap.start);
+  p = objptrToPointer (*opp, s->heap->start);
   dfsMarkByMode (s, p, MARK_MODE, TRUE);
 }
 
 void dfsMarkWithoutHashCons (GC_state s, objptr *opp) {
   pointer p;
 
-  p = objptrToPointer (*opp, s->heap.start);
+  p = objptrToPointer (*opp, s->heap->start);
   dfsMarkByMode (s, p, MARK_MODE, FALSE);
 }
 
 void dfsUnmark (GC_state s, objptr *opp) {
   pointer p;
 
-  p = objptrToPointer (*opp, s->heap.start);
+  p = objptrToPointer (*opp, s->heap->start);
   dfsMarkByMode (s, p, UNMARK_MODE, FALSE);
 }

Modified: mlton/branches/shared-heap-multicore/runtime/gc/done.c
===================================================================
--- mlton/branches/shared-heap-multicore/runtime/gc/done.c	2008-03-03 14:52:41 UTC (rev 6436)
+++ mlton/branches/shared-heap-multicore/runtime/gc/done.c	2008-03-03 15:07:53 UTC (rev 6437)
@@ -51,20 +51,22 @@
     fprintf (out, "-------------\t-------\t-------\t---------------\t---------------\n");
     displayCollectionStats
       (out, "copying\t\t", 
-       &s->cumulativeStatistics.ru_gcCopy, 
-       s->cumulativeStatistics.numCopyingGCs, 
-       s->cumulativeStatistics.bytesCopied);
+       &s->cumulativeStatistics->ru_gcCopy, 
+       s->cumulativeStatistics->numCopyingGCs, 
+       s->cumulativeStatistics->bytesCopied);
     displayCollectionStats
       (out, "mark-compact\t", 
-       &s->cumulativeStatistics.ru_gcMarkCompact, 
-       s->cumulativeStatistics.numMarkCompactGCs, 
-       s->cumulativeStatistics.bytesMarkCompacted);
+       &s->cumulativeStatistics->ru_gcMarkCompact, 
+       s->cumulativeStatistics->numMarkCompactGCs, 
+       s->cumulativeStatistics->bytesMarkCompacted);
     displayCollectionStats
       (out, "minor\t\t",
-       &s->cumulativeStatistics.ru_gcMinor, 
-       s->cumulativeStatistics.numMinorGCs, 
-       s->cumulativeStatistics.bytesCopiedMinor);
+       &s->cumulativeStatistics->ru_gcMinor, 
+       s->cumulativeStatistics->numMinorGCs, 
+       s->cumulativeStatistics->bytesCopiedMinor);
     totalTime = getCurrentTime () - s->startTime;
+    fprintf (out, "total time: %s ms\n",
+             uintmaxToCommaString (totalTime));
     fprintf (out, "total GC time: %s ms (%.1f%%)\n",
              uintmaxToCommaString (gcTime), 
              (0 == totalTime) 

Modified: mlton/branches/shared-heap-multicore/runtime/gc/forward.c
===================================================================
--- mlton/branches/shared-heap-multicore/runtime/gc/forward.c	2008-03-03 14:52:41 UTC (rev 6436)
+++ mlton/branches/shared-heap-multicore/runtime/gc/forward.c	2008-03-03 15:07:53 UTC (rev 6437)
@@ -31,7 +31,7 @@
   GC_header header;
 
   op = *opp;
-  p = objptrToPointer (op, s->heap.start);
+  p = objptrToPointer (op, s->heap->start);
   if (DEBUG_DETAILED)
     fprintf (stderr,
              "forwardObjptr  opp = "FMTPTR"  op = "FMTOBJPTR"  p = "FMTPTR"\n",
@@ -148,8 +148,8 @@
   pointer p;
 
   op = *opp;
-  p = objptrToPointer (op, s->heap.start);
-  if (p < s->heap.nursery)
+  p = objptrToPointer (op, s->heap->start);
+  if (p < s->heap->nursery)
     return;
   if (DEBUG_GENERATIONAL)
     fprintf (stderr,
@@ -195,7 +195,7 @@
   if (cardMap[cardIndex]) {
     pointer lastObject;
 
-    s->cumulativeStatistics.markedCards++;
+    s->cumulativeStatistics->markedCards++;
     if (DEBUG_GENERATIONAL)
       fprintf (stderr, "card %zu is marked  objectStart = "FMTPTR"\n", 
                cardIndex, (uintptr_t)objectStart);
@@ -213,7 +213,7 @@
      */
     objectStart = foreachObjptrInRange (s, objectStart, &cardEnd, 
                                         forwardObjptrIfInNursery, FALSE);
-    s->cumulativeStatistics.minorBytesScanned += objectStart - lastObject;
+    s->cumulativeStatistics->minorBytesScanned += objectStart - lastObject;
     if (objectStart == oldGenEnd)
       goto done;
     cardIndex = sizeToCardMapIndex (objectStart - oldGenStart);

Modified: mlton/branches/shared-heap-multicore/runtime/gc/garbage-collection.c
===================================================================
--- mlton/branches/shared-heap-multicore/runtime/gc/garbage-collection.c	2008-03-03 14:52:41 UTC (rev 6436)
+++ mlton/branches/shared-heap-multicore/runtime/gc/garbage-collection.c	2008-03-03 15:07:53 UTC (rev 6437)
@@ -14,20 +14,20 @@
   uintmax_t numGCs;
   size_t desiredSize;
 
-  s->lastMajorStatistics.numMinorGCs = 0;
+  s->lastMajorStatistics->numMinorGCs = 0;
   numGCs = 
-    s->cumulativeStatistics.numCopyingGCs 
-    + s->cumulativeStatistics.numMarkCompactGCs;
+    s->cumulativeStatistics->numCopyingGCs 
+    + s->cumulativeStatistics->numMarkCompactGCs;
   if (0 < numGCs
-      and ((float)(s->cumulativeStatistics.numHashConsGCs) / (float)(numGCs)
-           < s->controls.ratios.hashCons))
+      and ((float)(s->cumulativeStatistics->numHashConsGCs) / (float)(numGCs)
+           < s->controls->ratios.hashCons))
     s->hashConsDuringGC = TRUE;
   desiredSize = 
-    sizeofHeapDesired (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 isHeapInit (&s->secondaryHeap)
+      and s->heap->size < s->sysvals.ram
+      and (not isHeapInit (s->secondaryHeap)
            or createHeapSecondary (s, desiredSize)))
     majorCheneyCopyGC (s);
   else

Modified: mlton/branches/shared-heap-multicore/runtime/gc/gc_state.c
===================================================================
--- mlton/branches/shared-heap-multicore/runtime/gc/gc_state.c	2008-03-03 14:52:41 UTC (rev 6436)
+++ mlton/branches/shared-heap-multicore/runtime/gc/gc_state.c	2008-03-03 15:07:53 UTC (rev 6437)
@@ -10,7 +10,7 @@
   fprintf (stream,
            "GC state\n");
   fprintf (stream, "\tcurrentThread = "FMTOBJPTR"\n", s->currentThread);
-  displayThread (s, (GC_thread)(objptrToPointer (s->currentThread, s->heap.start)
+  displayThread (s, (GC_thread)(objptrToPointer (s->currentThread, s->heap->start)
                                 + offsetofThread (s)), 
                  stream);
   fprintf (stream, "\tgenerational\n");
@@ -111,26 +111,26 @@
   s->amOriginal = b;
 }
 
-void GC_setMessages (GC_state s, bool b) {
-  s->controls.messages = b;
+void GC_setMessages (__attribute__ ((unused)) GC_state *gs, bool b) {
+  GC_state s = pthread_getspecific (gcstate_key);
+  s->controls->messages = b;
 }
 
-void GC_setSummary (GC_state s, bool b) {
-  s->controls.summary = b;
+void GC_setSummary (__attribute__ ((unused)) GC_state *gs, bool b) {
+  GC_state s = pthread_getspecific (gcstate_key);
+  s->controls->summary = b;
 }
 
-void GC_setRusageMeasureGC (GC_state s, bool b) {
-  s->controls.rusageMeasureGC = b;
+void GC_setRusageMeasureGC (__attribute__ ((unused)) GC_state *gs, bool b) {
+  GC_state s = pthread_getspecific (gcstate_key);
+  s->controls->rusageMeasureGC = b;
 }
 
-void GC_setHashConsDuringGC (GC_state s, bool b) {
+void GC_setHashConsDuringGC (__attribute__ ((unused)) GC_state *gs, bool b) {
+  GC_state s = pthread_getspecific (gcstate_key);
   s->hashConsDuringGC = b;
 }
 
-struct rusage* GC_getRusageGCAddr (GC_state s) {
-  return &(s->cumulativeStatistics.ru_gc);
-}
-
 sigset_t* GC_getSignalsHandledAddr (GC_state s) {
   return &(s->signalsInfo.signalsHandled);
 }
@@ -151,28 +151,35 @@
   s->signalsInfo.gcSignalPending = b;
 }
 
-void GC_setCallFromCHandlerThread (GC_state s, pointer p) {
-  objptr op = pointerToObjptr (p, s->heap.start);
+void GC_setCallFromCHandlerThread (__attribute__ ((unused)) GC_state *gs, 
+                                   pointer p) {
+  GC_state s = pthread_getspecific (gcstate_key);
+  objptr op = pointerToObjptr (p, s->heap->start);
   s->callFromCHandlerThread = op;
 }
 
-pointer GC_getCurrentThread (GC_state s) {
-  pointer p = objptrToPointer (s->currentThread, s->heap.start);
+pointer GC_getCurrentThread (__attribute__ ((unused)) GC_state *gs) {
+  GC_state s = pthread_getspecific (gcstate_key);
+  pointer p = objptrToPointer (s->currentThread, s->heap->start);
   return p;
 }
 
-pointer GC_getSavedThread (GC_state s) {
-  pointer p = objptrToPointer (s->savedThread, s->heap.start);
+pointer GC_getSavedThread (__attribute__ ((unused)) GC_state *gs) {
+  GC_state s = pthread_getspecific (gcstate_key);
+  pointer p = objptrToPointer (s->savedThread, s->heap->start);
   s->savedThread = BOGUS_OBJPTR;
   return p;
 }
 
-void GC_setSavedThread (GC_state s, pointer p) {
-  objptr op = pointerToObjptr (p, s->heap.start);
+void GC_setSavedThread (__attribute__ ((unused)) GC_state *gs, 
+                        pointer p) {
+  GC_state s = pthread_getspecific (gcstate_key);
+  objptr op = pointerToObjptr (p, s->heap->start);
   s->savedThread = op;
 }
 
-void GC_setSignalHandlerThread (GC_state s, pointer p) {
-  objptr op = pointerToObjptr (p, s->heap.start);
+void GC_setSignalHandlerThread (__attribute__ ((unused)) GC_state *gs, pointer p) {
+  GC_state s = pthread_getspecific (gcstate_key);
+  objptr op = pointerToObjptr (p, s->heap->start);
   s->signalHandlerThread = op;
 }

Modified: mlton/branches/shared-heap-multicore/runtime/gc/gc_state.h
===================================================================
--- mlton/branches/shared-heap-multicore/runtime/gc/gc_state.h	2008-03-03 14:52:41 UTC (rev 6436)
+++ mlton/branches/shared-heap-multicore/runtime/gc/gc_state.h	2008-03-03 15:07:53 UTC (rev 6437)
@@ -38,10 +38,10 @@
   objptr *globals;
   uint32_t globalsLength;
   bool hashConsDuringGC;
-  struct GC_heap heap;
+  struct GC_heap *heap;
   struct GC_intInfInit *intInfInits;
   uint32_t intInfInitsLength;
-  struct GC_lastMajorStatistics lastMajorStatistics;
+  struct GC_lastMajorStatistics *lastMajorStatistics;
   pointer limitPlusSlop; /* limit + GC_HEAP_LIMIT_SLOP */
   int (*loadGlobals)(FILE *f); /* loads the globals from the file. */
   uint32_t magic; /* The magic number for this executable. */
@@ -57,7 +57,7 @@
                        */
   int (*saveGlobals)(FILE *f); /* saves the globals to the file. */
   bool saveWorldStatus; /* */
-  struct GC_heap secondaryHeap; /* Used for major copying collection. */
+  struct GC_heap *secondaryHeap; /* Used for major copying collection. */
   objptr signalHandlerThread; /* Handler for signals (in heap). */
   struct GC_signalsInfo signalsInfo;
   struct GC_sourceMaps sourceMaps;
@@ -85,23 +85,21 @@
 
 #if (defined (MLTON_GC_INTERNAL_BASIS)) 
 
-bool GC_getAmOriginal (GC_state s);
-void GC_setAmOriginal (GC_state s, bool b);
-void GC_setMessages (GC_state s, bool b);
-void GC_setSummary (GC_state s, bool b);
-void GC_setRusageMeasureGC (GC_state s, bool b);
-void GC_setHashConsDuringGC (GC_state s, bool b);
+bool GC_getAmOriginal (GC_state *gs);
+void GC_setAmOriginal (GC_state *gs, bool b);
+void GC_setMessages (GC_state *gs, bool b);
+void GC_setSummary (GC_state *gs, bool b);
+void GC_setRusageMeasureGC (GC_state *gs, bool b);
+void GC_setHashConsDuringGC (GC_state *gs, bool b);
 
-pointer GC_getCurrentThread (GC_state s);
-pointer GC_getSavedThread (GC_state s);
-void GC_setCallFromCHandlerThread (GC_state s, pointer p);
-void GC_setSavedThread (GC_state s, pointer p);
-void GC_setSignalHandlerThread (GC_state s, pointer p);
+pointer GC_getCurrentThread (GC_state *gs);
+pointer GC_getSavedThread (GC_state *gs);
+void GC_setCallFromCHandlerThread (GC_state *gs, pointer p);
+void GC_setSavedThread (GC_state *gs, pointer p);
+void GC_setSignalHandlerThread (GC_state *gs, pointer p);
 
 #endif /* (defined (MLTON_GC_INTERNAL_BASIS)) */
 
-struct rusage* GC_getRusageGCAddr (GC_state s);
-
 sigset_t* GC_getSignalsHandledAddr (GC_state s);
 sigset_t* GC_getSignalsPendingAddr (GC_state s);
 void GC_setGCSignalHandled (GC_state s, bool b);

Modified: mlton/branches/shared-heap-multicore/runtime/gc/generational.c
===================================================================
--- mlton/branches/shared-heap-multicore/runtime/gc/generational.c	2008-03-03 14:52:41 UTC (rev 6436)
+++ mlton/branches/shared-heap-multicore/runtime/gc/generational.c	2008-03-03 15:07:53 UTC (rev 6437)
@@ -88,7 +88,7 @@
    */
   s->generationalMaps.cardMapAbsolute = 
     s->generationalMaps.cardMap
-    - pointerToCardMapIndexAbsolute (s->heap.start);
+    - pointerToCardMapIndexAbsolute (s->heap->start);
   if (DEBUG_CARD_MARKING)
     fprintf (stderr, "setCardMapAbsolute = "FMTPTR"\n",
              (uintptr_t)s->generationalMaps.cardMapAbsolute);
@@ -99,8 +99,8 @@
    * into the index for the previous crossMap entry.
    */
   return 
-    (p == s->heap.start)
-    ? s->heap.start
+    (p == s->heap->start)
+    ? s->heap->start
     : (p - 1) - ((uintptr_t)(p - 1) % CARD_SIZE);
 }
 
@@ -128,7 +128,7 @@
     s->generationalMaps.crossMap = NULL;
     return;
   }
-  assert (isAligned (s->heap.size, CARD_SIZE));
+  assert (isAligned (s->heap->size, CARD_SIZE));
 
   GC_cardMapIndex cardMapLength;
   size_t cardMapSize;
@@ -136,12 +136,12 @@
   size_t crossMapSize;
   size_t totalMapSize;
 
-  cardMapLength = sizeToCardMapIndex (s->heap.size);
+  cardMapLength = sizeToCardMapIndex (s->heap->size);
   cardMapSize = align (cardMapLength * CARD_MAP_ELEM_SIZE, s->sysvals.pageSize);
   cardMapLength = (GC_cardMapIndex)(cardMapSize / CARD_MAP_ELEM_SIZE);
   s->generationalMaps.cardMapLength = cardMapLength;
 
-  crossMapLength = sizeToCardMapIndex (s->heap.size);
+  crossMapLength = sizeToCardMapIndex (s->heap->size);
   crossMapSize = align (crossMapLength * CROSS_MAP_ELEM_SIZE, s->sysvals.pageSize);
   crossMapLength = (GC_crossMapIndex)(crossMapSize / CROSS_MAP_ELEM_SIZE);
   s->generationalMaps.crossMapLength = crossMapLength;
@@ -166,7 +166,7 @@
 void resizeCardMapAndCrossMap (GC_state s) {
   if (s->mutatorMarksCards
       and (s->generationalMaps.cardMapLength * CARD_MAP_ELEM_SIZE)
-          != align (sizeToCardMapIndex (s->heap.size), s->sysvals.pageSize)) {
+          != align (sizeToCardMapIndex (s->heap->size), s->sysvals.pageSize)) {
     GC_cardMap oldCardMap;
     size_t oldCardMapSize;
     GC_crossMap oldCrossMap;
@@ -207,13 +207,13 @@
   mapSize = s->generationalMaps.crossMapLength * CROSS_MAP_ELEM_SIZE;
   map = GC_mmapAnon_safe (NULL, mapSize);
   memset (map, CROSS_MAP_EMPTY, mapSize);
-  back = s->heap.start + s->heap.oldGenSize;
+  back = s->heap->start + s->heap->oldGenSize;
   cardIndex = 0;
-  front = alignFrontier (s, s->heap.start);
+  front = alignFrontier (s, s->heap->start);
 loopObjects:
   assert (front <= back);
   cardStart = getCrossMapCardStart (s, front);
-  cardIndex = sizeToCardMapIndex (cardStart - s->heap.start);
+  cardIndex = sizeToCardMapIndex (cardStart - s->heap->start);
   map[cardIndex] = (front - cardStart) / CROSS_MAP_OFFSET_SCALE;
   if (front < back) {
     front += sizeofObject (s, advanceToObjectData (s, front));
@@ -238,20 +238,20 @@
     displayGenerationalMaps (s, &s->generationalMaps, stderr);
   }
   assert (isAligned (s->alignment, CROSS_MAP_OFFSET_SCALE));
-  if (s->generationalMaps.crossMapValidSize == s->heap.oldGenSize)
+  if (s->generationalMaps.crossMapValidSize == s->heap->oldGenSize)
     goto done;
-  oldGenEnd = s->heap.start + s->heap.oldGenSize;
-  objectStart = s->heap.start + s->generationalMaps.crossMapValidSize;
-  if (objectStart == s->heap.start) {
+  oldGenEnd = s->heap->start + s->heap->oldGenSize;
+  objectStart = s->heap->start + s->generationalMaps.crossMapValidSize;
+  if (objectStart == s->heap->start) {
     cardIndex = 0;
     objectStart = alignFrontier (s, objectStart);
   } else
-    cardIndex = sizeToCardMapIndex (objectStart - 1 - s->heap.start);
-  cardStart = s->heap.start + cardMapIndexToSize (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)
+  assert ((objectStart == s->heap->start or cardStart < objectStart)
           and objectStart <= cardEnd);
   nextObject = objectStart + sizeofObject (s, advanceToObjectData (s, objectStart));
   if (DEBUG_GENERATIONAL) {
@@ -278,8 +278,8 @@
       fprintf (stderr, "crossMap[%zu] = %zu\n",
                cardIndex, offset);
     s->generationalMaps.crossMap[cardIndex] = (GC_crossMapElem)offset;
-    cardIndex = sizeToCardMapIndex (nextObject - 1 - s->heap.start);
-    cardStart = s->heap.start + cardMapIndexToSize (cardIndex);
+    cardIndex = sizeToCardMapIndex (nextObject - 1 - s->heap->start);
+    cardStart = s->heap->start + cardMapIndexToSize (cardIndex);
     cardEnd = cardStart + CARD_SIZE;
   }
   objectStart = nextObject;
@@ -288,9 +288,9 @@
   assert (objectStart == oldGenEnd);
   s->generationalMaps.crossMap[cardIndex] = 
     (GC_crossMapElem)(oldGenEnd - cardStart) / CROSS_MAP_OFFSET_SCALE;
-  s->generationalMaps.crossMapValidSize = s->heap.oldGenSize;
+  s->generationalMaps.crossMapValidSize = s->heap->oldGenSize;
 done:
-  assert (s->generationalMaps.crossMapValidSize == s->heap.oldGenSize);
+  assert (s->generationalMaps.crossMapValidSize == s->heap->oldGenSize);
   assert (isCrossMapOk (s));
   if (DEBUG_GENERATIONAL) {
     fprintf (stderr, "updateCrossMap finished\n");

Modified: mlton/branches/shared-heap-multicore/runtime/gc/handler.c
===================================================================
--- mlton/branches/shared-heap-multicore/runtime/gc/handler.c	2008-03-03 14:52:41 UTC (rev 6436)
+++ mlton/branches/shared-heap-multicore/runtime/gc/handler.c	2008-03-03 15:07:53 UTC (rev 6437)
@@ -15,10 +15,12 @@
  * Don't make it inline, because it is also called in basis/Thread.c,
  * and when compiling with COMPILE_FAST, they may appear out of order.
  */
-void GC_startSignalHandler (GC_state s) {
+void GC_startSignalHandler (__attribute__ ((unused)) GC_state *gs) {
   /* Switch to the signal handler thread. */
+  GC_state s = pthread_getspecific (gcstate_key);
   if (DEBUG_SIGNALS) {
-    fprintf (stderr, "GC_startSignalHandler\n");
+    fprintf (stderr, "GC_startSignalHandler [%d]\n", 
+             Proc_processorNumber (s));
   }
   assert (s->atomicState == 1);
   assert (s->signalsInfo.signalIsPending);
@@ -34,9 +36,12 @@
   s->atomicState = 2;
 }
 
-void GC_finishSignalHandler (GC_state s) {
+void GC_finishSignalHandler (__attribute__ ((unused)) GC_state *gs) {
+
+  GC_state s = pthread_getspecific (gcstate_key);
   if (DEBUG_SIGNALS)
-    fprintf (stderr, "GC_finishSignalHandler ()\n");
+    fprintf (stderr, "GC_finishSignalHandler () [%d]\n",
+             Proc_processorNumber (s));
   assert (s->atomicState == 1);
   s->signalsInfo.amInSignalHandler = FALSE;     
 }
@@ -44,7 +49,7 @@
 void switchToSignalHandlerThreadIfNonAtomicAndSignalPending (GC_state s) {
   if (s->atomicState == 1 
       and s->signalsInfo.signalIsPending) {
-    GC_startSignalHandler (s);
+    GC_startSignalHandler (&s->procStates);
     switchToThread (s, s->signalHandlerThread);
   }
 }

Modified: mlton/branches/shared-heap-multicore/runtime/gc/handler.h
===================================================================
--- mlton/branches/shared-heap-multicore/runtime/gc/handler.h	2008-03-03 14:52:41 UTC (rev 6436)
+++ mlton/branches/shared-heap-multicore/runtime/gc/handler.h	2008-03-03 15:07:53 UTC (rev 6437)
@@ -14,8 +14,8 @@
 
 #if (defined (MLTON_GC_INTERNAL_BASIS))
 
-void GC_startSignalHandler (GC_state s);
-void GC_finishSignalHandler (GC_state s);
+void GC_startSignalHandler (GC_state *gs);
+void GC_finishSignalHandler (GC_state *gs);
 
 #endif /* (defined (MLTON_GC_INTERNAL_BASIS)) */
 

Modified: mlton/branches/shared-heap-multicore/runtime/gc/hash-cons.c
===================================================================
--- mlton/branches/shared-heap-multicore/runtime/gc/hash-cons.c	2008-03-03 14:52:41 UTC (rev 6436)
+++ mlton/branches/shared-heap-multicore/runtime/gc/hash-cons.c	2008-03-03 15:07:53 UTC (rev 6437)
@@ -33,22 +33,23 @@
 
   t = (GC_objectHashTable)(malloc_safe (sizeof(*t)));
   // Try to use space in the heap for the elements.
-  if (not (isHeapInit (&s->secondaryHeap))) {
+  if (not (isHeapInit (s->secondaryHeap))) {
     if (DEBUG_SHARE)
       fprintf (stderr, "using secondaryHeap\n");
-    regionStart = s->secondaryHeap.start;
-    regionEnd = s->secondaryHeap.start + s->secondaryHeap.size;
+    regionStart = s->secondaryHeap->start;
+    regionEnd = s->secondaryHeap->start + s->secondaryHeap->size;
   } else if (s->amInGC or not s->canMinor) {
     if (DEBUG_SHARE)
       fprintf (stderr, "using end of heap\n");
+    /* XX revisit this use of local frontier */
     regionStart = s->frontier;
     regionEnd = s->limitPlusSlop;
   } else {
     if (DEBUG_SHARE)
       fprintf (stderr, "using minor space\n");
     assert (s->canMinor);
-    regionStart = s->heap.start + s->heap.oldGenSize;
-    regionEnd = s->heap.nursery;
+    regionStart = s->heap->start + s->heap->oldGenSize;
+    regionEnd = s->heap->nursery;
   }
   elementsLengthMax = (regionEnd - regionStart) / sizeof (*(t->elements));
   if (DEBUG_SHARE)
@@ -269,7 +270,7 @@
       amount += GC_ARRAY_HEADER_SIZE;
     else
       amount += GC_NORMAL_HEADER_SIZE;
-    s->lastMajorStatistics.bytesHashConsed += amount;
+    s->lastMajorStatistics->bytesHashConsed += amount;
   }
 done:
   if (DEBUG_SHARE)
@@ -281,19 +282,19 @@
 void shareObjptr (GC_state s, objptr *opp) {
   pointer p;
 
-  p = objptrToPointer (*opp, s->heap.start);
+  p = objptrToPointer (*opp, s->heap->start);
   if (DEBUG_SHARE)
     fprintf (stderr, "shareObjptr  opp = "FMTPTR"  *opp = "FMTOBJPTR"\n",
              (uintptr_t)opp, *opp);
   p = hashConsPointer (s, p, FALSE);
-  *opp = pointerToObjptr (p, s->heap.start);
+  *opp = pointerToObjptr (p, s->heap->start);
   markIntergenerationalObjptr (s, opp);
 }
 
 void printBytesHashConsedMessage (GC_state s, uintmax_t total) {
   fprintf (stderr, "%s bytes hash-consed (%.1f%%).\n",
-           uintmaxToCommaString(s->lastMajorStatistics.bytesHashConsed),
+           uintmaxToCommaString(s->lastMajorStatistics->bytesHashConsed),
            (100.0 
-            * ((double)s->lastMajorStatistics.bytesHashConsed 
+            * ((double)s->lastMajorStatistics->bytesHashConsed 
                / (double)total)));
 }

Modified: mlton/branches/shared-heap-multicore/runtime/gc/heap.c
===================================================================
--- mlton/branches/shared-heap-multicore/runtime/gc/heap.c	2008-03-03 14:52:41 UTC (rev 6436)
+++ mlton/branches/shared-heap-multicore/runtime/gc/heap.c	2008-03-03 15:07:53 UTC (rev 6437)
@@ -38,26 +38,26 @@
   float ratio;
 
   ratio = (float)s->sysvals.ram / (float)live;
-  if (ratio >= s->controls.ratios.live + s->controls.ratios.grow) {
+  if (ratio >= s->controls->ratios.live + s->controls->ratios.grow) {
     /* Cheney copying fits in RAM with desired ratios.live. */
-    res = live * s->controls.ratios.live;
+    res = live * s->controls->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->controls.ratios.grow >= s->controls.ratios.copy
-             and ratio >= 2 * s->controls.ratios.copy) {
+  } else if (s->controls->ratios.grow >= s->controls->ratios.copy
+             and ratio >= 2 * s->controls->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->controls.ratios.copy + s->controls.ratios.grow) {
+  } else if (ratio >= s->controls->ratios.copy + s->controls->ratios.grow) {
     /* Cheney copying fits in RAM. */
-    res = s->sysvals.ram - s->controls.ratios.grow * live;
+    res = s->sysvals.ram - s->controls->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.
@@ -65,7 +65,7 @@
     if (currentSize <= res 
         and res <= 1.1 * currentSize)
       res = currentSize;
-  } else if (ratio >= s->controls.ratios.markCompact) {
+  } else if (ratio >= s->controls->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
@@ -74,7 +74,7 @@
      */
     res = s->sysvals.ram;
   } else { /* Required live ratio. */
-    res = live * s->controls.ratios.markCompact;
+    res = live * s->controls->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
@@ -82,20 +82,20 @@
      * growHeap will make the right thing happen.
      */ 
   }
-  if (s->controls.fixedHeap > 0) {
-    if (res > s->controls.fixedHeap / 2)
-      res = s->controls.fixedHeap;
+  if (s->controls->fixedHeap > 0) {
+    if (res > s->controls->fixedHeap / 2)
+      res = s->controls->fixedHeap;
     else
-      res = s->controls.fixedHeap / 2;
+      res = s->controls->fixedHeap / 2;
     if (res < live)
       die ("Out of memory with fixed heap size %s.",
-           uintmaxToCommaString(s->controls.fixedHeap));
-  } else if (s->controls.maxHeap > 0) {
-    if (res > s->controls.maxHeap)
-      res = s->controls.maxHeap;
+           uintmaxToCommaString(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 %s.",
-           uintmaxToCommaString(s->controls.maxHeap));
+           uintmaxToCommaString(s->controls->maxHeap));
   }
   if (DEBUG_RESIZING)
     fprintf (stderr, "%s = sizeofHeapDesired (%s, %s)\n",
@@ -109,7 +109,7 @@
 void releaseHeap (GC_state s, GC_heap h) {
   if (NULL == h->start)
     return;
-  if (DEBUG or s->controls.messages)
+  if (DEBUG or s->controls->messages)
     fprintf (stderr, "[GC: Releasing heap at "FMTPTR" of size %s bytes.]\n",
              (uintptr_t)(h->start),
              uintmaxToCommaString(h->size));
@@ -125,7 +125,7 @@
   }
   keep = align (keep, s->sysvals.pageSize);
   if (keep < h->size) {
-    if (DEBUG or s->controls.messages)
+    if (DEBUG or s->controls->messages)
       fprintf (stderr,
                "[GC: Shrinking heap at "FMTPTR" of size %s bytes to size %s bytes.]\n",
                (uintptr_t)(h->start),
@@ -187,9 +187,9 @@
         h->start = (void*)NULL;
       unless ((void*)NULL == h->start) {
         direction = not direction;
-        if (h->size > s->cumulativeStatistics.maxHeapSizeSeen)
-          s->cumulativeStatistics.maxHeapSizeSeen = h->size;
-        if (DEBUG or s->controls.messages)
+        if (h->size > s->cumulativeStatistics->maxHeapSizeSeen)
+          s->cumulativeStatistics->maxHeapSizeSeen = h->size;
+        if (DEBUG or s->controls->messages)
           fprintf (stderr, "[GC: Created heap at "FMTPTR" of size %s bytes.]\n",
                    (uintptr_t)(h->start),
                    uintmaxToCommaString(h->size));
@@ -197,7 +197,7 @@
         return TRUE;
       }
     }
-    if (s->controls.messages)
+    if (s->controls->messages)
       fprintf(stderr, 
               "[GC: Creating heap of size %s bytes cannot be satisfied; "
               "backing off by %s bytes (min size = %s).]\n",
@@ -212,12 +212,12 @@
 /* createHeapSecondary (s, 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))
+  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 createHeap (s, &s->secondaryHeap, desiredSize, s->heap.oldGenSize);
+  return createHeap (s, s->secondaryHeap, desiredSize, s->heap->oldGenSize);
 }
 
 /* remapHeap (s, h, desiredSize, minSize)
@@ -245,8 +245,8 @@
     unless ((void*)-1 == new) {
       h->start = new;
       h->size = size;
-      if (h->size > s->cumulativeStatistics.maxHeapSizeSeen)
-        s->cumulativeStatistics.maxHeapSizeSeen = h->size;
+      if (h->size > s->cumulativeStatistics->maxHeapSizeSeen)
+        s->cumulativeStatistics->maxHeapSizeSeen = h->size;
       assert (minSize <= h->size and h->size <= desiredSize);
       return TRUE;
     }
@@ -267,16 +267,16 @@
   pointer orig;
   size_t size;
 
-  curHeapp = &s->heap;
-  assert (desiredSize >= s->heap.size);
+  curHeapp = s->heap;
+  assert (desiredSize >= s->heap->size);
   if (DEBUG_RESIZING)
     fprintf (stderr, "Growing heap at "FMTPTR" of size %s to %s bytes.\n",
-             (uintptr_t)s->heap.start,
-             uintmaxToCommaString(s->heap.size),
+             (uintptr_t)s->heap->start,
+             uintmaxToCommaString(s->heap->size),
              uintmaxToCommaString(desiredSize));
   orig = curHeapp->start;
   size = curHeapp->oldGenSize;
-  assert (size <= s->heap.size);
+  assert (size <= s->heap->size);
   if (remapHeap (s, curHeapp, desiredSize, minSize))
     goto done;
   shrinkHeap (s, curHeapp, size);
@@ -318,15 +318,15 @@
       GC_diskBack_close (data);
     } else {
       GC_diskBack_close (data);
-      if (s->controls.messages)
+      if (s->controls->messages)
         GC_displayMem ();
       die ("Out of memory.  Unable to allocate %s bytes.\n",
            uintmaxToCommaString(minSize));
     }
   }
 done:
-  unless (orig == s->heap.start) {
-    translateHeap (s, orig, s->heap.start, s->heap.oldGenSize);
+  unless (orig == s->heap->start) {
+    translateHeap (s, orig, s->heap->start, s->heap->oldGenSize);
     setCardMapAbsolute (s);
   }
 }
@@ -339,17 +339,17 @@
   if (DEBUG_RESIZING)
     fprintf (stderr, "resizeHeap  minSize = %s  size = %s\n",
              uintmaxToCommaString(minSize), 
-             uintmaxToCommaString(s->heap.size));
-  desiredSize = sizeofHeapDesired (s, minSize, s->heap.size);
+             uintmaxToCommaString(s->heap->size));
+  desiredSize = sizeofHeapDesired (s, minSize, s->heap->size);
   assert (minSize <= desiredSize);
-  if (desiredSize <= s->heap.size)
-    shrinkHeap (s, &s->heap, desiredSize);
+  if (desiredSize <= s->heap->size)
+    shrinkHeap (s, s->heap, desiredSize);
   else {
-    releaseHeap (s, &s->secondaryHeap);
+    releaseHeap (s, s->secondaryHeap);
     growHeap (s, desiredSize, minSize);
   }
   resizeCardMapAndCrossMap (s);
-  assert (s->heap.size >= minSize);
+  assert (s->heap->size >= minSize);
 }
 
 /* resizeHeapSecondary (s)
@@ -358,20 +358,20 @@
   size_t primarySize;
   size_t secondarySize;
 
-  primarySize = s->heap.size;
-  secondarySize = s->secondaryHeap.size;
+  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. */
-    releaseHeap (s, &s->secondaryHeap);
+    releaseHeap (s, s->secondaryHeap);
   else if (secondarySize < primarySize) {
-    unless (remapHeap (s, &s->secondaryHeap, primarySize, primarySize))
-      releaseHeap (s, &s->secondaryHeap);
+    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);
+    shrinkHeap (s, s->secondaryHeap, primarySize);
+  assert (0 == s->secondaryHeap->size 
+          or s->heap->size == s->secondaryHeap->size);
 }

Modified: mlton/branches/shared-heap-multicore/runtime/gc/heap_predicates.c
===================================================================
--- mlton/branches/shared-heap-multicore/runtime/gc/heap_predicates.c	2008-03-03 14:52:41 UTC (rev 6436)
+++ mlton/branches/shared-heap-multicore/runtime/gc/heap_predicates.c	2008-03-03 15:07:53 UTC (rev 6437)
@@ -7,19 +7,19 @@
 
 bool isPointerInHeap (GC_state s, pointer p) {
   return (not (isPointer (p))
-          or (s->heap.start <= p 
-              and p < s->frontier));
+          or (s->heap->start <= p 
+              and p < s->heap->start + s->heap->size));
 }
 
 bool isPointerInOldGen (GC_state s, pointer p) {
   return (not (isPointer (p))
-          or (s->heap.start <= p 
-              and p < s->heap.start + s->heap.oldGenSize));
+          or (s->heap->start <= p 
+              and p < s->heap->start + s->heap->oldGenSize));
 }
 
 bool isPointerInNursery (GC_state s, pointer p) {
   return (not (isPointer (p))
-          or (s->heap.nursery <= p and p < s->frontier));
+          or (s->heap->nursery <= p and p < s->heap->frontier));
 }
 
 bool isPointerInFromSpace (GC_state s, pointer p) {
@@ -31,7 +31,7 @@
   pointer p;
   if (not (isObjptr(op)))
     return TRUE;
-  p = objptrToPointer (op, s->heap.start);
+  p = objptrToPointer (op, s->heap->start);
   return isPointerInHeap (s, p);
 }
 
@@ -39,7 +39,7 @@
   pointer p;
   if (not (isObjptr(op)))
     return TRUE;
-  p = objptrToPointer (op, s->heap.start);
+  p = objptrToPointer (op, s->heap->start);
   return isPointerInOldGen (s, p);
 }
 
@@ -47,7 +47,7 @@
   pointer p;
   if (not (isObjptr(op)))
     return TRUE;
-  p = objptrToPointer (op, s->heap.start);
+  p = objptrToPointer (op, s->heap->start);
   return isPointerInNursery (s, p);
 }
 

Modified: mlton/branches/shared-heap-multicore/runtime/gc/init-world.c
===================================================================
--- mlton/branches/shared-heap-multicore/runtime/gc/init-world.c	2008-03-03 14:52:41 UTC (rev 6436)
+++ mlton/branches/shared-heap-multicore/runtime/gc/init-world.c	2008-03-03 15:07:53 UTC (rev 6437)
@@ -93,7 +93,7 @@
                            ? OBJPTR_SIZE
                            : dataBytes),
                         s->alignment);
-    assert (objectSize <= (size_t)(s->heap.start + s->heap.size - frontier));
+    assert (objectSize <= (size_t)(s->heap->start + s->heap->size - frontier));
     *((GC_arrayCounter*)(frontier)) = 0;
     frontier = frontier + GC_ARRAY_COUNTER_SIZE;
     *((GC_arrayLength*)(frontier)) = inits[i].numElements;
@@ -117,7 +117,7 @@
     }
     *((GC_header*)(frontier)) = buildHeaderFromTypeIndex (typeIndex);
     frontier = frontier + GC_HEADER_SIZE;
-    s->globals[inits[i].globalIndex] = pointerToObjptr(frontier, s->heap.start);
+    s->globals[inits[i].globalIndex] = pointerToObjptr(frontier, s->heap->start);
     if (DEBUG_DETAILED)
       fprintf (stderr, "allocated vector at "FMTPTR"\n",
                (uintptr_t)(s->globals[inits[i].globalIndex]));
@@ -128,7 +128,7 @@
     fprintf (stderr, "frontier after string allocation is "FMTPTR"\n",
              (uintptr_t)frontier);
   GC_profileAllocInc (s, (size_t)(frontier - s->frontier));
-  s->cumulativeStatistics.bytesAllocated += (size_t)(frontier - s->frontier);
+  s->cumulativeStatistics->bytesAllocated += (size_t)(frontier - s->frontier);
   assert (isFrontierAligned (s, frontier));
   s->frontier = frontier;
 }
@@ -137,6 +137,7 @@
   uint32_t i;
   pointer start;
   GC_thread thread;
+  size_t minSize;
 
   for (i = 0; i < s->globalsLength; ++i)
     s->globals[i] = BOGUS_OBJPTR;
@@ -151,10 +152,29 @@
   s->limit = s->limitPlusSlop - GC_HEAP_LIMIT_SLOP;
   initIntInfs (s);
   initVectors (s);
-  assert ((size_t)(s->frontier - start) <= s->lastMajorStatistics.bytesLive);
-  s->heap.oldGenSize = s->frontier - s->heap.start;
-  setGCStateCurrentHeap (s, 0, 0);
+  assert ((size_t)(s->frontier - start) <= s->lastMajorStatistics->bytesLive);
+  s->heap->oldGenSize = s->frontier - s->heap->start;
+  setGCStateCurrentHeap (s, 0, 0, true);
   thread = newThread (s, sizeofStackInitial (s));
-  switchToThread (s, pointerToObjptr((pointer)thread - offsetofThread (s), s->heap.start));
+  switchToThread (s, pointerToObjptr((pointer)thread - offsetofThread (s), s->heap->start));
 }
 
+void duplicateWorld (GC_state d, GC_state s) {
+  GC_thread thread;
+
+  d->lastMajorStatistics->bytesLive = 0;
+
+  /* Use the original to allocate */
+  thread = newThread (s, sizeofStackInitial (s));
+
+  /* Now copy stats, heap data from original */
+  d->cumulativeStatistics->maxHeapSizeSeen = s->cumulativeStatistics->maxHeapSizeSeen;
+  d->heap = s->heap;
+  d->secondaryHeap = s->secondaryHeap;
+  d->generationalMaps = s->generationalMaps;
+
+  /* Allocation handled in setGCStateCurrentHeap when called from initWorld */
+
+  switchToThread (d, pointerToObjptr((pointer)thread - offsetofThread (d), d->heap->start));
+}
+

Modified: mlton/branches/shared-heap-multicore/runtime/gc/init-world.h
===================================================================
--- mlton/branches/shared-heap-multicore/runtime/gc/init-world.h	2008-03-03 14:52:41 UTC (rev 6436)
+++ mlton/branches/shared-heap-multicore/runtime/gc/init-world.h	2008-03-03 15:07:53 UTC (rev 6437)
@@ -41,5 +41,6 @@
 static void initIntInfs (GC_state s);
 static void initVectors (GC_state s);
 static void initWorld (GC_state s);
+static void duplicateWorld (GC_state d, GC_state s);
 
 #endif /* (defined (MLTON_GC_INTERNAL_FUNCS)) */

Modified: mlton/branches/shared-heap-multicore/runtime/gc/init.c
===================================================================
--- mlton/branches/shared-heap-multicore/runtime/gc/init.c	2008-03-03 14:52:41 UTC (rev 6436)
+++ mlton/branches/shared-heap-multicore/runtime/gc/init.c	2008-03-03 15:07:53 UTC (rev 6437)
@@ -77,7 +77,7 @@
   int i;
 
   i = 1;
-  while (s->controls.mayProcessAtMLton
+  while (s->controls->mayProcessAtMLton
          and i < argc
          and (0 == strcmp (argv [i], "@MLton"))) {
     bool done;
@@ -95,25 +95,25 @@
           i++;
           if (i == argc)
             die ("@MLton copy-generational-ratio missing argument.");
-          s->controls.ratios.copyGenerational = stringToFloat (argv[i++]);
-          unless (1.0 < s->controls.ratios.copyGenerational)
+          s->controls->ratios.copyGenerational = stringToFloat (argv[i++]);
+          unless (1.0 < s->controls->ratios.copyGenerational)
             die ("@MLton copy-generational-ratio argument must be greater than 1.0.");
         } else if (0 == strcmp (arg, "copy-ratio")) {
           i++;
           if (i == argc)
             die ("@MLton copy-ratio missing argument.");
-          s->controls.ratios.copy = stringToFloat (argv[i++]);
-          unless (1.0 < s->controls.ratios.copy)
+          s->controls->ratios.copy = stringToFloat (argv[i++]);
+          unless (1.0 < s->controls->ratios.copy)
             die ("@MLton copy-ratio argument must be greater than 1.0.");
         } else if (0 == strcmp (arg, "fixed-heap")) {
           i++;
           if (i == argc)
             die ("@MLton fixed-heap missing argument.");
-          s->controls.fixedHeap = align (stringToBytes (argv[i++]),
+          s->controls->fixedHeap = align (stringToBytes (argv[i++]),
                                          2 * s->sysvals.pageSize);
         } else if (0 == strcmp (arg, "gc-messages")) {
           i++;
-          s->controls.messages = TRUE;
+          s->controls->messages = TRUE;
         } else if (0 == strcmp (arg, "gc-summary")) {
           i++;
 #if (defined (__MINGW32__))
@@ -125,26 +125,26 @@
           i++;
           if (i == argc)
             die ("@MLton grow-ratio missing argument.");
-          s->controls.ratios.grow = stringToFloat (argv[i++]);
-          unless (1.0 < s->controls.ratios.grow)
+          s->controls->ratios.grow = stringToFloat (argv[i++]);
+          unless (1.0 < s->controls->ratios.grow)
             die ("@MLton grow-ratio argument must be greater than 1.0.");
         } else if (0 == strcmp (arg, "hash-cons")) {
           i++;
           if (i == argc)
             die ("@MLton hash-cons missing argument.");
-          s->controls.ratios.hashCons = stringToFloat (argv[i++]);
-          unless (0.0 <= s->controls.ratios.hashCons
-                  and s->controls.ratios.hashCons <= 1.0)
+          s->controls->ratios.hashCons = stringToFloat (argv[i++]);
+          unless (0.0 <= s->controls->ratios.hashCons
+                  and s->controls->ratios.hashCons <= 1.0)
             die ("@MLton hash-cons argument must be between 0.0 and 1.0.");
         } else if (0 == strcmp (arg, "live-ratio")) {
           i++;
           if (i == argc)
             die ("@MLton live-ratio missing argument.");
-          s->controls.ratios.live = stringToFloat (argv[i++]);
-          unless (1.0 < s->controls.ratios.live)
+          s->controls->ratios.live = stringToFloat (argv[i++]);
+          unless (1.0 < s->controls->ratios.live)
             die ("@MLton live-ratio argument must be greater than 1.0.");
         } else if (0 == strcmp (arg, "load-world")) {
-          unless (s->controls.mayLoadWorld)
+          unless (s->controls->mayLoadWorld)
             die ("May not load world.");
           i++;
           s->amOriginal = FALSE;
@@ -155,50 +155,50 @@
           i++;
           if (i == argc)
             die ("@MLton mark-compact-generational-ratio missing argument.");
-          s->controls.ratios.mark



More information about the MLton-commit mailing list