diff --git a/src/compile.cpp b/src/compile.cpp index 13554db687..914eabb109 100644 --- a/src/compile.cpp +++ b/src/compile.cpp @@ -159,11 +159,13 @@ class MyThread: public Thread { MyThread(Machine* m, object javaThread, vm::Thread* parent): vm::Thread(m, javaThread, parent), argumentList(0), - frame(0) + frame(0), + reference(0) { } ArgumentList* argumentList; void* frame; + Reference* reference; }; inline bool @@ -2023,11 +2025,15 @@ invoke(Thread* thread, object method, ArgumentList* arguments) unsigned returnType = fieldType(t, returnCode); void* frame = t->frame; + Reference* reference = t->reference; uint64_t result = vmInvoke (&compiledBody(t, methodCompiled(t, method), 0), arguments->array, arguments->position * BytesPerWord, returnType); + while (t->reference != reference) { + dispose(t, t->reference); + } t->frame = frame; object r; @@ -2187,15 +2193,26 @@ class MyProcessor: public Processor { } virtual object* - makeLocalReference(Thread* t, object) + makeLocalReference(Thread* vmt, object o) { - abort(t); + if (o) { + MyThread* t = static_cast(vmt); + + Reference* r = new (t->m->system->allocate(sizeof(Reference))) + Reference(o, &(t->reference)); + + return &(r->target); + } else { + return 0; + } } virtual void - disposeLocalReference(Thread* t, object*) + disposeLocalReference(Thread* t, object* r) { - abort(t); + if (r) { + vm::dispose(t, reinterpret_cast(r)); + } } virtual object diff --git a/src/jnienv.cpp b/src/jnienv.cpp index fb5276a08a..a6a65b8a4c 100644 --- a/src/jnienv.cpp +++ b/src/jnienv.cpp @@ -1015,26 +1015,25 @@ NewGlobalRef(Thread* t, jobject o) ACQUIRE(t, t->m->referenceLock); - t->m->jniReferences = new (t->m->system->allocate(sizeof(Reference))) - Reference(*o, t->m->jniReferences); + if (o) { + Reference* r = new (t->m->system->allocate(sizeof(Reference))) + Reference(*o, &(t->m->jniReferences)); - return &(t->m->jniReferences->target); + return &(r->target); + } else { + return 0; + } } void JNICALL -DeleteGlobalRef(Thread* t, jobject o) +DeleteGlobalRef(Thread* t, jobject r) { ENTER(t, Thread::ActiveState); ACQUIRE(t, t->m->referenceLock); - for (Reference** r = &(t->m->jniReferences); *r;) { - if (&((*r)->target) == o) { - *r = (*r)->next; - break; - } else { - r = &((*r)->next); - } + if (r) { + dispose(t, reinterpret_cast(r)); } } diff --git a/src/machine.h b/src/machine.h index 1be9e59ab1..7ab2103948 100644 --- a/src/machine.h +++ b/src/machine.h @@ -1076,13 +1076,20 @@ noop(); class Reference { public: - Reference(object target, Reference* next): + Reference(object target, Reference** handle): target(target), - next(next) - { } + next(*handle), + handle(handle) + { + if (next) { + next->handle = &next; + } + *handle = this; + } object target; Reference* next; + Reference** handle; }; class Machine { @@ -1255,6 +1262,13 @@ class StateResource { Thread::State oldState; }; +inline void +dispose(Thread* t, Reference* r) +{ + *(r->handle) = r->next; + t->m->system->free(r); +} + void collect(Thread* t, Heap::CollectionType type);