mirror of
https://github.com/corda/corda.git
synced 2025-01-03 19:54:13 +00:00
mark and fix up absolute addresses in boot image code
This commit is contained in:
parent
25ade1484a
commit
d4363d250a
@ -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 {
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user