[MLton-commit] r4124

Matthew Fluet MLton@mlton.org
Sat, 29 Oct 2005 20:31:51 -0700


init and done functions
----------------------------------------------------------------------

U   mlton/branches/on-20050822-x86_64-branch/runtime/gc/Makefile
A   mlton/branches/on-20050822-x86_64-branch/runtime/gc/done.c
U   mlton/branches/on-20050822-x86_64-branch/runtime/gc/gc_state.h
U   mlton/branches/on-20050822-x86_64-branch/runtime/gc/heap.c
U   mlton/branches/on-20050822-x86_64-branch/runtime/gc/init.c
U   mlton/branches/on-20050822-x86_64-branch/runtime/gc/read_write.c
U   mlton/branches/on-20050822-x86_64-branch/runtime/gc/safe.c
U   mlton/branches/on-20050822-x86_64-branch/runtime/gc/util.c
A   mlton/branches/on-20050822-x86_64-branch/runtime/gc/world.c
A   mlton/branches/on-20050822-x86_64-branch/runtime/gc/world.h

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

Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/Makefile
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/Makefile	2005-10-29 21:05:39 UTC (rev 4123)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/Makefile	2005-10-30 03:31:46 UTC (rev 4124)
@@ -114,7 +114,9 @@
 	pack.c								\
 	size.c								\
 	profiling.c							\
+	world.c								\
 	init.c								\
+	done.c								\
 	assumptions.c							\
 	gc_suffix.c
 
@@ -142,6 +144,7 @@
 	hash-cons.h							\
 	profiling.h							\
 	signals.h							\
+	world.h								\
 	init.h								\
 	gc_state.h							\
 	gc_suffix.h

Copied: mlton/branches/on-20050822-x86_64-branch/runtime/gc/done.c (from rev 4120, mlton/branches/on-20050822-x86_64-branch/runtime/gc.c)
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc.c	2005-10-26 00:53:09 UTC (rev 4120)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/done.c	2005-10-30 03:31:46 UTC (rev 4124)
@@ -0,0 +1,92 @@
+/* Copyright (C) 1999-2005 Henry Cejtin, Matthew Fluet, Suresh
+ *    Jagannathan, and Stephen Weeks.
+ * Copyright (C) 1997-2000 NEC Research Institute.
+ *
+ * MLton is released under a BSD-style license.
+ * See the file MLton-LICENSE for details.
+ */
+
+static void displayCol (FILE *out, int width, char *s) {
+  int extra;
+  int i;
+  int len;
+  
+  len = strlen (s);
+  if (len < width) {
+    extra = width - len;
+    for (i = 0; i < extra; i++)
+      fprintf (out, " ");
+  }
+  fprintf (out, "%s\t", s);
+}
+
+static void displayCollectionStats (FILE *out, char *name, struct rusage *ru, 
+                                    uintmax_t num, uintmax_t bytes) {
+  uintmax_t ms;
+  
+  ms = rusageTime (ru);
+  fprintf (out, "%s", name);
+  displayCol (out, 7, uintmaxToCommaString (ms));
+  displayCol (out, 7, uintmaxToCommaString (num));
+  displayCol (out, 15, uintmaxToCommaString (bytes));
+  displayCol (out, 15, 
+              (ms > 0)
+              ? uintmaxToCommaString (1000.0 * (float)bytes/(float)ms)
+              : "-");
+  fprintf (out, "\n");
+}
+
+void GC_done (GC_state s) {
+  FILE *out;
+
+  enter (s);
+  minorGC (s);
+  out = stderr;
+  if (s->controls.summary) {
+    uintmax_t time;
+    uintmax_t gcTime;
+    
+    gcTime = rusageTime (&s->cumulativeStatistics.ru_gc);
+    fprintf (out, "GC type\t\ttime ms\t number\t\t  bytes\t      bytes/sec\n");
+    fprintf (out, "-------------\t-------\t-------\t---------------\t---------------\n");
+    displayCollectionStats
+      (out, "copying\t\t", 
+       &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);
+    displayCollectionStats
+      (out, "minor\t\t",
+       &s->cumulativeStatistics.ru_gcMinor, 
+       s->cumulativeStatistics.numMinorGCs, 
+       s->cumulativeStatistics.bytesCopiedMinor);
+    time = currentTime () - s->startTime;
+    fprintf (out, "total GC time: %s ms (%.1f%%)\n",
+             uintmaxToCommaString (gcTime), 
+             (0 == time) 
+             ? 0.0 
+             : 100.0 * ((double) gcTime) / (double)time);
+    fprintf (out, "max pause: %s ms\n",
+             uintmaxToCommaString (s->cumulativeStatistics.maxPause));
+    fprintf (out, "total allocated: %s bytes\n",
+             uintmaxToCommaString (s->cumulativeStatistics.bytesAllocated));
+    fprintf (out, "max live: %s bytes\n",
+             uintmaxToCommaString (s->cumulativeStatistics.maxBytesLive));
+    fprintf (out, "max semispace: %s bytes\n", 
+             uintmaxToCommaString (s->cumulativeStatistics.maxHeapSizeSeen));
+    fprintf (out, "max stack size: %s bytes\n", 
+             uintmaxToCommaString (s->cumulativeStatistics.maxStackSizeSeen));
+    fprintf (out, "marked cards: %s\n", 
+             uintmaxToCommaString (s->cumulativeStatistics.markedCards));
+    fprintf (out, "minor scanned: %s bytes\n",
+             uintmaxToCommaString (s->cumulativeStatistics.minorBytesScanned));
+    fprintf (out, "minor skipped: %s bytes\n", 
+             uintmaxToCommaString (s->cumulativeStatistics.minorBytesSkipped));
+  }
+  heapRelease (s, &s->heap);
+  heapRelease (s, &s->secondaryHeap);
+}

Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/gc_state.h
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/gc_state.h	2005-10-29 21:05:39 UTC (rev 4123)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/gc_state.h	2005-10-30 03:31:46 UTC (rev 4124)
@@ -32,7 +32,7 @@
   struct GC_lastMajorStatistics lastMajorStatistics;
   pointer limit; /* limit = heap.start + heap.totalBytes */
   pointer limitPlusSlop; /* limit + LIMIT_SLOP */
