From d308ba93c7aa25f28fee4f65af70fcfb5b18130b Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Fri, 25 Jun 2010 21:13:59 -0600 Subject: [PATCH] fix tails=true bootimage=true build compileDirectInvoke does some magic to optimize tail calls to native methods which involves storing the return address (which we'll never actually return to, since it's a tail call) in a thread-local field so the thunk function can figure out which native method to look up at runtime. Since this address will change when the boot image is loaded, the boot image creation code needs to know about it. --- src/compile.cpp | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/compile.cpp b/src/compile.cpp index e2cd28c1a5..bba40493f4 100644 --- a/src/compile.cpp +++ b/src/compile.cpp @@ -2770,12 +2770,13 @@ compileDirectInvoke(MyThread* t, Frame* frame, object target, bool tailCall, traceFlags |= TraceElement::TailCall; TraceElement* trace = frame->trace(target, traceFlags); - Compiler::Operand* returnAddress = c->promiseConstant - (new (frame->context->zone.allocate(sizeof(TraceElementPromise))) - TraceElementPromise(t->m->system, trace), Compiler::AddressType); + + Promise* returnAddressPromise = new + (frame->context->zone.allocate(sizeof(TraceElementPromise))) + TraceElementPromise(t->m->system, trace); Compiler::Operand* result = c->stackCall - (returnAddress, + (c->promiseConstant(returnAddressPromise, Compiler::AddressType), flags, trace, rSize, @@ -2783,7 +2784,8 @@ compileDirectInvoke(MyThread* t, Frame* frame, object target, bool tailCall, methodParameterFootprint(t, target)); c->store - (BytesPerWord, returnAddress, BytesPerWord, c->memory + (BytesPerWord, frame->addressOperand(returnAddressPromise), + BytesPerWord, c->memory (c->register_(t->arch->thread()), Compiler::AddressType, difference(&(t->tailAddress), t))); @@ -2832,8 +2834,10 @@ compileDirectInvoke(MyThread* t, Frame* frame, object target, bool tailCall) } else { BootContext* bc = frame->context->bootContext; if (bc) { - if (methodClass(t, target) == methodClass(t, frame->context->method) - or (not classNeedsInit(t, methodClass(t, target)))) + if ((methodClass(t, target) == methodClass(t, frame->context->method) + or (not classNeedsInit(t, methodClass(t, target)))) + and (not (TailCalls and tailCall + and (methodFlags(t, target) & ACC_NATIVE)))) { Promise* p = new (bc->zone->allocate(sizeof(ListenPromise))) ListenPromise(t->m->system, bc->zone);