1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
|
/* Copyright (C) 2011 Matthew Fluet.
* Copyright (C) 1999-2008 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.
*/
/* ---------------------------------------------------------------- */
/* Initialization */
/* ---------------------------------------------------------------- */
size_t sizeofIntInfFromString (GC_state s, const char *str) {
size_t slen = strlen (str);
/* A slight overestimate. */
double bytesPerChar = 0.415241011861 /* = ((log(10.0) / log(2.0)) / 8.0) */ ;
double bytes = ceil((double)slen * bytesPerChar);
return align (GC_ARRAY_HEADER_SIZE
+ sizeof(mp_limb_t) // for the sign
+ align((size_t)bytes, sizeof(mp_limb_t)),
s->alignment);
}
size_t sizeofInitialBytesLive (GC_state s) {
uint32_t i;
size_t dataBytes;
size_t total;
total = 0;
for (i = 0; i < s->intInfInitsLength; ++i) {
total += sizeofIntInfFromString (s, s->intInfInits[i].mlstr);
}
for (i = 0; i < s->vectorInitsLength; ++i) {
dataBytes =
s->vectorInits[i].bytesPerElement
* s->vectorInits[i].numElements;
total += align (GC_ARRAY_HEADER_SIZE
+ ((dataBytes < OBJPTR_SIZE)
? OBJPTR_SIZE
: dataBytes),
s->alignment);
}
return total;
}
void initIntInfs (GC_state s) {
struct GC_intInfInit *inits;
uint32_t i;
const char *str;
size_t bytes;
bool neg;
__mpz_struct resmpz;
__attribute__ ((unused)) int ans;
assert (isFrontierAligned (s, s->frontier));
for (i = 0; i < s->intInfInitsLength; i++) {
inits = &(s->intInfInits[i]);
assert (inits->globalIndex < s->globalsLength);
str = inits->mlstr;
bytes = sizeofIntInfFromString (s, str);
neg = *str == '~';
if (neg)
str++;
initIntInfRes (s, &resmpz, bytes);
ans = mpz_set_str (&resmpz, str, 10);
assert (ans == 0);
if (neg)
resmpz._mp_size = - resmpz._mp_size;
s->globals[inits->globalIndex] = finiIntInfRes (s, &resmpz, bytes);
}
assert (isFrontierAligned (s, s->frontier));
}
void initVectors (GC_state s) {
struct GC_vectorInit *inits;
pointer frontier;
uint32_t i;
assert (isFrontierAligned (s, s->frontier));
inits = s->vectorInits;
frontier = s->frontier;
for (i = 0; i < s->vectorInitsLength; i++) {
size_t bytesPerElement;
size_t dataBytes;
size_t objectSize;
uint32_t typeIndex;
bytesPerElement = inits[i].bytesPerElement;
dataBytes = bytesPerElement * inits[i].numElements;
objectSize = align (GC_ARRAY_HEADER_SIZE
+ ((dataBytes < OBJPTR_SIZE)
? OBJPTR_SIZE
: dataBytes),
s->alignment);
assert (objectSize <= (size_t)(s->heap.start + s->heap.size - frontier));
*((GC_arrayCounter*)(frontier)) = 0;
frontier = frontier + GC_ARRAY_COUNTER_SIZE;
*((GC_arrayLength*)(frontier)) = inits[i].numElements;
frontier = frontier + GC_ARRAY_LENGTH_SIZE;
switch (bytesPerElement) {
case 1:
typeIndex = WORD8_VECTOR_TYPE_INDEX;
break;
case 2:
typeIndex = WORD16_VECTOR_TYPE_INDEX;
break;
case 4:
typeIndex = WORD32_VECTOR_TYPE_INDEX;
break;
case 8:
typeIndex = WORD64_VECTOR_TYPE_INDEX;
break;
default:
die ("unknown bytes per element in vectorInit: %"PRIuMAX"",
(uintmax_t)bytesPerElement);
}
*((GC_header*)(frontier)) = buildHeaderFromTypeIndex (typeIndex);
frontier = frontier + GC_HEADER_SIZE;
s->globals[inits[i].globalIndex] = pointerToObjptr(frontier, s->heap.start);
if (DEBUG_DETAILED)
fprintf (stderr, "allocated vector at "FMTPTR"\n",
(uintptr_t)(s->globals[inits[i].globalIndex]));
memcpy (frontier, inits[i].bytes, dataBytes);
frontier += objectSize - GC_ARRAY_HEADER_SIZE;
}
if (DEBUG_DETAILED)
fprintf (stderr, "frontier after string allocation is "FMTPTR"\n",
(uintptr_t)frontier);
GC_profileAllocInc (s, (size_t)(frontier - s->frontier));
s->cumulativeStatistics.bytesAllocated += (size_t)(frontier - s->frontier);
assert (isFrontierAligned (s, frontier));
s->frontier = frontier;
}
void initWorld (GC_state s) {
uint32_t i;
pointer start;
GC_thread thread;
for (i = 0; i < s->globalsLength; ++i)
s->globals[i] = BOGUS_OBJPTR;
s->lastMajorStatistics.bytesLive = sizeofInitialBytesLive (s);
createHeap (s, &s->heap,
sizeofHeapDesired (s, s->lastMajorStatistics.bytesLive, 0),
s->lastMajorStatistics.bytesLive);
setCardMapAndCrossMap (s);
start = alignFrontier (s, s->heap.start);
s->frontier = start;
s->limitPlusSlop = s->heap.start + s->heap.size;
s->limit = s->limitPlusSlop - GC_HEAP_LIMIT_SLOP;
initIntInfs (s);
initVectors (s);
assert ((size_t)(s->frontier - start) <= s->lastMajorStatistics.bytesLive);
s->heap.oldGenSize = s->frontier - s->heap.start;
setGCStateCurrentHeap (s, 0, 0);
thread = newThread (s, sizeofStackInitialReserved (s));
switchToThread (s, pointerToObjptr((pointer)thread - offsetofThread (s), s->heap.start));
}
|