mirror of
https://github.com/corda/corda.git
synced 2025-01-15 09:20:22 +00:00
simplify monitor lookup; add finalization
This commit is contained in:
parent
8acb32e4cb
commit
32b5d070fb
30
src/heap.cpp
30
src/heap.cpp
@ -707,13 +707,8 @@ bitset(Context* c, object o)
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline object
|
inline object
|
||||||
copyTo(Context* c, Segment* s, object o)
|
copyTo(Context* c, Segment* s, object o, unsigned size)
|
||||||
{
|
{
|
||||||
class Allocator: public Heap::Allocator {
|
|
||||||
public:
|
|
||||||
Allocator(Segment* s): s(s) { }
|
|
||||||
|
|
||||||
virtual void* allocate(unsigned size) {
|
|
||||||
if (s->remaining() < size) {
|
if (s->remaining() < size) {
|
||||||
s->ensure(size);
|
s->ensure(size);
|
||||||
|
|
||||||
@ -733,22 +728,21 @@ copyTo(Context* c, Segment* s, object o)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return s->allocate(size);
|
object dst = s->allocate(size);
|
||||||
}
|
c->client->copy(o, dst);
|
||||||
} allocator(s);
|
return dst;
|
||||||
|
|
||||||
c->client->copy(o, &allocator);
|
|
||||||
return p;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
object
|
object
|
||||||
copy2(Context* c, object o)
|
copy2(Context* c, object o)
|
||||||
{
|
{
|
||||||
|
unsigned size = c->client->copiedSizeInWords(o);
|
||||||
|
|
||||||
if (c->gen2.contains(o)) {
|
if (c->gen2.contains(o)) {
|
||||||
assert(c, c->mode == MajorCollection
|
assert(c, c->mode == MajorCollection
|
||||||
or c->mode == Gen2Collection);
|
or c->mode == Gen2Collection);
|
||||||
|
|
||||||
return copyTo(c, &(c->nextGen2), o);
|
return copyTo(c, &(c->nextGen2), o, size);
|
||||||
} else if (c->gen1.contains(o)) {
|
} else if (c->gen1.contains(o)) {
|
||||||
unsigned age = c->ageMap.get(o);
|
unsigned age = c->ageMap.get(o);
|
||||||
if (age == TenureThreshold) {
|
if (age == TenureThreshold) {
|
||||||
@ -760,7 +754,7 @@ copy2(Context* c, object o)
|
|||||||
c->gen2Base = c->gen2.position();
|
c->gen2Base = c->gen2.position();
|
||||||
}
|
}
|
||||||
|
|
||||||
return copyTo(c, &(c->gen2), o);
|
return copyTo(c, &(c->gen2), o, size);
|
||||||
} else {
|
} else {
|
||||||
if (Verbose) {
|
if (Verbose) {
|
||||||
fprintf(stderr, "overflow collection\n");
|
fprintf(stderr, "overflow collection\n");
|
||||||
@ -768,13 +762,13 @@ copy2(Context* c, object o)
|
|||||||
|
|
||||||
c->mode = OverflowCollection;
|
c->mode = OverflowCollection;
|
||||||
initNextGen2(c);
|
initNextGen2(c);
|
||||||
return copyTo(c, &(c->nextGen2), o);
|
return copyTo(c, &(c->nextGen2), o, size);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return copyTo(c, &(c->nextGen2), o);
|
return copyTo(c, &(c->nextGen2), o, size);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
o = copyTo(c, &(c->nextGen1), o);
|
o = copyTo(c, &(c->nextGen1), o, size);
|
||||||
c->nextAgeMap.setOnly(o, age + 1);
|
c->nextAgeMap.setOnly(o, age + 1);
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
@ -782,7 +776,7 @@ copy2(Context* c, object o)
|
|||||||
assert(c, not c->nextGen1.contains(o));
|
assert(c, not c->nextGen1.contains(o));
|
||||||
assert(c, not c->nextGen2.contains(o));
|
assert(c, not c->nextGen2.contains(o));
|
||||||
|
|
||||||
o = copyTo(c, &(c->nextGen1), o);
|
o = copyTo(c, &(c->nextGen1), o, size);
|
||||||
|
|
||||||
c->nextAgeMap.clear(o);
|
c->nextAgeMap.clear(o);
|
||||||
|
|
||||||
|
@ -24,18 +24,13 @@ class Heap {
|
|||||||
virtual bool visit(unsigned) = 0;
|
virtual bool visit(unsigned) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Allocator {
|
|
||||||
public:
|
|
||||||
virtual ~Allocator() { }
|
|
||||||
virtual void* allocate(unsigned sizeInWords) = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
class Client {
|
class Client {
|
||||||
public:
|
public:
|
||||||
virtual ~Client() { }
|
virtual ~Client() { }
|
||||||
virtual void visitRoots(Visitor*) = 0;
|
virtual void visitRoots(Visitor*) = 0;
|
||||||
virtual unsigned sizeInWords(void*) = 0;
|
virtual unsigned sizeInWords(void*) = 0;
|
||||||
virtual void copy(void*, Allocator*) = 0;
|
virtual unsigned copiedSizeInWords(void*) = 0;
|
||||||
|
virtual void copy(void*, void*) = 0;
|
||||||
virtual void walk(void*, Walker*) = 0;
|
virtual void walk(void*, Walker*) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -93,6 +93,11 @@
|
|||||||
(object second)
|
(object second)
|
||||||
(object third))
|
(object third))
|
||||||
|
|
||||||
|
(type finalizer
|
||||||
|
(object target)
|
||||||
|
(void* finalize)
|
||||||
|
(object next))
|
||||||
|
|
||||||
(type hashMap
|
(type hashMap
|
||||||
(uint32_t size)
|
(uint32_t size)
|
||||||
(object array))
|
(object array))
|
||||||
|
214
src/vm.cpp
214
src/vm.cpp
@ -25,8 +25,6 @@ const bool Debug = false;
|
|||||||
|
|
||||||
const uintptr_t HashTakenMark = 1;
|
const uintptr_t HashTakenMark = 1;
|
||||||
const uintptr_t ExtendedMark = 2;
|
const uintptr_t ExtendedMark = 2;
|
||||||
const uintptr_t MonitorFlag
|
|
||||||
= static_cast<uintptr_t>(1) << ((BytesPerWord * 8) - 1);
|
|
||||||
|
|
||||||
class Thread;
|
class Thread;
|
||||||
|
|
||||||
@ -81,13 +79,15 @@ class Machine {
|
|||||||
System::Monitor* stateLock;
|
System::Monitor* stateLock;
|
||||||
System::Monitor* heapLock;
|
System::Monitor* heapLock;
|
||||||
System::Monitor* classLock;
|
System::Monitor* classLock;
|
||||||
System::Monitor* monitorMapLock;
|
System::Monitor* finalizerLock;
|
||||||
System::Library* libraries;
|
System::Library* libraries;
|
||||||
object classMap;
|
object classMap;
|
||||||
object bootstrapClassMap;
|
object bootstrapClassMap;
|
||||||
object builtinMap;
|
object builtinMap;
|
||||||
object monitorMap;
|
object monitorMap;
|
||||||
object types;
|
object types;
|
||||||
|
object finalizers;
|
||||||
|
object doomed;
|
||||||
bool unsafe;
|
bool unsafe;
|
||||||
JNIEnvVTable jniEnvVTable;
|
JNIEnvVTable jniEnvVTable;
|
||||||
};
|
};
|
||||||
@ -271,30 +271,7 @@ baseSize(Thread* t, object o, object class_)
|
|||||||
unsigned
|
unsigned
|
||||||
extendedSize(Thread* t, object o, unsigned baseSize)
|
extendedSize(Thread* t, object o, unsigned baseSize)
|
||||||
{
|
{
|
||||||
unsigned n = baseSize;
|
return baseSize + objectExtended(t, o);
|
||||||
|
|
||||||
if (objectExtended(t, o)) {
|
|
||||||
if (extendedWord(t, o, n) & MonitorFlag) {
|
|
||||||
n += BytesPerWord;
|
|
||||||
}
|
|
||||||
n += BytesPerWord;
|
|
||||||
}
|
|
||||||
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool
|
|
||||||
monitorAttached(Thread* t, object o, unsigned baseSize)
|
|
||||||
{
|
|
||||||
return objectExtended(t, o)
|
|
||||||
and (extendedWord(t, o, baseSize) & MonitorFlag);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline System::Monitor*&
|
|
||||||
attachedMonitor(Thread* t, object o, unsigned baseSize)
|
|
||||||
{
|
|
||||||
assert(t, monitorAttached(t, o, baseSize));
|
|
||||||
return cast<System::Monitor*>(o, (baseSize + 1) * BytesPerWord);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool
|
inline bool
|
||||||
@ -320,7 +297,7 @@ inline uint32_t
|
|||||||
objectHash(Thread* t, object o)
|
objectHash(Thread* t, object o)
|
||||||
{
|
{
|
||||||
if (objectExtended(t, o)) {
|
if (objectExtended(t, o)) {
|
||||||
return extendedWord(t, o, baseSize(t, o, objectClass(o))) & PointerMask;
|
return extendedWord(t, o, baseSize(t, o, objectClass(t, o)));
|
||||||
} else {
|
} else {
|
||||||
markHashTaken(t, o);
|
markHashTaken(t, o);
|
||||||
return takeHash(t, o);
|
return takeHash(t, o);
|
||||||
@ -402,7 +379,8 @@ hashMapFind(Thread* t, object map, object key,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
hashMapGrow(Thread* t, object map, uint32_t (*hash)(Thread*, object))
|
hashMapResize(Thread* t, object map, uint32_t (*hash)(Thread*, object),
|
||||||
|
unsigned size)
|
||||||
{
|
{
|
||||||
PROTECT(t, map);
|
PROTECT(t, map);
|
||||||
|
|
||||||
@ -410,7 +388,7 @@ hashMapGrow(Thread* t, object map, uint32_t (*hash)(Thread*, object))
|
|||||||
unsigned oldLength = (oldArray ? arrayLength(t, oldArray) : 0);
|
unsigned oldLength = (oldArray ? arrayLength(t, oldArray) : 0);
|
||||||
PROTECT(t, oldArray);
|
PROTECT(t, oldArray);
|
||||||
|
|
||||||
unsigned newLength = (oldLength ? oldLength * 2 : 32);
|
unsigned newLength = max(nextPowerOfTwo(size), 16);
|
||||||
object newArray = makeArray(t, newLength, true);
|
object newArray = makeArray(t, newLength, true);
|
||||||
|
|
||||||
if (oldArray) {
|
if (oldArray) {
|
||||||
@ -446,7 +424,7 @@ hashMapInsert(Thread* t, object map, object key, object value,
|
|||||||
PROTECT(t, key);
|
PROTECT(t, key);
|
||||||
PROTECT(t, value);
|
PROTECT(t, value);
|
||||||
|
|
||||||
hashMapGrow(t, map, hash);
|
hashMapResize(t, map, hash, arrayLength(t, array) * 2);
|
||||||
array = hashMapArray(t, map);
|
array = hashMapArray(t, map);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -458,6 +436,39 @@ hashMapInsert(Thread* t, object map, object key, object value,
|
|||||||
set(t, arrayBody(t, array, index), n);
|
set(t, arrayBody(t, array, index), n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
object
|
||||||
|
hashMapRemove(Thread* t, object map, object key,
|
||||||
|
uint32_t (*hash)(Thread*, object),
|
||||||
|
bool (*equal)(Thread*, object, object))
|
||||||
|
{
|
||||||
|
object array = hashMapArray(t, map);
|
||||||
|
object o = 0;
|
||||||
|
if (array) {
|
||||||
|
unsigned index = hash(t, key) & (arrayLength(t, array) - 1);
|
||||||
|
object n = arrayBody(t, array, index);
|
||||||
|
object p = 0;
|
||||||
|
while (n) {
|
||||||
|
if (equal(t, tripleFirst(t, n), key)) {
|
||||||
|
o = tripleFirst(t, n);
|
||||||
|
if (p) {
|
||||||
|
set(t, tripleThird(t, p), tripleThird(t, n));
|
||||||
|
} else {
|
||||||
|
set(t, arrayBody(t, array, index), tripleThird(t, n));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
p = n;
|
||||||
|
n = tripleThird(t, n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hashMapSize(t, map) <= arrayLength(t, array) / 3) {
|
||||||
|
hashMapResize(t, map, hash, arrayLength(t, array) / 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
object
|
object
|
||||||
hashMapIterator(Thread* t, object map)
|
hashMapIterator(Thread* t, object map)
|
||||||
{
|
{
|
||||||
@ -594,6 +605,28 @@ collect(Machine* m, Heap::CollectionType type)
|
|||||||
for (Thread* t = m->rootThread; t; t = t->next) {
|
for (Thread* t = m->rootThread; t; t = t->next) {
|
||||||
::visitRoots(t, v);
|
::visitRoots(t, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Thread* t = m->rootThread;
|
||||||
|
for (object* f = &(m->finalizers); *f;) {
|
||||||
|
object o = finalizerTarget(t, *f);
|
||||||
|
if (m->heap->follow(o) == o) {
|
||||||
|
// object has not been collected
|
||||||
|
object x = *f;
|
||||||
|
*f = finalizerNext(t, x);
|
||||||
|
finalizerNext(t, x) = m->doomed;
|
||||||
|
m->doomed = x;
|
||||||
|
} else {
|
||||||
|
f = &finalizerNext(t, *f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (object* f = &(m->finalizers); *f; f = &finalizerNext(t, *f)) {
|
||||||
|
v->visit(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (object* f = &(m->doomed); *f; f = &finalizerNext(t, *f)) {
|
||||||
|
v->visit(f);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual unsigned sizeInWords(object o) {
|
virtual unsigned sizeInWords(object o) {
|
||||||
@ -605,55 +638,35 @@ collect(Machine* m, Heap::CollectionType type)
|
|||||||
(t, o, baseSize(t, o, m->heap->follow(objectClass(t, o))));
|
(t, o, baseSize(t, o, m->heap->follow(objectClass(t, o))));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void copy(object o, Heap::Allocator* allocator) {
|
virtual unsigned copiedSizeInWords(object o) {
|
||||||
|
Thread* t = m->rootThread;
|
||||||
|
|
||||||
|
o = m->heap->follow(mask(o));
|
||||||
|
|
||||||
|
unsigned n = baseSize(t, o, m->heap->follow(objectClass(t, o)));
|
||||||
|
|
||||||
|
if (objectExtended(t, o) or hashTaken(t, o)) {
|
||||||
|
++ n;
|
||||||
|
}
|
||||||
|
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void copy(object o, object dst) {
|
||||||
Thread* t = m->rootThread;
|
Thread* t = m->rootThread;
|
||||||
|
|
||||||
o = m->heap->follow(mask(o));
|
o = m->heap->follow(mask(o));
|
||||||
|
|
||||||
unsigned base = baseSize(t, o, m->heap->follow(objectClass(t, o)));
|
unsigned base = baseSize(t, o, m->heap->follow(objectClass(t, o)));
|
||||||
unsigned copyCount = base;
|
unsigned n = extendedSize(t, o, base);
|
||||||
unsigned allocateCount = base;
|
|
||||||
|
|
||||||
System::Monitor* monitor = 0;
|
memcpy(o, dst, n * BytesPerWord);
|
||||||
|
|
||||||
if (objectExtended(t, o)) {
|
|
||||||
copyCount += BytesPerWord;
|
|
||||||
allocateCount += BytesPerWord;
|
|
||||||
|
|
||||||
if (extendedWord(t, o, base) & MonitorFlag) {
|
|
||||||
copyCount += BytesPerWord;
|
|
||||||
allocateCount += BytesPerWord;
|
|
||||||
} else {
|
|
||||||
monitor = gcHashMapRemove
|
|
||||||
(t, m->monitorMap, o, gcObjectHash, gcObjectEqual);
|
|
||||||
|
|
||||||
if (monitor) {
|
|
||||||
allocateCount += BytesPerWord;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (hashTaken(t, o)) {
|
|
||||||
allocateCount += BytesPerWord;
|
|
||||||
|
|
||||||
monitor = gcHashMapRemove
|
|
||||||
(t, m->monitorMap, o, gcObjectHash, gcObjectEqual);
|
|
||||||
|
|
||||||
if (monitor) {
|
|
||||||
allocateCount += BytesPerWord;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
object dst = allocator->allocate(allocateCount);
|
|
||||||
memcpy(o, dst, copyCount * BytesPerWord);
|
|
||||||
|
|
||||||
if (hashTaken(t, o)) {
|
if (hashTaken(t, o)) {
|
||||||
extendedWord(t, dst, base) = takeHash(t, o);
|
extendedWord(t, dst, base) = takeHash(t, o);
|
||||||
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 (monitor) {
|
|
||||||
attachedMonitor(t, dst, base) = monitor;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void walk(void* p, Heap::Walker* w) {
|
virtual void walk(void* p, Heap::Walker* w) {
|
||||||
@ -730,6 +743,13 @@ collect(Machine* m, Heap::CollectionType type)
|
|||||||
m->unsafe = false;
|
m->unsafe = false;
|
||||||
|
|
||||||
postCollect(m->rootThread);
|
postCollect(m->rootThread);
|
||||||
|
|
||||||
|
Thread* t = m->rootThread;
|
||||||
|
for (object f = m->doomed; f; f = tripleThird(t, f)) {
|
||||||
|
reinterpret_cast<void (*)(Thread*, object)>(finalizerFinalize(t, f))
|
||||||
|
(t, finalizerTarget(t, f));
|
||||||
|
}
|
||||||
|
m->doomed = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -913,39 +933,48 @@ make(Thread* t, object class_)
|
|||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
System::Monitor*
|
void
|
||||||
mappedMonitor(Thread* t, object o)
|
addFinalizer(Thread* t, object target, void (*finalize)(Thread*, object))
|
||||||
{
|
{
|
||||||
PROTECT(t, o);
|
PROTECT(t, target);
|
||||||
|
|
||||||
ACQUIRE(t, t->vm->monitorMapLock);
|
ACQUIRE(t, t->vm->finalizerLock);
|
||||||
|
|
||||||
|
object p = makePointer(t, reinterpret_cast<void*>(finalize));
|
||||||
|
t->vm->finalizers = makeTriple(t, target, p, t->vm->finalizers);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
removeMonitor(Thread* t, object o)
|
||||||
|
{
|
||||||
|
hashMapRemove(t, t->vm->monitorMap, o, objectHash, objectEqual);
|
||||||
|
}
|
||||||
|
|
||||||
|
System::Monitor*
|
||||||
|
objectMonitor(Thread* t, object o)
|
||||||
|
{
|
||||||
object p = hashMapFind(t, t->vm->monitorMap, o, objectHash, objectEqual);
|
object p = hashMapFind(t, t->vm->monitorMap, o, objectHash, objectEqual);
|
||||||
|
|
||||||
if (p) {
|
if (p) {
|
||||||
return static_cast<System::Monitor*>(pointerValue(t, p));
|
return static_cast<System::Monitor*>(pointerValue(t, p));
|
||||||
} else {
|
} else {
|
||||||
|
PROTECT(t, o);
|
||||||
|
|
||||||
|
ENTER(t, Thread::ExclusiveState);
|
||||||
|
|
||||||
|
System::Monitor* m;
|
||||||
System::Status s = t->vm->system->make(&m);
|
System::Status s = t->vm->system->make(&m);
|
||||||
expect(t, t->vm->system->success(s));
|
expect(t, t->vm->system->success(s));
|
||||||
|
|
||||||
object pointer = makePointer(t, m);
|
p = makePointer(t, m);
|
||||||
hashMapInsert(t, t->vm->monitorMap, o, pointer, objectHash);
|
hashMapInsert(t, t->vm->monitorMap, o, p, objectHash);
|
||||||
|
|
||||||
|
addFinalizer(t, o, removeMonitor);
|
||||||
|
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline System::Monitor*
|
|
||||||
objectMonitor(Thread* t, object o)
|
|
||||||
{
|
|
||||||
unsigned base = baseSize(t, o);
|
|
||||||
if (monitorAttached(t, o, base)) {
|
|
||||||
return attachedMonitor(t, o, base);
|
|
||||||
} else {
|
|
||||||
return mappedMonitor(t, o);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
object
|
object
|
||||||
makeByteArray(Thread* t, const char* format, va_list a)
|
makeByteArray(Thread* t, const char* format, va_list a)
|
||||||
{
|
{
|
||||||
@ -2167,7 +2196,10 @@ updateBootstrapClass(Thread* t, object bootstrapClass, object class_)
|
|||||||
|
|
||||||
ENTER(t, Thread::ExclusiveState);
|
ENTER(t, Thread::ExclusiveState);
|
||||||
|
|
||||||
memcpy(bootstrapClass, class_, extendedSize(t, class_) * BytesPerWord);
|
memcpy(bootstrapClass,
|
||||||
|
class_,
|
||||||
|
extendedSize(t, class_, baseSize(t, class_, objectClass(t, class_)))
|
||||||
|
* BytesPerWord);
|
||||||
|
|
||||||
object fieldTable = classFieldTable(t, class_);
|
object fieldTable = classFieldTable(t, class_);
|
||||||
if (fieldTable) {
|
if (fieldTable) {
|
||||||
@ -2471,7 +2503,7 @@ invokeNative(Thread* t, object method)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
object
|
object&
|
||||||
frameLocals(Thread* t, object frame, unsigned index)
|
frameLocals(Thread* t, object frame, unsigned index)
|
||||||
{
|
{
|
||||||
return t->stack[frameStackBase(t, frame) + index];
|
return t->stack[frameStackBase(t, frame) + index];
|
||||||
@ -2608,13 +2640,15 @@ Machine::Machine(System* system, Heap* heap, ClassFinder* classFinder):
|
|||||||
stateLock(0),
|
stateLock(0),
|
||||||
heapLock(0),
|
heapLock(0),
|
||||||
classLock(0),
|
classLock(0),
|
||||||
monitorMapLock(0),
|
finalizerLock(0),
|
||||||
libraries(0),
|
libraries(0),
|
||||||
classMap(0),
|
classMap(0),
|
||||||
bootstrapClassMap(0),
|
bootstrapClassMap(0),
|
||||||
builtinMap(0),
|
builtinMap(0),
|
||||||
monitorMap(0),
|
monitorMap(0),
|
||||||
types(0),
|
types(0),
|
||||||
|
finalizers(0),
|
||||||
|
doomed(0),
|
||||||
unsafe(false)
|
unsafe(false)
|
||||||
{
|
{
|
||||||
memset(&jniEnvVTable, 0, sizeof(JNIEnvVTable));
|
memset(&jniEnvVTable, 0, sizeof(JNIEnvVTable));
|
||||||
@ -2626,7 +2660,7 @@ Machine::Machine(System* system, Heap* heap, ClassFinder* classFinder):
|
|||||||
if (not system->success(system->make(&stateLock)) or
|
if (not system->success(system->make(&stateLock)) or
|
||||||
not system->success(system->make(&heapLock)) or
|
not system->success(system->make(&heapLock)) or
|
||||||
not system->success(system->make(&classLock)) or
|
not system->success(system->make(&classLock)) or
|
||||||
not system->success(system->make(&monitorMapLock)))
|
not system->success(system->make(&finalizerLock)))
|
||||||
{
|
{
|
||||||
system->abort();
|
system->abort();
|
||||||
}
|
}
|
||||||
@ -2638,6 +2672,8 @@ Machine::dispose()
|
|||||||
stateLock->dispose();
|
stateLock->dispose();
|
||||||
heapLock->dispose();
|
heapLock->dispose();
|
||||||
classLock->dispose();
|
classLock->dispose();
|
||||||
|
finalizerLock->dispose();
|
||||||
|
|
||||||
if (libraries) {
|
if (libraries) {
|
||||||
libraries->dispose();
|
libraries->dispose();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user