several bugfixes for powerpc continuations

This commit is contained in:
Joel Dice 2009-05-28 18:56:05 -06:00
parent ca4e62cdb7
commit d99f8df6e6
2 changed files with 52 additions and 54 deletions

View File

@ -87,12 +87,12 @@ GLOBAL(vmInvoke):
// copy arguments into place // copy arguments into place
li r16,0 li r16,0
addi r18,r1,ARGUMENT_BASE
b LOCAL(vmInvoke_argumentTest) b LOCAL(vmInvoke_argumentTest)
LOCAL(vmInvoke_argumentLoop): LOCAL(vmInvoke_argumentLoop):
lwzx r17,r16,r5 lwzx r17,r16,r5
addi r18,r16,ARGUMENT_BASE stwx r17,r16,r18
stwx r17,r18,r1
addi r16,r16,BYTES_PER_WORD addi r16,r16,BYTES_PER_WORD
LOCAL(vmInvoke_argumentTest): LOCAL(vmInvoke_argumentTest):
@ -103,8 +103,7 @@ LOCAL(vmInvoke_argumentTest):
mtctr r4 mtctr r4
bctrl bctrl
.globl GLOBAL(vmInvoke_returnAddress) LOCAL(vmInvoke_returnAddress):
GLOBAL(vmInvoke_returnAddress):
// restore stack pointer // restore stack pointer
lwz r1,0(r1) lwz r1,0(r1)
@ -116,17 +115,18 @@ GLOBAL(vmInvoke_returnAddress):
lwz r6,CONTINUATION_LENGTH(r5) lwz r6,CONTINUATION_LENGTH(r5)
slwi r6,r6,2 slwi r6,r6,2
subfic r6,r6,-80 subfic r7,r6,-80
stwux r1,r1,r6 stwux r1,r1,r7
addi r7,r5,CONTINUATION_BODY addi r7,r5,CONTINUATION_BODY
li r8,0 li r8,0
addi r10,r1,ARGUMENT_BASE
b LOCAL(vmInvoke_continuationTest) b LOCAL(vmInvoke_continuationTest)
LOCAL(vmInvoke_continuationLoop): LOCAL(vmInvoke_continuationLoop):
lwzx r9,r7,r8 lwzx r9,r7,r8
stwx r9,r1,r8 stwx r9,r10,r8
addi r8,r8,4 addi r8,r8,4
LOCAL(vmInvoke_continuationTest): LOCAL(vmInvoke_continuationTest):
@ -138,8 +138,7 @@ LOCAL(vmInvoke_continuationTest):
LOCAL(vmInvoke_getPC): LOCAL(vmInvoke_getPC):
mflr r10 mflr r10
addis r10,r10,ha16(GLOBAL(vmInvoke_returnAddress)-LOCAL(vmInvoke_getPC)) la r10,lo16(LOCAL(vmInvoke_returnAddress)-LOCAL(vmInvoke_getPC))(r10)
la r10,lo16(GLOBAL(vmInvoke_returnAddress)-LOCAL(vmInvoke_getPC))(r10)
stwx r10,r1,r7 stwx r10,r1,r7
lwz r7,CONTINUATION_FRAME_POINTER_OFFSET(r5) lwz r7,CONTINUATION_FRAME_POINTER_OFFSET(r5)
@ -155,7 +154,7 @@ LOCAL(vmInvoke_getPC):
lwz r7,THREAD_EXCEPTION(r13) lwz r7,THREAD_EXCEPTION(r13)
cmpwi r7,0 cmpwi r7,0
bne LOCAL(vmInvoke_handleException) bne LOCAL(vmInvoke_handleException)
addi r7,r5,CONTINUATION_ADDRESS lwz r7,CONTINUATION_ADDRESS(r5)
mtctr r7 mtctr r7
bctr bctr
@ -170,7 +169,7 @@ LOCAL(vmInvoke_handleException):
lwz r8,THREAD_EXCEPTION_OFFSET(r13) lwz r8,THREAD_EXCEPTION_OFFSET(r13)
stwx r7,r1,r8 stwx r7,r1,r8
addi r7,r13,THREAD_EXCEPTION_HANDLER lwz r7,THREAD_EXCEPTION_HANDLER(r13)
mtctr r7 mtctr r7
bctr bctr
@ -226,6 +225,7 @@ LOCAL(vmInvoke_return):
.globl GLOBAL(vmJumpAndInvoke) .globl GLOBAL(vmJumpAndInvoke)
GLOBAL(vmJumpAndInvoke): GLOBAL(vmJumpAndInvoke):
#ifdef AVIAN_CONTINUATIONS
// r3: thread // r3: thread
// r4: address // r4: address
// r5: (unused) // r5: (unused)
@ -234,36 +234,50 @@ GLOBAL(vmJumpAndInvoke):
// r8: arguments // r8: arguments
// r9: frameSize // 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) stw r6,0(r1)
// allocate new frame, adding room for callee-saved registers
subfic r10,r9,-80
stwux r6,r6,r10
mr r13,r3 mr r13,r3
// copy arguments into place // copy arguments into place
li r9,0 li r9,0
addi r10,r6,ARGUMENT_BASE addi r11,r6,ARGUMENT_BASE
b LOCAL(vmJumpAndInvoke_argumentTest) b LOCAL(vmJumpAndInvoke_argumentTest)
LOCAL(vmJumpAndInvoke_argumentLoop): LOCAL(vmJumpAndInvoke_argumentLoop):
lwzx r11,r8,r9 lwzx r12,r8,r9
stwx r11,r10,r9 stwx r12,r11,r9
addi r9,r9,4 addi r9,r9,4
LOCAL(vmJumpAndInvoke_argumentTest): LOCAL(vmJumpAndInvoke_argumentTest):
cmplw r9,r7 cmplw r9,r7
ble LOCAL(vmJumpAndInvoke_argumentLoop) ble LOCAL(vmJumpAndInvoke_argumentLoop)
subf r7,r6,r9 // the arguments have been copied, so we can set the real stack
stw r6,0(r7) // pointer now
mr r1,r7 mr r1,r6
// set return address // set return address to vmInvoke_returnAddress
bl LOCAL(vmJumpAndInvoke_getPC) bl LOCAL(vmJumpAndInvoke_getPC)
LOCAL(vmJumpAndInvoke_getPC): LOCAL(vmJumpAndInvoke_getPC):
mflr r10 mflr r10
addis r10,r10,ha16(GLOBAL(vmInvoke_returnAddress)-LOCAL(vmJumpAndInvoke_getPC)) la r10,lo16(LOCAL(vmInvoke_returnAddress)-LOCAL(vmJumpAndInvoke_getPC))(r10)
la r10,lo16(GLOBAL(vmInvoke_returnAddress)-LOCAL(vmJumpAndInvoke_getPC))(r10)
mtlr r10 mtlr r10
mtctr r4 mtctr r4
bctr bctr
#else // not AVIAN_CONTINUATIONS
// vmJumpAndInvoke should only be called when continuations are
// enabled
trap
#endif // not AVIAN_CONTINUATIONS

