[MLton-commit] r4161

Matthew Fluet MLton@mlton.org
Sun, 6 Nov 2005 09:13:43 -0800


More cleanup
----------------------------------------------------------------------

U   mlton/branches/on-20050822-x86_64-branch/runtime/gc/Makefile
U   mlton/branches/on-20050822-x86_64-branch/runtime/gc/TODO
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/call-stack.c
A   mlton/branches/on-20050822-x86_64-branch/runtime/gc/call-stack.h
U   mlton/branches/on-20050822-x86_64-branch/runtime/gc/cheney-copy.c
U   mlton/branches/on-20050822-x86_64-branch/runtime/gc/debug.c
U   mlton/branches/on-20050822-x86_64-branch/runtime/gc/foreach.c
U   mlton/branches/on-20050822-x86_64-branch/runtime/gc/forward.c
U   mlton/branches/on-20050822-x86_64-branch/runtime/gc/gc_state.c
U   mlton/branches/on-20050822-x86_64-branch/runtime/gc/gc_state.h
U   mlton/branches/on-20050822-x86_64-branch/runtime/gc/init-world.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
U   mlton/branches/on-20050822-x86_64-branch/runtime/gc/object.c
U   mlton/branches/on-20050822-x86_64-branch/runtime/gc/object.h
A   mlton/branches/on-20050822-x86_64-branch/runtime/gc/object_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/signals.c
A   mlton/branches/on-20050822-x86_64-branch/runtime/gc/sources.c
A   mlton/branches/on-20050822-x86_64-branch/runtime/gc/sources.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

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

Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/Makefile
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/Makefile	2005-11-05 00:04:36 UTC (rev 4160)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/Makefile	2005-11-06 17:12:54 UTC (rev 4161)
@@ -83,6 +83,7 @@
 	array-allocate.c						\
 	array.c								\
 	atomic.c							\
+	call-stack.c							\
 	cheney-copy.c							\
 	controls.c							\
 	copy-thread.c							\
@@ -109,6 +110,7 @@
 	new-object.c   							\
 	object-size.c							\
 	object.c							\
+	object_predicates.c						\
 	pack.c								\
 	pointer.c							\
 	pointer_predicates.c						\
@@ -116,6 +118,7 @@
 	share.c								\
 	signals.c							\
 	size.c								\
+	sources.c							\
 	stack.c								\
 	stack_predicates.c						\
 	switch-thread.c							\
@@ -167,6 +170,8 @@
 	garbage-collection.h						\
 	new-object.h							\
 	array-allocate.h						\
+	sources.h							\
+	call-stack.h							\
 	profiling.h							\
 	init-world.h							\
 	world.h								\

Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/TODO
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/TODO	2005-11-05 00:04:36 UTC (rev 4160)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/TODO	2005-11-06 17:12:54 UTC (rev 4161)
@@ -1,6 +1,7 @@
 
 * reorder ZZZ_TYPE_INDEX
 * eliminate STRING_TYPE_INDEX, STRING_TYPE_HEADER in favor of WORD8.
+* reorder SOURCE_SEQ_UNKNOWN
 * fix semantics of numNonPointers for normal objects to mean bytes of
         non-pointer data, rather than number of 32-bit words of
         non-pointer data.  Rename to sizeNonPointers.
@@ -19,4 +20,4 @@
         be unnecessary.
 * Why do {load,save}Globals differ in the representation of the file?
 * Why does hash-table use malloc/free while generational maps use mmap/munmap?
-
+* The succssor field of GC_source appears to be unused.
\ No newline at end of file

Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/align.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/align.c	2005-11-05 00:04:36 UTC (rev 4160)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/align.c	2005-11-06 17:12:54 UTC (rev 4161)
@@ -47,38 +47,3 @@
 static inline size_t pad (GC_state s, size_t bytes, size_t extra) {
   return align (bytes + extra, s->alignment) - extra;
 }
-
-#if ASSERT
-static inline bool isAlignedFrontier (GC_state s, pointer p) {
-  return isAligned ((size_t)p + GC_NORMAL_HEADER_SIZE, 
-                    s->alignment);
-}
-#endif
-
-static inline pointer alignFrontier (GC_state s, pointer p) {
-  size_t res;
-
-  res = pad (s, (size_t)p, GC_NORMAL_HEADER_SIZE);
-  if (DEBUG_STACKS)
-    fprintf (stderr, FMTPTR" = stackReserved ("FMTPTR")\n", 
-             (uintptr_t)p, (uintptr_t)res);
-  assert (isAlignedFrontier (s, (pointer)res));
-  return (pointer)res;
-}
-
-#if ASSERT
-static inline bool isAlignedStackReserved (GC_state s, size_t reserved) {
-  return isAligned (GC_STACK_HEADER_SIZE + sizeof (struct GC_stack) + reserved, 
-                    s->alignment);
-}
-#endif
-
-static inline size_t alignStackReserved (GC_state s, size_t reserved) {
-  size_t res;
-  
-  res = pad (s, reserved, GC_STACK_HEADER_SIZE + sizeof (struct GC_stack));
-  if (DEBUG_STACKS)
-    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-11-05 00:04:36 UTC (rev 4160)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/array-allocate.c	2005-11-06 17:12:54 UTC (rev 4161)
@@ -62,7 +62,7 @@
     }
     frontier = s->frontier;
     last = frontier + arraySize;
-    assert (isAlignedFrontier (s, last));
+    assert (isFrontierAligned (s, last));
     s->frontier = last;
   }
   *((GC_arrayCounter*)(frontier)) = 0;

Copied: mlton/branches/on-20050822-x86_64-branch/runtime/gc/call-stack.c (from rev 4158, mlton/branches/on-20050822-x86_64-branch/runtime/gc/profiling.c)
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/profiling.c	2005-11-04 22:09:10 UTC (rev 4158)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/call-stack.c	2005-11-06 17:12:54 UTC (rev 4161)
@@ -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.
+ */
+
+static void numStackFramesAux (GC_state s, 
+                               __attribute__ ((unused)) GC_frameIndex i) {
+  s->callStackState.numStackFrames++;
+}
+
+uint32_t GC_numStackFrames (GC_state s) {
+  s->callStackState.numStackFrames = 0;
+  foreachStackFrame (s, numStackFramesAux);
+  if (DEBUG_CALL_STACK)
+    fprintf (stderr, "%"PRIu32" = GC_numStackFrames\n", 
+             s->callStackState.numStackFrames);
+  return s->callStackState.numStackFrames;
+}
+
+static void callStackAux (GC_state s, 
+                          GC_frameIndex i) {
+  if (DEBUG_CALL_STACK)
+    fprintf (stderr, "callStackAux ("FMTFI")\n", i);
+  s->callStackState.callStack[s->callStackState.numStackFrames] = i;
+  s->callStackState.numStackFrames++;
+}
+
+void GC_callStack (GC_state s, pointer p) {
+  if (DEBUG_CALL_STACK)
+    fprintf (stderr, "GC_callStack\n");
+  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 *res;
+
+  res = s->sourceMaps.sourceSeqs[s->sourceMaps.frameSources[frameIndex]];
+  if (DEBUG_CALL_STACK)
+    fprintf (stderr, FMTPTR" = GC_frameIndexSourceSeq ("FMTFI")\n",
+             (uintptr_t)res, frameIndex);
+  return res;
+}

Copied: mlton/branches/on-20050822-x86_64-branch/runtime/gc/call-stack.h (from rev 4158, mlton/branches/on-20050822-x86_64-branch/runtime/gc/profiling.h)
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/profiling.h	2005-11-04 22:09:10 UTC (rev 4158)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/call-stack.h	2005-11-06 17:12:54 UTC (rev 4161)
@@ -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.
+ */
+
+struct GC_callStackState {
+  uint32_t numStackFrames;
+  uint32_t *callStack;
+};
+
+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);

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-11-05 00:04:36 UTC (rev 4160)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/cheney-copy.c	2005-11-06 17:12:54 UTC (rev 4161)
@@ -120,7 +120,7 @@
     s->forwardState.toStart = s->heap.start + s->heap.oldGenSize;
     if (DEBUG_GENERATIONAL)
       fprintf (stderr, "toStart = "FMTPTR"\n", (uintptr_t)s->forwardState.toStart);
