weak reference support

This commit is contained in:
Joel Dice 2007-07-04 09:56:55 -06:00
parent da1e12b589
commit cabc069b16
3 changed files with 73 additions and 10 deletions

View File

@ -1496,7 +1496,7 @@ writeInitialization(Output* out, Object* type)
} }
out->write(" object class_ = makeClass"); out->write(" object class_ = makeClass");
out->write("(t, 0, "); out->write("(t, 0, 0, ");
out->write(typeFixedSize(type)); out->write(typeFixedSize(type));
out->write(", "); out->write(", ");
out->write(typeArrayElementSize(type)); out->write(typeArrayElementSize(type));

View File

@ -3,6 +3,7 @@
(type class (type class
(uint16_t flags) (uint16_t flags)
(uint16_t vmFlags)
(uint16_t fixedSize) (uint16_t fixedSize)
(uint16_t arrayElementSize) (uint16_t arrayElementSize)
(object objectMask) (object objectMask)
@ -229,3 +230,11 @@
(type double java/lang/Double (type double java/lang/Double
(extends jobject) (extends jobject)
(uint64_t value)) (uint64_t value))
(type jreference java/lang/ref/Reference
(extends jobject)
(object target))
(type weakReference java/lang/ref/WeakReference
(extends jreference)
(object next))

View File

@ -57,8 +57,10 @@ enum StackTag {
ObjectTag ObjectTag
}; };
static const int NativeLine = -1; const int NativeLine = -1;
static const int UnknownLine = -2; const int UnknownLine = -2;
const unsigned WeakReferenceFlag = 1 << 0;
class Machine { class Machine {
public: public:
@ -93,6 +95,7 @@ class Machine {
object types; object types;
object finalizers; object finalizers;
object doomed; object doomed;
object weakReferences;
bool unsafe; bool unsafe;
JNIEnvVTable jniEnvVTable; JNIEnvVTable jniEnvVTable;
}; };
@ -315,6 +318,18 @@ objectEqual(Thread*, object a, object b)
return a == b; return a == b;
} }
inline uint32_t
referenceHash(Thread* t, object o)
{
return objectHash(t, jreferenceTarget(t, o));
}
inline bool
referenceEqual(Thread* t, object a, object b)
{
return a == jreferenceTarget(t, b);
}
inline uint32_t inline uint32_t
byteArrayHash(Thread* t, object array) byteArrayHash(Thread* t, object array)
{ {
@ -364,7 +379,7 @@ hashMapFindNode(Thread* t, object map, object key,
unsigned index = hash(t, key) & (arrayLength(t, array) - 1); unsigned index = hash(t, key) & (arrayLength(t, array) - 1);
object n = arrayBody(t, array, index); object n = arrayBody(t, array, index);
while (n) { while (n) {
if (equal(t, tripleFirst(t, n), key)) { if (equal(t, key, tripleFirst(t, n))) {
return n; return n;
} }
@ -453,7 +468,7 @@ hashMapRemove(Thread* t, object map, object key,
object n = arrayBody(t, array, index); object n = arrayBody(t, array, index);
object p = 0; object p = 0;
while (n) { while (n) {
if (equal(t, tripleFirst(t, n), key)) { if (equal(t, key, tripleFirst(t, n))) {
o = tripleFirst(t, n); o = tripleFirst(t, n);
if (p) { if (p) {
set(t, tripleThird(t, p), tripleThird(t, n)); set(t, tripleThird(t, p), tripleThird(t, n));
@ -690,6 +705,21 @@ collect(Machine* m, Heap::CollectionType type)
for (object* f = &(m->doomed); *f; f = &finalizerNext(t, *f)) { for (object* f = &(m->doomed); *f; f = &finalizerNext(t, *f)) {
v->visit(f); v->visit(f);
} }
for (object p = m->weakReferences; p;) {
object o = jreferenceTarget(t, p);
object followed = m->heap->follow(o);
if (followed == o) {
// object has not been collected
jreferenceTarget(t, p) = 0;
} else {
jreferenceTarget(t, p) = followed;
}
object last = p;
p = weakReferenceNext(t, p);
weakReferenceNext(t, last) = 0;
}
} }
virtual unsigned sizeInWords(object o) { virtual unsigned sizeInWords(object o) {
@ -719,8 +749,9 @@ collect(Machine* m, Heap::CollectionType type)
Thread* t = m->rootThread; Thread* t = m->rootThread;
o = m->heap->follow(mask(o)); o = m->heap->follow(mask(o));
object class_ = m->heap->follow(objectClass(t, o));
unsigned base = baseSize(t, o, m->heap->follow(objectClass(t, o))); unsigned base = baseSize(t, o, class_);
unsigned n = extendedSize(t, o, base); unsigned n = extendedSize(t, o, base);
memcpy(o, dst, n * BytesPerWord); memcpy(o, dst, n * BytesPerWord);
@ -730,6 +761,11 @@ collect(Machine* m, Heap::CollectionType type)
cast<uintptr_t>(dst, 0) &= PointerMask; cast<uintptr_t>(dst, 0) &= PointerMask;
cast<uintptr_t>(dst, 0) |= ExtendedMark; cast<uintptr_t>(dst, 0) |= ExtendedMark;
} }
if (classVmFlags(t, class_) & WeakReferenceFlag) {
weakReferenceNext(t, dst) = m->weakReferences;
m->weakReferences = dst;
}
} }
virtual void walk(void* p, Heap::Walker* w) { virtual void walk(void* p, Heap::Walker* w) {
@ -743,6 +779,7 @@ collect(Machine* m, Heap::CollectionType type)
// fprintf(stderr, "p: %p; class: %p; mask: %p; mask length: %d\n", // fprintf(stderr, "p: %p; class: %p; mask: %p; mask length: %d\n",
// p, class_, objectMask, intArrayLength(t, objectMask)); // p, class_, objectMask, intArrayLength(t, objectMask));
unsigned vmFlags = classVmFlags(t, class_);
unsigned fixedSize = classFixedSize(t, class_); unsigned fixedSize = classFixedSize(t, class_);
unsigned arrayElementSize = classArrayElementSize(t, class_); unsigned arrayElementSize = classArrayElementSize(t, class_);
unsigned arrayLength unsigned arrayLength
@ -762,7 +799,9 @@ collect(Machine* m, Heap::CollectionType type)
= divide(arrayElementSize, BytesPerWord); = divide(arrayElementSize, BytesPerWord);
for (unsigned i = 0; i < fixedSizeInWords; ++i) { for (unsigned i = 0; i < fixedSizeInWords; ++i) {
if (mask[wordOf(i)] & (static_cast<uintptr_t>(1) << bitOf(i))) { if ((i != 1 or (vmFlags & WeakReferenceFlag) == 0)
and mask[wordOf(i)] & (static_cast<uintptr_t>(1) << bitOf(i)))
{
if (not w->visit(i)) { if (not w->visit(i)) {
return; return;
} }
@ -813,6 +852,8 @@ collect(Machine* m, Heap::CollectionType type)
(t, finalizerTarget(t, f)); (t, finalizerTarget(t, f));
} }
m->doomed = 0; m->doomed = 0;
m->weakReferences = 0;
} }
void void
@ -1010,13 +1051,13 @@ addFinalizer(Thread* t, object target, void (*finalize)(Thread*, object))
void void
removeMonitor(Thread* t, object o) removeMonitor(Thread* t, object o)
{ {
hashMapRemove(t, t->vm->monitorMap, o, objectHash, objectEqual); hashMapRemove(t, t->vm->monitorMap, o, objectHash, referenceEqual);
} }
System::Monitor* System::Monitor*
objectMonitor(Thread* t, object o) objectMonitor(Thread* t, object o)
{ {
object p = hashMapFind(t, t->vm->monitorMap, o, objectHash, objectEqual); object p = hashMapFind(t, t->vm->monitorMap, o, objectHash, referenceEqual);
if (p) { if (p) {
return static_cast<System::Monitor*>(pointerValue(t, p)); return static_cast<System::Monitor*>(pointerValue(t, p));
@ -1030,7 +1071,11 @@ objectMonitor(Thread* t, object o)
expect(t, t->vm->system->success(s)); expect(t, t->vm->system->success(s));
p = makePointer(t, m); p = makePointer(t, m);
hashMapInsert(t, t->vm->monitorMap, o, p, objectHash); PROTECT(t, p);
object wr = makeWeakReference(t, o, 0);
hashMapInsert(t, t->vm->monitorMap, wr, p, referenceHash);
addFinalizer(t, o, removeMonitor); addFinalizer(t, o, removeMonitor);
@ -2169,6 +2214,7 @@ parseClass(Thread* t, const uint8_t* data, unsigned size)
object class_ = makeClass(t, object class_ = makeClass(t,
flags, flags,
0, // VM flags
0, // fixed size 0, // fixed size
0, // array size 0, // array size
0, // object mask 0, // object mask
@ -2188,6 +2234,8 @@ parseClass(Thread* t, const uint8_t* data, unsigned size)
if (UNLIKELY(t->exception)) return 0; if (UNLIKELY(t->exception)) return 0;
set(t, classSuper(t, class_), sc); set(t, classSuper(t, class_), sc);
classVmFlags(t, class_) |= classVmFlags(t, sc);
} }
parseInterfaceTable(t, s, class_, pool); parseInterfaceTable(t, s, class_, pool);
@ -2220,6 +2268,8 @@ updateBootstrapClass(Thread* t, object bootstrapClass, object class_)
ENTER(t, Thread::ExclusiveState); ENTER(t, Thread::ExclusiveState);
classVmFlags(t, class_) |= classVmFlags(t, bootstrapClass);
memcpy(bootstrapClass, memcpy(bootstrapClass,
class_, class_,
extendedSize(t, class_, baseSize(t, class_, objectClass(t, class_))) extendedSize(t, class_, baseSize(t, class_, objectClass(t, class_)))
@ -2675,6 +2725,7 @@ Machine::Machine(System* system, Heap* heap, ClassFinder* classFinder):
types(0), types(0),
finalizers(0), finalizers(0),
doomed(0), doomed(0),
weakReferences(0),
unsafe(false) unsafe(false)
{ {
memset(&jniEnvVTable, 0, sizeof(JNIEnvVTable)); memset(&jniEnvVTable, 0, sizeof(JNIEnvVTable));
@ -2742,6 +2793,9 @@ Thread::Thread(Machine* m):
object intArrayClass = arrayBody(t, m->types, Machine::IntArrayType); object intArrayClass = arrayBody(t, m->types, Machine::IntArrayType);
set(t, cast<object>(intArrayClass, 0), classClass); set(t, cast<object>(intArrayClass, 0), classClass);
classVmFlags(t, arrayBody(t, m->types, Machine::WeakReferenceType))
|= WeakReferenceFlag;
m->unsafe = false; m->unsafe = false;
m->bootstrapClassMap = makeHashMap(this, 0, 0); m->bootstrapClassMap = makeHashMap(this, 0, 0);