diff --git a/src/compile-powerpc.S b/src/compile-powerpc.S index 034ca9321e..03e85b1ff9 100644 --- a/src/compile-powerpc.S +++ b/src/compile-powerpc.S @@ -87,12 +87,12 @@ GLOBAL(vmInvoke): // copy arguments into place li r16,0 + addi r18,r1,ARGUMENT_BASE b LOCAL(vmInvoke_argumentTest) LOCAL(vmInvoke_argumentLoop): lwzx r17,r16,r5 - addi r18,r16,ARGUMENT_BASE - stwx r17,r18,r1 + stwx r17,r16,r18 addi r16,r16,BYTES_PER_WORD LOCAL(vmInvoke_argumentTest): @@ -102,9 +102,8 @@ LOCAL(vmInvoke_argumentTest): // load and call function address mtctr r4 bctrl - -.globl GLOBAL(vmInvoke_returnAddress) -GLOBAL(vmInvoke_returnAddress): + +LOCAL(vmInvoke_returnAddress): // restore stack pointer lwz r1,0(r1) @@ -116,17 +115,18 @@ GLOBAL(vmInvoke_returnAddress): lwz r6,CONTINUATION_LENGTH(r5) slwi r6,r6,2 - subfic r6,r6,-80 - stwux r1,r1,r6 + subfic r7,r6,-80 + stwux r1,r1,r7 addi r7,r5,CONTINUATION_BODY li r8,0 + addi r10,r1,ARGUMENT_BASE b LOCAL(vmInvoke_continuationTest) LOCAL(vmInvoke_continuationLoop): lwzx r9,r7,r8 - stwx r9,r1,r8 + stwx r9,r10,r8 addi r8,r8,4 LOCAL(vmInvoke_continuationTest): @@ -138,8 +138,7 @@ LOCAL(vmInvoke_continuationTest): LOCAL(vmInvoke_getPC): mflr r10 - addis r10,r10,ha16(GLOBAL(vmInvoke_returnAddress)-LOCAL(vmInvoke_getPC)) - la r10,lo16(GLOBAL(vmInvoke_returnAddress)-LOCAL(vmInvoke_getPC))(r10) + la r10,lo16(LOCAL(vmInvoke_returnAddress)-LOCAL(vmInvoke_getPC))(r10) stwx r10,r1,r7 lwz r7,CONTINUATION_FRAME_POINTER_OFFSET(r5) @@ -155,7 +154,7 @@ LOCAL(vmInvoke_getPC): lwz r7,THREAD_EXCEPTION(r13) cmpwi r7,0 bne LOCAL(vmInvoke_handleException) - addi r7,r5,CONTINUATION_ADDRESS + lwz r7,CONTINUATION_ADDRESS(r5) mtctr r7 bctr @@ -170,7 +169,7 @@ LOCAL(vmInvoke_handleException): lwz r8,THREAD_EXCEPTION_OFFSET(r13) stwx r7,r1,r8 - addi r7,r13,THREAD_EXCEPTION_HANDLER + lwz r7,THREAD_EXCEPTION_HANDLER(r13) mtctr r7 bctr @@ -226,6 +225,7 @@ LOCAL(vmInvoke_return): .globl GLOBAL(vmJumpAndInvoke) GLOBAL(vmJumpAndInvoke): +#ifdef AVIAN_CONTINUATIONS // r3: thread // r4: address // r5: (unused) @@ -234,36 +234,50 @@ GLOBAL(vmJumpAndInvoke): // r8: arguments // r9: frameSize + // restore (pseudo)-stack pointer (we don't want to touch the real + // stack pointer, since we haven't copied the arguments yet) + lwz r6,0(r6) + + // make everything between r1 and r6 one big stack frame while we + // shuffle things around stw r6,0(r1) + + // allocate new frame, adding room for callee-saved registers + subfic r10,r9,-80 + stwux r6,r6,r10 mr r13,r3 // copy arguments into place li r9,0 - addi r10,r6,ARGUMENT_BASE + addi r11,r6,ARGUMENT_BASE b LOCAL(vmJumpAndInvoke_argumentTest) LOCAL(vmJumpAndInvoke_argumentLoop): - lwzx r11,r8,r9 - stwx r11,r10,r9 + lwzx r12,r8,r9 + stwx r12,r11,r9 addi r9,r9,4 LOCAL(vmJumpAndInvoke_argumentTest): cmplw r9,r7 ble LOCAL(vmJumpAndInvoke_argumentLoop) - subf r7,r6,r9 - stw r6,0(r7) - mr r1,r7 + // the arguments have been copied, so we can set the real stack + // pointer now + mr r1,r6 - // set return address + // set return address to vmInvoke_returnAddress bl LOCAL(vmJumpAndInvoke_getPC) LOCAL(vmJumpAndInvoke_getPC): mflr r10 - addis r10,r10,ha16(GLOBAL(vmInvoke_returnAddress)-LOCAL(vmJumpAndInvoke_getPC)) - la r10,lo16(GLOBAL(vmInvoke_returnAddress)-LOCAL(vmJumpAndInvoke_getPC))(r10) + la r10,lo16(LOCAL(vmInvoke_returnAddress)-LOCAL(vmJumpAndInvoke_getPC))(r10) mtlr r10 mtctr r4 bctr +#else // not AVIAN_CONTINUATIONS + // vmJumpAndInvoke should only be called when continuations are + // enabled + trap +#endif // not AVIAN_CONTINUATIONS diff --git a/src/compile.cpp b/src/compile.cpp index fe5a05d3ea..8d51a80b5c 100644 --- a/src/compile.cpp +++ b/src/compile.cpp @@ -1380,7 +1380,7 @@ releaseLock(MyThread* t, object method, void* stack) void findUnwindTarget(MyThread* t, void** targetIp, void** targetBase, - void** targetStack, unsigned* oldArgumentFootprint = 0) + void** targetStack) { void* ip = t->ip; void* base = t->base; @@ -1427,11 +1427,6 @@ findUnwindTarget(MyThread* t, void** targetIp, void** targetBase, *targetStack = static_cast(stack) + t->arch->frameReturnAddressSize(); - if (oldArgumentFootprint) { - *oldArgumentFootprint - = t->arch->argumentFootprint(methodParameterFootprint(t, target)); - } - while (Continuations and t->continuation) { object c = t->continuation; @@ -1468,7 +1463,7 @@ findUnwindTarget(MyThread* t, void** targetIp, void** targetBase, object makeCurrentContinuation(MyThread* t, void** targetIp, void** targetBase, - void** targetStack, unsigned* oldArgumentFootprint) + void** targetStack) { void* ip = t->ip; void* base = t->base; @@ -1498,7 +1493,8 @@ makeCurrentContinuation(MyThread* t, void** targetIp, void** targetBase, PROTECT(t, method); void** top = static_cast(stack) - + t->arch->frameReturnAddressSize(); + + t->arch->frameReturnAddressSize() + + t->arch->frameFooterSize(); unsigned argumentFootprint = t->arch->argumentFootprint(methodParameterFootprint(t, target)); unsigned alignment = t->arch->stackAlignmentInWords(); @@ -1518,9 +1514,11 @@ makeCurrentContinuation(MyThread* t, void** targetIp, void** targetBase, object c = makeContinuation (t, 0, context, method, ip, ((frameSize + + t->arch->frameFooterSize() + t->arch->returnAddressOffset() - t->arch->frameReturnAddressSize()) * BytesPerWord), ((frameSize + + t->arch->frameFooterSize() + t->arch->framePointerOffset() - t->arch->frameReturnAddressSize()) * BytesPerWord), totalSize); @@ -1541,9 +1539,7 @@ makeCurrentContinuation(MyThread* t, void** targetIp, void** targetBase, *targetIp = ip; *targetBase = base; *targetStack = static_cast(stack) - + t->arch->frameReturnAddressSize(); - *oldArgumentFootprint - = t->arch->argumentFootprint(methodParameterFootprint(t, target)); + + t->arch->frameReturnAddressSize();; } } @@ -5392,8 +5388,7 @@ compatibleReturnType(MyThread* t, object oldMethod, object newMethod) } void -jumpAndInvoke(MyThread* t, object method, void* base, void* stack, - unsigned oldArgumentFootprint, ...) +jumpAndInvoke(MyThread* t, object method, void* base, void* stack, ...) { t->trace->targetMethod = 0; @@ -5405,7 +5400,7 @@ jumpAndInvoke(MyThread* t, object method, void* base, void* stack, unsigned argumentCount = methodParameterFootprint(t, method); uintptr_t arguments[argumentCount]; - va_list a; va_start(a, oldArgumentFootprint); + va_list a; va_start(a, stack); for (unsigned i = 0; i < argumentCount; ++i) { arguments[i] = va_arg(a, uintptr_t); } @@ -5417,10 +5412,8 @@ jumpAndInvoke(MyThread* t, object method, void* base, void* stack, stack, argumentCount * BytesPerWord, arguments, - (oldArgumentFootprint - - t->arch->argumentFootprint(argumentCount) - - t->arch->frameFooterSize() - - t->arch->frameReturnAddressSize()) * BytesPerWord); + t->arch->alignFrameSize(t->arch->argumentFootprint(argumentCount)) + * BytesPerWord); } void @@ -5527,8 +5520,7 @@ callContinuation(MyThread* t, object continuation, object result, void* ip; void* base; void* stack; - unsigned oldArgumentFootprint; - findUnwindTarget(t, &ip, &base, &stack, &oldArgumentFootprint); + findUnwindTarget(t, &ip, &base, &stack); switch (action) { case Call: { @@ -5543,7 +5535,7 @@ callContinuation(MyThread* t, object continuation, object result, t->continuation = nextContinuation; jumpAndInvoke - (t, rewindMethod(t), base, stack, oldArgumentFootprint, + (t, rewindMethod(t), base, stack, continuationContextBefore(t, continuationContext(t, nextContinuation)), continuation, result, exception); } break; @@ -5564,7 +5556,6 @@ callWithCurrentContinuation(MyThread* t, object receiver) void* ip = 0; void* base = 0; void* stack = 0; - unsigned oldArgumentFootprint = 0; { PROTECT(t, receiver); @@ -5601,16 +5592,13 @@ callWithCurrentContinuation(MyThread* t, object receiver) compile(t, ::codeAllocator(t), 0, method); if (LIKELY(t->exception == 0)) { - t->continuation = makeCurrentContinuation - (t, &ip, &base, &stack, &oldArgumentFootprint); + t->continuation = makeCurrentContinuation(t, &ip, &base, &stack); } } } if (LIKELY(t->exception == 0)) { - jumpAndInvoke - (t, method, base, stack, oldArgumentFootprint, receiver, - t->continuation); + jumpAndInvoke(t, method, base, stack, receiver, t->continuation); } else { unwind(t); } @@ -5622,7 +5610,6 @@ dynamicWind(MyThread* t, object before, object thunk, object after) void* ip = 0; void* base = 0; void* stack = 0; - unsigned oldArgumentFootprint = 0; { PROTECT(t, before); PROTECT(t, thunk); @@ -5648,8 +5635,7 @@ dynamicWind(MyThread* t, object before, object thunk, object after) } if (LIKELY(t->exception == 0)) { - t->continuation = makeCurrentContinuation - (t, &ip, &base, &stack, &oldArgumentFootprint); + t->continuation = makeCurrentContinuation(t, &ip, &base, &stack); object newContext = makeContinuationContext (t, continuationContext(t, t->continuation), before, after, @@ -5660,9 +5646,7 @@ dynamicWind(MyThread* t, object before, object thunk, object after) } if (LIKELY(t->exception == 0)) { - jumpAndInvoke - (t, windMethod(t), base, stack, oldArgumentFootprint, before, thunk, - after); + jumpAndInvoke(t, windMethod(t), base, stack, before, thunk, after); } else { unwind(t); }