fix powerpc bootimage build (second try)

This commit is contained in:
Joel Dice 2009-03-10 19:08:16 -06:00
parent 3e08a2f875
commit 49cd2dd9bf
7 changed files with 77 additions and 44 deletions

View File

@ -82,7 +82,7 @@ class Promise {
public: public:
class Listener { class Listener {
public: public:
virtual void* resolve(int64_t value) = 0; virtual bool resolve(int64_t value, void** location) = 0;
Listener* next; Listener* next;
}; };

View File

@ -97,19 +97,25 @@ makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code,
} }
static_cast<ListenPromise*>(pointerValue(t, tripleSecond(t, calls))) static_cast<ListenPromise*>(pointerValue(t, tripleSecond(t, calls)))
->listener->resolve(address); ->listener->resolve(address, 0);
} }
for (; addresses; addresses = addresses->next) { for (; addresses; addresses = addresses->next) {
uint8_t* value = reinterpret_cast<uint8_t*>(addresses->basis->value()); uint8_t* value = reinterpret_cast<uint8_t*>(addresses->basis->value());
assert(t, value >= code); assert(t, value >= code);
void* dst = addresses->listener->resolve void* location;
((value - code) | (1 << BootShift)); bool flat = addresses->listener->resolve(0, &location);
assert(t, reinterpret_cast<intptr_t>(dst) uintptr_t offset = value - code;
if (flat) {
offset |= BootFlatConstant;
}
memcpy(location, &offset, BytesPerWord);
assert(t, reinterpret_cast<intptr_t>(location)
>= reinterpret_cast<intptr_t>(code)); >= reinterpret_cast<intptr_t>(code));
markBit(codeMap, reinterpret_cast<intptr_t>(dst) markBit(codeMap, reinterpret_cast<intptr_t>(location)
- reinterpret_cast<intptr_t>(code)); - reinterpret_cast<intptr_t>(code));
} }
@ -255,12 +261,18 @@ updateConstants(Thread* t, object constants, uint8_t* code, uintptr_t* codeMap,
(pointerValue(t, tripleSecond(t, constants)))->listener; (pointerValue(t, tripleSecond(t, constants)))->listener;
pl; pl = pl->next) pl; pl = pl->next)
{ {
void* dst = pl->resolve(target); void* location;
bool flat = pl->resolve(0, &location);
uintptr_t offset = target | BootHeapOffset;
if (flat) {
offset |= BootFlatConstant;
}
memcpy(location, &offset, BytesPerWord);
assert(t, reinterpret_cast<intptr_t>(dst) assert(t, reinterpret_cast<intptr_t>(location)
>= reinterpret_cast<intptr_t>(code)); >= reinterpret_cast<intptr_t>(code));
markBit(codeMap, reinterpret_cast<intptr_t>(dst) markBit(codeMap, reinterpret_cast<intptr_t>(location)
- reinterpret_cast<intptr_t>(code)); - reinterpret_cast<intptr_t>(code));
} }
} }

View File

