reuse JNI references when possible

Before allocating a new reference in NewGlobalReference or when
creating a local reference, we look for a previously-allocated
reference pointing to the same object.  This is a linear search, but
usually the number of elements in the reference list is small, whereas
the memory, locking, and allocation overhead of creating duplicate
references can be large.
This commit is contained in:
Joel Dice 2009-12-16 19:16:51 -07:00
parent 70da0df46b
commit 4c0ede8b9a
3 changed files with 39 additions and 4 deletions

View File

@ -7122,11 +7122,20 @@ class MyProcessor: public Processor {
{
if (o) {
MyThread* t = static_cast<MyThread*>(vmt);
PROTECT(t, o);
for (Reference* r = t->reference; r; r = r->next) {
if (r->target == o) {
acquire(t, r);
return &(r->target);
}
}
Reference* r = new (t->m->heap->allocate(sizeof(Reference)))
Reference(o, &(t->reference));
acquire(t, r);
return &(r->target);
} else {
return 0;
@ -7137,7 +7146,7 @@ class MyProcessor: public Processor {
disposeLocalReference(Thread* t, object* r)
{
if (r) {
vm::dispose(t, reinterpret_cast<Reference*>(r));
release(t, reinterpret_cast<Reference*>(r));
}
}

View File

@ -1186,9 +1186,19 @@ NewGlobalRef(Thread* t, jobject o)
ACQUIRE(t, t->m->referenceLock);
if (o) {
for (Reference* r = t->m->jniReferences; r; r = r->next) {
if (r->target == *o) {
acquire(t, r);
return &(r->target);
}
}
Reference* r = new (t->m->heap->allocate(sizeof(Reference)))
Reference(*o, &(t->m->jniReferences));
acquire(t, r);
return &(r->target);
} else {
return 0;
@ -1203,7 +1213,7 @@ DeleteGlobalRef(Thread* t, jobject r)
ACQUIRE(t, t->m->referenceLock);
if (r) {
dispose(t, reinterpret_cast<Reference*>(r));
release(t, reinterpret_cast<Reference*>(r));
}
}

View File

@ -1131,7 +1131,8 @@ class Reference {
Reference(object target, Reference** handle):
target(target),
next(*handle),
handle(handle)
handle(handle),
count(0)
{
if (next) {
next->handle = &next;
@ -1142,6 +1143,7 @@ class Reference {
object target;
Reference* next;
Reference** handle;
unsigned count;
};
class Machine {
@ -1404,6 +1406,20 @@ dispose(Thread* t, Reference* r)
t->m->heap->free(r, sizeof(*r));
}
inline void
acquire(Thread*, Reference* r)
{
++ r->count;
}
inline void
release(Thread* t, Reference* r)
{
if ((-- r->count) == 0) {
dispose(t, r);
}
}
void
collect(Thread* t, Heap::CollectionType type);