more work on continuation support

This commit is contained in:
Joel Dice 2009-05-05 18:29:05 -06:00
parent eb3bd25aa1
commit 66c4867f18
9 changed files with 189 additions and 33 deletions

View File

@ -0,0 +1,16 @@
/* Copyright (c) 2009, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
that the above copyright notice and this permission notice appear
in all copies.
There is NO WARRANTY for this software. See license.txt for
details. */
package avian;
public interface Callback<T> {
public void handleResult(T result);
public void handleException(Throwable exception);
}

View File

@ -0,0 +1,15 @@
/* Copyright (c) 2009, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
that the above copyright notice and this permission notice appear
in all copies.
There is NO WARRANTY for this software. See license.txt for
details. */
package avian;
public interface CallbackReceiver<T> {
public T receive(Callback<T> callback) throws Exception;
}

View File

@ -0,0 +1,27 @@
/* Copyright (c) 2009, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
that the above copyright notice and this permission notice appear
in all copies.
There is NO WARRANTY for this software. See license.txt for
details. */
package avian;
import java.util.concurrent.Callable;
public abstract class Continuations {
public static native <T> T callWithCurrentContinuation
(CallbackReceiver<T> receiver) throws Exception;
public static native <T> T dynamicWind(Runnable before,
Callable<T> thunk,
Runnable after) throws Exception;
private static class Continuation<T> implements Callback<T> {
public native void handleResult(T result);
public native void handleException(Throwable exception);
}
}

View File

@ -0,0 +1,15 @@
/* Copyright (c) 2009, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
that the above copyright notice and this permission notice appear
in all copies.
There is NO WARRANTY for this software. See license.txt for
details. */
package java.util.concurrent;
public interface Callable<T> {
public T call() throws Exception;
}

View File

@ -847,3 +847,38 @@ Java_java_net_URL_00024ResourceInputStream_close(Thread*, jclass, jlong peer)
{ {
reinterpret_cast<System::Region*>(peer)->dispose(); reinterpret_cast<System::Region*>(peer)->dispose();
} }
extern "C" JNIEXPORT void JNICALL
Avian_avian_Continuations_callWithCurrentContinuation(Thread* t,
object,
uintptr_t* arguments)
{
t->m->processor->callWithCurrentContinuation
(t, reinterpret_cast<object>(*arguments));
abort(t);
}
extern "C" JNIEXPORT void JNICALL
Avian_avian_Continuation_handleResult(Thread* t,
object,
uintptr_t* arguments)
{
t->m->processor->feedResultToContinuation
(t, reinterpret_cast<object>(arguments[0]),
reinterpret_cast<object>(arguments[1]));
abort(t);
}
extern "C" JNIEXPORT void JNICALL
Avian_avian_Continuation_handleException(Thread* t,
object,
uintptr_t* arguments)
{
t->m->processor->feedExceptionToContinuation
(t, reinterpret_cast<object>(arguments[0]),
reinterpret_cast<object>(arguments[1]));
abort(t);
}

View File