@ -19,6 +19,9 @@ const unsigned BootMask = (~static_cast<unsigned>(0)) / BytesPerWord;
const unsigned BootShift = 32 - log(BytesPerWord); const unsigned BootShift = 32 - log(BytesPerWord);
const unsigned BootFlatConstant = 1 << BootShift;
const unsigned BootHeapOffset = 1 << (BootShift + 1);
class BootImage { class BootImage {
public: public:
static const unsigned Magic = 0x22377322; static const unsigned Magic = 0x22377322;

View File

@ -5639,14 +5639,19 @@ fixupCode(Thread* t, uintptr_t* map, unsigned size, uint8_t* code,
for (unsigned bit = 0; bit < BitsPerWord; ++bit) { for (unsigned bit = 0; bit < BitsPerWord; ++bit) {
if (w & (static_cast<uintptr_t>(1) << bit)) { if (w & (static_cast<uintptr_t>(1) << bit)) {
unsigned index = indexOf(word, bit); unsigned index = indexOf(word, bit);
uintptr_t v = arch->getConstant(code + index); uintptr_t oldValue; memcpy(&oldValue, code + index, BytesPerWord);
uintptr_t mark = v >> BootShift; uintptr_t newValue;
if (mark) { if (oldValue & BootHeapOffset) {
arch->setConstant(code + index, reinterpret_cast<uintptr_t> newValue = reinterpret_cast<uintptr_t>
(code + (v & BootMask))); (heap + (oldValue & BootMask) - 1);
} else { } else {
arch->setConstant(code + index, reinterpret_cast<uintptr_t> newValue = reinterpret_cast<uintptr_t>
(heap + v - 1)); (code + (oldValue & BootMask));
}
if (oldValue & BootFlatConstant) {
memcpy(code + index, &newValue, BytesPerWord);
} else {
arch->setConstant(code + index, newValue);
} }
} }
} }
@ -5766,6 +5771,8 @@ boot(MyThread* t, BootImage* image)
fixupCode(t, codeMap, codeMapSizeInWords, code, heap); fixupCode(t, codeMap, codeMapSizeInWords, code, heap);
syncInstructionCache(code, image->codeSize);
t->m->classMap = makeClassMap(t, classTable, image->classCount, heap); t->m->classMap = makeClassMap(t, classTable, image->classCount, heap);
t->m->stringMap = makeStringMap(t, stringTable, image->stringCount, heap); t->m->stringMap = makeStringMap(t, stringTable, image->stringCount, heap);
@ -5889,39 +5896,41 @@ compileThunks(MyThread* t, Allocator* allocator, MyProcessor* p,
p->defaultThunk = finish p->defaultThunk = finish
(t, allocator, defaultContext.context.assembler, "default"); (t, allocator, defaultContext.context.assembler, "default");
{ uint8_t* call = static_cast<uint8_t*> { void* call;
(defaultContext.promise.listener->resolve defaultContext.promise.listener->resolve
(reinterpret_cast<intptr_t>(voidPointer(compileMethod)))); (reinterpret_cast<intptr_t>(voidPointer(compileMethod)), &call);
if (image) { if (image) {
image->defaultThunk = p->defaultThunk - imageBase; image->defaultThunk = p->defaultThunk - imageBase;
image->compileMethodCall = call - imageBase; image->compileMethodCall = static_cast<uint8_t*>(call) - imageBase;
} }
} }
p->nativeThunk = finish p->nativeThunk = finish
(t, allocator, nativeContext.context.assembler, "native"); (t, allocator, nativeContext.context.assembler, "native");
{ uint8_t* call = static_cast<uint8_t*> { void* call;
(nativeContext.promise.listener->resolve nativeContext.promise.listener->resolve
(reinterpret_cast<intptr_t>(voidPointer(invokeNative)))); (reinterpret_cast<intptr_t>(voidPointer(invokeNative)), &call);
if (image) { if (image) {
image->nativeThunk = p->nativeThunk - imageBase; image->nativeThunk = p->nativeThunk - imageBase;
image->invokeNativeCall = call - imageBase; image->invokeNativeCall = static_cast<uint8_t*>(call) - imageBase;
} }
} }
p->aioobThunk = finish p->aioobThunk = finish
(t, allocator, aioobContext.context.assembler, "aioob"); (t, allocator, aioobContext.context.assembler, "aioob");
{ uint8_t* call = static_cast<uint8_t*> { void* call;
(aioobContext.promise.listener->resolve aioobContext.promise.listener->resolve
(reinterpret_cast<intptr_t>(voidPointer(throwArrayIndexOutOfBounds)))); (reinterpret_cast<intptr_t>(voidPointer(throwArrayIndexOutOfBounds)),
&call);
if (image) { if (image) {
image->aioobThunk = p->aioobThunk - imageBase; image->aioobThunk = p->aioobThunk - imageBase;
image->throwArrayIndexOutOfBoundsCall = call - imageBase; image->throwArrayIndexOutOfBoundsCall
= static_cast<uint8_t*>(call) - imageBase;
} }
} }
@ -5940,11 +5949,11 @@ compileThunks(MyThread* t, Allocator* allocator, MyProcessor* p,
#define THUNK(s) \ #define THUNK(s) \
tableContext.context.assembler->writeTo(start); \ tableContext.context.assembler->writeTo(start); \
start += p->thunkSize; \ start += p->thunkSize; \
{ uint8_t* call = static_cast<uint8_t*> \ { void* call; \
(tableContext.promise.listener->resolve \ tableContext.promise.listener->resolve \
(reinterpret_cast<intptr_t>(voidPointer(s)))); \ (reinterpret_cast<intptr_t>(voidPointer(s)), &call); \
if (image) { \ if (image) { \
image->s##Call = call - imageBase; \ image->s##Call = static_cast<uint8_t*>(call) - imageBase; \
} \ } \
} }

View File

@ -5288,9 +5288,10 @@ class MyCompiler: public Compiler {
public: public:
Listener(intptr_t* target): target(target){ } Listener(intptr_t* target): target(target){ }
virtual void* resolve(int64_t value) { virtual bool resolve(int64_t value, void** location) {
*target = value; *target = value;
return target; if (location) *location = target;
return true;
} }
intptr_t* target; intptr_t* target;

View File

@ -328,8 +328,10 @@ class OffsetListener: public Promise::Listener {
conditional(conditional) conditional(conditional)
{ } { }
virtual void* resolve(int64_t value) { virtual bool resolve(int64_t value, void** location) {
return updateOffset(s, instruction, conditional, value); void* p = updateOffset(s, instruction, conditional, value);
if (location) *location = p;
return false;
} }
System* s; System* s;
@ -518,8 +520,10 @@ updateImmediate(System* s, void* dst, int64_t src, unsigned size)
switch (size) { switch (size) {
case 4: { case 4: {
int32_t* p = static_cast<int32_t*>(dst); int32_t* p = static_cast<int32_t*>(dst);
p[0] = (src >> 16) | ((~0xFFFF) & p[0]); int r = (p[1] >> 21) & 31;
p[1] = (src & 0xFFFF) | ((~0xFFFF) & p[1]);
p[0] = lis(r, src >> 16);
p[1] = ori(r, r, src);
} break; } break;
default: abort(s); default: abort(s);
@ -532,9 +536,10 @@ class ImmediateListener: public Promise::Listener {
s(s), dst(dst), size(size), offset(offset) s(s), dst(dst), size(size), offset(offset)
{ } { }
virtual void* resolve(int64_t value) { virtual bool resolve(int64_t value, void** location) {
updateImmediate(s, dst, value, size); updateImmediate(s, dst, value, size);
return static_cast<uint8_t*>(dst) + offset; if (location) *location = static_cast<uint8_t*>(dst) + offset;
return false;
} }
System* s; System* s;

View File

@ -246,8 +246,10 @@ class OffsetListener: public Promise::Listener {
instructionSize(instructionSize) instructionSize(instructionSize)
{ } { }
virtual void* resolve(int64_t value) { virtual bool resolve(int64_t value, void** location) {
return resolveOffset(s, instruction, instructionSize, value); void* p = resolveOffset(s, instruction, instructionSize, value);
if (location) *location = p;
return false;
} }
System* s; System* s;
@ -314,9 +316,10 @@ class ImmediateListener: public Promise::Listener {
s(s), dst(dst), size(size), offset(offset) s(s), dst(dst), size(size), offset(offset)
{ } { }
virtual void* resolve(int64_t value) { virtual bool resolve(int64_t value, void** location) {
copy(s, dst, value, size); copy(s, dst, value, size);
return static_cast<uint8_t*>(dst) + offset; if (location) *location = static_cast<uint8_t*>(dst) + offset;
return offset == 0;
} }
System* s; System* s;