mark and fix up absolute addresses in boot image code

This commit is contained in:
Joel Dice 2008-12-02 09:45:20 -07:00
parent 25ade1484a
commit d4363d250a
6 changed files with 124 additions and 21 deletions

View File

@ -129,6 +129,33 @@ class ListenPromise: public Promise {
System* s;
Allocator* allocator;
Listener* listener;
Promise* promise;
};
class DelayedPromise: public ListenPromise {
public:
DelayedPromise(System* s, Allocator* allocator, Promise* basis,
DelayedPromise* next):
ListenPromise(s, allocator), basis(basis), next(next)
{ }
virtual int64_t value() {
abort(s);
}
virtual bool resolved() {
return false;
}
virtual Listener* listen(unsigned sizeInBytes) {
Listener* l = static_cast<Listener*>(allocator->allocate(sizeInBytes));
l->next = listener;
listener = l;
return l;
}
Promise* basis;
DelayedPromise* next;
};
class TraceHandler {

View File

@ -33,7 +33,7 @@ endsWith(const char* suffix, const char* s, unsigned length)
object
makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code,
unsigned capacity)
unsigned capacity, uintptr_t* codeMap)
{
unsigned size = 0;
t->m->processor->compileThunks(t, image, code, &size, capacity);
@ -44,6 +44,8 @@ makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code,
object calls = 0;
PROTECT(t, calls);
DelayedPromise* addresses = 0;
for (Finder::Iterator it(t->m->finder); it.hasMore();) {
unsigned nameSize;
const char* name = it.next(&nameSize);
@ -59,7 +61,8 @@ makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code,
object method = arrayBody(t, classMethodTable(t, c), i);
if (methodCode(t, method) or (methodFlags(t, method) & ACC_NATIVE)) {
t->m->processor->compileMethod
(t, zone, code, &size, capacity, &constants, &calls, method);
(t, zone, code, &size, capacity, &constants, &calls, &addresses,
method);
}
}
}
@ -79,6 +82,19 @@ makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code,
->listener->resolve(address);
}
for (; addresses; addresses = addresses->next) {
uint8_t* value = reinterpret_cast<uint8_t*>(addresses->basis->value());
assert(t, value >= code);
void* dst = addresses->listener->resolve
((value - code) | (1 << BootShift));
assert(t, reinterpret_cast<intptr_t>(dst)
>= reinterpret_cast<intptr_t>(code));
markBit(codeMap, reinterpret_cast<intptr_t>(dst)
- reinterpret_cast<intptr_t>(code));
}
image->codeSize = size;
return constants;
@ -250,7 +266,8 @@ writeBootImage(Thread* t, FILE* out)
(t->m->heap->allocate(codeMapSize(CodeCapacity)));
memset(codeMap, 0, codeMapSize(CodeCapacity));
object constants = makeCodeImage(t, &zone, &image, code, CodeCapacity);
object constants = makeCodeImage
(t, &zone, &image, code, CodeCapacity, codeMap);
PROTECT(t, constants);
const unsigned HeapCapacity = 32 * 1024 * 1024;

View File

