fix stack unwinding and GC root scan for new calling convention

This commit is contained in:
Joel Dice 2009-04-26 15:55:35 -06:00
parent 605ddffa31
commit 03653d2dd8

View File

@ -413,7 +413,7 @@ localOffset(MyThread* t, int v, object method)
return offset; return offset;
} }
inline object* object*
localObject(MyThread* t, void* stack, object method, unsigned index) localObject(MyThread* t, void* stack, object method, unsigned index)
{ {
return reinterpret_cast<object*> return reinterpret_cast<object*>
@ -422,6 +422,14 @@ localObject(MyThread* t, void* stack, object method, unsigned index)
+ (t->arch->frameReturnAddressSize() * BytesPerWord)); + (t->arch->frameReturnAddressSize() * BytesPerWord));
} }
void*
stackForFrame(MyThread* t, void* frame, object method)
{
return static_cast<void**>(frame)
- alignedFrameSize(t, method)
- t->arch->frameHeaderSize();
}
class PoolElement: public Promise { class PoolElement: public Promise {
public: public:
PoolElement(Thread* t, object target, PoolElement* next): PoolElement(Thread* t, object target, PoolElement* next):
@ -1306,8 +1314,12 @@ findUnwindTarget(MyThread* t, void** targetIp, void** targetBase,
void* handler = findExceptionHandler(t, method, ip); void* handler = findExceptionHandler(t, method, ip);
t->arch->nextFrame(&stack, &base);
void* canonicalStack = stackForFrame(t, stack, method);
if (handler) { if (handler) {
void** sp = static_cast<void**>(stack) void** sp = static_cast<void**>(canonicalStack)
+ t->arch->frameReturnAddressSize(); + t->arch->frameReturnAddressSize();
sp[localOffset(t, localSize(t, method), method) / BytesPerWord] sp[localOffset(t, localSize(t, method), method) / BytesPerWord]
@ -1324,13 +1336,13 @@ findUnwindTarget(MyThread* t, void** targetIp, void** targetBase,
if (methodFlags(t, method) & ACC_STATIC) { if (methodFlags(t, method) & ACC_STATIC) {
lock = methodClass(t, method); lock = methodClass(t, method);
} else { } else {
lock = *localObject(t, stack, method, savedTargetIndex(t, method)); lock = *localObject
(t, canonicalStack, method, savedTargetIndex(t, method));
} }
release(t, lock); release(t, lock);
} }
t->arch->nextFrame(&stack, &base);
ip = t->arch->frameIp(stack); ip = t->arch->frameIp(stack);
} }
} else { } else {
@ -4445,15 +4457,15 @@ finish(MyThread* t, Allocator* allocator, Context* context)
(&byteArrayBody(t, methodSpec(t, context->method), 0))); (&byteArrayBody(t, methodSpec(t, context->method), 0)));
// for debugging: // for debugging:
if (false and if (//false and
strcmp strcmp
(reinterpret_cast<const char*> (reinterpret_cast<const char*>
(&byteArrayBody(t, className(t, methodClass(t, context->method)), 0)), (&byteArrayBody(t, className(t, methodClass(t, context->method)), 0)),
"java/lang/Throwable") == 0 and "java/lang/Long") == 0 and
strcmp strcmp
(reinterpret_cast<const char*> (reinterpret_cast<const char*>
(&byteArrayBody(t, methodName(t, context->method), 0)), (&byteArrayBody(t, methodName(t, context->method), 0)),
"printStackTrace") == 0) "toString") == 0)
{ {
trap(); trap();
} }
@ -4937,22 +4949,24 @@ frameMapIndex(MyThread* t, object method, int32_t offset)
} }
void void
visitStackAndLocals(MyThread* t, Heap::Visitor* v, void* stack, object method, visitStackAndLocals(MyThread* t, Heap::Visitor* v, void* frame, object method,
void* ip, void* calleeStack, unsigned argumentFootprint) void* ip, bool skipArguments, unsigned argumentFootprint)
{ {
unsigned count; unsigned count;
if (calleeStack) { if (skipArguments) {
count = usableFrameSizeWithParameters(t, method) - argumentFootprint; count = usableFrameSizeWithParameters(t, method) - argumentFootprint;
} else { } else {
count = usableFrameSizeWithParameters(t, method); count = usableFrameSizeWithParameters(t, method);
} }
if (count) { if (count) {
object map = codePool(t, methodCode(t, method)); object map = codePool(t, methodCode(t, method));
int index = frameMapIndex int index = frameMapIndex
(t, method, difference (t, method, difference
(ip, reinterpret_cast<void*>(methodAddress(t, method)))); (ip, reinterpret_cast<void*>(methodAddress(t, method))));
void* stack = stackForFrame(t, frame, method);
for (unsigned i = 0; i < count; ++i) { for (unsigned i = 0; i < count; ++i) {
int j = index + i; int j = index + i;
if ((intArrayBody(t, map, j / 32) if ((intArrayBody(t, map, j / 32)
@ -4975,7 +4989,7 @@ visitStack(MyThread* t, Heap::Visitor* v)
} }
MyThread::CallTrace* trace = t->trace; MyThread::CallTrace* trace = t->trace;
void* calleeStack = 0; bool skipArguments = false;
unsigned argumentFootprint = 0; unsigned argumentFootprint = 0;
while (stack) { while (stack) {
@ -4983,16 +4997,17 @@ visitStack(MyThread* t, Heap::Visitor* v)
if (method) { if (method) {
PROTECT(t, method); PROTECT(t, method);
visitStackAndLocals t->arch->nextFrame(&stack, &base);
(t, v, stack, method, ip, calleeStack, argumentFootprint);
calleeStack = stack; visitStackAndLocals
(t, v, stack, method, ip, skipArguments, argumentFootprint);
skipArguments = true;
argumentFootprint = methodParameterFootprint(t, method); argumentFootprint = methodParameterFootprint(t, method);
t->arch->nextFrame(&stack, &base);
ip = t->arch->frameIp(stack); ip = t->arch->frameIp(stack);
} else if (trace) { } else if (trace) {
calleeStack = 0; skipArguments = false;
argumentFootprint = 0; argumentFootprint = 0;
stack = trace->stack; stack = trace->stack;
base = trace->base; base = trace->base;