diff --git a/src/compile.cpp b/src/compile.cpp index 3a4bc7ed63..214cc7ba2c 100644 --- a/src/compile.cpp +++ b/src/compile.cpp @@ -8532,7 +8532,7 @@ class MyProcessor: public Processor { } Reference* r = new (t->m->heap->allocate(sizeof(Reference))) - Reference(o, &(t->reference)); + Reference(o, &(t->reference), false); acquire(t, r); diff --git a/src/jnienv.cpp b/src/jnienv.cpp index 34f82efc65..f815497078 100644 --- a/src/jnienv.cpp +++ b/src/jnienv.cpp @@ -2157,7 +2157,7 @@ SetStaticDoubleField(Thread* t, jobject c, jfieldID field, jdouble v) } jobject JNICALL -NewGlobalRef(Thread* t, jobject o) +newGlobalRef(Thread* t, jobject o, bool weak) { ENTER(t, Thread::ActiveState); @@ -2165,7 +2165,7 @@ NewGlobalRef(Thread* t, jobject o) if (o) { for (Reference* r = t->m->jniReferences; r; r = r->next) { - if (r->target == *o) { + if (r->target == *o and r->weak == weak) { acquire(t, r); return &(r->target); @@ -2173,7 +2173,7 @@ NewGlobalRef(Thread* t, jobject o) } Reference* r = new (t->m->heap->allocate(sizeof(Reference))) - Reference(*o, &(t->m->jniReferences)); + Reference(*o, &(t->m->jniReferences), weak); acquire(t, r); @@ -2183,6 +2183,12 @@ NewGlobalRef(Thread* t, jobject o) } } +jobject JNICALL +NewGlobalRef(Thread* t, jobject o) +{ + return newGlobalRef(t, o, false); +} + void JNICALL DeleteGlobalRef(Thread* t, jobject r) { @@ -2195,6 +2201,18 @@ DeleteGlobalRef(Thread* t, jobject r) } } +jobject JNICALL +NewWeakGlobalRef(Thread* t, jobject o) +{ + return newGlobalRef(t, o, true); +} + +void JNICALL +DeleteWeakGlobalRef(Thread* t, jobject r) +{ + DeleteGlobalRef(t, r); +} + jint JNICALL EnsureLocalCapacity(Thread*, jint) { @@ -3166,8 +3184,9 @@ populateJNITables(JavaVMVTable* vmTable, JNIEnvVTable* envTable) envTable->SetStaticFloatField = local::SetStaticFloatField; envTable->SetStaticDoubleField = local::SetStaticDoubleField; envTable->NewGlobalRef = local::NewGlobalRef; - envTable->NewWeakGlobalRef = local::NewGlobalRef; + envTable->NewWeakGlobalRef = local::NewWeakGlobalRef; envTable->DeleteGlobalRef = local::DeleteGlobalRef; + envTable->DeleteWeakGlobalRef = local::DeleteWeakGlobalRef; envTable->EnsureLocalCapacity = local::EnsureLocalCapacity; envTable->ExceptionOccurred = local::ExceptionOccurred; envTable->ExceptionDescribe = local::ExceptionDescribe; diff --git a/src/machine.cpp b/src/machine.cpp index 0ff4539bf6..65213cd637 100644 --- a/src/machine.cpp +++ b/src/machine.cpp @@ -584,6 +584,16 @@ postVisit(Thread* t, Heap::Visitor* v) = m->tenuredWeakReferences; m->tenuredWeakReferences = firstNewTenuredWeakReference; } + + for (Reference* r = m->jniReferences; r; r = r->next) { + if (r->weak) { + if (m->heap->status(r->target) == Heap::Unreachable) { + r->target = 0; + } else { + v->visit(&(r->target)); + } + } + } } void @@ -4142,7 +4152,9 @@ visitRoots(Machine* m, Heap::Visitor* v) } for (Reference* r = m->jniReferences; r; r = r->next) { - v->visit(&(r->target)); + if (not r->weak) { + v->visit(&(r->target)); + } } } diff --git a/src/machine.h b/src/machine.h index 8f2a6f4cf7..44b239c690 100644 --- a/src/machine.h +++ b/src/machine.h @@ -1215,11 +1215,12 @@ noop(); class Reference { public: - Reference(object target, Reference** handle): + Reference(object target, Reference** handle, bool weak): target(target), next(*handle), handle(handle), - count(0) + count(0), + weak(weak) { if (next) { next->handle = &next; @@ -1231,6 +1232,7 @@ class Reference { Reference* next; Reference** handle; unsigned count; + bool weak; }; class Classpath;