-    assert (isAlignedFrontier (s, s->forwardState.toStart));
+    assert (isFrontierAligned (s, s->forwardState.toStart));
     s->forwardState.toLimit = s->forwardState.toStart + bytesAllocated;
     assert (invariantForGC (s));
     s->cumulativeStatistics.numMinorGCs++;

Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/debug.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/debug.c	2005-11-05 00:04:36 UTC (rev 4160)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/debug.c	2005-11-06 17:12:54 UTC (rev 4161)
@@ -24,6 +24,7 @@
   DEBUG_SHARE = FALSE,
   DEBUG_SIGNALS = FALSE,
   DEBUG_SIZE = FALSE,
+  DEBUG_SOURCES = FALSE,
   DEBUG_STACKS = FALSE,
   DEBUG_THREADS = FALSE,
   DEBUG_WEAK = FALSE,

Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/foreach.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/foreach.c	2005-11-05 00:04:36 UTC (rev 4160)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/foreach.c	2005-11-06 17:12:54 UTC (rev 4161)
@@ -178,7 +178,7 @@
                               GC_foreachObjptrFun f, bool skipWeaks) {
   pointer b;
 
-  assert (isAlignedFrontier (s, front));
+  assert (isFrontierAligned (s, front));
   if (DEBUG_DETAILED)
     fprintf (stderr, 
              "foreachObjptrInRange  front = "FMTPTR"  *back = "FMTPTR"\n",

Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/forward.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/forward.c	2005-11-05 00:04:36 UTC (rev 4160)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/forward.c	2005-11-06 17:12:54 UTC (rev 4161)
@@ -71,7 +71,7 @@
          */
         if (stack->used <= stack->reserved / 4) {
           size_t new = 
-            alignStackReserved 
+            alignStackReserved
             (s, max (stack->reserved / 2, 
                      sizeofStackMinimumReserved (s, stack)));
           /* It's possible that new > stack->reserved if the stack
@@ -180,7 +180,7 @@
   cardStart = oldGenStart;
 checkAll:
   assert (cardIndex <= maxCardIndex);
-  assert (isAlignedFrontier (s, objectStart));
+  assert (isFrontierAligned (s, objectStart));
   if (cardIndex == maxCardIndex)
     goto done;
 checkCard:
@@ -198,7 +198,7 @@
                cardIndex, (uintptr_t)objectStart);
     lastObject = objectStart;
 skipObjects:
-    assert (isAlignedFrontier (s, objectStart));
+    assert (isFrontierAligned (s, objectStart));
     size = sizeofObject (s, advanceToObjectData (s, objectStart));
     if (objectStart + size < cardStart) {
       objectStart += size;

Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/gc_state.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/gc_state.c	2005-11-05 00:04:36 UTC (rev 4160)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/gc_state.c	2005-11-06 17:12:54 UTC (rev 4161)
@@ -55,7 +55,7 @@
              /*uintToCommaString*/(oldGenBytesRequested),
              /*uintToCommaString*/(nurseryBytesRequested));
   h = &s->heap;
-  assert (isAlignedFrontier (s, h->start + h->oldGenSize + oldGenBytesRequested));
+  assert (isFrontierAligned (s, h->start + h->oldGenSize + oldGenBytesRequested));
   nurserySize = h->size - h->oldGenSize - oldGenBytesRequested;
   s->limitPlusSlop = h->start + h->size;
   s->limit = s->limitPlusSlop - GC_HEAP_LIMIT_SLOP;
@@ -106,6 +106,6 @@
   s->heap.nursery = alignFrontier (s, s->limitPlusSlop - nurserySize);
   s->frontier = s->heap.nursery;
   assert (nurseryBytesRequested <= (size_t)(s->limitPlusSlop - s->frontier));
-  assert (isAlignedFrontier (s, s->heap.nursery));
+  assert (isFrontierAligned (s, s->heap.nursery));
   assert (hasHeapBytesFree (s, oldGenBytesRequested, nurseryBytesRequested));
 }

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-11-05 00:04:36 UTC (rev 4160)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/gc_state.h	2005-11-06 17:12:54 UTC (rev 4161)
@@ -11,9 +11,10 @@
   bool amInGC;
   bool amOriginal;
   char **atMLtons; /* Initial @MLton args, processed before command line. */
-  int32_t atMLtonsLength;
+  uint32_t atMLtonsLength;
   uint32_t atomicState;
   objptr callFromCHandlerThread; /* Handler for exported C calls (in heap). */
+  struct GC_callStackState callStackState;
   bool canMinor; /* TRUE iff there is space for a minor gc. */
   struct GC_controls controls;
   struct GC_cumulativeStatistics cumulativeStatistics;
@@ -49,6 +50,7 @@
   struct GC_heap secondaryHeap; /* Used for major copying collection. */
   objptr signalHandlerThread; /* Handler for signals (in heap). */
   struct GC_signalsInfo signalsInfo;
+  struct GC_sourceMaps sourceMaps;
   pointer stackBottom; /* Bottom of stack in current thread. */
   pointer stackLimit; /* stackBottom + stackSize - maxFrameSize */
   pointer stackTop; /* Top of stack in current thread. */

Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/init-world.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/init-world.c	2005-11-05 00:04:36 UTC (rev 4160)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/init-world.c	2005-11-06 17:12:54 UTC (rev 4161)
@@ -49,7 +49,7 @@
   GC_intInf bp;
   unsigned char *cp;
 
-  assert (isAlignedFrontier (s, s->frontier));
+  assert (isFrontierAligned (s, s->frontier));
   frontier = s->frontier;
   for (i= 0; i < s->intInfInitsLength; i++) {
     inits = &s->intInfInits[i];
@@ -111,7 +111,7 @@
     bp->isneg = neg;
     frontier = alignFrontier (s, (pointer)&bp->limbs[alen]);
   }
-  assert (isAlignedFrontier (s, frontier));
+  assert (isFrontierAligned (s, frontier));
   GC_profileAllocInc (s, (size_t)(frontier - s->frontier));
   s->frontier = frontier;
   s->cumulativeStatistics.bytesAllocated += frontier - s->frontier;
@@ -122,7 +122,7 @@
   pointer frontier;
   uint32_t i;
 
-  assert (isAlignedFrontier (s, s->frontier));
+  assert (isFrontierAligned (s, s->frontier));
   inits = s->vectorInits;
   frontier = s->frontier;
   for (i = 0; i < s->vectorInitsLength; i++) {
@@ -171,7 +171,7 @@
              (uintptr_t)frontier);
   GC_profileAllocInc (s, (size_t)(frontier - s->frontier));
   s->cumulativeStatistics.bytesAllocated += (size_t)(frontier - s->frontier);
-  assert (isAlignedFrontier (s, frontier));
+  assert (isFrontierAligned (s, frontier));
   s->frontier = frontier;
 }
 

Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/init.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/init.c	2005-11-05 00:04:36 UTC (rev 4160)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/init.c	2005-11-06 17:12:54 UTC (rev 4161)
@@ -184,8 +184,8 @@
           if (i == argc)
             die ("@MLton ram-slop missing argument.");
           s->controls.ratios.ramSlop = stringToFloat (argv[i++]);
