mirror of
https://github.com/corda/corda.git
synced 2025-01-19 03:06:36 +00:00
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:
parent
70da0df46b
commit
4c0ede8b9a
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user