@@ -22,123 +22,104 @@ size_t sizeofInitialBytesLive (GC_state s) {
22
22
}
23
23
24
24
void initDynHeap (GC_state s , GC_thread thread ) {
25
+ assert (0 == thread -> currentDepth );
26
+
27
+ HM_chunk currentChunk ;
28
+ pointer frontier , limit ;
29
+ pointer start = s -> staticHeaps .dynamic .start ;
30
+ pointer end = start + s -> staticHeaps .dynamic .size ;
31
+ pointer p = start ;
32
+ size_t metaDataSize = 0 , objectSize = 0 ;
33
+
34
+ // While there are segments of the initial dynamic heap to be copied
35
+ // into the root hierarchical heap.
36
+ while (1 ) {
37
+ currentChunk = thread -> currentChunk ;
38
+ frontier = HM_getChunkFrontier (currentChunk );
39
+ assert (isFrontierAligned (s , frontier ));
40
+ limit = HM_getChunkLimit (currentChunk );
41
+ assert (frontier <= limit );
42
+
43
+ // Find the end of this segement of the initial dynamic heap to
44
+ // copy into the current chunk of the root hierarchical heap.
45
+ // `start` is the start of the segment.
46
+ // `p` is the candidate end of segment.
47
+ while (1 ) {
48
+ if (p >= end ) {
49
+ // This segment is the last to be copied.
50
+ break ;
51
+ }
52
+ pointer q = advanceToObjectData (s , p );
53
+ #if ASSERT
54
+ GC_header header = getHeader (q );
55
+ assert (header == GC_REAL32_VECTOR_HEADER
56
+ || header == GC_REAL64_VECTOR_HEADER
57
+ || header == GC_WORD8_VECTOR_HEADER
58
+ || header == GC_WORD16_VECTOR_HEADER
59
+ || header == GC_WORD32_VECTOR_HEADER
60
+ || header == GC_WORD64_VECTOR_HEADER );
61
+ #endif
62
+ sizeofObjectAux (s , q , & metaDataSize , & objectSize );
63
+ pointer r = q + objectSize ;
64
+ if (!inFirstBlockOfChunk (currentChunk , frontier + (q - start ))
65
+ || frontier + (r - start ) > limit ) {
66
+ // Next object does not fit into current chunk.
67
+ break ;
68
+ }
69
+ // Next object fits into current chunk; advance `p`.
70
+ p = r ;
71
+ }
72
+
73
+ // Copy segment `[start,p)` into current segment.
74
+ memcpy (frontier , start , p - start );
75
+ // Adjust global objptrs that referenced an object in the segment.
76
+ for (uint32_t i = 0 ; i < s -> globalsLength ; i ++ ) {
77
+ pointer g = objptrToPointer (s -> globals [i ], NULL );
78
+ if (start <= g && g < p ) {
79
+ g = (g - start ) + frontier ;
80
+ s -> globals [i ] = pointerToObjptr (g , NULL );
81
+ }
82
+ }
83
+ // Advance frontier.
84
+ frontier += p - start ;
85
+ HM_updateChunkValues (currentChunk , frontier );
86
+
87
+ if (p >= end ) {
88
+ // This segment was the last to be copied.
89
+ break ;
90
+ }
91
+
92
+ // Initialize search for next segment.
93
+ start = p ;
94
+ // `p` points to the beginning of an object that did not fit in
95
+ // the last chunk; extend hierarchical heap with a chunk
96
+ // sufficient to hold the next object.
97
+ if (!HM_HH_extend (s , thread , metaDataSize + objectSize )) {
98
+ DIE ("Ran out of space for Hierarchical Heap!" );
99
+ }
100
+ }
101
+
102
+ /* If the last allocation passed a block boundary, we need to extend to have
103
+ * a valid frontier. Extending with GC_HEAP_LIMIT_SLOP is arbitrary. */
104
+ if (!inFirstBlockOfChunk (currentChunk , frontier + GC_SEQUENCE_METADATA_SIZE )) {
105
+ if (!HM_HH_extend (s , thread , GC_HEAP_LIMIT_SLOP )) {
106
+ DIE ("Ran out of space for Hierarchical Heap!" );
107
+ }
108
+ currentChunk = thread -> currentChunk ;
109
+ frontier = HM_getChunkFrontier (currentChunk );
110
+ assert (isFrontierAligned (s , frontier ));
111
+ limit = HM_getChunkLimit (currentChunk );
112
+ assert (frontier <= limit );
113
+ }
114
+
115
+ s -> frontier = frontier ;
116
+ s -> limitPlusSlop = limit ;
117
+ s -> limit = s -> limitPlusSlop - GC_HEAP_LIMIT_SLOP ;
25
118
119
+ assert (isFrontierAligned (s , s -> frontier ));
120
+ assert (inFirstBlockOfChunk (currentChunk , s -> frontier + GC_SEQUENCE_METADATA_SIZE ));
26
121
}
27
122
28
- /* void initVectors(GC_state s, GC_thread thread) { */
29
- /* struct GC_vectorInit *inits; */
30
- /* HM_chunk currentChunk; */
31
- /* pointer frontier; */
32
- /* pointer limit; */
33
- /* uint32_t i; */
34
-
35
- /* assert(isFrontierAligned(s, s->frontier)); */
36
- /* inits = s->vectorInits; */
37
- /* frontier = s->frontier; */
38
- /* limit = s->limitPlusSlop; */
39
-
40
- /* currentChunk = HM_getChunkOf(frontier); */
41
- /* assert(currentChunk == thread->currentChunk); */
42
- /* assert(0 == thread->currentDepth); */
43
-
44
- /* for (i = 0; i < s->vectorInitsLength; i++) { */
45
- /* size_t elementSize; */
46
- /* size_t dataBytes; */
47
- /* size_t objectSize; */
48
- /* uint32_t typeIndex; */
49
-
50
- /* elementSize = inits[i].elementSize; */
51
- /* dataBytes = elementSize * inits[i].length; */
52
- /* objectSize = align(GC_SEQUENCE_METADATA_SIZE + dataBytes, s->alignment); */
53
-
54
- /* #if ASSERT */
55
- /* assert(limit == HM_getChunkLimit(currentChunk)); */
56
- /* assert(frontier >= HM_getChunkFrontier(currentChunk)); */
57
- /* assert(frontier <= limit); */
58
- /* #endif */
59
-
60
- /* /\* Extend with a new chunk, if there is not enough free space or if we have */
61
- /* * crossed a block boundary. *\/ */
62
- /* if ((size_t)(limit - frontier) < objectSize || */
63
- /* !inFirstBlockOfChunk(currentChunk, frontier + GC_SEQUENCE_METADATA_SIZE)) */
64
- /* { */
65
- /* HM_HH_updateValues(thread, frontier); */
66
- /* if (!HM_HH_extend(s, thread, objectSize)) { */
67
- /* DIE("Ran out of space for Hierarchical Heap!"); */
68
- /* } */
69
- /* s->frontier = HM_HH_getFrontier(thread); */
70
- /* s->limitPlusSlop = HM_HH_getLimit(thread); */
71
- /* s->limit = s->limitPlusSlop - GC_HEAP_LIMIT_SLOP; */
72
-
73
- /* frontier = s->frontier; */
74
- /* limit = s->limitPlusSlop; */
75
-
76
- /* currentChunk = HM_getChunkOf(frontier); */
77
- /* assert(currentChunk == thread->currentChunk); */
78
- /* } */
79
-
80
- /* assert(isFrontierAligned(s, frontier)); */
81
- /* assert((size_t)(limit - frontier) >= objectSize); */
82
- /* assert(inFirstBlockOfChunk(currentChunk, frontier + GC_SEQUENCE_METADATA_SIZE)); */
83
-
84
- /* *((GC_sequenceCounter*)(frontier)) = 0; */
85
- /* frontier = frontier + GC_SEQUENCE_COUNTER_SIZE; */
86
- /* *((GC_sequenceLength*)(frontier)) = inits[i].length; */
87
- /* frontier = frontier + GC_SEQUENCE_LENGTH_SIZE; */
88
- /* switch (elementSize) { */
89
- /* case 1: */
90
- /* typeIndex = WORD8_VECTOR_TYPE_INDEX; */
91
- /* break; */
92
- /* case 2: */
93
- /* typeIndex = WORD16_VECTOR_TYPE_INDEX; */
94
- /* break; */
95
- /* case 4: */
96
- /* typeIndex = WORD32_VECTOR_TYPE_INDEX; */
97
- /* break; */
98
- /* case 8: */
99
- /* typeIndex = WORD64_VECTOR_TYPE_INDEX; */
100
- /* break; */
101
- /* default: */
102
- /* die ("unknown element size in vectorInit: %"PRIuMAX"", */
103
- /* (uintmax_t)elementSize); */
104
- /* } */
105
- /* *((GC_header*)(frontier)) = buildHeaderFromTypeIndex (typeIndex); */
106
- /* frontier = frontier + GC_HEADER_SIZE; */
107
- /* // *((objptr*)(frontier)) = BOGUS_OBJPTR; */
108
- /* // frontier = frontier + OBJPTR_SIZE; */
109
- /* s->globals[inits[i].globalIndex] = pointerToObjptr(frontier, NULL); */
110
- /* if (DEBUG_DETAILED) */
111
- /* fprintf (stderr, "allocated vector at "FMTPTR"\n", */
112
- /* (uintptr_t)(s->globals[inits[i].globalIndex])); */
113
- /* memcpy (frontier, inits[i].words, dataBytes); */
114
- /* frontier += objectSize - GC_SEQUENCE_METADATA_SIZE; */
115
- /* } */
116
-
117
- /* s->frontier = frontier; */
118
-
119
- /* /\* If the last allocation passed a block boundary, we need to extend to have */
120
- /* * a valid frontier. Extending with GC_HEAP_LIMIT_SLOP is arbitrary. *\/ */
121
- /* if (!inFirstBlockOfChunk(currentChunk, frontier + GC_SEQUENCE_METADATA_SIZE)) */
122
- /* { */
123
- /* HM_HH_updateValues(thread, frontier); */
124
- /* if (!HM_HH_extend(s, thread, GC_HEAP_LIMIT_SLOP)) { */
125
- /* DIE("Ran out of space for Hierarchical Heap!"); */
126
- /* } */
127
- /* s->frontier = HM_HH_getFrontier(thread); */
128
- /* s->limitPlusSlop = HM_HH_getLimit(thread); */
129
- /* s->limit = s->limitPlusSlop - GC_HEAP_LIMIT_SLOP; */
130
-
131
- /* frontier = s->frontier; */
132
- /* limit = s->limitPlusSlop; */
133
-
134
- /* currentChunk = HM_getChunkOf(frontier); */
135
- /* assert(currentChunk == thread->currentChunk); */
136
- /* } */
137
-
138
- /* assert(isFrontierAligned(s, s->frontier)); */
139
- /* assert(inFirstBlockOfChunk(currentChunk, s->frontier + GC_SEQUENCE_METADATA_SIZE)); */
140
- /* } */
141
-
142
123
GC_thread initThreadAndHeap (GC_state s , uint32_t depth ) {
143
124
GC_thread thread = newThreadWithHeap (s , sizeofStackInitialReserved (s ), depth );
144
125
0 commit comments