1 /* Copyright (C) 1999-2008 Henry Cejtin, Matthew Fluet, Suresh
2 * Jagannathan, and Stephen Weeks.
3 * Copyright (C) 1997-2000 NEC Research Institute.
5 * MLton is released under a BSD-style license.
6 * See the file MLton-LICENSE for details.
9 void loadWorldFromFILE (GC_state s
, FILE *f
) {
14 fprintf (stderr
, "loadWorldFromFILE\n");
15 until (readChar (f
) == '\000') ;
16 magic
= readUint32 (f
);
17 unless (s
->magic
== magic
)
18 die ("Invalid world: wrong magic number.");
19 start
= readPointer (f
);
20 s
->heap
.oldGenSize
= readSize (f
);
21 s
->atomicState
= readUint32 (f
);
22 s
->callFromCHandlerThread
= readObjptr (f
);
23 s
->currentThread
= readObjptr (f
);
24 s
->signalHandlerThread
= readObjptr (f
);
25 createHeap (s
, &s
->heap
,
26 sizeofHeapDesired (s
, s
->heap
.oldGenSize
, 0),
28 setCardMapAndCrossMap (s
);
29 fread_safe (s
->heap
.start
, 1, s
->heap
.oldGenSize
, f
);
30 if ((*(s
->loadGlobals
)) (f
) != 0) diee("couldn't load globals");
31 // unless (EOF == fgetc (file))
32 // die ("Invalid world: junk at end of file.");
33 /* translateHeap must occur after loading the heap and globals,
34 * since it changes pointers in all of them.
36 translateHeap (s
, start
, s
->heap
.start
, s
->heap
.oldGenSize
);
37 setGCStateCurrentHeap (s
, 0, 0);
38 setGCStateCurrentThreadAndStack (s
);
41 void loadWorldFromFileName (GC_state s
, const char *fileName
) {
45 fprintf (stderr
, "loadWorldFromFileName (%s)\n", fileName
);
46 f
= fopen_safe (fileName
, "rb");
47 loadWorldFromFILE (s
, f
);
51 /* Don't use 'safe' functions, because we don't want the ML program to die.
52 * Instead, check return values, and propogate them up to SML for an exception.
54 int saveWorldToFILE (GC_state s
, FILE *f
) {
59 fprintf (stderr
, "saveWorldToFILE\n");
60 /* Compact the heap. */
61 performGC (s
, 0, 0, TRUE
, TRUE
);
62 snprintf (buf
, cardof(buf
),
63 "Heap file created by MLton.\nheap.start = "FMTPTR
"\nbytesLive = %"PRIuMAX
"\n",
64 (uintptr_t)s
->heap
.start
,
65 (uintmax_t)s
->lastMajorStatistics
.bytesLive
);
66 len
= strlen(buf
) + 1; /* +1 to get the '\000' */
68 if (fwrite (buf
, 1, len
, f
) != len
) return -1;
69 if (fwrite (&s
->magic
, sizeof(uint32_t), 1, f
) != 1) return -1;
70 if (fwrite (&s
->heap
.start
, sizeof(uintptr_t), 1, f
) != 1) return -1;
71 if (fwrite (&s
->heap
.oldGenSize
, sizeof(size_t), 1, f
) != 1) return -1;
73 /* atomicState must be saved in the heap, because the saveWorld may
74 * be run in the context of a critical section, which will expect to
75 * be in the same context when it is restored.
77 if (fwrite (&s
->atomicState
, sizeof(uint32_t), 1, f
) != 1) return -1;
78 if (fwrite (&s
->callFromCHandlerThread
, sizeof(objptr
), 1, f
) != 1) return -1;
79 if (fwrite (&s
->currentThread
, sizeof(objptr
), 1, f
) != 1) return -1;
80 if (fwrite (&s
->signalHandlerThread
, sizeof(objptr
), 1, f
) != 1) return -1;
82 if (fwrite (s
->heap
.start
, 1, s
->heap
.oldGenSize
, f
) != s
->heap
.oldGenSize
)
84 if ((*(s
->saveGlobals
)) (f
) != 0)
89 void GC_saveWorld (GC_state s
, NullString8_t fileName
) {
93 f
= fopen ((const char*)fileName
, "wb");
95 s
->saveWorldStatus
= false;
98 if (saveWorldToFILE (s
, f
) != 0) {
99 s
->saveWorldStatus
= false;
102 if (fclose (f
) != 0) {
103 s
->saveWorldStatus
= false;
107 s
->saveWorldStatus
= true;
113 C_Errno_t(Bool_t
) GC_getSaveWorldStatus (GC_state s
) {
114 return (Bool_t
)(s
->saveWorldStatus
);