[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);