-        } else if (0 == strcmp (arg, "show-prof")) {
-          showProf (s);
+        } else if (0 == strcmp (arg, "show-sources")) {
+          showSources (s);
           exit (0);
         } else if (0 == strcmp (arg, "stop")) {
           i++;
@@ -308,21 +308,24 @@
     fprintf (stderr, "total RAM = %zu  RAM = %zu\n",
              /*uintToCommaString*/(s->sysvals.totalRam),
              /*uintToCommaString*/(s->sysvals.ram));
-  if (DEBUG_PROFILE) {
+  if (DEBUG_SOURCES or DEBUG_PROFILE) {
     uint32_t i;
-    for (i = 0; i < s->profiling.frameSourcesLength; i++) {
+    for (i = 0; i < s->sourceMaps.frameSourcesLength; i++) {
       uint32_t j;
       uint32_t *sourceSeq;
       fprintf (stderr, "%"PRIu32"\n", i);
-      sourceSeq = s->profiling.sourceSeqs[s->profiling.frameSources[i]];
+      sourceSeq = s->sourceMaps.sourceSeqs[s->sourceMaps.frameSources[i]];
       for (j = 1; j <= sourceSeq[0]; j++)
         fprintf (stderr, "\t%s\n",
-                 s->profiling.sourceNames[s->profiling.sources[sourceSeq[j]].nameIndex]);
+                 s->sourceMaps.sourceNames[
+                 s->sourceMaps.sources[sourceSeq[j]].sourceNameIndex
+                 ]);
     }
   }
   /* Initialize profiling.  This must occur after processing
-   * command-line arguments, because those may just be doing a show
-   * prof, in which case we don't want to initialize the atExit.
+   * command-line arguments, because those may just be doing a
+   * show-sources, in which case we don't want to initialize the
+   * atExit.
    */
   initProfiling (s);
   if (s->amOriginal) {
@@ -334,7 +337,7 @@
   } else {
     loadWorldFromFileName (s, worldFile);
     if (s->profiling.isOn and s->profiling.stack)
-      foreachStackFrame (s, enterFrame);
+      foreachStackFrame (s, enterFrameForProfiling);
     assert (invariantForMutator (s, TRUE, TRUE));
   }
   s->amInGC = FALSE;

Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/invariant.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/invariant.c	2005-11-05 00:04:36 UTC (rev 4160)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/invariant.c	2005-11-06 17:12:54 UTC (rev 4161)
@@ -41,9 +41,9 @@
   }
   assert (isAligned (s->heap.size, s->sysvals.pageSize));
   assert (isAligned ((size_t)s->heap.start, CARD_SIZE));
-  assert (isAlignedFrontier (s, s->heap.start + s->heap.oldGenSize));
-  assert (isAlignedFrontier (s, s->heap.nursery));
-  assert (isAlignedFrontier (s, s->frontier));
+  assert (isFrontierAligned (s, s->heap.start + s->heap.oldGenSize));
+  assert (isFrontierAligned (s, s->heap.nursery));
+  assert (isFrontierAligned (s, s->frontier));
   assert (s->heap.nursery <= s->frontier);
   unless (0 == s->heap.size) {
     assert (s->heap.nursery <= s->frontier);
@@ -66,7 +66,7 @@
                         assertIsObjptrInFromSpace, FALSE);
   /* Current thread. */
   GC_stack stack = getStackCurrent(s);
-  assert (isAlignedStackReserved (s, stack->reserved));
+  assert (isStackReservedAligned (s, stack->reserved));
   assert (s->stackBottom == getStackBottom (s, stack));
   assert (s->stackTop == getStackTop (s, stack));
   assert (s->stackLimit == getStackLimit (s, stack));

Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/object.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/object.c	2005-11-05 00:04:36 UTC (rev 4160)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/object.c	2005-11-06 17:12:54 UTC (rev 4161)
@@ -86,6 +86,17 @@
     *numObjptrsRet = numObjptrs;
 }
 
+pointer alignFrontier (GC_state s, pointer p) {
+  size_t res;
+
+  res = pad (s, (size_t)p, GC_NORMAL_HEADER_SIZE);
+  if (DEBUG_STACKS)
+    fprintf (stderr, FMTPTR" = alignFrontier ("FMTPTR")\n", 
+             (uintptr_t)p, (uintptr_t)res);
+  assert (isFrontierAligned (s, (pointer)res));
+  return (pointer)res;
+}
+
 /* advanceToObjectData (s, p)
  *
  * If p points at the beginning of an object, then advanceToObjectData
@@ -95,7 +106,7 @@
   GC_header header;
   pointer res;
 
-  assert (isAlignedFrontier (s, p));
+  assert (isFrontierAligned (s, p));
   header = *(GC_header*)p;
   if (0 == header)
     /* Looking at the counter word in an array. */

Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/object.h
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/object.h	2005-11-05 00:04:36 UTC (rev 4160)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/object.h	2005-11-06 17:12:54 UTC (rev 4161)
@@ -120,4 +120,9 @@
 void splitHeader (GC_state s, GC_header header,
                   GC_objectTypeTag *tagRet, bool *hasIdentityRet,
                   uint16_t *numNonObjptrsRet, uint16_t *numObjptrsRet);
+
+bool isFrontierAligned (GC_state s, pointer p);
+pointer alignFrontier (GC_state s, pointer p);
+
 pointer advanceToObjectData (GC_state s, pointer p);
+

Added: mlton/branches/on-20050822-x86_64-branch/runtime/gc/object_predicates.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/object_predicates.c	2005-11-05 00:04:36 UTC (rev 4160)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/object_predicates.c	2005-11-06 17:12:54 UTC (rev 4161)
@@ -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.
+ */
+
+#if ASSERT
+bool isFrontierAligned (GC_state s, pointer p) {
+  return isAligned ((size_t)p + GC_NORMAL_HEADER_SIZE, 
+                    s->alignment);
+}
+#endif
+

Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/profiling.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/profiling.c	2005-11-05 00:04:36 UTC (rev 4160)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/profiling.c	2005-11-06 17:12:54 UTC (rev 4161)
@@ -6,140 +6,54 @@
  * See the file MLton-LICENSE for details.
  */
 
