continuation bugfixes

This commit is contained in:
Joel Dice 2009-05-16 18:39:08 -06:00
parent 8cb59c9d4c
commit 195d95d809
4 changed files with 78 additions and 28 deletions

View File

@ -87,6 +87,7 @@ vmInvoke_returnAddress:
movq CONTINUATION_LENGTH(%rcx),%rsi
shlq $3,%rsi
subq %rsi,%rsp
subq $48,%rsp
leaq CONTINUATION_BODY(%rcx),%rdi

View File

@ -61,6 +61,7 @@ class MyThread: public Thread {
t->trace = this;
t->base = 0;
t->stack = 0;
t->continuation = 0;
}
~CallTrace() {
@ -292,6 +293,7 @@ class MyStackWalker: public Processor::StackWalker {
if (method_) {
state = Method;
} else if (continuation) {
method_ = continuationMethod(t, continuation);
state = Continuation;
} else if (trace) {
continuation = trace->continuation;
@ -1379,12 +1381,12 @@ findUnwindTarget(MyThread* t, void** targetIp, void** targetBase,
ip = t->arch->frameIp(stack);
}
object target = t->trace->targetMethod;
*targetIp = 0;
while (*targetIp == 0) {
object method = methodForIp(t, ip);
if (method) {
PROTECT(t, method);
void* handler = findExceptionHandler(t, method, ip);
if (handler) {
@ -1407,6 +1409,8 @@ findUnwindTarget(MyThread* t, void** targetIp, void** targetBase,
ip = t->arch->frameIp(stack);
releaseLock(t, method, stack);
target = method;
}
} else {
*targetIp = ip;
@ -1415,20 +1419,23 @@ findUnwindTarget(MyThread* t, void** targetIp, void** targetBase,
+ t->arch->frameReturnAddressSize();
while (t->continuation) {
object method = continuationMethod(t, t->continuation);
void* handler = findExceptionHandler
(t, continuationMethod(t, t->continuation),
continuationAddress(t, t->continuation));
(t, method, continuationAddress(t, t->continuation));
if (handler) {
t->exceptionHandler = handler;
t->exceptionStack = stackForFrame
(t, stack, continuationMethod(t, t->continuation));
t->exceptionStack = static_cast<void**>(*targetStack)
+ t->arch->argumentFootprint(methodParameterFootprint(t, target))
- t->arch->argumentFootprint(methodParameterFootprint(t, method))
- stackOffsetFromFrame(t, method);
t->exceptionOffset = localOffset(t, localSize(t, method), method);
break;
} else {
releaseLock(t, continuationMethod(t, t->continuation),
releaseLock(t, method,
reinterpret_cast<uint8_t*>(t->continuation)
+ ContinuationBody
+ continuationReturnAddressOffset(t, t->continuation)
@ -1443,7 +1450,7 @@ findUnwindTarget(MyThread* t, void** targetIp, void** targetBase,
object
makeCurrentContinuation(MyThread* t, void** targetIp, void** targetBase,
void** targetStack)
void** targetStack, unsigned* oldArgumentFootprint)
{
void* ip = t->ip;
void* base = t->base;
@ -1512,6 +1519,8 @@ makeCurrentContinuation(MyThread* t, void** targetIp, void** targetBase,
*targetBase = base;
*targetStack = static_cast<void**>(stack)
+ t->arch->frameReturnAddressSize();
*oldArgumentFootprint
= t->arch->argumentFootprint(methodParameterFootprint(t, target));
}
}
@ -5020,18 +5029,6 @@ invokeNativeSlow(MyThread* t, object method)
default: abort(t);
}
unsigned parameterFootprint = methodParameterFootprint(t, method);
if (t->arch->argumentFootprint(parameterFootprint)
> t->arch->stackAlignmentInWords())
{
t->stack = static_cast<uintptr_t*>(t->stack)
+ (t->arch->argumentFootprint(parameterFootprint)
- t->arch->stackAlignmentInWords());
}
t->stack = static_cast<uintptr_t*>(t->stack)
+ t->arch->frameReturnAddressSize();
} else {
result = 0;
}
@ -5087,12 +5084,26 @@ invokeNative(MyThread* t)
}
}
unsigned parameterFootprint = methodParameterFootprint
(t, t->trace->targetMethod);
t->trace->targetMethod = 0;
t->trace->nativeMethod = 0;
if (UNLIKELY(t->exception)) {
unwind(t);
} else {
if (t->arch->argumentFootprint(parameterFootprint)
> t->arch->stackAlignmentInWords())
{
t->stack = static_cast<uintptr_t*>(t->stack)
+ (t->arch->argumentFootprint(parameterFootprint)
- t->arch->stackAlignmentInWords());
}
t->stack = static_cast<uintptr_t*>(t->stack)
+ t->arch->frameReturnAddressSize();
return result;
}
}
@ -5270,7 +5281,8 @@ walkContinuationBody(MyThread* t, Heap::Walker* w, object c, int start)
void
callWithContinuation(MyThread* t, object method, object this_,
object continuation, void* base, void* stack)
object continuation, void* base, void* stack,
unsigned oldArgumentFootprint)
{
t->trace->targetMethod = 0;
@ -5286,6 +5298,7 @@ callWithContinuation(MyThread* t, object method, object this_,
continuation,
base,
static_cast<void**>(stack)
+ oldArgumentFootprint
- t->arch->argumentFootprint(methodParameterFootprint(t, method))
- t->arch->frameFooterSize()
- t->arch->frameReturnAddressSize());
@ -5438,7 +5451,7 @@ invoke(Thread* thread, object method, ArgumentList* arguments)
arguments->array,
arguments->position * BytesPerWord,
t->arch->alignFrameSize
(arguments->position + t->arch->frameFootprint(0))
(t->arch->argumentFootprint(arguments->position))
* BytesPerWord,
returnType);
}
@ -5958,6 +5971,7 @@ class MyProcessor: public Processor {
object continuation;
void* base;
void* stack;
unsigned oldArgumentFootprint;
{ PROTECT(t, receiver);
@ -5992,13 +6006,16 @@ class MyProcessor: public Processor {
compile(t, ::codeAllocator(t), 0, method);
if (LIKELY(t->exception == 0)) {
void* ip;
continuation = makeCurrentContinuation(t, &ip, &base, &stack);
continuation = makeCurrentContinuation
(t, &ip, &base, &stack, &oldArgumentFootprint);
}
}
}
if (LIKELY(t->exception == 0)) {
callWithContinuation(t, method, receiver, continuation, base, stack);
t->continuation = continuation;
callWithContinuation(t, method, receiver, continuation, base, stack,
oldArgumentFootprint);
} else {
unwind(t);
}

View File

@ -2150,8 +2150,7 @@ class MyArchitecture: public Assembler::Architecture {
}
virtual unsigned alignFrameSize(unsigned sizeInWords) {
const unsigned alignment = StackAlignmentInBytes / BytesPerWord;
return (ceiling(sizeInWords + FrameHeaderSize, alignment) * alignment)
return pad(sizeInWords + FrameHeaderSize, StackAlignmentInWords)
- FrameHeaderSize;
}

View File

@ -12,8 +12,41 @@ public class Continuations {
callWithCurrentContinuation(new CallbackReceiver<Integer>() {
public Integer receive(Callback<Integer> continuation) {
continuation.handleResult(42);
throw new RuntimeException();
throw new RuntimeException("unreachable");
}
}));
System.out.println
("result: " +
callWithCurrentContinuation(new CallbackReceiver<Integer>() {
public Integer receive(Callback<Integer> continuation) {
return 43;
}
}));
try {
callWithCurrentContinuation(new CallbackReceiver<Integer>() {
public Integer receive(Callback<Integer> continuation) {
continuation.handleException(new MyException());
throw new RuntimeException("unreachable");
}
});
} catch (MyException e) {
e.printStackTrace();
}
try {
callWithCurrentContinuation(new CallbackReceiver<Integer>() {
public Integer receive(Callback<Integer> continuation)
throws MyException
{
throw new MyException();
}
});
} catch (MyException e) {
e.printStackTrace();
}
}
private static class MyException extends Exception { }
}