more bugfixes, mainly monitor-related

This commit is contained in:
Joel Dice 2007-07-10 22:19:26 -06:00
parent 93748f2df9
commit 01d858e1bc
5 changed files with 139 additions and 70 deletions

View File

@ -13,7 +13,11 @@ public class TestExceptions {
} }
public static void main(String[] args) { public static void main(String[] args) {
try {
dangerous(); dangerous();
} catch (Exception e) {
e.printStackTrace();
}
} }
} }

View File

@ -22,13 +22,13 @@ public class TestThreads implements Runnable {
try { try {
System.out.println("I'm running in a separate thread!"); System.out.println("I'm running in a separate thread!");
// final int arrayCount = 8; final int arrayCount = 16;
// final int arraySize = 4; final int arraySize = 4;
// System.out.println("Allocating and discarding " + arrayCount + System.out.println("Allocating and discarding " + arrayCount +
// " arrays of " + arraySize + "MB each"); " arrays of " + arraySize + "MB each");
// for (; i < arrayCount; ++i) { for (; i < arrayCount; ++i) {
// byte[] array = new byte[arraySize * 1024 * 1024]; byte[] array = new byte[arraySize * 1024 * 1024];
// } }
long nap = 5; long nap = 5;
System.out.println("sleeping for " + nap + " seconds"); System.out.println("sleeping for " + nap + " seconds");

View File

@ -428,14 +428,6 @@ collect(Thread* t, Heap::CollectionType type)
killZombies(t, m->rootThread); killZombies(t, m->rootThread);
} }
void
removeMonitor(Thread* t, object o)
{
object p = hashMapRemove
(t, t->vm->monitorMap, o, objectHash, referenceEqual);
static_cast<System::Monitor*>(pointerValue(t, p))->dispose();
}
object object
makeByteArray(Thread* t, const char* format, va_list a) makeByteArray(Thread* t, const char* format, va_list a)
{ {
@ -606,7 +598,6 @@ Thread::dispose()
if (allocator) { if (allocator) {
allocator->free(this); allocator->free(this);
allocator = 0;
} }
} }
@ -622,6 +613,11 @@ exit(Thread* t)
(t, finalizerTarget(t, f)); (t, finalizerTarget(t, f));
} }
for (object f = t->vm->tenuredFinalizers; f; f = finalizerNext(t, f)) {
reinterpret_cast<void (*)(Thread*, object)>(finalizerFinalize(t, f))
(t, finalizerTarget(t, f));
}
disposeAll(t, t->vm->rootThread); disposeAll(t, t->vm->rootThread);
} }
@ -800,13 +796,10 @@ hashMapFindNode(Thread* t, object map, object key,
object array = hashMapArray(t, map); object array = hashMapArray(t, map);
if (array) { if (array) {
unsigned index = hash(t, key) & (arrayLength(t, array) - 1); unsigned index = hash(t, key) & (arrayLength(t, array) - 1);
object n = arrayBody(t, array, index); for (object n = arrayBody(t, array, index); n; n = tripleThird(t, n)) {
while (n) {
if (equal(t, key, tripleFirst(t, n))) { if (equal(t, key, tripleFirst(t, n))) {
return n; return n;
} }
n = tripleThird(t, n);
} }
} }
return 0; return 0;
@ -818,34 +811,36 @@ hashMapResize(Thread* t, object map, uint32_t (*hash)(Thread*, object),
{ {
PROTECT(t, map); PROTECT(t, map);
object newArray = 0;
if (size) {
object oldArray = hashMapArray(t, map); object oldArray = hashMapArray(t, map);
unsigned oldLength = (oldArray ? arrayLength(t, oldArray) : 0);
PROTECT(t, oldArray); PROTECT(t, oldArray);
unsigned newLength = nextPowerOfTwo(size); unsigned newLength = nextPowerOfTwo(size);
object newArray = makeArray(t, newLength, true); newArray = makeArray(t, newLength, true);
if (oldArray) { if (oldArray) {
for (unsigned i = 0; i < oldLength; ++i) { for (unsigned i = 0; i < arrayLength(t, oldArray); ++i) {
object next; object next;
for (object p = arrayBody(t, oldArray, i); p; p = next) { for (object p = arrayBody(t, oldArray, i); p; p = next) {
next = tripleThird(t, p); next = tripleThird(t, p);
object key = tripleFirst(t, p); object key = tripleFirst(t, p);
unsigned index = hash(t, key) & (newLength - 1); unsigned index = hash(t, key) & (newLength - 1);
object n = arrayBody(t, newArray, index);
set(t, tripleThird(t, p), n); set(t, tripleThird(t, p), arrayBody(t, newArray, index));
set(t, arrayBody(t, newArray, index), p); set(t, arrayBody(t, newArray, index), p);
} }
} }
} }
}
set(t, hashMapArray(t, map), newArray); set(t, hashMapArray(t, map), newArray);
} }
void void
hashMapInsert(Thread* t, object map, object key, object value, hashMapInsert2(Thread* t, object map, object key, object value, uint32_t h,
uint32_t (*hash)(Thread*, object)) uint32_t (*hash)(Thread*, object))
{ {
object array = hashMapArray(t, map); object array = hashMapArray(t, map);
@ -862,7 +857,7 @@ hashMapInsert(Thread* t, object map, object key, object value,
array = hashMapArray(t, map); 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); object n = arrayBody(t, array, index);
n = makeTriple(t, key, value, n); n = makeTriple(t, key, value, n);
@ -870,39 +865,48 @@ hashMapInsert(Thread* t, object map, object key, object value,
set(t, arrayBody(t, array, index), n); 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 object
hashMapRemove(Thread* t, object map, object key, hashMapRemove2(Thread* t, object map, object key, uint32_t h,
uint32_t (*hash)(Thread*, object), uint32_t (*hash)(Thread*, object),
bool (*equal)(Thread*, object, object)) bool (*equal)(Thread*, object, object))
{ {
object array = hashMapArray(t, map); object array = hashMapArray(t, map);
object o = 0; object o = 0;
if (array) { if (array) {
unsigned index = hash(t, key) & (arrayLength(t, array) - 1); unsigned index = h & (arrayLength(t, array) - 1);
object n = arrayBody(t, array, index); for (object* n = &arrayBody(t, array, index); *n;) {
object p = 0; if (equal(t, key, tripleFirst(t, *n))) {
while (n) { o = tripleSecond(t, *n);
if (equal(t, key, tripleFirst(t, n))) { set(t, *n, tripleThird(t, *n));
o = tripleSecond(t, n); -- hashMapSize(t, map);
if (p) {
set(t, tripleThird(t, p), tripleThird(t, n));
} else { } else {
set(t, arrayBody(t, array, index), tripleThird(t, n)); n = &tripleThird(t, *n);
}
}
p = n;
n = tripleThird(t, n);
} }
} }
if (hashMapSize(t, map) <= arrayLength(t, array) / 3) { if (hashMapSize(t, map) <= arrayLength(t, array) / 3) {
hashMapResize(t, map, hash, arrayLength(t, array) / 2); hashMapResize(t, map, hash, arrayLength(t, array) / 2);
} }
}
return o; return o;
} }
object
hashMapRemove(Thread* t, object map, object key,
uint32_t (*hash)(Thread*, object),
bool (*equal)(Thread*, object, object))
{
return hashMapRemove2(t, map, key, hash(t, key), hash, equal);
}
object object
makeTrace(Thread* t, int frame) makeTrace(Thread* t, int frame)
{ {
@ -986,6 +990,23 @@ addFinalizer(Thread* t, object target, void (*finalize)(Thread*, object))
(t, target, reinterpret_cast<void*>(finalize), t->vm->finalizers); (t, target, reinterpret_cast<void*>(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<System::Monitor*>(pointerValue(t, p)),
objectHash(t, o));
}
static_cast<System::Monitor*>(pointerValue(t, p))->dispose();
}
System::Monitor* System::Monitor*
objectMonitor(Thread* t, object o) objectMonitor(Thread* t, object o)
{ {
@ -993,7 +1014,7 @@ objectMonitor(Thread* t, object o)
if (p) { if (p) {
if (DebugMonitors) { if (DebugMonitors) {
fprintf(stderr, "found monitor %p for object 0x%x\n", fprintf(stderr, "found monitor %p for object %x\n",
static_cast<System::Monitor*>(pointerValue(t, p)), static_cast<System::Monitor*>(pointerValue(t, p)),
objectHash(t, o)); objectHash(t, o));
} }
@ -1015,7 +1036,7 @@ objectMonitor(Thread* t, object o)
t->vm->weakReferences = wr; t->vm->weakReferences = wr;
if (DebugMonitors) { if (DebugMonitors) {
fprintf(stderr, "made monitor %p for object 0x%x\n", fprintf(stderr, "made monitor %p for object %x\n",
m, m,
objectHash(t, o)); objectHash(t, o));
} }

View File

@ -24,7 +24,7 @@ namespace vm {
const bool Verbose = false; const bool Verbose = false;
const bool DebugRun = false; const bool DebugRun = false;
const bool DebugStack = false; const bool DebugStack = false;
const bool DebugMonitors = false; const bool DebugMonitors = true;
const uintptr_t HashTakenMark = 1; const uintptr_t HashTakenMark = 1;
const uintptr_t ExtendedMark = 2; const uintptr_t ExtendedMark = 2;
@ -1831,6 +1831,12 @@ inline void
acquire(Thread* t, object o) acquire(Thread* t, object o)
{ {
System::Monitor* m = objectMonitor(t, 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)) { if (not m->tryAcquire(t)) {
ENTER(t, Thread::IdleState); ENTER(t, Thread::IdleState);
m->acquire(t); m->acquire(t);
@ -1840,25 +1846,49 @@ acquire(Thread* t, object o)
inline void inline void
release(Thread* t, object o) 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 inline void
wait(Thread* t, object o, int64_t milliseconds) wait(Thread* t, object o, int64_t milliseconds)
{ {
System::Monitor* m = objectMonitor(t, o); 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) { if (m->owner() == t) {
ENTER(t, Thread::IdleState); ENTER(t, Thread::IdleState);
m->wait(t, milliseconds); m->wait(t, milliseconds);
} else { } else {
t->exception = makeIllegalMonitorStateException(t); t->exception = makeIllegalMonitorStateException(t);
} }
if (DebugMonitors) {
fprintf(stderr, "thread %p wakes up on %p for %x\n",
t, m, objectHash(t, o));
}
} }
inline void inline void
notify(Thread* t, object o) notify(Thread* t, object o)
{ {
System::Monitor* m = objectMonitor(t, 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) { if (m->owner() == t) {
m->notify(t); m->notify(t);
} else { } else {
@ -1870,6 +1900,12 @@ inline void
notifyAll(Thread* t, object o) notifyAll(Thread* t, object o)
{ {
System::Monitor* m = objectMonitor(t, 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) { if (m->owner() == t) {
m->notifyAll(t); m->notifyAll(t);
} else { } else {

View File

@ -139,7 +139,9 @@ class System: public vm::System {
} }
virtual void dispose() { virtual void dispose() {
if (r) {
r->dispose(); r->dispose();
}
s->free(this); s->free(this);
} }
@ -196,6 +198,9 @@ class System: public vm::System {
virtual void wait(void* context, int64_t time) { virtual void wait(void* context, int64_t time) {
if (this->context == context) { if (this->context == context) {
unsigned depth = this->depth;
this->depth = 0;
this->context = 0;
if (time) { if (time) {
int64_t then = now() + time; int64_t then = now() + time;
timespec ts = { then / 1000, (then % 1000) * 1000 * 1000 }; timespec ts = { then / 1000, (then % 1000) * 1000 * 1000 };
@ -205,6 +210,8 @@ class System: public vm::System {
int rv = pthread_cond_wait(&condition, &mutex); int rv = pthread_cond_wait(&condition, &mutex);
assert(s, rv == 0); assert(s, rv == 0);
} }
this->context = context;
this->depth = depth;
} else { } else {
vm::abort(s); vm::abort(s);
} }
@ -233,6 +240,7 @@ class System: public vm::System {
} }
virtual void dispose() { virtual void dispose() {
assert(s, context == 0);
pthread_mutex_destroy(&mutex); pthread_mutex_destroy(&mutex);
pthread_cond_destroy(&condition); pthread_cond_destroy(&condition);
s->free(this); s->free(this);