Import Upstream version 20180207
[hcoop/debian/mlton.git] / runtime / gc / world.c
CommitLineData
7f918cf1
CE
1/* Copyright (C) 1999-2008 Henry Cejtin, Matthew Fluet, Suresh
2 * Jagannathan, and Stephen Weeks.
3 * Copyright (C) 1997-2000 NEC Research Institute.
4 *
5 * MLton is released under a BSD-style license.
6 * See the file MLton-LICENSE for details.
7 */
8
9void loadWorldFromFILE (GC_state s, FILE *f) {
10 uint32_t magic;
11 pointer start;
12
13 if (DEBUG_WORLD)
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),
27 s->heap.oldGenSize);
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.
35 */
36 translateHeap (s, start, s->heap.start, s->heap.oldGenSize);
37 setGCStateCurrentHeap (s, 0, 0);
38 setGCStateCurrentThreadAndStack (s);
39}
40
41void loadWorldFromFileName (GC_state s, const char *fileName) {
42 FILE *f;
43
44 if (DEBUG_WORLD)
45 fprintf (stderr, "loadWorldFromFileName (%s)\n", fileName);
46 f = fopen_safe (fileName, "rb");
47 loadWorldFromFILE (s, f);
48 fclose_safe (f);
49}
50
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.
53 */
54int saveWorldToFILE (GC_state s, FILE *f) {
55 char buf[128];
56 size_t len;
57
58 if (DEBUG_WORLD)
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' */
67
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;
72
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.
76 */
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;
81
82 if (fwrite (s->heap.start, 1, s->heap.oldGenSize, f) != s->heap.oldGenSize)
83 return -1;
84 if ((*(s->saveGlobals)) (f) != 0)
85 return -1;
86 return 0;
87}
88
89void GC_saveWorld (GC_state s, NullString8_t fileName) {
90 FILE *f;
91
92 enter (s);
93 f = fopen ((const char*)fileName, "wb");
94 if (f == 0) {
95 s->saveWorldStatus = false;
96 goto done;
97 }
98 if (saveWorldToFILE (s, f) != 0) {
99 s->saveWorldStatus = false;
100 goto done;
101 }
102 if (fclose (f) != 0) {
103 s->saveWorldStatus = false;
104 goto done;
105 }
106
107 s->saveWorldStatus = true;
108done:
109 leave (s);
110 return;
111}
112
113C_Errno_t(Bool_t) GC_getSaveWorldStatus (GC_state s) {
114 return (Bool_t)(s->saveWorldStatus);
115}