View File

@ -1380,7 +1380,7 @@ releaseLock(MyThread* t, object method, void* stack)
void void
findUnwindTarget(MyThread* t, void** targetIp, void** targetBase, findUnwindTarget(MyThread* t, void** targetIp, void** targetBase,
void** targetStack, unsigned* oldArgumentFootprint = 0) void** targetStack)
{ {
void* ip = t->ip; void* ip = t->ip;
void* base = t->base; void* base = t->base;
@ -1427,11 +1427,6 @@ findUnwindTarget(MyThread* t, void** targetIp, void** targetBase,
*targetStack = static_cast<void**>(stack) *targetStack = static_cast<void**>(stack)
+ t->arch->frameReturnAddressSize(); + t->arch->frameReturnAddressSize();
if (oldArgumentFootprint) {
*oldArgumentFootprint
= t->arch->argumentFootprint(methodParameterFootprint(t, target));
}
while (Continuations and t->continuation) { while (Continuations and t->continuation) {
object c = t->continuation; object c = t->continuation;
@ -1468,7 +1463,7 @@ findUnwindTarget(MyThread* t, void** targetIp, void** targetBase,
object object
makeCurrentContinuation(MyThread* t, void** targetIp, void** targetBase, makeCurrentContinuation(MyThread* t, void** targetIp, void** targetBase,
void** targetStack, unsigned* oldArgumentFootprint) void** targetStack)
{ {
void* ip = t->ip; void* ip = t->ip;
void* base = t->base; void* base = t->base;
@ -1498,7 +1493,8 @@ makeCurrentContinuation(MyThread* t, void** targetIp, void** targetBase,
PROTECT(t, method); PROTECT(t, method);
void** top = static_cast<void**>(stack) void** top = static_cast<void**>(stack)
+ t->arch->frameReturnAddressSize(); + t->arch->frameReturnAddressSize()
+ t->arch->frameFooterSize();
unsigned argumentFootprint unsigned argumentFootprint
= t->arch->argumentFootprint(methodParameterFootprint(t, target)); = t->arch->argumentFootprint(methodParameterFootprint(t, target));
unsigned alignment = t->arch->stackAlignmentInWords(); unsigned alignment = t->arch->stackAlignmentInWords();
@ -1518,9 +1514,11 @@ makeCurrentContinuation(MyThread* t, void** targetIp, void** targetBase,
object c = makeContinuation object c = makeContinuation
(t, 0, context, method, ip, (t, 0, context, method, ip,
((frameSize ((frameSize
+ t->arch->frameFooterSize()
+ t->arch->returnAddressOffset() + t->arch->returnAddressOffset()
- t->arch->frameReturnAddressSize()) * BytesPerWord), - t->arch->frameReturnAddressSize()) * BytesPerWord),
((frameSize ((frameSize
+ t->arch->frameFooterSize()
+ t->arch->framePointerOffset() + t->arch->framePointerOffset()
- t->arch->frameReturnAddressSize()) * BytesPerWord), - t->arch->frameReturnAddressSize()) * BytesPerWord),
totalSize); totalSize);
@ -1541,9 +1539,7 @@ makeCurrentContinuation(MyThread* t, void** targetIp, void** targetBase,
*targetIp = ip; *targetIp = ip;
*targetBase = base; *targetBase = base;
*targetStack = static_cast<void**>(stack) *targetStack = static_cast<void**>(stack)
+ t->arch->frameReturnAddressSize(); + t->arch->frameReturnAddressSize();;
*oldArgumentFootprint
= t->arch->argumentFootprint(methodParameterFootprint(t, target));
} }
} }
@ -5392,8 +5388,7 @@ compatibleReturnType(MyThread* t, object oldMethod, object newMethod)
} }
void void
jumpAndInvoke(MyThread* t, object method, void* base, void* stack, jumpAndInvoke(MyThread* t, object method, void* base, void* stack, ...)
unsigned oldArgumentFootprint, ...)
{ {
t->trace->targetMethod = 0; t->trace->targetMethod = 0;
@ -5405,7 +5400,7 @@ jumpAndInvoke(MyThread* t, object method, void* base, void* stack,
unsigned argumentCount = methodParameterFootprint(t, method); unsigned argumentCount = methodParameterFootprint(t, method);
uintptr_t arguments[argumentCount]; 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) { for (unsigned i = 0; i < argumentCount; ++i) {
arguments[i] = va_arg(a, uintptr_t); arguments[i] = va_arg(a, uintptr_t);
} }
@ -5417,10 +5412,8 @@ jumpAndInvoke(MyThread* t, object method, void* base, void* stack,
stack, stack,
argumentCount * BytesPerWord, argumentCount * BytesPerWord,
arguments, arguments,
(oldArgumentFootprint t->arch->alignFrameSize(t->arch->argumentFootprint(argumentCount))
- t->arch->argumentFootprint(argumentCount) * BytesPerWord);
- t->arch->frameFooterSize()
- t->arch->frameReturnAddressSize()) * BytesPerWord);
} }
void void
@ -5527,8 +5520,7 @@ callContinuation(MyThread* t, object continuation, object result,
void* ip; void* ip;
void* base; void* base;
void* stack; void* stack;
unsigned oldArgumentFootprint; findUnwindTarget(t, &ip, &base, &stack);
findUnwindTarget(t, &ip, &base, &stack, &oldArgumentFootprint);
switch (action) { switch (action) {
case Call: { case Call: {
@ -5543,7 +5535,7 @@ callContinuation(MyThread* t, object continuation, object result,
t->continuation = nextContinuation; t->continuation = nextContinuation;
jumpAndInvoke jumpAndInvoke
(t, rewindMethod(t), base, stack, oldArgumentFootprint, (t, rewindMethod(t), base, stack,
continuationContextBefore(t, continuationContext(t, nextContinuation)), continuationContextBefore(t, continuationContext(t, nextContinuation)),
continuation, result, exception); continuation, result, exception);
} break; } break;
@ -5564,7 +5556,6 @@ callWithCurrentContinuation(MyThread* t, object receiver)
void* ip = 0; void* ip = 0;
void* base = 0; void* base = 0;
void* stack = 0; void* stack = 0;
unsigned oldArgumentFootprint = 0;
{ PROTECT(t, receiver); { PROTECT(t, receiver);
@ -5601,16 +5592,13 @@ callWithCurrentContinuation(MyThread* t, object receiver)
compile(t, ::codeAllocator(t), 0, method); compile(t, ::codeAllocator(t), 0, method);
if (LIKELY(t->exception == 0)) { if (LIKELY(t->exception == 0)) {
t->continuation = makeCurrentContinuation t->continuation = makeCurrentContinuation(t, &ip, &base, &stack);
(t, &ip, &base, &stack, &oldArgumentFootprint);
} }
} }
} }
if (LIKELY(t->exception == 0)) { if (LIKELY(t->exception == 0)) {
jumpAndInvoke jumpAndInvoke(t, method, base, stack, receiver, t->continuation);
(t, method, base, stack, oldArgumentFootprint, receiver,
t->continuation);
} else { } else {
unwind(t); unwind(t);
} }
@ -5622,7 +5610,6 @@ dynamicWind(MyThread* t, object before, object thunk, object after)
void* ip = 0; void* ip = 0;
void* base = 0; void* base = 0;
void* stack = 0; void* stack = 0;
unsigned oldArgumentFootprint = 0;
{ PROTECT(t, before); { PROTECT(t, before);
PROTECT(t, thunk); PROTECT(t, thunk);
@ -5648,8 +5635,7 @@ dynamicWind(MyThread* t, object before, object thunk, object after)
} }
if (LIKELY(t->exception == 0)) { if (LIKELY(t->exception == 0)) {
t->continuation = makeCurrentContinuation t->continuation = makeCurrentContinuation(t, &ip, &base, &stack);
(t, &ip, &base, &stack, &oldArgumentFootprint);
object newContext = makeContinuationContext object newContext = makeContinuationContext
(t, continuationContext(t, t->continuation), before, after, (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)) { if (LIKELY(t->exception == 0)) {
jumpAndInvoke jumpAndInvoke(t, windMethod(t), base, stack, before, thunk, after);
(t, windMethod(t), base, stack, oldArgumentFootprint, before, thunk,
after);
} else { } else {
unwind(t); unwind(t);
} }