From faf9b63798139c3c2854454408025cfba8b64219 Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Thu, 19 Jul 2007 19:07:30 -0600 Subject: [PATCH] more work on java/lang/ref/* support --- classpath/java/lang/ref/PhantomReference.java | 4 ++ classpath/java/lang/ref/Reference.java | 1 + classpath/java/lang/ref/ReferenceQueue.java | 4 +- src/machine.cpp | 63 ++++++++++++++----- src/machine.h | 2 - src/types.def | 7 ++- 6 files changed, 59 insertions(+), 22 deletions(-) diff --git a/classpath/java/lang/ref/PhantomReference.java b/classpath/java/lang/ref/PhantomReference.java index 33d7c06d12..4cad8f8141 100644 --- a/classpath/java/lang/ref/PhantomReference.java +++ b/classpath/java/lang/ref/PhantomReference.java @@ -8,4 +8,8 @@ public class PhantomReference extends Reference { public PhantomReference(T target) { this(target, null); } + + public T get() { + return null; + } } diff --git a/classpath/java/lang/ref/Reference.java b/classpath/java/lang/ref/Reference.java index 0f4246ddad..f195306a16 100644 --- a/classpath/java/lang/ref/Reference.java +++ b/classpath/java/lang/ref/Reference.java @@ -3,6 +3,7 @@ package java.lang.ref; public abstract class Reference { private T target; private ReferenceQueue queue; + private Object vmNext; Reference next; protected Reference(T target, ReferenceQueue queue) { diff --git a/classpath/java/lang/ref/ReferenceQueue.java b/classpath/java/lang/ref/ReferenceQueue.java index c688157c59..87ded829a1 100644 --- a/classpath/java/lang/ref/ReferenceQueue.java +++ b/classpath/java/lang/ref/ReferenceQueue.java @@ -19,10 +19,10 @@ public abstract class ReferenceQueue { void add(Reference r) { r.next = r; if (front == null) { - front = rear = r; + front = r; } else { rear.next = r; - rear = r; } + rear = r; } } diff --git a/src/machine.cpp b/src/machine.cpp index 27dc45628e..6346c21a67 100644 --- a/src/machine.cpp +++ b/src/machine.cpp @@ -136,6 +136,44 @@ visitRoots(Thread* t, Heap::Visitor* v) } } +void +referenceTargetUnreachable(Thread* t, object* p, Heap::Visitor* v) +{ + v->visit(p); + jreferenceTarget(t, *p) = 0; + + if (t->vm->heap->status(jreferenceQueue(t, *p)) != Heap::Unreachable) { + // queue is reachable - add the reference + + v->visit(&jreferenceQueue(t, *p)); + + object q = jreferenceQueue(t, *p); + + set(t, jreferenceJnext(t, *p), *p); + if (referenceQueueFront(t, q)) { + set(t, jreferenceJnext(t, referenceQueueRear(t, q)), *p); + } else { + set(t, referenceQueueFront(t, q), *p); + } + set(t, referenceQueueRear(t, q), *p); + + jreferenceQueue(t, *p) = 0; + } +} + +void +referenceTargetReachable(Thread* t, object* p, Heap::Visitor* v) +{ + v->visit(p); + v->visit(&jreferenceTarget(t, *p)); + + if (t->vm->heap->status(jreferenceQueue(t, *p)) == Heap::Unreachable) { + jreferenceQueue(t, *p) = 0; + } else { + v->visit(&jreferenceQueue(t, *p)); + } +} + void postVisit(Thread* t, Heap::Visitor* v) { @@ -188,16 +226,15 @@ postVisit(Thread* t, Heap::Visitor* v) *p = jreferenceNext(t, *p); } else if (m->heap->status(jreferenceTarget(t, *p)) == Heap::Unreachable) { - // target is unreachable - clear the reference and remove it - // from the list + // target is unreachable - clear the reference, remove it from + // the list, and enqueue it if it has a live reference queue - jreferenceTarget(t, *p) = 0; + referenceTargetUnreachable(t, p, v); *p = jreferenceNext(t, *p); } else { // both reference and target are reachable - v->visit(p); - v->visit(&jreferenceTarget(t, *p)); + referenceTargetReachable(t, p, v); if (m->heap->status(*p) == Heap::Tenured) { // the reference is tenured, so we remove it from @@ -248,17 +285,15 @@ postVisit(Thread* t, Heap::Visitor* v) } else if (m->heap->status(jreferenceTarget(t, *p)) == Heap::Unreachable) { - // target is unreachable - clear the reference and remove it - // from the list + // target is unreachable - clear the reference, remove it from + // the list, and enqueue it if it has a live reference queue - jreferenceTarget(t, *p) = 0; + referenceTargetUnreachable(t, p, v); *p = jreferenceNext(t, *p); } else { // target is reachable - v->visit(p); - v->visit(&jreferenceTarget(t, *p)); - + referenceTargetReachable(t, p, v); p = &jreferenceNext(t, *p); } } @@ -1308,9 +1343,6 @@ Thread::Thread(Machine* m, Allocator* allocator, object javaThread, #include "type-java-initializations.cpp" - classVmFlags(t, arrayBody(t, m->types, Machine::WeakReferenceType)) - |= WeakReferenceFlag; - m->classMap = makeHashMap(this, NormalMap, 0, 0); m->builtinMap = makeHashMap(this, NormalMap, 0, 0); m->monitorMap = makeHashMap(this, WeakMap, 0, 0); @@ -1736,7 +1768,8 @@ hashMapInsert(Thread* t, object map, object key, object value, PROTECT(t, key); PROTECT(t, value); - t->vm->weakReferences = makeWeakReference(t, 0, t->vm->weakReferences); + t->vm->weakReferences = makeWeakReference + (t, 0, 0, t->vm->weakReferences, 0); jreferenceTarget(t, t->vm->weakReferences) = key; key = t->vm->weakReferences; } diff --git a/src/machine.h b/src/machine.h index 5803bc636c..d2d3c82a60 100644 --- a/src/machine.h +++ b/src/machine.h @@ -61,8 +61,6 @@ enum MapType { const int NativeLine = -1; const int UnknownLine = -2; -const unsigned WeakReferenceFlag = 1 << 0; - class Thread; typedef Thread JNIEnv; diff --git a/src/types.def b/src/types.def index 96990f0009..b97224add7 100644 --- a/src/types.def +++ b/src/types.def @@ -190,7 +190,7 @@ (type boolean java/lang/Boolean (extends jobject) - (int8_t value)) + (uint8_t value)) (type short java/lang/Short (extends jobject) @@ -225,7 +225,8 @@ (extends jobject) (void* target) (void* queue) - (void* next)) + (void* next) + (object jnext)) (type weakReference java/lang/ref/WeakReference (extends jreference)) @@ -239,7 +240,7 @@ (type booleanArray [Z (extends jobject) - (array int8_t body)) + (array uint8_t body)) (type shortArray [S (extends jobject)