@ -5553,6 +5553,7 @@ class MyProcessor: public Processor {
objectPools(0), objectPools(0),
staticTableArray(0), staticTableArray(0),
virtualThunks(0), virtualThunks(0),
receiveMethod(0),
codeAllocator(s, 0, 0) codeAllocator(s, 0, 0)
{ } { }
@ -5952,33 +5953,52 @@ class MyProcessor: public Processor {
(t->m->system->handleSegFault(&segFaultHandler))); (t->m->system->handleSegFault(&segFaultHandler)));
} }
virtual void callWithCurrentContinuation(Thread* vmt, object method, virtual void callWithCurrentContinuation(Thread* vmt, object receiver) {
object this_)
{
MyThread* t = static_cast<MyThread*>(vmt); MyThread* t = static_cast<MyThread*>(vmt);
object method;
object continuation; object continuation;
void* base; void* base;
void* stack; void* stack;
{ PROTECT(t, method); { PROTECT(t, receiver);
PROTECT(t, this_);
compile(t, ::codeAllocator(t), 0, method); if (receiveMethod == 0) {
const char* const className = "avian/CallbackReceiver";
const char* const methodName = "receive";
const char* const methodSpec = "(Lavian/Callback;)Ljava/lang/Object;";
receiveMethod = resolveMethod(t, className, methodName, methodSpec);
if (receiveMethod == 0) {
object message = makeString
(t, "%s %s not found in %s", methodName, methodSpec, className);
t->exception = makeNoSuchMethodError(t, message);
}
}
if (LIKELY(t->exception == 0)) { if (LIKELY(t->exception == 0)) {
void* ip; method = findInterfaceMethod
continuation = makeCurrentContinuation(t, &ip, &base, &stack); (t, receiveMethod, objectClass(t, receiver));
PROTECT(t, method);
compile(t, ::codeAllocator(t), 0, method);
if (LIKELY(t->exception == 0)) {
void* ip;
continuation = makeCurrentContinuation(t, &ip, &base, &stack);
}
} }
} }
if (LIKELY(t->exception == 0)) { if (LIKELY(t->exception == 0)) {
callWithContinuation(t, method, this_, continuation, base, stack); callWithContinuation(t, method, receiver, continuation, base, stack);
} else {
unwind(t);
} }
} }
virtual void callContinuation(Thread* vmt, object continuation, virtual void feedResultToContinuation(Thread* vmt, object continuation,
object result) object result)
{ {
MyThread* t = static_cast<MyThread*>(vmt); MyThread* t = static_cast<MyThread*>(vmt);
@ -5997,6 +6017,30 @@ class MyProcessor: public Processor {
vmJump(ip, base, stack, t, reinterpret_cast<uintptr_t>(result), 0); vmJump(ip, base, stack, t, reinterpret_cast<uintptr_t>(result), 0);
} }
virtual void feedExceptionToContinuation(Thread* vmt, object continuation,
object exception)
{
MyThread* t = static_cast<MyThread*>(vmt);
assert(t, t->exception == 0);
void* ip;
void* base;
void* stack;
findUnwindTarget(t, &ip, &base, &stack);
t->trace->nativeMethod = 0;
t->trace->targetMethod = 0;
t->continuation = continuation;
t->exception = exception;
findUnwindTarget(t, &ip, &base, &stack);
vmJump(ip, base, stack, t, 0, 0);
}
virtual void walkContinuationBody(Thread* t, Heap::Walker* w, object o, virtual void walkContinuationBody(Thread* t, Heap::Walker* w, object o,
unsigned start) unsigned start)
{ {
@ -6018,6 +6062,7 @@ class MyProcessor: public Processor {
object objectPools; object objectPools;
object staticTableArray; object staticTableArray;
object virtualThunks; object virtualThunks;
object receiveMethod;
SegFaultHandler segFaultHandler; SegFaultHandler segFaultHandler;
FixedAllocator codeAllocator; FixedAllocator codeAllocator;
}; };

View File

@ -134,10 +134,14 @@ class Processor {
boot(Thread* t, BootImage* image) = 0; boot(Thread* t, BootImage* image) = 0;
virtual void virtual void
callWithCurrentContinuation(Thread* t, object method, object this_) = 0; callWithCurrentContinuation(Thread* t, object receiver) = 0;
virtual void virtual void
callContinuation(Thread* t, object continuation, object result) = 0; feedResultToContinuation(Thread* t, object continuation, object result) = 0;
virtual void
feedExceptionToContinuation(Thread* t, object continuation,
object exception) = 0;
virtual void virtual void
walkContinuationBody(Thread* t, Heap::Walker* w, object o, unsigned start) walkContinuationBody(Thread* t, Heap::Walker* w, object o, unsigned start)

View File

@ -1323,12 +1323,6 @@ parseJavaClass(Object* type, Stream* s, Object* declarations)
} }
} }
if (equal(typeJavaName(type), "java/lang/Class")) {
// add inline vtable
addMember(type, Array::make
(type, 0, "void*", "vtable", sizeOf("void*", 0)));
}
if (typeSuper(type)) { if (typeSuper(type)) {
for (Object* p = typeMethods(typeSuper(type)); p; p = cdr(p)) { for (Object* p = typeMethods(typeSuper(type)); p; p = cdr(p)) {
addMethod(type, car(p)); addMethod(type, car(p));
@ -1372,23 +1366,25 @@ parseType(Object::ObjectType type, Object* p, Object* declarations,
Type* t = Type::make(type, name, javaName); Type* t = Type::make(type, name, javaName);
if (javaName and *javaName != '[') { bool isJavaType = javaName and *javaName != '[';
assert(cdr(p) == 0);
if (isJavaType) {
const char* file = append(javaClassDirectory, "/", javaName, ".class"); const char* file = append(javaClassDirectory, "/", javaName, ".class");
Stream s(fopen(file, "rb"), true); Stream s(fopen(file, "rb"), true);
parseJavaClass(t, &s, declarations); parseJavaClass(t, &s, declarations);
} else { }
for (p = cdr(p); p; p = cdr(p)) {
if (type == Object::Type) {
parseSubdeclaration(t, car(p), declarations);
} else {
Object* member = parseMember(t, car(p), declarations);
assert(member->type == Object::Scalar);
addMember(t, member);
}
}
for (p = cdr(p); p; p = cdr(p)) {
if (type == Object::Type) {
parseSubdeclaration(t, car(p), declarations);
} else {
Object* member = parseMember(t, car(p), declarations);
assert(member->type == Object::Scalar);
addMember(t, member);
}
}
if (not isJavaType) {
if (type == Object::Type and typeSuper(t)) { if (type == Object::Type and typeSuper(t)) {
for (Object* p = typeMethods(typeSuper(t)); p; p = cdr(p)) { for (Object* p = typeMethods(typeSuper(t)); p; p = cdr(p)) {
addMethod(t, car(p)); addMethod(t, car(p));

View File

@ -1,6 +1,7 @@
(type jobject java/lang/Object) (type jobject java/lang/Object)
(type class java/lang/Class) (type class java/lang/Class
(array void* vtable))
(type singleton (type singleton
(array uintptr_t body)) (array uintptr_t body))
@ -103,7 +104,7 @@
(type array (type array
(noassert array object body)) (noassert array object body))
(type continuation (type continuation avian/Continuations$Continuation
(object next) (object next)
(object method) (object method)
(void* address) (void* address)
@ -111,6 +112,8 @@
(uintptr_t framePointerOffset) (uintptr_t framePointerOffset)
(array uintptr_t body)) (array uintptr_t body))
(type callbackReceiver avian/CallbackReceiver)
(type string java/lang/String) (type string java/lang/String)
(type thread java/lang/Thread) (type thread java/lang/Thread)