-#define SOURCES_INDEX_UNKNOWN 0
-#define SOURCES_INDEX_GC      1
-#define SOURCE_SEQ_GC         1
-#define SOURCE_SEQ_UNKNOWN    0
-
-static uint32_t numStackFrames;
-static uint32_t *callStack;
-
-static void fillCallStack (__attribute__ ((unused))GC_state s, 
-                           GC_frameIndex i) {
-  if (DEBUG_CALL_STACK)
-    fprintf (stderr, "fillCallStack ("FMTFI")\n", i);
-  callStack[numStackFrames] = i;
-  numStackFrames++;
+GC_profileMasterIndex sourceIndexToProfileMasterIndex (GC_state s, 
+                                                       GC_sourceIndex i) {
+  return s->sourceMaps.sources[i].sourceNameIndex + s->sourceMaps.sourcesLength;
 }
 
-void GC_callStack (GC_state s, pointer p) {
-  if (DEBUG_CALL_STACK)
-    fprintf (stderr, "GC_callStack\n");
-  numStackFrames = 0;
-  callStack = (uint32_t*)p;
-  foreachStackFrame (s, fillCallStack);
+GC_sourceNameIndex profileMasterIndexToSourceNameIndex (GC_state s, 
+                                                        GC_profileMasterIndex i) {
+  assert (i >= s->sourceMaps.sourcesLength);
+  return i - s->sourceMaps.sourcesLength;
 }
 
-static void incNumStackFrames (__attribute__ ((unused)) GC_state s, 
-                               __attribute__ ((unused)) GC_frameIndex i) {
-  numStackFrames++;
+GC_profileStack getProfileStackInfo (GC_state s, GC_profileMasterIndex i) {
+  assert (s->profiling.data != NULL);
+  return &(s->profiling.data->stack[i]);
 }
 
-uint32_t GC_numStackFrames (GC_state s) {
-  numStackFrames = 0;
-  foreachStackFrame (s, incNumStackFrames);
-  if (DEBUG_CALL_STACK)
-    fprintf (stderr, "%"PRIu32" = GC_numStackFrames\n", numStackFrames);
-  return numStackFrames;
-}
 
-static inline uint32_t topFrameSourceSeqIndex (GC_state s, GC_stack stack) {
-  return s->profiling.frameSources[getStackTopFrameIndex (s, stack)];
-}
+static int profileDepth = 0;
 
-uint32_t* GC_frameIndexSourceSeq (GC_state s, GC_frameIndex frameIndex) {
-  uint32_t *res;
-
-  res = s->profiling.sourceSeqs[s->profiling.frameSources[frameIndex]];
-  if (DEBUG_CALL_STACK)
-    fprintf (stderr, FMTPTR" = GC_frameIndexSourceSeq ("FMTFI")\n",
-             (uintptr_t)res, frameIndex);
-  return res;
+static void profileIndent (void) {
+  int i;
+  
+  for (i = 0; i < profileDepth; ++i)
+    fprintf (stderr, " ");
 }
 
-inline char* GC_sourceName (GC_state s, uint32_t i) {
-  if (i < s->profiling.sourcesLength)
-    return s->profiling.sourceNames[s->profiling.sources[i].nameIndex];
-  else
-    return s->profiling.sourceNames[i - s->profiling.sourcesLength];
-}
 
-static inline GC_profileStack profileStackInfo (GC_state s, uint32_t i) {
-  assert (s->profiling.data != NULL);
-  return &(s->profiling.data->stack[i]);
-}
-
-static inline uint32_t profileMaster (GC_state s, uint32_t i) {
-  return s->profiling.sources[i].nameIndex + s->profiling.sourcesLength;
-}
-
-static inline void removeFromStack (GC_state s, uint32_t i) {
+void addToStackForProfiling (GC_state s, GC_profileMasterIndex i) {
   GC_profileData p;
   GC_profileStack ps;
-  uintmax_t totalInc;
 
   p = s->profiling.data;
-  ps = profileStackInfo (s, i);
-  totalInc = p->total - ps->lastTotal;
+  ps = getProfileStackInfo (s, i);
   if (DEBUG_PROFILE)
-    fprintf (stderr, "removing %s from stack  ticksInc = %"PRIuMAX"  ticksInGCInc = %"PRIuMAX"\n",
-             GC_sourceName (s, i), totalInc,
-             p->totalGC - ps->lastTotalGC);
-  ps->ticks += totalInc;
-  ps->ticksInGC += p->totalGC - ps->lastTotalGC;
+    fprintf (stderr, "adding %s to stack  lastTotal = %"PRIuMAX"  lastTotalGC = %"PRIuMAX"\n",
+             GC_sourceName (s, i), 
+             p->total,
+             p->totalGC);
+  ps->lastTotal = p->total;
+  ps->lastTotalGC = p->totalGC;
 }
 
-static void setProfTimer (long usec) {
-  struct itimerval iv;
-  
-  iv.it_interval.tv_sec = 0;
-  iv.it_interval.tv_usec = usec;
-  iv.it_value.tv_sec = 0;
-  iv.it_value.tv_usec = usec;
-  unless (0 == setitimer (ITIMER_PROF, &iv, NULL))
-    die ("setProfTimer failed");
-}
-
-void GC_profileDone (GC_state s) {
+void enterSourceForProfiling (GC_state s, GC_profileMasterIndex i) {
   GC_profileData p;
-  uint32_t sourceIndex;
-
-  if (DEBUG_PROFILE)
-    fprintf (stderr, "GC_profileDone ()\n");
-  assert (s->profiling.isOn);
-  if (PROFILE_TIME == s->profiling.kind)
-    setProfTimer (0);
-  s->profiling.isOn = FALSE;
-  p = s->profiling.data;
-  if (s->profiling.stack) {
-    for (sourceIndex = 0;
-         sourceIndex < s->profiling.sourcesLength + s->profiling.sourceNamesLength;
-         sourceIndex++) {
-      if (p->stack[sourceIndex].numOccurrences > 0) {
-        if (DEBUG_PROFILE)
-          fprintf (stderr, "done leaving %s\n",
-                   GC_sourceName (s, sourceIndex));
-        removeFromStack (s, sourceIndex);
-      }
-    }
-  }
-}
-
-static int profileDepth = 0;
-
-static void profileIndent (void) {
-  int i;
-
-  for (i = 0; i < profileDepth; ++i)
-    fprintf (stderr, " ");
-}
-
-static inline void profileEnterSource (GC_state s, uint32_t i) {
-  GC_profileData p;
   GC_profileStack ps;
   
   p = s->profiling.data;
-  ps = profileStackInfo (s, i);
+  ps = getProfileStackInfo (s, i);
   if (0 == ps->numOccurrences) {
     ps->lastTotal = p->total;
     ps->lastTotalGC = p->totalGC;
@@ -147,18 +61,18 @@
   ps->numOccurrences++;
 }
 
-static void profileEnter (GC_state s, uint32_t sourceSeqIndex) {
+void enterForProfiling (GC_state s, GC_sourceSeqIndex sourceSeqIndex) {
   uint32_t i;
   GC_profileData p;
-  uint32_t sourceIndex;
+  GC_sourceIndex sourceIndex;
   uint32_t *sourceSeq;
 
   if (DEBUG_PROFILE)
-    fprintf (stderr, "profileEnter (%"PRIu32")\n", sourceSeqIndex);
+    fprintf (stderr, "enterForProfiling ("FMTSSI")\n", sourceSeqIndex);
   assert (s->profiling.stack);
-  assert (sourceSeqIndex < s->profiling.sourceSeqsLength);
+  assert (sourceSeqIndex < s->sourceMaps.sourceSeqsLength);
   p = s->profiling.data;
-  sourceSeq = s->profiling.sourceSeqs[sourceSeqIndex];
+  sourceSeq = s->sourceMaps.sourceSeqs[sourceSeqIndex];
   for (i = 1; i <= sourceSeq[0]; i++) {
     sourceIndex = sourceSeq[i];
     if (DEBUG_ENTER_LEAVE or DEBUG_PROFILE) {
@@ -167,41 +81,58 @@
                GC_sourceName (s, sourceIndex));
       profileDepth++;
     }
-    profileEnterSource (s, sourceIndex);
-    profileEnterSource (s, profileMaster (s, sourceIndex));
+    enterSourceForProfiling (s, (GC_profileMasterIndex)sourceIndex);
+    enterSourceForProfiling (s, sourceIndexToProfileMasterIndex (s, sourceIndex));
   }
 }
 
-static void enterFrame (GC_state s, uint32_t i) {
-  profileEnter (s, s->profiling.frameSources[i]);
+void enterFrameForProfiling (GC_state s, GC_frameIndex i) {
+  enterForProfiling (s, s->sourceMaps.frameSources[i]);
 }
 
-static inline void profileLeaveSource (GC_state s, uint32_t i) {
+void GC_profileEnter (GC_state s) {
+  enterForProfiling (s, getStackTopFrameSourceSeqIndex (s, getStackCurrent (s)));
+}
+
+void removeFromStackForProfiling (GC_state s, GC_profileMasterIndex i) {
   GC_profileData p;
   GC_profileStack ps;
 
+  p = s->profiling.data;
+  ps = getProfileStackInfo (s, i);
   if (DEBUG_PROFILE)
-    fprintf (stderr, "profileLeaveSource (%"PRIu32")\n", i);
+    fprintf (stderr, "removing %s from stack  ticksInc = %"PRIuMAX"  ticksGCInc = %"PRIuMAX"\n",
+             GC_sourceName (s, i), 
+             p->total - ps->lastTotal,
+             p->totalGC - ps->lastTotalGC);
+  ps->ticks += p->total - ps->lastTotal;
+  ps->ticksGC += p->totalGC - ps->lastTotalGC;
+}
+
+void leaveSourceForProfiling (GC_state s, GC_profileMasterIndex i) {
+  GC_profileData p;
+  GC_profileStack ps;
+
   p = s->profiling.data;
-  ps = profileStackInfo (s, i);
+  ps = getProfileStackInfo (s, i);
   assert (ps->numOccurrences > 0);
   ps->numOccurrences--;
   if (0 == ps->numOccurrences)
-    removeFromStack (s, i);
+    removeFromStackForProfiling (s, i);
 }
 
-static void profileLeave (GC_state s, uint32_t sourceSeqIndex) {
+void leaveForProfiling (GC_state s, GC_sourceSeqIndex sourceSeqIndex) {
   int32_t i;
   GC_profileData p;
-  uint32_t sourceIndex;
+  GC_sourceIndex sourceIndex;
   uint32_t *sourceSeq;
 
   if (DEBUG_PROFILE)
-    fprintf (stderr, "profileLeave (%"PRIu32")\n", sourceSeqIndex);
+    fprintf (stderr, "profileLeave ("FMTSSI")\n", sourceSeqIndex);
   assert (s->profiling.stack);
-  assert (sourceSeqIndex < s->profiling.sourceSeqsLength);
+  assert (sourceSeqIndex < s->sourceMaps.sourceSeqsLength);
   p = s->profiling.data;
-  sourceSeq = s->profiling.sourceSeqs[sourceSeqIndex];
+  sourceSeq = s->sourceMaps.sourceSeqs[sourceSeqIndex];
   for (i = sourceSeq[0]; i > 0; i--) {
     sourceIndex = sourceSeq[i];
     if (DEBUG_ENTER_LEAVE or DEBUG_PROFILE) {
@@ -210,100 +141,81 @@
       fprintf (stderr, "leaving %s)\n",
                GC_sourceName (s, sourceIndex));
     }
-    profileLeaveSource (s, sourceIndex);
-    profileLeaveSource (s, profileMaster (s, sourceIndex));
+    leaveSourceForProfiling (s, (GC_profileMasterIndex)sourceIndex);
+    leaveSourceForProfiling (s, sourceIndexToProfileMasterIndex (s, sourceIndex));
   }
 }
 
-static inline void profileInc (GC_state s, size_t amount, uint32_t sourceSeqIndex) {
+void leaveFrameForProfiling (GC_state s, GC_frameIndex i) {
+  leaveForProfiling (s, s->sourceMaps.frameSources[i]);
+}
+
+void GC_profileLeave (GC_state s) {
+  leaveForProfiling (s, getStackTopFrameSourceSeqIndex (s, getStackCurrent (s)));
+}
+
+
+void profileInc (GC_state s, size_t amount, GC_sourceSeqIndex sourceSeqIndex) {
   uint32_t *sourceSeq;
-  uint32_t topSourceIndex;
+  GC_sourceIndex topSourceIndex;
 
   if (DEBUG_PROFILE)
-    fprintf (stderr, "profileInc (%zu, %"PRIu32")\n",
+    fprintf (stderr, "profileInc (%zu, "FMTSSI")\n",
              amount, sourceSeqIndex);
-  assert (sourceSeqIndex < s->profiling.sourceSeqsLength);
-  sourceSeq = s->profiling.sourceSeqs[sourceSeqIndex];
-  topSourceIndex = sourceSeq[0] > 0 ? sourceSeq[sourceSeq[0]] : SOURCES_INDEX_UNKNOWN;
+  assert (sourceSeqIndex < s->sourceMaps.sourceSeqsLength);
+  sourceSeq = s->sourceMaps.sourceSeqs[sourceSeqIndex];
+  topSourceIndex = 
+    sourceSeq[0] > 0 
+    ? sourceSeq[sourceSeq[0]] 
+    : SOURCES_INDEX_UNKNOWN;
   if (DEBUG_PROFILE) {
     profileIndent ();
     fprintf (stderr, "bumping %s by %zu\n",
              GC_sourceName (s, topSourceIndex), amount);
   }
   s->profiling.data->countTop[topSourceIndex] += amount;
-  s->profiling.data->countTop[profileMaster (s, topSourceIndex)] += amount;
+  s->profiling.data->countTop[sourceIndexToProfileMasterIndex (s, topSourceIndex)] += amount;
   if (s->profiling.stack)
-    profileEnter (s, sourceSeqIndex);
+    enterForProfiling (s, sourceSeqIndex);
   if (SOURCES_INDEX_GC == topSourceIndex)
     s->profiling.data->totalGC += amount;
   else
     s->profiling.data->total += amount;
   if (s->profiling.stack)
-    profileLeave (s, sourceSeqIndex);
+    leaveForProfiling (s, sourceSeqIndex);
 }
 
-void GC_profileEnter (GC_state s) {
-  profileEnter (s, topFrameSourceSeqIndex (s, getStackCurrent (s)));
-}
-
-void GC_profileLeave (GC_state s) {
-  profileLeave (s, topFrameSourceSeqIndex (s, getStackCurrent (s)));
-}
-
 void GC_profileInc (GC_state s, size_t amount) {
   if (DEBUG_PROFILE)
     fprintf (stderr, "GC_profileInc (%zu)\n", amount);
   profileInc (s, amount,
-              s->amInGC 
-              ? SOURCE_SEQ_GC 
-              : topFrameSourceSeqIndex (s, getStackCurrent (s)));
+              s->amInGC
+              ? SOURCE_SEQ_GC
+              : getStackTopFrameSourceSeqIndex (s, getStackCurrent (s)));
 }
 
 void GC_profileAllocInc (GC_state s, size_t amount) {
   if (s->profiling.isOn and (PROFILE_ALLOC == s->profiling.kind)) {
     if (DEBUG_PROFILE)
-      fprintf (stderr, "GC_profileAllocInc (%u)\n", (uint)amount);
+      fprintf (stderr, "GC_profileAllocInc (%zu)\n", amount);
     GC_profileInc (s, amount);
   }
 }
 
-static void showProf (GC_state s) {
-  uint32_t i;
-  uint32_t j;
-  
-  fprintf (stdout, "0x%08"PRIx32"\n", s->magic);
-  fprintf (stdout, "%"PRIu32"\n", s->profiling.sourceNamesLength);
-  for (i = 0; i < s->profiling.sourceNamesLength; i++)
-    fprintf (stdout, "%s\n", s->profiling.sourceNames[i]);
-  fprintf (stdout, "%"PRIu32"\n", s->profiling.sourcesLength);
-  for (i = 0; i < s->profiling.sourcesLength; i++)
-    fprintf (stdout, "%"PRIu32" %"PRIu32"\n",
-             s->profiling.sources[i].nameIndex,
-             s->profiling.sources[i].successorsIndex);
-  fprintf (stdout, "%"PRIu32"\n", s->profiling.sourceSeqsLength);
-  for (i = 0; i < s->profiling.sourceSeqsLength; i++) {
-    uint32_t *sourceSeq;
-    
-    sourceSeq = s->profiling.sourceSeqs[i];
-    for (j = 1; j <= sourceSeq[0]; j++)
-      fprintf (stdout, "%"PRIu32" ", sourceSeq[j]);
-    fprintf (stdout, "\n");
-  }
-}
 
 GC_profileData GC_profileNew (GC_state s) {
   GC_profileData p;
-  uint32_t size;
+  uint32_t profileMasterLength;
 
   p = (GC_profileData)(malloc_safe (sizeof(*p)));
   p->total = 0;
   p->totalGC = 0;
-  size = s->profiling.sourcesLength + s->profiling.sourceNamesLength;
-  p->countTop = (uintmax_t*)(calloc_safe(size, sizeof(*(p->countTop))));
+  profileMasterLength = s->sourceMaps.sourcesLength + s->sourceMaps.sourceNamesLength;
+  p->countTop = (uintmax_t*)(calloc_safe(profileMasterLength, sizeof(*(p->countTop))));
   if (s->profiling.stack)
-    p->stack = 
+    p->stack =
       (struct GC_profileStack *)
-      (calloc_safe(size, sizeof(*(p->stack))));
+      (calloc_safe(profileMasterLength, sizeof(*(p->stack))));
   if (DEBUG_PROFILE)
     fprintf (stderr, FMTPTR" = GC_profileNew ()\n", (uintptr_t)p);
   return p;
@@ -316,7 +228,8 @@
   free (p);
 }
 
-static void profileWriteCount (GC_state s, GC_profileData p, int fd, uint32_t i) {
+static void writeProfileCount (GC_state s, int fd,
+                               GC_profileData p, GC_profileMasterIndex i) {
   writeUintmaxU (fd, p->countTop[i]);
   if (s->profiling.stack) {
     GC_profileStack ps;
@@ -325,13 +238,12 @@
     writeString (fd, " ");
     writeUintmaxU (fd, ps->ticks);
     writeString (fd, " ");
-    writeUintmaxU (fd, ps->ticksInGC);
+    writeUintmaxU (fd, ps->ticksGC);
   }
   writeNewline (fd);
 }
 
 void GC_profileWrite (GC_state s, GC_profileData p, int fd) {
-  uint32_t i;
   char* kind;
 
   if (DEBUG_PROFILE)
@@ -360,37 +272,51 @@
   writeString (fd, " ");
   writeUintmaxU (fd, p->totalGC);
   writeNewline (fd);
-  writeUint32U (fd, s->profiling.sourcesLength);
+  writeUint32U (fd, s->sourceMaps.sourcesLength);
   writeNewline (fd);
-  for (i = 0; i < s->profiling.sourcesLength; i++)
-    profileWriteCount (s, p, fd, i);
-  writeUint32U (fd, s->profiling.sourceNamesLength);
+  for (GC_sourceIndex i = 0; i < s->sourceMaps.sourcesLength; i++)
+    writeProfileCount (s, fd, p, 
+                       (GC_profileMasterIndex)i);
+  writeUint32U (fd, s->sourceMaps.sourceNamesLength);
   writeNewline (fd);
-  for (i = 0; i < s->profiling.sourceNamesLength; i++)
-    profileWriteCount (s, p, fd, i + s->profiling.sourcesLength);
+  for (GC_sourceNameIndex i = 0; i < s->sourceMaps.sourceNamesLength; i++)
+    writeProfileCount (s, fd, p,  
+                       (GC_profileMasterIndex)(i + s->sourceMaps.sourcesLength));
 }
 
+
+void setProfTimer (long usec) {
+  struct itimerval iv;
+  
+  iv.it_interval.tv_sec = 0;
+  iv.it_interval.tv_usec = usec;
+  iv.it_value.tv_sec = 0;
+  iv.it_value.tv_usec = usec;
+  unless (0 == setitimer (ITIMER_PROF, &iv, NULL))
+    die ("setProfTimer: setitimer failed");
+}
+
 #if not HAS_TIME_PROFILING
 
 /* No time profiling on this platform.  There is a check in
  * mlton/main/main.fun to make sure that time profiling is never
  * turned on.
  */
-static void profileTimeInit (GC_state s) __attribute__ ((noreturn));
-static void profileTimeInit (GC_state s) {
+void initProfilingTime (GC_state s) __attribute__ ((noreturn));
+void initProfilingTime (__attribute__ ((unused)) GC_state s) {
   die ("no time profiling");
 }
 
 #else
 
-static GC_state catcherState;
+static GC_state handleSigProfState;
 
 void GC_handleSigProf (pointer pc) {
   GC_frameIndex frameIndex;
   GC_state s;
-  uint32_t sourceSeqIndex;
+  GC_sourceSeqIndex sourceSeqIndex;
 
-  s = catcherState;
+  s = handleSigProfState;
   if (DEBUG_PROFILE)
     fprintf (stderr, "GC_handleSigProf ("FMTPTR")\n", (uintptr_t)pc);
   if (s->amInGC)
@@ -398,10 +324,10 @@
   else {
     frameIndex = getStackTopFrameIndex (s, getStackCurrent (s));
     if (C_FRAME == s->frameLayouts[frameIndex].kind)
-      sourceSeqIndex = s->profiling.frameSources[frameIndex];
+      sourceSeqIndex = s->sourceMaps.frameSources[frameIndex];
     else {
-      if (s->profiling.textStart <= pc and pc < s->profiling.textEnd)
-        sourceSeqIndex = s->profiling.textSources [pc - s->profiling.textStart];
+      if (s->sourceMaps.textStart <= pc and pc < s->sourceMaps.textEnd)
+        sourceSeqIndex = s->sourceMaps.textSources [pc - s->sourceMaps.textStart];
       else {
         if (DEBUG_PROFILE)
           fprintf (stderr, "pc out of bounds\n");
@@ -412,69 +338,12 @@
   profileInc (s, 1, sourceSeqIndex);
 }
 
-static int compareSourceLabels (const void *v1, const void *v2) {
-  uintptr_t ui1;
-  uintptr_t ui2;
-
-  ui1 = (uintptr_t)v1;
-  ui2 = (uintptr_t)v2;
-
-  if (ui1 < ui2)
-    return -1;
-  else if (ui1 == ui2)
-    return 0;
-  else /* if (ui1 > ui2) */
-    return 1;
-}
-
-static void profileTimeInit (GC_state s) {
-  uint32_t i;
-  pointer p;
+static void initProfilingTime (GC_state s) {
   struct sigaction sa;
   uint32_t sourceSeqsIndex;
 
   s->profiling.data = GC_profileNew (s);
-  /* Sort sourceLabels by address. */
-  qsort (s->profiling.sourceLabels, 
-         s->profiling.sourceLabelsLength, 
-         sizeof (*s->profiling.sourceLabels),
-         compareSourceLabels);
-  if (0 == s->profiling.sourceLabels[s->profiling.sourceLabelsLength - 1].label)
-    die ("Max profile label is 0 -- something is wrong.");
-  if (DEBUG_PROFILE)
-    for (i = 0; i < s->profiling.sourceLabelsLength; i++)
-      fprintf (stderr, FMTPTR"  %"PRIu32"\n",
-               (uintptr_t)s->profiling.sourceLabels[i].label,
-               s->profiling.sourceLabels[i].sourceSeqsIndex);
-  if (ASSERT)
-    for (i = 1; i < s->profiling.sourceLabelsLength; i++)
-      assert (s->profiling.sourceLabels[i-1].label
-              <= s->profiling.sourceLabels[i].label);
-  /* Initialize s->textSources. */
-  s->profiling.textEnd = (pointer)(getTextEnd());
-  s->profiling.textStart = (pointer)(getTextStart());
-  if (ASSERT)
-    for (i = 0; i < s->profiling.sourceLabelsLength; i++) {
-      pointer label;
-
-      label = s->profiling.sourceLabels[i].label;
-      assert (0 == label
-              or (s->profiling.textStart <= label
-                  and label < s->profiling.textEnd));
-    }
-  s->profiling.textSources =
-    (uint32_t*)
-    (calloc_safe((size_t)(s->profiling.textEnd - s->profiling.textStart), 
-                 sizeof(*(s->profiling.textSources))));
-  p = s->profiling.textStart;
-  sourceSeqsIndex = SOURCE_SEQ_UNKNOWN;
-  for (i = 0; i < s->profiling.sourceLabelsLength; i++) {
-    for ( ; p < s->profiling.sourceLabels[i].label; p++)
-      s->profiling.textSources[p - s->profiling.textStart] = sourceSeqsIndex;
-    sourceSeqsIndex = s->profiling.sourceLabels[i].sourceSeqsIndex;
-  }
-  for ( ; p < s->profiling.textEnd; p++)
-    s->profiling.textSources[p - s->profiling.textStart] = sourceSeqsIndex;
+  initTextSources (s);
   /*
    * Install catcher, which handles SIGPROF and calls MLton_Profile_inc.
    *
@@ -488,31 +357,31 @@
    * in order to have profiling cover as much as possible, you want it
    * to occur right after the sigaltstack() call.
    */
-  catcherState = s;
+  handleSigProfState = s;
   sigemptyset (&sa.sa_mask);
   setSigProfHandler (&sa);
   unless (sigaction (SIGPROF, &sa, NULL) == 0)
-    diee ("sigaction() failed");
+    diee ("initProfilingTime: sigaction failed");
   /* Start the SIGPROF timer. */
   setProfTimer (10000);
 }
 
 #endif
 
-/* profileEnd is for writing out an mlmon.out file even if the C code
+/* atexitForProfiling is for writing out an mlmon.out file even if the C code
  * terminates abnormally, e.g. due to running out of memory.  It will
  * only run if the usual SML profile atExit cleanup code did not
  * manage to run.
  */
-static GC_state profileEndState;
+static GC_state atexitForProfilingState;
 
-static void profileEnd (void) {
+static void atexitForProfiling (void) {
   int fd;
   GC_state s;
 
   if (DEBUG_PROFILE)
-    fprintf (stderr, "profileEnd ()\n");
-  s = profileEndState;
+    fprintf (stderr, "atexitForProfiling ()\n");
+  s = atexitForProfilingState;
   if (s->profiling.isOn) {
     fd = creat ("mlmon.out", 0666);
     if (fd < 0)
@@ -526,7 +395,7 @@
     s->profiling.isOn = FALSE;
   else {
     s->profiling.isOn = TRUE;
-    assert (s->profiling.frameSourcesLength == s->frameLayoutsLength);
+    assert (s->sourceMaps.frameSourcesLength == s->frameLayoutsLength);
     switch (s->profiling.kind) {
     case PROFILE_ALLOC:
     case PROFILE_COUNT:
@@ -535,10 +404,40 @@
     case PROFILE_NONE:
       die ("impossible PROFILE_NONE");
     case PROFILE_TIME:
-      profileTimeInit (s);
+      initProfilingTime (s);
       break;
     }
-    profileEndState = s;
-    atexit (profileEnd);
+    atexitForProfilingState = s;
+    atexit (atexitForProfiling);
   }
 }
+
+void GC_profileDone (GC_state s) {
+  GC_profileData p;
+  GC_profileMasterIndex profileMasterIndex;
+
+  if (DEBUG_PROFILE)
+    fprintf (stderr, "GC_profileDone ()\n");
+  assert (s->profiling.isOn);
+  if (PROFILE_TIME == s->profiling.kind)
+    setProfTimer (0);
+  s->profiling.isOn = FALSE;
+  p = s->profiling.data;
+  if (s->profiling.stack) {
+    uint32_t profileMasterLength = 
+      s->sourceMaps.sourcesLength + s->sourceMaps.sourceNamesLength;
+    for (profileMasterIndex = 0;
+         profileMasterIndex < profileMasterLength;
+         profileMasterIndex++) {
+      if (p->stack[profileMasterIndex].numOccurrences > 0) {
+        if (DEBUG_PROFILE)
+          fprintf (stderr, "done leaving %s\n",
+                   (profileMasterIndex < s->sourceMaps.sourcesLength)
+                   ? GC_sourceName (s, (GC_sourceIndex)profileMasterIndex)
+                   : s->sourceMaps.sourceNames[
+                     profileMasterIndexToSourceNameIndex (s, profileMasterIndex)]);
+        removeFromStackForProfiling (s, profileMasterIndex);
+      }
+    }
+  }
+}

Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/profiling.h
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/profiling.h	2005-11-05 00:04:36 UTC (rev 4160)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/profiling.h	2005-11-06 17:12:54 UTC (rev 4161)
@@ -13,24 +13,14 @@
   PROFILE_TIME,
 } GC_profileKind;
 
-typedef struct GC_source {
-  uint32_t nameIndex;
-  uint32_t successorsIndex;
-} *GC_source;
-
-typedef struct GC_sourceLabel {
-  pointer label;
-  uint32_t sourceSeqsIndex;
-} *GC_sourceLabel;
-
 /* If profileStack, then there is one struct GC_profileStack for each
  * function.
  */
 typedef struct GC_profileStack {
   /* ticks counts ticks while the function was on the stack. */
   uintmax_t ticks;
-  /* ticksInGC counts ticks in GC while the function was on the stack. */
-  uintmax_t ticksInGC; 
+  /* ticksGC counts ticks in GC while the function was on the stack. */
+  uintmax_t ticksGC; 
   /* lastTotal is the value of total when the oldest occurrence of f
    * on the stack was pushed, i.e., the most recent time that
    * numTimesOnStack changed from 0 to 1.  lastTotal is used to
@@ -46,11 +36,13 @@
   uintmax_t numOccurrences;
 } *GC_profileStack;
 
+typedef uint32_t GC_profileMasterIndex;
+
 /* GC_profileData is used for both time and allocation profiling.
  * In the comments below, "ticks" mean clock ticks with time profiling and
  * bytes allocated with allocation profiling.
  *
- * All of the arrays in GC_profileData are of length sourcesSize + sourceNamesSize.
+ * All of the arrays in GC_profileData are of length sourcesLength + sourceNamesLength.
  * The first sourceLength entries are for handling the duplicate copies of 
  * functions, and the next sourceNamesLength entries are for the master versions.
  */
@@ -71,45 +63,29 @@
 
 struct GC_profiling {
   GC_profileData data;
-  /* frameSources is an array of cardinality frameLayoutsLength that
-   * for each stack frame, gives an index into sourceSeqs of the
-   * sequence of source functions corresponding to the frame.
-   */
-  uint32_t *frameSources;
-  uint32_t frameSourcesLength;
   bool isOn;
   GC_profileKind kind;
-  struct GC_sourceLabel *sourceLabels;
-  uint32_t sourceLabelsLength;
-  char **sourceNames;
-  uint32_t sourceNamesLength;
-  /* Each entry in sourceSeqs is a vector, whose first element is a
-   * length, and subsequent elements index into sources.
-   */
-  uint32_t **sourceSeqs;
-  uint32_t sourceSeqsLength;
-  /* sources is an array of cardinality sourcesLength.  Each entry
-   * specifies an index into sourceNames and an index into sourceSeqs,
-   * giving the name of the function and the successors, respectively.
-   */
-  struct GC_source *sources;
-  uint32_t sourcesLength;
   bool stack;
-  pointer textEnd;
-  /* An array of indices, one entry for each address in the text
-   * segment, giving and index into sourceSeqs.
-   */
-  uint32_t *textSources;
-  pointer textStart;
 };
 
-static void showProf (GC_state s);
-void initProfiling (GC_state s);
-static void enterFrame (GC_state s, uint32_t i);
+void enterSourceForProfiling (GC_state s, GC_profileMasterIndex i);
+void enterForProfiling (GC_state s, GC_sourceSeqIndex sourceSeqIndex);
+void enterFrameForProfiling (GC_state s, GC_frameIndex i);
+void GC_profileEnter (GC_state s);
 
+void leaveSourceForProfiling (GC_state s, GC_profileMasterIndex i);
+void leaveForProfiling (GC_state s, GC_sourceSeqIndex sourceSeqIndex);
+void leaveFrameForProfiling (GC_state s, GC_frameIndex i);
+void GC_profileLeave (GC_state s);
 
-void GC_profileAllocInc (GC_state s, size_t bytes);
+void GC_profileInc (GC_state s, size_t amount);
+void GC_profileAllocInc (GC_state s, size_t amount);
 
-void GC_profileEnter (GC_state s);
+GC_profileData GC_profileNew (GC_state s);
+void GC_profileFree (GC_state s, GC_profileData p);
+void GC_profileWrite (GC_state s, GC_profileData p, int fd);
 
-void GC_profileLeave (GC_state s);
+void GC_handleSigProf (pointer pc);
+void initProfiling (GC_state s);
+void GC_profileDone (GC_state s);
+

Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/signals.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/signals.c	2005-11-05 00:04:36 UTC (rev 4160)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/signals.c	2005-11-06 17:12:54 UTC (rev 4161)
@@ -6,12 +6,14 @@
  * See the file MLton-LICENSE for details.
  */
 
-/* ---------------------------------------------------------------- */
-/*                          Initialization                          */
-/* ---------------------------------------------------------------- */
+#if not HAS_SIGALTSTACK
 
+void initSignalStack (__attribute__ ((unused)) GC_state s) {
+}
+
+#else
+
 void initSignalStack (GC_state s) {
-#if HAS_SIGALTSTACK
   static stack_t altstack;
   size_t ss_size = align (SIGSTKSZ, s->sysvals.pageSize);
   size_t psize = s->sysvals.pageSize;
@@ -20,5 +22,6 @@
   altstack.ss_size = ss_size;
   altstack.ss_flags = 0;
   sigaltstack (&altstack, NULL);
+}
+
 #endif
-}

Copied: mlton/branches/on-20050822-x86_64-branch/runtime/gc/sources.c (from rev 4158, mlton/branches/on-20050822-x86_64-branch/runtime/gc/profiling.c)
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/profiling.c	2005-11-04 22:09:10 UTC (rev 4158)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/sources.c	2005-11-06 17:12:54 UTC (rev 4161)
@@ -0,0 +1,110 @@
+/* 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_sourceSeqIndex getStackTopFrameSourceSeqIndex (GC_state s, GC_stack stack) {
+  return s->sourceMaps.frameSources[getStackTopFrameIndex (s, stack)];
+}
+
+char* GC_sourceName (GC_state s, GC_sourceIndex i) {
+  assert (i < s->sourceMaps.sourcesLength);
+  return s->sourceMaps.sourceNames[s->sourceMaps.sources[i].sourceNameIndex];
+}
+
+static int compareSourceLabels (const void *v1, const void *v2) {
+  uintptr_t ui1;
+  uintptr_t ui2;
+
+  ui1 = (uintptr_t)v1;
+  ui2 = (uintptr_t)v2;
+
+  if (ui1 < ui2)
+    return -1;
+  else if (ui1 == ui2)
+    return 0;
+  else /* if (ui1 > ui2) */
+    return 1;
+}
+
+void sortSourceLabels (GC_state s) {
+  GC_sourceLabelIndex i;
+
+  /* Sort sourceLabels by address. */
+  qsort (s->sourceMaps.sourceLabels, 
+         s->sourceMaps.sourceLabelsLength, 
+         sizeof (*s->sourceMaps.sourceLabels),
+         compareSourceLabels);
+  if (0 == s->sourceMaps.sourceLabels[s->sourceMaps.sourceLabelsLength - 1].label)
+    die ("Max profile label is 0 -- something is wrong.");
+  if (DEBUG_SOURCES)
+    for (i = 0; i < s->sourceMaps.sourceLabelsLength; i++)
+      fprintf (stderr, FMTPTR"  %"PRIu32"\n",
+               (uintptr_t)s->sourceMaps.sourceLabels[i].label,
+               s->sourceMaps.sourceLabels[i].sourceSeqIndex);
+  if (ASSERT)
+    for (i = 1; i < s->sourceMaps.sourceLabelsLength; i++)
+      assert (s->sourceMaps.sourceLabels[i-1].label
+              <= s->sourceMaps.sourceLabels[i].label);
+}
+
+void initTextSources (GC_state s) {
+  GC_sourceLabelIndex i;
+  pointer p;
+  GC_sourceSeqIndex sourceSeqIndex;
+
+  sortSourceLabels (s);
+  /* Initialize s->sourceMaps.textSources. */
+  s->sourceMaps.textEnd = (pointer)(getTextEnd());
+  s->sourceMaps.textStart = (pointer)(getTextStart());
+  if (ASSERT)
+    for (i = 0; i < s->sourceMaps.sourceLabelsLength; i++) {
+      pointer label;
+
+      label = s->sourceMaps.sourceLabels[i].label;
+      assert (0 == label
+              or (s->sourceMaps.textStart <= label
+                  and label < s->sourceMaps.textEnd));
+    }
+  s->sourceMaps.textSources =
+    (uint32_t*)
+    (calloc_safe((size_t)(s->sourceMaps.textEnd - s->sourceMaps.textStart), 
+                 sizeof(*(s->sourceMaps.textSources))));
+  p = s->sourceMaps.textStart;
+  sourceSeqIndex = SOURCE_SEQ_UNKNOWN;
+  for (i = 0; i < s->sourceMaps.sourceLabelsLength; i++) {
+    for ( ; p < s->sourceMaps.sourceLabels[i].label; p++)
+      s->sourceMaps.textSources[p - s->sourceMaps.textStart] = sourceSeqIndex;
+    sourceSeqIndex = s->sourceMaps.sourceLabels[i].sourceSeqIndex;
+  }
+  for ( ; p < s->sourceMaps.textEnd; p++)
+    s->sourceMaps.textSources[p - s->sourceMaps.textStart] = sourceSeqIndex;
+}
+
+
+void showSources (GC_state s) {
+  uint32_t i;
+  uint32_t j;
+  
+  fprintf (stdout, "0x%08"PRIx32"\n", s->magic);
+  fprintf (stdout, "%"PRIu32"\n", s->sourceMaps.sourceNamesLength);
+  for (i = 0; i < s->sourceMaps.sourceNamesLength; i++)
+    fprintf (stdout, "%s\n", s->sourceMaps.sourceNames[i]);
+  fprintf (stdout, "%"PRIu32"\n", s->sourceMaps.sourcesLength);
+  for (i = 0; i < s->sourceMaps.sourcesLength; i++)
+    fprintf (stdout, "%"PRIu32" %"PRIu32"\n",
+             s->sourceMaps.sources[i].sourceNameIndex,
+             s->sourceMaps.sources[i].successorSourceSeqIndex);
+  fprintf (stdout, "%"PRIu32"\n", s->sourceMaps.sourceSeqsLength);
+  for (i = 0; i < s->sourceMaps.sourceSeqsLength; i++) {
+    uint32_t *sourceSeq;
+    
+    sourceSeq = s->sourceMaps.sourceSeqs[i];
+    for (j = 1; j <= sourceSeq[0]; j++)
+      fprintf (stdout, "%"PRIu32" ", sourceSeq[j]);
+    fprintf (stdout, "\n");
+  }
+}

Copied: mlton/branches/on-20050822-x86_64-branch/runtime/gc/sources.h (from rev 4158, mlton/branches/on-20050822-x86_64-branch/runtime/gc/profiling.h)
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/profiling.h	2005-11-04 22:09:10 UTC (rev 4158)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/sources.h	2005-11-06 17:12:54 UTC (rev 4161)
@@ -0,0 +1,77 @@
+/* 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 uint32_t GC_sourceNameIndex;
+#define PRISNI PRIu32
+#define FMTSNI "%"PRISNI
+
+typedef uint32_t GC_sourceLabelIndex;
+#define PRISLI PRIu32
+#define FMTSLI "%"PRISLI
+
+typedef uint32_t GC_sourceIndex;
+#define PRISI PRIu32
+#define FMTSI "%"PRISI
+
+#define SOURCES_INDEX_UNKNOWN 0
+#define SOURCES_INDEX_GC      1
+
+typedef uint32_t GC_sourceSeqIndex;
+#define PRISSI PRIu32
+#define FMTSSI "%"PRISSI
+
+#define SOURCE_SEQ_GC         1
+#define SOURCE_SEQ_UNKNOWN    0
+
+typedef struct GC_source {
+  GC_sourceNameIndex sourceNameIndex;
+  GC_sourceSeqIndex successorSourceSeqIndex;
+} *GC_source;
+
+typedef struct GC_sourceLabel {
+  pointer label;
+  GC_sourceSeqIndex sourceSeqIndex;
+} *GC_sourceLabel;
+
+struct GC_sourceMaps {
+  /* frameSources is an array of cardinality frameLayoutsLength that
+   * for each stack frame, gives an index into sourceSeqs of the
+   * sequence of source functions corresponding to the frame.
+   */
+  GC_sourceSeqIndex *frameSources;
+  uint32_t frameSourcesLength;
+  struct GC_sourceLabel *sourceLabels;
+  uint32_t sourceLabelsLength;
+  char **sourceNames;
+  uint32_t sourceNamesLength;
+  /* Each entry in sourceSeqs is a vector, whose first element is a
+   * length, and subsequent elements index into sources.
+   */
+  uint32_t **sourceSeqs;
+  uint32_t sourceSeqsLength;
+  /* sources is an array of cardinality sourcesLength.  Each entry
+   * specifies an index into sourceNames and an index into sourceSeqs,
+   * giving the name of the function and the successors, respectively.
+   */
+  struct GC_source *sources;
+  uint32_t sourcesLength;
+  pointer textEnd;
+  /* An array of indices, one entry for each address in the text
+   * segment, giving and index into sourceSeqs.
+   */
+  GC_sourceSeqIndex *textSources;
+  pointer textStart;
+};
+
+GC_sourceSeqIndex getStackTopFrameSourceSeqIndex (GC_state s, GC_stack stack);
+char* GC_sourceName (GC_state s, GC_sourceIndex i);
+
+void sortSourceLabels (GC_state s);
+void initTextSources (GC_state s);
+
+void showSources (GC_state s);

Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/stack.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/stack.c	2005-11-05 00:04:36 UTC (rev 4160)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/stack.c	2005-11-06 17:12:54 UTC (rev 4161)
@@ -86,6 +86,16 @@
   return res;
 }
 
+size_t alignStackReserved (GC_state s, size_t reserved) {
+  size_t res;
+  
+  res = pad (s, reserved, GC_STACK_HEADER_SIZE + sizeof (struct GC_stack));
+  if (DEBUG_STACKS)
+    fprintf (stderr, "%zu = alignStackReserved (%zu)\n", res, reserved);
+  assert (isStackReservedAligned (s, res));
+  return res;
+}
+
 size_t sizeofStackWithHeaderAligned (GC_state s, size_t reserved) {
   size_t 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-11-05 00:04:36 UTC (rev 4160)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/stack.h	2005-11-06 17:12:54 UTC (rev 4161)
@@ -50,6 +50,7 @@
 #define GC_STACK_HEADER_SIZE GC_HEADER_SIZE
 
 bool isStackEmpty (GC_stack stack);
+bool isStackReservedAligned (GC_state s, size_t reserved);
 void displayStack (GC_state s, GC_stack stack, FILE *stream);
 
 size_t sizeofStackSlop (GC_state s);
@@ -64,6 +65,7 @@
 uint16_t getStackTopFrameSize (GC_state s, GC_stack stack);
 
 size_t sizeofStackMinimumReserved (GC_state s, GC_stack stack);
+size_t alignStackReserved (GC_state s, size_t reserved);
 size_t sizeofStackWithHeaderAligned (GC_state s, size_t reserved);
 size_t sizeofStackGrow (GC_state s, GC_stack stack);
 

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-11-05 00:04:36 UTC (rev 4160)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/stack_predicates.c	2005-11-06 17:12:54 UTC (rev 4161)
@@ -9,3 +9,11 @@
 bool isStackEmpty (GC_stack stack) {
   return 0 == stack->used;
 }
+
+#if ASSERT
+bool isStackReservedAligned (GC_state s, size_t reserved) {
+  return isAligned (GC_STACK_HEADER_SIZE + sizeof (struct GC_stack) + reserved, 
+                    s->alignment);
+}
+#endif
+