more progress on PowerPC build

Also, hide frame mapping for stack unwinding (which is still
incomplete) in x86.cpp, since no other platform needs it.
This commit is contained in:
Joel Dice 2011-01-30 14:14:57 -07:00
parent 1187613ad0
commit fff51bad06
8 changed files with 121 additions and 152 deletions

View File

@ -1618,7 +1618,7 @@ argumentFootprint(unsigned footprint)
void
nextFrame(ArchitectureContext* c, uint32_t* start, unsigned size UNUSED,
unsigned footprint, int32_t*, void* link, void*,
unsigned footprint, void* link, void*,
unsigned targetParameterFootprint UNUSED, void** ip, void** stack)
{
assert(c, *ip >= start);
@ -1891,12 +1891,12 @@ class MyArchitecture: public Assembler::Architecture {
}
virtual void nextFrame(void* start, unsigned size, unsigned footprint,
int32_t* frameTable, void* link, void* stackLimit,
void* link, void* stackLimit,
unsigned targetParameterFootprint, void** ip,
void** stack)
{
::nextFrame(&c, static_cast<uint32_t*>(start), size, footprint, frameTable,
link, stackLimit, targetParameterFootprint, ip, stack);
::nextFrame(&c, static_cast<uint32_t*>(start), size, footprint, link,
stackLimit, targetParameterFootprint, ip, stack);
}
virtual void* frameIp(void* stack) {
@ -1923,12 +1923,6 @@ class MyArchitecture: public Assembler::Architecture {
return 0;
}
virtual void nextFrame(void** stack, void**) {
assert(&c, *static_cast<void**>(*stack) != *stack);
*stack = *static_cast<void**>(*stack);
}
virtual BinaryOperation hasBinaryIntrinsic(Thread*, object) {
return NoBinaryOperation;
}
@ -2120,6 +2114,18 @@ class MyAssembler: public Assembler {
return arch_;
}
virtual void checkStackOverflow(uintptr_t handler,
unsigned stackLimitOffsetFromThread)
{
Register stack(StackRegister);
Memory stackLimit(ThreadRegister, stackLimitOffsetFromThread);
Constant handlerConstant
(new (c.zone->allocate(sizeof(ResolvedPromise)))
ResolvedPromise(handler));
branchRM(&c, JumpIfGreaterOrEqual, BytesPerWord, &stack, &stackLimit,
&handlerConstant);
}
virtual void saveFrame(unsigned stackOffset) {
Register stack(StackRegister);
Memory stackDst(ThreadRegister, stackOffset);
@ -2444,11 +2450,7 @@ class MyAssembler: public Assembler {
return c.code.length();
}
virtual unsigned frameEventCount() {
return 0;
}
virtual FrameEvent* firstFrameEvent() {
virtual unsigned footerSize() {
return 0;
}

View File

@ -304,12 +304,6 @@ class Assembler {
virtual unsigned resolve(unsigned start, Block* next) = 0;
};
class FrameEvent {
public:
virtual unsigned offset() = 0;
virtual FrameEvent* next() = 0;
};
class Architecture {
public:
virtual unsigned floatRegisterSize() = 0;
@ -351,7 +345,7 @@ class Assembler {
virtual unsigned alignFrameSize(unsigned sizeInWords) = 0;
virtual void nextFrame(void* start, unsigned size, unsigned footprint,
int32_t* frameTable, void* link, void* stackLimit,
void* link, void* stackLimit,
unsigned targetParameterFootprint, void** ip,
void** stack) = 0;
virtual void* frameIp(void* stack) = 0;
@ -401,6 +395,8 @@ class Assembler {
virtual Architecture* arch() = 0;
virtual void checkStackOverflow(uintptr_t handler,
unsigned stackLimitOffsetFromThread) = 0;
virtual void saveFrame(unsigned stackOffset) = 0;
virtual void pushFrame(unsigned argumentCount, ...) = 0;
virtual void allocateFrame(unsigned footprint) = 0;
@ -440,9 +436,7 @@ class Assembler {
virtual unsigned length() = 0;
virtual unsigned frameEventCount() = 0;
virtual FrameEvent* firstFrameEvent() = 0;
virtual unsigned footerSize() = 0;
virtual void dispose() = 0;
};

View File

@ -396,35 +396,10 @@ alignedFrameSize(MyThread* t, object method)
+ t->arch->frameFootprint(MaxNativeCallFootprint));
}
unsigned
bitsNeeded(unsigned v)
{
return log(v + 1);
}
void
setTableValue(Thread* t, object table, unsigned base, unsigned max,
unsigned index, unsigned value)
{
unsigned bits = bitsNeeded(max);
setBits<int32_t>
(&intArrayBody(t, table, base), bits, index * bits, value);
}
unsigned
getTableValue(Thread* t, object table, unsigned base, unsigned max,
unsigned index)
{
unsigned bits = bitsNeeded(max);
return getBits<int32_t>
(&intArrayBody(t, table, base), bits, index * bits);
}
void
nextFrame(MyThread* t, void** ip, void** sp, object method, object target)
{
object code = methodCode(t, method);
object table = codeFrameTable(t, code);
intptr_t start = codeCompiled(t, code);
void* link;
void* javaStackLimit;
@ -454,9 +429,8 @@ nextFrame(MyThread* t, void** ip, void** sp, object method, object target)
t->arch->nextFrame
(reinterpret_cast<void*>(start), compiledSize(start),
alignedFrameSize(t, method), table ? &intArrayBody(t, table, 0) : 0,
link, javaStackLimit, target ? methodParameterFootprint(t, target) : -1,
ip, sp);
alignedFrameSize(t, method), link, javaStackLimit,
target ? methodParameterFootprint(t, target) : -1, ip, sp);
// fprintf(stderr, "next frame ip %p sp %p\n", *ip, *sp);
}
@ -5226,37 +5200,6 @@ translateLineNumberTable(MyThread* t, Compiler* c, object code, intptr_t start)
}
}
object
makeFrameTable(MyThread* t, Context* c, unsigned codeSize)
{
Assembler* a = c->assembler;
unsigned count = a->frameEventCount();
if (count == 0) {
return 0;
}
unsigned size = ceiling(count * bitsNeeded(codeSize), 32);
object table = makeIntArray(t, 1 + size);
intArrayBody(t, table, 0) = count;
unsigned index = 0;
for (Assembler::FrameEvent* e = a->firstFrameEvent();
e; e = e->next())
{
assert(t, index < count);
unsigned offset = e->offset();
assert(t, offset <= codeSize);
setTableValue(t, table, 1, codeSize, index, offset);
++ index;
}
return table;
}
void
printSet(uintptr_t m, unsigned limit)
{
@ -5943,14 +5886,10 @@ finish(MyThread* t, Allocator* allocator, Context* context)
(t, c, methodCode(t, context->method),
reinterpret_cast<intptr_t>(start));
PROTECT(t, newLineNumberTable);
object frameTable = makeFrameTable(t, context, codeSize);
object code = methodCode(t, context->method);
code = makeCode
(t, 0, newExceptionHandlerTable, newLineNumberTable, frameTable,
(t, 0, newExceptionHandlerTable, newLineNumberTable,
reinterpret_cast<uintptr_t>(start), codeMaxStack(t, code),
codeMaxLocals(t, code), 0);

View File

@ -5720,12 +5720,7 @@ compile(Context* c, uintptr_t stackOverflowHandler, unsigned stackLimitOffset)
Block* block = firstBlock;
if (stackOverflowHandler) {
Assembler::Register stack(c->arch->stack());
Assembler::Memory stackLimit(c->arch->thread(), stackLimitOffset);
Assembler::Constant handler(resolved(c, stackOverflowHandler));
a->apply(JumpIfGreaterOrEqual, BytesPerWord, RegisterOperand, &stack,
BytesPerWord, MemoryOperand, &stackLimit,
BytesPerWord, ConstantOperand, &handler);
a->checkStackOverflow(stackOverflowHandler, stackLimitOffset);
}
a->allocateFrame(c->alignedFrameSize);
@ -5854,7 +5849,7 @@ compile(Context* c, uintptr_t stackOverflowHandler, unsigned stackLimitOffset)
block = next;
}
return block->assemblerBlock->resolve(block->start, 0);
return block->assemblerBlock->resolve(block->start, 0) + a->footerSize();
}
unsigned

View File

@ -1227,7 +1227,7 @@ parseCode(Thread* t, Stream& s, object pool)
unsigned maxLocals = s.read2();
unsigned length = s.read4();
object code = makeCode(t, pool, 0, 0, 0, 0, maxStack, maxLocals, length);
object code = makeCode(t, pool, 0, 0, 0, maxStack, maxLocals, length);
s.read(&codeBody(t, code, 0), length);
PROTECT(t, code);
@ -2065,7 +2065,7 @@ boot(Thread* t)
m->processor->boot(t, 0);
{ object bootCode = makeCode(t, 0, 0, 0, 0, 0, 0, 0, 1);
{ object bootCode = makeCode(t, 0, 0, 0, 0, 0, 0, 1);
codeBody(t, bootCode, 0) = impdep1;
object bootMethod = makeMethod
(t, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, bootCode);

View File

@ -191,13 +191,15 @@ class MyBlock: public Assembler::Block {
class Task;
class ConstantPoolEntry;
class JumpPromise;
class Context {
public:
Context(System* s, Allocator* a, Zone* zone):
s(s), zone(zone), client(0), code(s, a, 1024), tasks(0), result(0),
firstBlock(new (zone->allocate(sizeof(MyBlock))) MyBlock(0)),
lastBlock(firstBlock), constantPool(0), constantPoolCount(0)
lastBlock(firstBlock), constantPool(0), jumps(0), constantPoolCount(0),
jumpCount(0)
{ }
System* s;
@ -209,7 +211,9 @@ class Context {
MyBlock* firstBlock;
MyBlock* lastBlock;
ConstantPoolEntry* constantPool;
JumpPromise* jumps;
unsigned constantPoolCount;
unsigned jumpCount;
};
class Task {
@ -312,6 +316,38 @@ offset(Context* c)
Offset(c, c->lastBlock, c->code.length());
}
class JumpPromise: public Promise {
public:
JumpPromise(Context* c, uintptr_t target):
c(c), target(target), next(c->jumps), index(c->jumpCount++)
{
c->jumps = this;
}
virtual bool resolved() {
return c->result != 0;
}
virtual int64_t value() {
assert(c, resolved());
return reinterpret_cast<intptr_t>
(c->result + c->code.length() + (index * BytesPerWord));
}
Context* c;
uintptr_t target;
JumpPromise* next;
unsigned index;
};
Promise*
jump(Context* c, uintptr_t target)
{
return new (c->zone->allocate(sizeof(JumpPromise)))
JumpPromise(c, target);
}
bool
bounded(int right, int left, int32_t v)
{
@ -659,7 +695,6 @@ class ConstantPoolEntry: public Promise {
Promise* constant;
ConstantPoolEntry* next;
void* address;
unsigned constantPoolCount;
};
ConstantPoolEntry*
@ -1699,7 +1734,7 @@ argumentFootprint(unsigned footprint)
void
nextFrame(ArchitectureContext* c UNUSED, int32_t* start, unsigned size UNUSED,
unsigned footprint, int32_t*, void* link, void*,
unsigned footprint, void* link, void*,
unsigned targetParameterFootprint, void** ip, void** stack)
{
assert(c, *ip >= start);
@ -1970,12 +2005,12 @@ class MyArchitecture: public Assembler::Architecture {
}
virtual void nextFrame(void* start, unsigned size, unsigned footprint,
int32_t* frameTable, void* link, void* stackLimit,
void* link, void* stackLimit,
unsigned targetParameterFootprint, void** ip,
void** stack)
{
::nextFrame(&c, static_cast<int32_t*>(start), size, footprint, frameTable,
link, stackLimit, targetParameterFootprint, ip, stack);
::nextFrame(&c, static_cast<int32_t*>(start), size, footprint, link,
stackLimit, targetParameterFootprint, ip, stack);
}
virtual void* frameIp(void* stack) {
@ -2002,12 +2037,6 @@ class MyArchitecture: public Assembler::Architecture {
return 0;
}
virtual void nextFrame(void** stack, void**) {
assert(&c, *static_cast<void**>(*stack) != *stack);
*stack = *static_cast<void**>(*stack);
}
virtual BinaryOperation hasBinaryIntrinsic(Thread*, object) {
return NoBinaryOperation;
}
@ -2203,6 +2232,16 @@ class MyAssembler: public Assembler {
return arch_;
}
virtual void checkStackOverflow(uintptr_t handler,
unsigned stackLimitOffsetFromThread)
{
Register stack(StackRegister);
Memory stackLimit(ThreadRegister, stackLimitOffsetFromThread);
Constant handlerConstant(jump(&c, handler));
branchRM(&c, JumpIfGreaterOrEqual, BytesPerWord, &stack, &stackLimit,
&handlerConstant);
}
virtual void saveFrame(unsigned stackOffset) {
Register returnAddress(0);
emit(&c, mflr(returnAddress.low));
@ -2420,12 +2459,20 @@ class MyAssembler: public Assembler {
virtual void writeTo(uint8_t* dst) {
c.result = dst;
for (MyBlock* b = c.firstBlock; b; b = b->next) {
memcpy(dst + b->start, c.code.data + b->offset, b->size);
}
for (JumpPromise* j = c.jumps; j; j = j->next) {
uint8_t* instruction
= dst + c.code.length() + (c.jumpCount - j->index - 1);
int32_t op = ::b(0);
memcpy(instruction, &op, BytesPerWord);
updateOffset(c.s, instruction, false, j->target);
}
unsigned index = c.code.length();
unsigned index = c.code.length() + (c.jumpCount * BytesPerWord);
assert(&c, index % BytesPerWord == 0);
for (ConstantPoolEntry* e = c.constantPool; e; e = e->next) {
e->address = dst + index;
@ -2466,12 +2513,8 @@ class MyAssembler: public Assembler {
return c.code.length();
}
virtual unsigned frameEventCount() {
return 0;
}
virtual FrameEvent* firstFrameEvent() {
return 0;
virtual unsigned footerSize() {
return (c.jumpCount + c.constantPoolCount) * BytesPerWord;
}
virtual void dispose() {

View File

@ -86,7 +86,6 @@
(object pool)
(object exceptionHandlerTable)
(object lineNumberTable)
(object frameTable)
(intptr_t compiled)
(uint16_t maxStack)
(uint16_t maxLocals)

View File

@ -86,7 +86,7 @@ isInt32(intptr_t v)
class Task;
class AlignmentPadding;
class MyFrameEvent;
class FrameEvent;
unsigned
padding(AlignmentPadding* p, unsigned index, unsigned offset,
@ -115,8 +115,8 @@ class MyBlock: public Assembler::Block {
MyBlock* next;
AlignmentPadding* firstPadding;
AlignmentPadding* lastPadding;
MyFrameEvent* firstFrameEvent;
MyFrameEvent* lastFrameEvent;
FrameEvent* firstFrameEvent;
FrameEvent* lastFrameEvent;
unsigned offset;
unsigned start;
unsigned size;
@ -171,8 +171,8 @@ class Context {
uint8_t* result;
MyBlock* firstBlock;
MyBlock* lastBlock;
MyFrameEvent* firstFrameEvent;
MyFrameEvent* lastFrameEvent;
FrameEvent* firstFrameEvent;
FrameEvent* lastFrameEvent;
ArchitectureContext* ac;
unsigned frameEventCount;
};
@ -461,33 +461,25 @@ padding(AlignmentPadding* p, unsigned start, unsigned offset,
return padding;
}
class MyFrameEvent: public Assembler::FrameEvent {
class FrameEvent {
public:
MyFrameEvent(Context* c, Promise* offset):
c(c), next_(0), offset_(offset)
FrameEvent(Context* c, Promise* offset):
c(c), next(0), offset(offset)
{ }
virtual unsigned offset() {
return offset_->value();
}
virtual Assembler::FrameEvent* next() {
return next_;
}
Context* c;
MyFrameEvent* next_;
Promise* offset_;
FrameEvent* next;
Promise* offset;
};
void
appendFrameEvent(Context* c, MyBlock* b, Promise* offset)
{
MyFrameEvent* e = new (c->zone->allocate(sizeof(MyFrameEvent)))
MyFrameEvent(c, offset);
FrameEvent* e = new (c->zone->allocate(sizeof(FrameEvent)))
FrameEvent(c, offset);
if (b->firstFrameEvent) {
b->lastFrameEvent->next_ = e;
b->lastFrameEvent->next = e;
} else {
b->firstFrameEvent = e;
}
@ -2577,7 +2569,7 @@ read4(uint8_t* p)
void
nextFrame(ArchitectureContext* c UNUSED, uint8_t* start, unsigned size UNUSED,
unsigned footprint, int32_t*, void*, void* stackLimit,
unsigned footprint, void*, void* stackLimit,
unsigned targetParameterFootprint, void** ip, void** stack)
{
assert(c, *ip >= start);
@ -2643,7 +2635,7 @@ nextFrame(ArchitectureContext* c UNUSED, uint8_t* start, unsigned size UNUSED,
/ BytesPerWord;
}
// todo: use frameTable to check for and handle tail calls
// todo: check for and handle tail calls
}
*ip = static_cast<void**>(*stack)[offset];
@ -2977,13 +2969,12 @@ class MyArchitecture: public Assembler::Architecture {
}
virtual void nextFrame(void* start, unsigned size, unsigned footprint,
int32_t* frameTable, void* link, void* stackLimit,
void* link, void* stackLimit,
unsigned targetParameterFootprint, void** ip,
void** stack)
{
local::nextFrame(&c, static_cast<uint8_t*>(start), size, footprint,
frameTable, link, stackLimit, targetParameterFootprint,
ip, stack);
link, stackLimit, targetParameterFootprint, ip, stack);
}
virtual void* frameIp(void* stack) {
@ -3421,6 +3412,16 @@ class MyAssembler: public Assembler {
return arch_;
}
virtual void checkStackOverflow(uintptr_t handler,
unsigned stackLimitOffsetFromThread)
{
Register stack(rsp);
Memory stackLimit(rbx, stackLimitOffsetFromThread);
Constant handlerConstant(resolved(&c, handler));
branchRM(&c, JumpIfGreaterOrEqual, BytesPerWord, &stack, &stackLimit,
&handlerConstant);
}
virtual void saveFrame(unsigned stackOffset) {
Register stack(rsp);
Memory stackDst(rbx, stackOffset);
@ -3661,7 +3662,7 @@ class MyAssembler: public Assembler {
for (MyBlock* b = c.firstBlock; b; b = b->next) {
if (b->firstFrameEvent) {
if (c.firstFrameEvent) {
c.lastFrameEvent->next_ = b->firstFrameEvent;
c.lastFrameEvent->next = b->firstFrameEvent;
} else {
c.firstFrameEvent = b->firstFrameEvent;
}
@ -3721,12 +3722,8 @@ class MyAssembler: public Assembler {
return c.code.length();
}
virtual unsigned frameEventCount() {
return c.frameEventCount;
}
virtual FrameEvent* firstFrameEvent() {
return c.firstFrameEvent;
virtual unsigned footerSize() {
return 0;
}
virtual void dispose() {