Commit | Line | Data |
---|---|---|
7f918cf1 CE |
1 | /* Copyright (C) 2011-2012,2014,2016 Matthew Fluet. |
2 | * Copyright (C) 1999-2008 Henry Cejtin, Matthew Fluet, Suresh | |
3 | * Jagannathan, and Stephen Weeks. | |
4 | * Copyright (C) 1997-2000 NEC Research Institute. | |
5 | * | |
6 | * MLton is released under a BSD-style license. | |
7 | * See the file MLton-LICENSE for details. | |
8 | */ | |
9 | ||
10 | /* ---------------------------------------------------------------- */ | |
11 | /* Initialization */ | |
12 | /* ---------------------------------------------------------------- */ | |
13 | ||
14 | size_t sizeofInitialBytesLive (GC_state s) { | |
15 | uint32_t i; | |
16 | size_t dataBytes; | |
17 | size_t total; | |
18 | ||
19 | total = 0; | |
20 | for (i = 0; i < s->vectorInitsLength; ++i) { | |
21 | dataBytes = | |
22 | s->vectorInits[i].elementSize | |
23 | * s->vectorInits[i].length; | |
24 | total += align (GC_ARRAY_METADATA_SIZE + dataBytes, s->alignment); | |
25 | } | |
26 | return total; | |
27 | } | |
28 | ||
29 | void initVectors (GC_state s) { | |
30 | struct GC_vectorInit *inits; | |
31 | pointer frontier; | |
32 | uint32_t i; | |
33 | ||
34 | assert (isFrontierAligned (s, s->frontier)); | |
35 | inits = s->vectorInits; | |
36 | frontier = s->frontier; | |
37 | for (i = 0; i < s->vectorInitsLength; i++) { | |
38 | size_t elementSize; | |
39 | size_t dataBytes; | |
40 | size_t objectSize; | |
41 | uint32_t typeIndex; | |
42 | ||
43 | elementSize = inits[i].elementSize; | |
44 | dataBytes = elementSize * inits[i].length; | |
45 | objectSize = align (GC_ARRAY_METADATA_SIZE + dataBytes, s->alignment); | |
46 | assert (objectSize <= (size_t)(s->heap.start + s->heap.size - frontier)); | |
47 | *((GC_arrayCounter*)(frontier)) = 0; | |
48 | frontier = frontier + GC_ARRAY_COUNTER_SIZE; | |
49 | *((GC_arrayLength*)(frontier)) = inits[i].length; | |
50 | frontier = frontier + GC_ARRAY_LENGTH_SIZE; | |
51 | switch (elementSize) { | |
52 | case 1: | |
53 | typeIndex = WORD8_VECTOR_TYPE_INDEX; | |
54 | break; | |
55 | case 2: | |
56 | typeIndex = WORD16_VECTOR_TYPE_INDEX; | |
57 | break; | |
58 | case 4: | |
59 | typeIndex = WORD32_VECTOR_TYPE_INDEX; | |
60 | break; | |
61 | case 8: | |
62 | typeIndex = WORD64_VECTOR_TYPE_INDEX; | |
63 | break; | |
64 | default: | |
65 | die ("unknown element size in vectorInit: %"PRIuMAX"", | |
66 | (uintmax_t)elementSize); | |
67 | } | |
68 | *((GC_header*)(frontier)) = buildHeaderFromTypeIndex (typeIndex); | |
69 | frontier = frontier + GC_HEADER_SIZE; | |
70 | s->globals[inits[i].globalIndex] = pointerToObjptr(frontier, s->heap.start); | |
71 | if (DEBUG_DETAILED) | |
72 | fprintf (stderr, "allocated vector at "FMTPTR"\n", | |
73 | (uintptr_t)(s->globals[inits[i].globalIndex])); | |
74 | memcpy (frontier, inits[i].words, dataBytes); | |
75 | frontier += objectSize - GC_ARRAY_METADATA_SIZE; | |
76 | } | |
77 | if (DEBUG_DETAILED) | |
78 | fprintf (stderr, "frontier after string allocation is "FMTPTR"\n", | |
79 | (uintptr_t)frontier); | |
80 | GC_profileAllocInc (s, (size_t)(frontier - s->frontier)); | |
81 | s->cumulativeStatistics.bytesAllocated += (size_t)(frontier - s->frontier); | |
82 | assert (isFrontierAligned (s, frontier)); | |
83 | s->frontier = frontier; | |
84 | } | |
85 | ||
86 | void initWorld (GC_state s) { | |
87 | uint32_t i; | |
88 | pointer start; | |
89 | GC_thread thread; | |
90 | ||
91 | for (i = 0; i < s->globalsLength; ++i) | |
92 | s->globals[i] = BOGUS_OBJPTR; | |
93 | s->lastMajorStatistics.bytesLive = sizeofInitialBytesLive (s); | |
94 | createHeap (s, &s->heap, | |
95 | sizeofHeapDesired (s, s->lastMajorStatistics.bytesLive, 0), | |
96 | s->lastMajorStatistics.bytesLive); | |
97 | setCardMapAndCrossMap (s); | |
98 | start = alignFrontier (s, s->heap.start); | |
99 | s->frontier = start; | |
100 | s->limitPlusSlop = s->heap.start + s->heap.size; | |
101 | s->limit = s->limitPlusSlop - GC_HEAP_LIMIT_SLOP; | |
102 | initVectors (s); | |
103 | assert ((size_t)(s->frontier - start) <= s->lastMajorStatistics.bytesLive); | |
104 | s->heap.oldGenSize = (size_t)(s->frontier - s->heap.start); | |
105 | setGCStateCurrentHeap (s, 0, 0); | |
106 | thread = newThread (s, sizeofStackInitialReserved (s)); | |
107 | switchToThread (s, pointerToObjptr((pointer)thread - offsetofThread (s), s->heap.start)); | |
108 | } |