Import Debian changes 20180207-1
[hcoop/debian/mlton.git] / runtime / gc / init-world.c
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 }