diff --git a/src/machine.cpp b/src/machine.cpp index 4b6d12d8ae..36c7780bb8 100644 --- a/src/machine.cpp +++ b/src/machine.cpp @@ -1571,6 +1571,11 @@ makeArrayClass(Thread* t, object spec) void removeMonitor(Thread* t, object o) { + unsigned hash; + if (DebugMonitors) { + hash = objectHash(t, o); + } + object p = hashMapRemove(t, t->m->monitorMap, o, objectHash, objectEqual); assert(t, p); @@ -1578,7 +1583,7 @@ removeMonitor(Thread* t, object o) if (DebugMonitors) { fprintf(stderr, "dispose monitor %p for object %x\n", static_cast(pointerValue(t, p)), - objectHash(t, o)); + hash); } static_cast(pointerValue(t, p))->dispose(); diff --git a/src/machine.h b/src/machine.h index dcf771f148..4ea31165e7 100644 --- a/src/machine.h +++ b/src/machine.h @@ -2015,11 +2015,16 @@ objectMonitor(Thread* t, object o, bool createNew); inline void acquire(Thread* t, object o) { + unsigned hash; + if (DebugMonitors) { + hash = objectHash(t, o); + } + System::Monitor* m = objectMonitor(t, o, true); if (DebugMonitors) { fprintf(stderr, "thread %p acquires %p for %x\n", - t, m, objectHash(t, o)); + t, m, hash); } acquire(t, m); @@ -2028,11 +2033,16 @@ acquire(Thread* t, object o) inline void release(Thread* t, object o) { + unsigned hash; + if (DebugMonitors) { + hash = objectHash(t, o); + } + System::Monitor* m = objectMonitor(t, o, false); if (DebugMonitors) { fprintf(stderr, "thread %p releases %p for %x\n", - t, m, objectHash(t, o)); + t, m, hash); } release(t, m); @@ -2041,11 +2051,16 @@ release(Thread* t, object o) inline void wait(Thread* t, object o, int64_t milliseconds) { + unsigned hash; + if (DebugMonitors) { + hash = objectHash(t, o); + } + System::Monitor* m = objectMonitor(t, o, false); if (DebugMonitors) { fprintf(stderr, "thread %p waits %"LLD" millis on %p for %x\n", - t, milliseconds, m, objectHash(t, o)); + t, milliseconds, m, hash); } if (m and m->owner() == t->systemThread) { @@ -2063,7 +2078,7 @@ wait(Thread* t, object o, int64_t milliseconds) if (DebugMonitors) { fprintf(stderr, "thread %p wakes up on %p for %x\n", - t, m, objectHash(t, o)); + t, m, hash); } stress(t); @@ -2072,11 +2087,16 @@ wait(Thread* t, object o, int64_t milliseconds) inline void notify(Thread* t, object o) { + unsigned hash; + if (DebugMonitors) { + hash = objectHash(t, o); + } + System::Monitor* m = objectMonitor(t, o, false); if (DebugMonitors) { fprintf(stderr, "thread %p notifies on %p for %x\n", - t, m, objectHash(t, o)); + t, m, hash); } if (m and m->owner() == t->systemThread) { diff --git a/src/util.cpp b/src/util.cpp index c7579ee839..76cd74069c 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -102,24 +102,31 @@ void hashMapInsert(Thread* t, object map, object key, object value, uint32_t (*hash)(Thread*, object)) { + // note that we reinitialize the array and index variables whenever + // an allocation (and thus possibly a collection) occurs, in case + // the array changes due to a table resize. + + PROTECT(t, map); + + uint32_t h = hash(t, key); + bool weak = objectClass(t, map) == arrayBody(t, t->m->types, Machine::WeakHashMapType); object array = hashMapArray(t, map); - PROTECT(t, array); ++ hashMapSize(t, map); if (array == 0 or hashMapSize(t, map) >= arrayLength(t, array) * 2) { - PROTECT(t, map); PROTECT(t, key); PROTECT(t, value); hashMapResize(t, map, hash, array ? arrayLength(t, array) * 2 : 16); + array = hashMapArray(t, map); } - unsigned index = hash(t, key) & (arrayLength(t, array) - 1); + object k = key; if (weak) { PROTECT(t, key); @@ -128,10 +135,17 @@ hashMapInsert(Thread* t, object map, object key, object value, object r = makeWeakReference(t, 0, 0, 0, 0); jreferenceTarget(t, r) = key; jreferenceVmNext(t, r) = t->m->weakReferences; - key = t->m->weakReferences = r; + k = t->m->weakReferences = r; + + array = hashMapArray(t, map); } - object n = makeTriple(t, key, value, arrayBody(t, array, index)); + unsigned index = h & (arrayLength(t, array) - 1); + + object n = makeTriple(t, k, value, arrayBody(t, array, index)); + + array = hashMapArray(t, map); + index = h & (arrayLength(t, array) - 1); set(t, array, ArrayBody + (index * BytesPerWord), n); }