diff --git a/classpath/TestExceptions.java b/classpath/TestExceptions.java index c37e685879..fb12e9f7bc 100644 --- a/classpath/TestExceptions.java +++ b/classpath/TestExceptions.java @@ -13,7 +13,11 @@ public class TestExceptions { } public static void main(String[] args) { - dangerous(); + try { + dangerous(); + } catch (Exception e) { + e.printStackTrace(); + } } } diff --git a/classpath/TestThreads.java b/classpath/TestThreads.java index 8a7ac9a28d..b4a2366f9f 100644 --- a/classpath/TestThreads.java +++ b/classpath/TestThreads.java @@ -22,13 +22,13 @@ public class TestThreads implements Runnable { try { System.out.println("I'm running in a separate thread!"); -// final int arrayCount = 8; -// final int arraySize = 4; -// System.out.println("Allocating and discarding " + arrayCount + -// " arrays of " + arraySize + "MB each"); -// for (; i < arrayCount; ++i) { -// byte[] array = new byte[arraySize * 1024 * 1024]; -// } + final int arrayCount = 16; + final int arraySize = 4; + System.out.println("Allocating and discarding " + arrayCount + + " arrays of " + arraySize + "MB each"); + for (; i < arrayCount; ++i) { + byte[] array = new byte[arraySize * 1024 * 1024]; + } long nap = 5; System.out.println("sleeping for " + nap + " seconds"); diff --git a/src/machine.cpp b/src/machine.cpp index 14174e97d2..c45469014f 100644 --- a/src/machine.cpp +++ b/src/machine.cpp @@ -428,14 +428,6 @@ collect(Thread* t, Heap::CollectionType type) killZombies(t, m->rootThread); } -void -removeMonitor(Thread* t, object o) -{ - object p = hashMapRemove - (t, t->vm->monitorMap, o, objectHash, referenceEqual); - static_cast(pointerValue(t, p))->dispose(); -} - object makeByteArray(Thread* t, const char* format, va_list a) { @@ -606,7 +598,6 @@ Thread::dispose() if (allocator) { allocator->free(this); - allocator = 0; } } @@ -622,6 +613,11 @@ exit(Thread* t) (t, finalizerTarget(t, f)); } + for (object f = t->vm->tenuredFinalizers; f; f = finalizerNext(t, f)) { + reinterpret_cast(finalizerFinalize(t, f)) + (t, finalizerTarget(t, f)); + } + disposeAll(t, t->vm->rootThread); } @@ -800,13 +796,10 @@ hashMapFindNode(Thread* t, object map, object key, object array = hashMapArray(t, map); if (array) { unsigned index = hash(t, key) & (arrayLength(t, array) - 1); - object n = arrayBody(t, array, index); - while (n) { + for (object n = arrayBody(t, array, index); n; n = tripleThird(t, n)) { if (equal(t, key, tripleFirst(t, n))) { return n; } - - n = tripleThird(t, n); } } return 0; @@ -818,25 +811,27 @@ hashMapResize(Thread* t, object map, uint32_t (*hash)(Thread*, object), { PROTECT(t, map); - object oldArray = hashMapArray(t, map); - unsigned oldLength = (oldArray ? arrayLength(t, oldArray) : 0); - PROTECT(t, oldArray); + object newArray = 0; - unsigned newLength = nextPowerOfTwo(size); - object newArray = makeArray(t, newLength, true); + if (size) { + object oldArray = hashMapArray(t, map); + PROTECT(t, oldArray); - if (oldArray) { - for (unsigned i = 0; i < oldLength; ++i) { - object next; - for (object p = arrayBody(t, oldArray, i); p; p = next) { - next = tripleThird(t, p); + unsigned newLength = nextPowerOfTwo(size); + newArray = makeArray(t, newLength, true); - object key = tripleFirst(t, p); - unsigned index = hash(t, key) & (newLength - 1); - object n = arrayBody(t, newArray, index); + if (oldArray) { + for (unsigned i = 0; i < arrayLength(t, oldArray); ++i) { + object next; + for (object p = arrayBody(t, oldArray, i); p; p = next) { + next = tripleThird(t, p); - set(t, tripleThird(t, p), n); - set(t, arrayBody(t, newArray, index), p); + object key = tripleFirst(t, p); + unsigned index = hash(t, key) & (newLength - 1); + + set(t, tripleThird(t, p), arrayBody(t, newArray, index)); + set(t, arrayBody(t, newArray, index), p); + } } } } @@ -845,8 +840,8 @@ hashMapResize(Thread* t, object map, uint32_t (*hash)(Thread*, object), } void -hashMapInsert(Thread* t, object map, object key, object value, - uint32_t (*hash)(Thread*, object)) +hashMapInsert2(Thread* t, object map, object key, object value, uint32_t h, + uint32_t (*hash)(Thread*, object)) { object array = hashMapArray(t, map); PROTECT(t, array); @@ -862,7 +857,7 @@ hashMapInsert(Thread* t, object map, object key, object value, array = hashMapArray(t, map); } - unsigned index = hash(t, key) & (arrayLength(t, array) - 1); + unsigned index = h & (arrayLength(t, array) - 1); object n = arrayBody(t, array, index); n = makeTriple(t, key, value, n); @@ -870,37 +865,46 @@ hashMapInsert(Thread* t, object map, object key, object value, set(t, arrayBody(t, array, index), n); } +void +hashMapInsert(Thread* t, object map, object key, object value, + uint32_t (*hash)(Thread*, object)) +{ + hashMapInsert2(t, map, key, value, hash(t, key), hash); +} + +object +hashMapRemove2(Thread* t, object map, object key, uint32_t h, + uint32_t (*hash)(Thread*, object), + bool (*equal)(Thread*, object, object)) +{ + object array = hashMapArray(t, map); + object o = 0; + if (array) { + unsigned index = h & (arrayLength(t, array) - 1); + for (object* n = &arrayBody(t, array, index); *n;) { + if (equal(t, key, tripleFirst(t, *n))) { + o = tripleSecond(t, *n); + set(t, *n, tripleThird(t, *n)); + -- hashMapSize(t, map); + } else { + n = &tripleThird(t, *n); + } + } + + if (hashMapSize(t, map) <= arrayLength(t, array) / 3) { + hashMapResize(t, map, hash, arrayLength(t, array) / 2); + } + } + + return o; +} + 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, key, tripleFirst(t, n))) { - o = tripleSecond(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; + return hashMapRemove2(t, map, key, hash(t, key), hash, equal); } object @@ -986,6 +990,23 @@ addFinalizer(Thread* t, object target, void (*finalize)(Thread*, object)) (t, target, reinterpret_cast(finalize), t->vm->finalizers); } +void +removeMonitor(Thread* t, object o) +{ + object p = hashMapRemove2 + (t, t->vm->monitorMap, o, objectHash(t, o), referenceHash, referenceEqual); + + assert(t, p); + + if (DebugMonitors) { + fprintf(stderr, "dispose monitor %p for object %x\n", + static_cast(pointerValue(t, p)), + objectHash(t, o)); + } + + static_cast(pointerValue(t, p))->dispose(); +} + System::Monitor* objectMonitor(Thread* t, object o) { @@ -993,7 +1014,7 @@ objectMonitor(Thread* t, object o) if (p) { if (DebugMonitors) { - fprintf(stderr, "found monitor %p for object 0x%x\n", + fprintf(stderr, "found monitor %p for object %x\n", static_cast(pointerValue(t, p)), objectHash(t, o)); } @@ -1015,7 +1036,7 @@ objectMonitor(Thread* t, object o) t->vm->weakReferences = wr; if (DebugMonitors) { - fprintf(stderr, "made monitor %p for object 0x%x\n", + fprintf(stderr, "made monitor %p for object %x\n", m, objectHash(t, o)); } diff --git a/src/machine.h b/src/machine.h index 41a618c455..1c397a0a5a 100644 --- a/src/machine.h +++ b/src/machine.h @@ -24,7 +24,7 @@ namespace vm { const bool Verbose = false; const bool DebugRun = false; const bool DebugStack = false; -const bool DebugMonitors = false; +const bool DebugMonitors = true; const uintptr_t HashTakenMark = 1; const uintptr_t ExtendedMark = 2; @@ -1831,6 +1831,12 @@ inline void acquire(Thread* t, object o) { System::Monitor* m = objectMonitor(t, o); + + if (DebugMonitors) { + fprintf(stderr, "thread %p acquires %p for %x\n", + t, m, objectHash(t, o)); + } + if (not m->tryAcquire(t)) { ENTER(t, Thread::IdleState); m->acquire(t); @@ -1840,25 +1846,49 @@ acquire(Thread* t, object o) inline void release(Thread* t, object o) { - objectMonitor(t, o)->release(t); + System::Monitor* m = objectMonitor(t, o); + + if (DebugMonitors) { + fprintf(stderr, "thread %p releases %p for %x\n", + t, m, objectHash(t, o)); + } + + m->release(t); } inline void wait(Thread* t, object o, int64_t milliseconds) { System::Monitor* m = objectMonitor(t, o); + + if (DebugMonitors) { + fprintf(stderr, "thread %p waits " LLD " millis on %p for %x\n", + t, milliseconds, m, objectHash(t, o)); + } + if (m->owner() == t) { ENTER(t, Thread::IdleState); m->wait(t, milliseconds); } else { t->exception = makeIllegalMonitorStateException(t); } + + if (DebugMonitors) { + fprintf(stderr, "thread %p wakes up on %p for %x\n", + t, m, objectHash(t, o)); + } } inline void notify(Thread* t, object o) { System::Monitor* m = objectMonitor(t, o); + + if (DebugMonitors) { + fprintf(stderr, "thread %p notifies on %p for %x\n", + t, m, objectHash(t, o)); + } + if (m->owner() == t) { m->notify(t); } else { @@ -1870,6 +1900,12 @@ inline void notifyAll(Thread* t, object o) { System::Monitor* m = objectMonitor(t, o); + + if (DebugMonitors) { + fprintf(stderr, "thread %p notifies all on %p for %x\n", + t, m, objectHash(t, o)); + } + if (m->owner() == t) { m->notifyAll(t); } else { diff --git a/src/main.cpp b/src/main.cpp index bccbc6a1f4..c2439b0b56 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -139,7 +139,9 @@ class System: public vm::System { } virtual void dispose() { - r->dispose(); + if (r) { + r->dispose(); + } s->free(this); } @@ -196,6 +198,9 @@ class System: public vm::System { virtual void wait(void* context, int64_t time) { if (this->context == context) { + unsigned depth = this->depth; + this->depth = 0; + this->context = 0; if (time) { int64_t then = now() + time; timespec ts = { then / 1000, (then % 1000) * 1000 * 1000 }; @@ -205,6 +210,8 @@ class System: public vm::System { int rv = pthread_cond_wait(&condition, &mutex); assert(s, rv == 0); } + this->context = context; + this->depth = depth; } else { vm::abort(s); } @@ -233,6 +240,7 @@ class System: public vm::System { } virtual void dispose() { + assert(s, context == 0); pthread_mutex_destroy(&mutex); pthread_cond_destroy(&condition); s->free(this);