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
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

View File

@ -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<void**>(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<void**>(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<void**>(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);
}