@ -466,13 +466,17 @@ class BootContext {
BootContext* c;
};
BootContext(Thread* t, object constants, object calls, Zone* zone):
protector(t, this), constants(constants), calls(calls), zone(zone)
BootContext(Thread* t, object constants, object calls,
DelayedPromise* addresses, Zone* zone):
protector(t, this), constants(constants), calls(calls),
addresses(addresses), addressSentinal(addresses), zone(zone)
{ }
MyProtector protector;
object constants;
object calls;
DelayedPromise* addresses;
DelayedPromise* addressSentinal;
Zone* zone;
};
@ -856,6 +860,21 @@ class Frame {
set(sp - 2, saved);
}
Promise* addressPromise(Promise* p) {
BootContext* bc = context->bootContext;
if (bc) {
bc->addresses = new (bc->zone->allocate(sizeof(DelayedPromise)))
DelayedPromise(t->m->system, bc->zone, p, bc->addresses);
return bc->addresses;
} else {
return p;
}
}
Compiler::Operand* addressOperand(Promise* p) {
return c->promiseConstant(addressPromise(p));
}
Compiler::Operand* machineIp(unsigned logicalIp) {
return c->promiseConstant(c->machineIp(logicalIp));
}
@ -2997,7 +3016,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
c->saveStack();
frame->pushAddress(frame->machineIp(ip));
frame->pushAddress(frame->addressOperand(c->machineIp(ip)));
c->jmp(frame->machineIp(newIp));
// NB: we assume that the stack will look the same on return
@ -3145,8 +3164,8 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
uint32_t defaultIp = base + codeReadInt32(t, code, ip);
assert(t, defaultIp < codeLength(t, code));
Compiler::Operand* default_ = c->address
(c->poolAppendPromise(c->machineIp(defaultIp)));
Compiler::Operand* default_ = frame->addressOperand
(c->machineIp(defaultIp));
int32_t pairCount = codeReadInt32(t, code, ip);
@ -3162,9 +3181,9 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
Promise* p = c->poolAppend(key);
if (i == 0) {
start = c->promiseConstant(p);
start = frame->addressOperand(p);
}
c->poolAppendPromise(c->machineIp(newIp));
c->poolAppendPromise(frame->addressPromise(c->machineIp(newIp)));
}
assert(t, start);
@ -3475,9 +3494,10 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
ipTable[i] = newIp;
Promise* p = c->poolAppendPromise(c->machineIp(newIp));
Promise* p = c->poolAppendPromise
(frame->addressPromise(c->machineIp(newIp)));
if (i == 0) {
start = c->promiseConstant(p);
start = frame->addressOperand(p);
}
}
assert(t, start);
@ -3854,6 +3874,17 @@ finish(MyThread* t, Allocator* allocator, Context* context)
c->writeTo(start);
BootContext* bc = context->bootContext;
if (bc) {
for (DelayedPromise* p = bc->addresses;
p != bc->addressSentinal;
p = p->next)
{
p->basis = new (bc->zone->allocate(sizeof(ResolvedPromise)))
ResolvedPromise(p->basis->value());
}
}
translateExceptionHandlerTable(t, c, methodCode(t, context->method),
reinterpret_cast<intptr_t>(start));
if (UNLIKELY(t->exception)) return 0;
@ -5063,16 +5094,18 @@ class MyProcessor: public Processor {
virtual void compileMethod(Thread* vmt, Zone* zone, uint8_t* code,
unsigned* offset, unsigned capacity,
object* constants, object* calls, object method)
object* constants, object* calls,
DelayedPromise** addresses, object method)
{
MyThread* t = static_cast<MyThread*>(vmt);
FixedAllocator allocator(t, code + *offset, capacity);
BootContext bootContext(t, *constants, *calls, zone);
BootContext bootContext(t, *constants, *calls, *addresses, zone);
compile(t, &allocator, &bootContext, method);
*constants = bootContext.constants;
*calls = bootContext.calls;
*addresses = bootContext.addresses;
*offset += allocator.offset;
}
@ -5334,8 +5367,14 @@ fixupCode(Thread*, uintptr_t* map, unsigned size, uint8_t* code,
if (w & (static_cast<uintptr_t>(1) << bit)) {
unsigned index = indexOf(word, bit);
uintptr_t v; memcpy(&v, code + index, BytesPerWord);
v = reinterpret_cast<uintptr_t>(heap + v - 1);
memcpy(code + index, &v, BytesPerWord);
uintptr_t mark = v >> BootShift;
if (mark) {
v = reinterpret_cast<uintptr_t>(code + (v & BootMask));
memcpy(code + index, &v, BytesPerWord);
} else {
v = reinterpret_cast<uintptr_t>(heap + v - 1);
memcpy(code + index, &v, BytesPerWord);
}
}
}
}
@ -5435,8 +5474,8 @@ boot(MyThread* t, BootImage* image)
(codeMapSize(image->codeSize), BytesPerWord);
uint8_t* code = reinterpret_cast<uint8_t*>(codeMap + codeMapSizeInWords);
fprintf(stderr, "code from %p to %p\n",
code, code + image->codeSize);
// fprintf(stderr, "code from %p to %p\n",
// code, code + image->codeSize);
fixupHeap(t, heapMap, heapMapSizeInWords, heap);

View File

@ -3060,8 +3060,26 @@ class MyCompiler: public Compiler {
int i = 0;
for (ConstantPoolNode* n = c.firstConstant; n; n = n->next) {
*reinterpret_cast<intptr_t*>(dst + pad(c.assembler->length()) + i)
= n->promise->value();
intptr_t* target = reinterpret_cast<intptr_t*>
(dst + pad(c.assembler->length()) + i);
if (n->promise->resolved()) {
*target = n->promise->value();
} else {
class Listener: public Promise::Listener {
public:
Listener(intptr_t* target): target(target){ }
virtual void* resolve(int64_t value) {
*target = value;
return target;
}
intptr_t* target;
};
new (n->promise->listen(sizeof(Listener))) Listener(target);
}
i += BytesPerWord;
}
}

View File

@ -1759,6 +1759,7 @@ class MyHeap: public Heap {
bool targetNeedsMark(void* target) {
return target
and not c.gen2.contains(target)
and not immortalHeapContains(&c, target)
and not (c.client->isFixed(target)
and fixie(target)->age >= FixieTenureThreshold);
}

View File

@ -17,6 +17,7 @@
#include "bootimage.h"
#include "heapwalk.h"
#include "zone.h"
#include "assembler.h"
namespace vm {
@ -122,7 +123,7 @@ class Processor {
virtual void
compileMethod(Thread* t, Zone* zone, uint8_t* code, unsigned* offset,
unsigned capacity, object* constants, object* calls,
object method) = 0;
DelayedPromise** addresses, object method) = 0;
virtual void
visitRoots(BootImage* image, HeapWalker* w) = 0;