-  void (*loadGlobals)(FILE *file); /* loads the globals from the stream. */
+  void (*loadGlobals)(int fd); /* loads the globals from the fd. */
   uint32_t magic; /* The magic number for this executable. */
   uint32_t maxFrameSize;
   /*Bool*/bool mutatorMarksCards;
@@ -46,7 +46,7 @@
   objptr savedThread; /* Result of GC_copyCurrentThread.
                        * Thread interrupted by arrival of signal.
                        */
-  void (*saveGlobals)(int fd); /* writes out the values of all of the globals to fd. */
+  void (*saveGlobals)(int fd); /* saves the globals to the fd. */
   struct GC_heap secondaryHeap; /* Used for major copying collection. */
   objptr signalHandlerThread; /* Handler for signals (in heap). */
   struct GC_signalsInfo signalsInfo;

Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/heap.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/heap.c	2005-10-29 21:05:39 UTC (rev 4123)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/heap.c	2005-10-30 03:31:46 UTC (rev 4124)
@@ -227,7 +227,6 @@
   } else {
     /* Write the heap to a file and try again. */
     int fd;
-    FILE *stream;
     char template[80];
     char *tmpDefault;
     char *tmpDir;
@@ -248,14 +247,14 @@
     if (s->controls.messages)
       fprintf (stderr, "Paging heap from "FMTPTR" to %s.\n", 
                (uintptr_t)orig, template);
-    stream = fopen_safe (template, "wb");
-    fwrite_safe (orig, 1, size, stream);
-    fclose_safe (stream);
+    fd = open_safe (template, O_WRONLY, 0);
+    write_safe (fd, orig, size);
+    close_safe (fd);
     heapRelease (s, curHeapp);
     if (heapCreate (s, curHeapp, desiredSize, minSize)) {
-      stream = fopen_safe (template, "rb");
-      fread_safe (curHeapp->start, 1, size, stream);
-      fclose_safe (stream);
+      fd = open_safe (template, O_RDONLY, 0);
+      read_safe (fd, curHeapp->start, size);
+      close_safe (fd);
       unlink_safe (template);
     } else {
       unlink_safe (template);

Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/init.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/init.c	2005-10-29 21:05:39 UTC (rev 4123)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/init.c	2005-10-30 03:31:46 UTC (rev 4124)
@@ -263,46 +263,6 @@
   switchToThread (s, pointerToObjptr((pointer)thread, s->heap.start));
 }
 
-/* worldTerminator is used to separate the human readable messages at the
- * beginning of the world file from the machine readable data.
- */
-static const char worldTerminator = '\000';
-
-static void loadWorld (GC_state s, char *fileName) {
-  FILE *file;
-  uint32_t magic;
-  pointer oldGen;
-  int c;
-        
-  if (DEBUG_WORLD)
-    fprintf (stderr, "loadWorld (%s)\n", fileName);
-  file = fopen_safe (fileName, "rb"); 
-  until ((c = fgetc (file)) == worldTerminator or EOF == c) ;
-  if (EOF == c) die ("Invalid world.");
-  // magic = sfreadUint (file);
-  unless (s->magic == magic)
-    die ("Invalid world: wrong magic number.");
-/*         oldGen = (pointer) sfreadUint (file); */
-/*         s->oldGenSize = sfreadUint (file); */
-/*         s->callFromCHandler = (GC_thread) sfreadUint (file); */
-/*         s->canHandle = sfreadUint (file); */
-/*         s->currentThread = (GC_thread) sfreadUint (file); */
-/*         s->signalHandler = (GC_thread) sfreadUint (file); */
-  heapCreate (s, &s->heap, heapDesiredSize (s, s->heap.oldGenSize, 0), s->heap.oldGenSize);
-  createCardMapAndCrossMap (s); 
-/*         sfread (s->heap.start, 1, s->oldGenSize, file); */
-  (*s->loadGlobals) (file);
-  unless (EOF == fgetc (file))
-    die ("Invalid world: junk at end of file.");
-  fclose_safe (file); 
-  /* translateHeap must occur after loading the heap and globals, since it
-   * changes pointers in all of them.
-   */
-  translateHeap (s, oldGen, s->heap.start, s->heap.oldGenSize);
-  heapSetNursery (s, 0, 0); 
-  setCurrentStack (s); 
-}
-
 /* ---------------------------------------------------------------- */
 /*                             GC_init                              */
 /* ---------------------------------------------------------------- */
@@ -594,82 +554,3 @@
 /*         CommandLine_argc = argc - start; */
 /*         CommandLine_argv = (uint)(argv + start); */
 /* } */
-
-/* static void displayCol (FILE *out, int width, string s) { */
-/*         int extra; */
-/*         int i; */
-/*         int len; */
-
-/*         len = strlen (s); */
-/*         if (len < width) { */
-/*                 extra = width - len; */
-/*                 for (i = 0; i < extra; ++i) */
-/*                         fprintf (out, " "); */
-/*         } */
-/*         fprintf (out, "%s\t", s); */
-/* } */
-
-/* static void displayCollectionStats (FILE *out, string name, struct rusage *ru,  */
-/*                                         uint num, ullong bytes) { */
-/*         uint ms; */
-
-/*         ms = rusageTime (ru); */
-/*         fprintf (out, "%s", name); */
-/*         displayCol (out, 7, uintToCommaString (ms)); */
-/*         displayCol (out, 7, uintToCommaString (num)); */
-/*         displayCol (out, 15, ullongToCommaString (bytes)); */
-/*         displayCol (out, 15,  */
-/*                         (ms > 0) */
-/*                         ? uintToCommaString (1000.0 * (float)bytes/(float)ms) */
-/*                         : "-"); */
-/*         fprintf (out, "\n"); */
-/* } */
-
-/* void GC_done (GC_state s) { */
-/*         FILE *out; */
-
-/*         enter (s); */
-/*         minorGC (s); */
-/*         out = stderr; */
-/*         if (s->summary) { */
-/*                 double time; */
-/*                 uint gcTime; */
-
-/*                 gcTime = rusageTime (&s->ru_gc); */
-/*                 fprintf (out, "GC type\t\ttime ms\t number\t\t  bytes\t      bytes/sec\n"); */
-/*                 fprintf (out, "-------------\t-------\t-------\t---------------\t---------------\n"); */
-/*                 displayCollectionStats */
-/*                         (out, "copying\t\t", &s->ru_gcCopy, s->numCopyingGCs,  */
-/*                                 s->bytesCopied); */
-/*                 displayCollectionStats */
-/*                         (out, "mark-compact\t", &s->ru_gcMarkCompact,  */
-/*                                 s->numMarkCompactGCs, s->bytesMarkCompacted); */
-/*                 displayCollectionStats */
-/*                         (out, "minor\t\t", &s->ru_gcMinor, s->numMinorGCs,  */
-/*                                 s->bytesCopiedMinor); */
-/*                 time = (double)(currentTime () - s->startTime); */
-/*                 fprintf (out, "total GC time: %s ms (%.1f%%)\n", */
-/*                                 intToCommaString (gcTime),  */
-/*                                 (0.0 == time)  */
-/*                                         ? 0.0  */
-/*                                         : 100.0 * ((double) gcTime) / time); */
-/*                 fprintf (out, "max pause: %s ms\n", */
-/*                                 uintToCommaString (s->maxPause)); */
-/*                 fprintf (out, "total allocated: %s bytes\n", */
-/*                                 ullongToCommaString (s->bytesAllocated)); */
-/*                 fprintf (out, "max live: %s bytes\n", */
-/*                                 uintToCommaString (s->maxBytesLive)); */
-/*                 fprintf (out, "max semispace: %s bytes\n",  */
-/*                                 uintToCommaString (s->maxHeapSizeSeen)); */
-/*                 fprintf (out, "max stack size: %s bytes\n",  */
-/*                                 uintToCommaString (s->maxStackSizeSeen)); */
-/*                 fprintf (out, "marked cards: %s\n",  */
-/*                                 ullongToCommaString (s->markedCards)); */
-/*                 fprintf (out, "minor scanned: %s bytes\n", */
-/*                                 uintToCommaString (s->minorBytesScanned)); */
-/*                 fprintf (out, "minor skipped: %s bytes\n",  */
-/*                                 uintToCommaString (s->minorBytesSkipped)); */
-/*         } */
-/*         heapRelease (s, &s->heap); */
-/*         heapRelease (s, &s->heap2); */
-/* } */

Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/read_write.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/read_write.c	2005-10-29 21:05:39 UTC (rev 4123)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/read_write.c	2005-10-30 03:31:46 UTC (rev 4124)
@@ -6,19 +6,79 @@
  * See the file MLton-LICENSE for details.
  */
 
+static inline char readChar (int fd) {
+  char res;
+  read_safe (fd, &res, sizeof(char));
+  return res;
+}
 
-static void writeString (int fd, char* s) {
+static inline pointer readPointer (int fd) {
+  uintptr_t res;
+  read_safe (fd, &res, sizeof(uintptr_t));
+  return (pointer)res;
+}
+
+static inline objptr readObjptr (int fd) {
+  objptr res;
+  read_safe (fd, &res, sizeof(objptr));
+  return res;
+}
+
+static inline size_t readSize (int fd) {
+  size_t res;
+  read_safe (fd, &res, sizeof(size_t));
+  return res;
+}
+
+static inline uint32_t readUint32 (int fd) {
+  uint32_t res;
+  read_safe (fd, &res, sizeof(uint32_t));
+  return res;
+}
+
+static inline uintptr_t readUintptr (int fd) {
+  uintptr_t res;
+  read_safe (fd, &res, sizeof(uintptr_t));
+  return res;
+}
+
+static inline void writeChar (int fd, char c) {
+  write_safe (fd, &c, sizeof(char));
+}
+
+static inline void writePointer (int fd, pointer p) {
+  uintptr_t u = (uintptr_t)p;
+  write_safe (fd, &u, sizeof(uintptr_t));
+}
+
+static inline void writeObjptr (int fd, objptr op) {
+  write_safe (fd, &op, sizeof(objptr));
+}
+
+static inline void writeSize (int fd, size_t z) {
+  write_safe (fd, &z, sizeof(size_t));
+}
+
+static inline void writeUint32 (int fd, uint32_t u) {
+  write_safe (fd, &u, sizeof(uint32_t));
+}
+
+static inline void writeUintptr (int fd, uintptr_t u) {
+  write_safe (fd, &u, sizeof(uintptr_t));
+}
+
+static inline void writeString (int fd, char* s) {
   write_safe (fd, s, strlen(s));
 }
 
-static void writeUint32U (int fd, uint32_t u) {
+static inline void writeUint32U (int fd, uint32_t u) {
   char buf[(UINT32_MAX / 10) + 2];
 
   sprintf (buf, "%"PRIu32, u);
   writeString (fd, buf);
 }
 
-static void writeUintmaxU (int fd, uintmax_t u) {
+static inline void writeUintmaxU (int fd, uintmax_t u) {
   // char buf[(UINTMAX_MAX / 10) + 2];
   char buf[20];
 
@@ -26,13 +86,13 @@
   writeString (fd, buf);
 }
 
-static void writeUint32X (int fd, uint32_t u) {
+static inline void writeUint32X (int fd, uint32_t u) {
   char buf[5 + (UINT32_MAX / 16) + 2];
   
   sprintf (buf, "0x%08"PRIx32, u);
   writeString (fd, buf);
 }
 
-static inline void writeNewline (int fd) {
-        writeString (fd, "\n");
+static inline inline void writeNewline (int fd) {
+  writeString (fd, "\n");
 }

Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/safe.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/safe.c	2005-10-29 21:05:39 UTC (rev 4123)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/safe.c	2005-10-30 03:31:46 UTC (rev 4124)
@@ -34,6 +34,15 @@
   return fd;
 }
 
+int open_safe (const char *fileName, int flags, mode_t mode) {
+  int res;
+
+  res = open (fileName, flags, mode);
+  if (-1 == res)
+    diee ("open (%s,_,_) failed.\n", fileName);
+  return res;
+}
+
 void close_safe (int fd) {
   int res;
 
@@ -43,6 +52,7 @@
   return;
 }
 
+/*
 FILE *fopen_safe (char *fileName, char *mode) {
   FILE *file;
   
@@ -83,6 +93,7 @@
     diee ("fread (_, _, _, _) failed.\n");
   return;
 }
+*/
 
 void unlink_safe (const char *pathname) {
   int res;

Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/util.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/util.c	2005-10-29 21:05:39 UTC (rev 4123)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/util.c	2005-10-30 03:31:46 UTC (rev 4124)
@@ -8,3 +8,32 @@
 const char* boolToString (bool b) {
         return b ? "TRUE" : "FALSE";
 }
+
+#define BUF_SIZE 81
+char* uintmaxToCommaString (uintmax_t n) {
+  static char buf1[BUF_SIZE];
+  static char buf2[BUF_SIZE];
+  static char buf3[BUF_SIZE];
+  static char buf4[BUF_SIZE];
+  static char buf5[BUF_SIZE];
+  static char *bufs[] = {buf1, buf2, buf3, buf4, buf5};
+  static int bufIndex = 0;
+  static char *buf;
+  int i;
+  
+  buf = bufs[bufIndex++];
+  bufIndex %= 5;
+  
+  i = BUF_SIZE - 1;
+  buf[i--] = '\000';
+  if (0 == n)
+    buf[i--] = '0';
+  else {
+    while (n > 0) {
+      buf[i--] = n % 10 + '0';
+      n = n / 10;
+      if (i % 4 == 0 and n > 0) buf[i--] = ',';
+    }
+  }
+  return buf + i + 1;
+}

Copied: mlton/branches/on-20050822-x86_64-branch/runtime/gc/world.c (from rev 4120, mlton/branches/on-20050822-x86_64-branch/runtime/gc.c)
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc.c	2005-10-26 00:53:09 UTC (rev 4120)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/world.c	2005-10-30 03:31:46 UTC (rev 4124)
@@ -0,0 +1,71 @@
+/* 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 loadWorld (GC_state s, char *fileName) {
+  int fd;
+  uint32_t magic;
+  pointer start;
+        
+  if (DEBUG_WORLD)
+    fprintf (stderr, "loadWorld (%s)\n", fileName);
+  fd = open_safe (fileName, O_RDONLY, 0); 
+  until (readChar (fd) == '\000') ;
+  magic = readUint32 (fd);
+  unless (s->magic == magic)
+    die ("Invalid world: wrong magic number.");
+  start = readPointer (fd);
+  s->heap.oldGenSize = readSize (fd);
+  s->atomicState = readUint32 (fd);
+  s->callFromCHandlerThread =  readObjptr (fd); 
+  s->currentThread = readObjptr (fd); 
+  s->signalHandlerThread = readObjptr (fd); 
+  heapCreate (s, &s->heap, 
+              heapDesiredSize (s, s->heap.oldGenSize, 0), 
+              s->heap.oldGenSize);
+  createCardMapAndCrossMap (s); 
+  read_safe (fd, s->heap.start, s->heap.oldGenSize);
+  (*s->loadGlobals) (fd);
+  // unless (EOF == fgetc (file))
+  //  die ("Invalid world: junk at end of file.");
+  close_safe (fd); 
+  /* translateHeap must occur after loading the heap and globals,
+   * since it changes pointers in all of them.
+   */
+  translateHeap (s, start, s->heap.start, s->heap.oldGenSize);
+  heapSetNursery (s, 0, 0); 
+  setCurrentStack (s); 
+}
+
+static void saveWorld (GC_state s, int fd) {
+  char buf[80];
+
+  if (DEBUG_WORLD)
+    fprintf (stderr, "GC_saveWorld (%d).\n", fd);
+  enter (s);
+  /* Compact the heap. */
+  doGC (s, 0, 0, TRUE, TRUE);
+  sprintf (buf,
+           "Heap file created by MLton.\nheap.start = "FMTPTR"\nbytesLive = %zu\n",
+           (uintptr_t)s->heap.start, 
+           s->lastMajorStatistics.bytesLive);
+  write_safe (fd, buf, 1 + strlen(buf)); /* +1 to get the '\000' */
+  writeUint32 (fd, s->magic);
+  writePointer (fd, s->heap.start);
+  writeSize (fd, s->heap.oldGenSize);
+  /* atomicState must be saved in the heap, because the saveWorld may
+   * be run in the context of a critical section, which will expect to
+   * be in the same context when it is restored.
+   */
+  writeUint32 (fd, s->atomicState);
+  writeObjptr (fd, s->callFromCHandlerThread);
+  writeObjptr (fd, s->currentThread);
+  writeObjptr (fd, s->signalHandlerThread);
+  write_safe (fd, s->heap.start, s->heap.oldGenSize);
+  (*s->saveGlobals) (fd);
+  leave (s);
+}

Copied: mlton/branches/on-20050822-x86_64-branch/runtime/gc/world.h (from rev 4120, mlton/branches/on-20050822-x86_64-branch/runtime/gc.h)
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc.h	2005-10-26 00:53:09 UTC (rev 4120)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/world.h	2005-10-30 03:31:46 UTC (rev 4124)
@@ -0,0 +1,11 @@
+/* Copyright (C) 1999-2005 Henry Cejtin, Matthew Fluet, Suresh
+ *    Jagannathan, and Stephen Weeks.
+ * Copyright (C) 1997-2000 NEC Research Institute.
+ *
+ * MLton is released under a BSD-style license.
+ * See the file MLton-LICENSE for details.
+ */
+
+static void loadWorld (GC_state s, char *fileName);
+
+static void saveWorld (GC_state s, int fd);