@@ -67,8 +67,16 @@ makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code,
67
67
}
68
68
69
69
for (; calls; calls = tripleThird (t, calls)) {
70
+ object method = tripleFirst (t, calls);
71
+ uintptr_t address;
72
+ if (methodFlags (t, method) & ACC_NATIVE) {
73
+ address = reinterpret_cast <uintptr_t >(code + image->nativeThunk );
74
+ } else {
75
+ address = methodCompiled (t, method);
76
+ }
77
+
70
78
static_cast <ListenPromise*>(pointerValue (t, tripleSecond (t, calls)))
71
- ->listener ->resolve (methodCompiled (t, tripleFirst (t, calls)) );
79
+ ->listener ->resolve (address );
72
80
}
73
81
74
82
image->codeSize = size;
@@ -80,6 +88,7 @@ unsigned
80
88
objectSize (Thread* t, object o)
81
89
{
82
90
assert (t, not objectExtended (t, o));
91
+
83
92
return baseSize (t, o, objectClass (t, o));
84
93
}
85
94
@@ -88,8 +97,11 @@ visitRoots(Thread* t, BootImage* image, HeapWalker* w, object constants)
88
97
{
89
98
Machine* m = t->m ;
90
99
100
+ for (HashMapIterator it (t, m->classMap ); it.hasMore ();) {
101
+ w->visitRoot (tripleSecond (t, it.next ()));
102
+ }
103
+
91
104
image->loader = w->visitRoot (m->loader );
92
- image->stringMap = w->visitRoot (m->stringMap );
93
105
image->types = w->visitRoot (m->types );
94
106
95
107
m->processor ->visitRoots (image, w);
@@ -99,51 +111,63 @@ visitRoots(Thread* t, BootImage* image, HeapWalker* w, object constants)
99
111
}
100
112
}
101
113
102
- void
103
- visitReference (Thread* t, HeapWalker* w, uintptr_t * heap, uintptr_t * map,
104
- object r)
105
- {
106
- int target = w->map ()->find (jreferenceTarget (t, r));
107
- assert (t, target > 0 );
108
-
109
- int reference = w->map ()->find (r);
110
- assert (t, reference > 0 );
111
-
112
- unsigned index = reference - 1 + (JreferenceTarget / BytesPerWord);
113
- markBit (map, index);
114
- heap[index] = target;
115
- }
116
-
117
114
HeapWalker*
118
115
makeHeapImage (Thread* t, BootImage* image, uintptr_t * heap, uintptr_t * map,
119
116
unsigned capacity, object constants)
120
117
{
121
118
class Visitor : public HeapVisitor {
122
119
public:
123
120
Visitor (Thread* t, uintptr_t * heap, uintptr_t * map, unsigned capacity):
124
- t (t), current(0 ), heap(heap), map(map), position(0 ), capacity(capacity)
121
+ t (t), currentObject(0 ), currentNumber(0 ), currentOffset(0 ), heap(heap),
122
+ map (map), position(0 ), capacity(capacity)
125
123
{ }
126
124
127
125
void visit (unsigned number) {
128
- if (current) {
129
- if (number) markBit (map, current - 1 );
130
- heap[current - 1 ] = number;
126
+ if (currentObject) {
127
+ unsigned offset = currentNumber - 1 + currentOffset;
128
+ unsigned mark = heap[offset] & (~PointerMask);
129
+ unsigned value = number | (mark << BootShift);
130
+
131
+ if (value) markBit (map, offset);
132
+
133
+ heap[offset] = value;
131
134
}
132
135
}
133
136
134
137
virtual void root () {
135
- current = 0 ;
138
+ currentObject = 0 ;
136
139
}
137
140
138
141
virtual unsigned visitNew (object p) {
139
142
if (p) {
140
143
unsigned size = objectSize (t, p);
141
- assert (t, position + size < capacity);
142
144
143
- memcpy (heap + position, p, size * BytesPerWord);
145
+ unsigned number;
146
+ if (currentObject
147
+ and (currentOffset * BytesPerWord) == ClassStaticTable)
148
+ {
149
+ FixedAllocator allocator
150
+ (t, reinterpret_cast <uint8_t *>(heap + position),
151
+ (capacity - position) * BytesPerWord);
152
+
153
+ unsigned totalInBytes;
154
+ uintptr_t * dst = static_cast <uintptr_t *>
155
+ (t->m ->heap ->allocateImmortalFixed
156
+ (&allocator, size, true , &totalInBytes));
157
+
158
+ memcpy (dst, p, size * BytesPerWord);
144
159
145
- unsigned number = position + 1 ;
146
- position += size;
160
+ dst[0 ] |= FixedMark;
161
+
162
+ number = (dst - heap) + 1 ;
163
+ position += ceiling (totalInBytes, BytesPerWord);
164
+ } else {
165
+ assert (t, position + size < capacity);
166
+ memcpy (heap + position, p, size * BytesPerWord);
167
+
168
+ number = position + 1 ;
169
+ position += size;
170
+ }
147
171
148
172
visit (number);
149
173
@@ -157,16 +181,20 @@ makeHeapImage(Thread* t, BootImage* image, uintptr_t* heap, uintptr_t* map,
157
181
visit (number);
158
182
}
159
183
160
- virtual void push (object, unsigned number, unsigned offset) {
161
- current = number + offset;
184
+ virtual void push (object object, unsigned number, unsigned offset) {
185
+ currentObject = object;
186
+ currentNumber = number;
187
+ currentOffset = offset;
162
188
}
163
189
164
190
virtual void pop () {
165
- current = 0 ;
191
+ currentObject = 0 ;
166
192
}
167
193
168
194
Thread* t;
169
- unsigned current;
195
+ object currentObject;
196
+ unsigned currentNumber;
197
+ unsigned currentOffset;
170
198
uintptr_t * heap;
171
199
uintptr_t * map;
172
200
unsigned position;
@@ -176,14 +204,6 @@ makeHeapImage(Thread* t, BootImage* image, uintptr_t* heap, uintptr_t* map,
176
204
HeapWalker* w = makeHeapWalker (t, &visitor);
177
205
visitRoots (t, image, w, constants);
178
206
179
- for (object r = t->m ->weakReferences ; r; r = jreferenceVmNext (t, r)) {
180
- visitReference (t, w, heap, map, r);
181
- }
182
-
183
- for (object r = t->m ->tenuredWeakReferences ; r; r = jreferenceVmNext (t, r)) {
184
- visitReference (t, w, heap, map, r);
185
- }
186
-
187
207
image->heapSize = visitor.position * BytesPerWord;
188
208
189
209
return w;
@@ -197,14 +217,18 @@ updateConstants(Thread* t, object constants, uint8_t* code, uintptr_t* codeMap,
197
217
unsigned target = heapTable->find (tripleFirst (t, constants));
198
218
assert (t, target > 0 );
199
219
200
- void * dst = static_cast <ListenPromise*>
201
- (pointerValue (t, tripleSecond (t, constants)))->listener ->resolve (target);
220
+ for (Promise::Listener* pl = static_cast <ListenPromise*>
221
+ (pointerValue (t, tripleSecond (t, constants)))->listener ;
222
+ pl; pl = pl->next )
223
+ {
224
+ void * dst = pl->resolve (target);
202
225
203
- assert (t, reinterpret_cast <intptr_t >(dst)
204
- >= reinterpret_cast <intptr_t >(code));
226
+ assert (t, reinterpret_cast <intptr_t >(dst)
227
+ >= reinterpret_cast <intptr_t >(code));
205
228
206
- markBit (codeMap, reinterpret_cast <intptr_t >(dst)
207
- - reinterpret_cast <intptr_t >(code));
229
+ markBit (codeMap, reinterpret_cast <intptr_t >(dst)
230
+ - reinterpret_cast <intptr_t >(code));
231
+ }
208
232
}
209
233
}
210
234
@@ -227,6 +251,7 @@ writeBootImage(Thread* t, FILE* out)
227
251
memset (codeMap, 0 , codeMapSize (CodeCapacity));
228
252
229
253
object constants = makeCodeImage (t, &zone, &image, code, CodeCapacity);
254
+ PROTECT (t, constants);
230
255
231
256
const unsigned HeapCapacity = 32 * 1024 * 1024 ;
232
257
uintptr_t * heap = static_cast <uintptr_t *>
@@ -235,25 +260,64 @@ writeBootImage(Thread* t, FILE* out)
235
260
(t->m ->heap ->allocate (heapMapSize (HeapCapacity)));
236
261
memset (heapMap, 0 , heapMapSize (HeapCapacity));
237
262
238
- PROTECT (t, constants);
239
263
collect (t, Heap::MajorCollection);
240
264
241
265
HeapWalker* heapWalker = makeHeapImage
242
266
(t, &image, heap, heapMap, HeapCapacity, constants);
243
267
244
268
updateConstants (t, constants, code, codeMap, heapWalker->map ());
245
269
270
+ image.classCount = hashMapSize (t, t->m ->classMap );
271
+ unsigned * classTable = static_cast <unsigned *>
272
+ (t->m ->heap ->allocate (image.classCount * sizeof (unsigned )));
273
+
274
+ { unsigned i = 0 ;
275
+ for (HashMapIterator it (t, t->m ->classMap ); it.hasMore ();) {
276
+ classTable[i++] = heapWalker->map ()->find (tripleSecond (t, it.next ()));
277
+ }
278
+ }
279
+
280
+ image.stringCount = hashMapSize (t, t->m ->stringMap );
281
+ unsigned * stringTable = static_cast <unsigned *>
282
+ (t->m ->heap ->allocate (image.stringCount * sizeof (unsigned )));
283
+
284
+ { unsigned i = 0 ;
285
+ for (HashMapIterator it (t, t->m ->stringMap ); it.hasMore ();) {
286
+ stringTable[i++] = heapWalker->map ()->find
287
+ (jreferenceTarget (t, tripleFirst (t, it.next ())));
288
+ }
289
+ }
290
+
291
+ unsigned * callTable = t->m ->processor ->makeCallTable
292
+ (t, &image, heapWalker, code);
293
+
246
294
heapWalker->dispose ();
247
295
248
296
image.magic = BootImage::Magic;
249
297
image.codeBase = reinterpret_cast <uintptr_t >(code);
250
298
251
- fprintf (stderr, " heap size %d code size %d\n " ,
252
- image.heapSize , image.codeSize );
299
+ fprintf (stderr, " class count %d string count %d call count %d\n "
300
+ " heap size %d code size %d\n " ,
301
+ image.classCount , image.stringCount , image.callCount , image.heapSize ,
302
+ image.codeSize );
253
303
254
304
if (true ) {
255
305
fwrite (&image, sizeof (BootImage), 1 , out);
256
306
307
+ fwrite (classTable, image.classCount * sizeof (unsigned ), 1 , out);
308
+ fwrite (stringTable, image.stringCount * sizeof (unsigned ), 1 , out);
309
+ fwrite (callTable, image.callCount * sizeof (unsigned ) * 2 , 1 , out);
310
+
311
+ unsigned offset = (image.classCount * sizeof (unsigned ))
312
+ + (image.stringCount * sizeof (unsigned ))
313
+ + (image.callCount * sizeof (unsigned ) * 2 );
314
+
315
+ while (offset % BytesPerWord) {
316
+ uint8_t c = 0 ;
317
+ fwrite (&c, 1 , 1 , out);
318
+ ++ offset;
319
+ }
320
+
257
321
fwrite (heapMap, pad (heapMapSize (image.heapSize )), 1 , out);
258
322
fwrite (heap, pad (image.heapSize ), 1 , out);
259
323
0 commit comments