[vmkit-commits] [vmkit] r109976 - /vmkit/trunk/lib/J3/VMCore/JavaObject.cpp

Nicolas Geoffray nicolas.geoffray at lip6.fr
Sun Aug 1 05:50:27 PDT 2010


Author: geoffray
Date: Sun Aug  1 07:50:27 2010
New Revision: 109976

URL: http://llvm.org/viewvc/llvm-project?rev=109976&view=rev
Log:
Bugfix in hashCode for movable collectors.


Modified:
    vmkit/trunk/lib/J3/VMCore/JavaObject.cpp

Modified: vmkit/trunk/lib/J3/VMCore/JavaObject.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/J3/VMCore/JavaObject.cpp?rev=109976&r1=109975&r2=109976&view=diff
==============================================================================
--- vmkit/trunk/lib/J3/VMCore/JavaObject.cpp (original)
+++ vmkit/trunk/lib/J3/VMCore/JavaObject.cpp Sun Aug  1 07:50:27 2010
@@ -20,30 +20,44 @@
 
 using namespace j3;
 
-uint16_t JavaObject::hashCodeGenerator = 1;
+static const int hashCodeIncrement = mvm::GCBitMask + 1;
+uint16_t JavaObject::hashCodeGenerator = hashCodeIncrement;
 
 /// hashCode - Return the hash code of this object.
 uint32_t JavaObject::hashCode(JavaObject* self) {
   llvm_gcroot(self, 0);
   if (!mvm::MovesObject) return (uint32_t)(long)self;
 
-  uintptr_t oldLock = self->lock.lock;
-  uintptr_t val = (oldLock & mvm::HashMask) >> mvm::GCBits;
-  if (val) return val ^ (uintptr_t)getClass(self);
-  if (hashCodeGenerator >= (mvm::HashMask >> mvm::GCBits)) {
-    val = hashCodeGenerator = 1;
-  } else {
-    val = ++hashCodeGenerator;
+  uintptr_t header = self->lock.lock;
+  uintptr_t GCBits = header & mvm::GCBitMask;
+  uintptr_t val = header & mvm::HashMask;
+  if (val != 0) {
+    return val ^ (uintptr_t)getClass(self);
+  }
+  val = hashCodeGenerator;
+  hashCodeGenerator += hashCodeIncrement;
+  val = val % mvm::HashMask;
+  if (val == 0) {
+    // It is possible that in the same time, a thread is in this method and
+    // gets the same hash code value than this thread. This is fine.
+    val = hashCodeIncrement;
+    hashCodeGenerator += hashCodeIncrement;
   }
+  assert(val > mvm::GCBitMask);
+  assert(val <= mvm::HashMask);
+  assert(val != hashCodeGenerator);
 
   do {
-    uintptr_t oldLock = self->lock.lock;
-    uintptr_t newLock = (val << mvm::GCBits) | oldLock;
-      __sync_val_compare_and_swap(&(self->lock.lock), oldLock, newLock);
-  } while ((self->lock.lock & mvm::HashMask)  == 0);
-
-  return ((self->lock.lock & mvm::HashMask) >> mvm::GCBits) ^
-      (uintptr_t)getClass(self);
+    header = self->lock.lock;
+    if ((header & mvm::HashMask) != 0) break;
+    uintptr_t newHeader = header | val;
+    assert((newHeader & ~mvm::HashMask) == header);
+    __sync_val_compare_and_swap(&(self->lock.lock), header, newHeader);
+  } while (true);
+
+  assert((self->lock.lock & mvm::HashMask) != 0);
+  assert(GCBits == (self->lock.lock & mvm::GCBitMask));
+  return (self->lock.lock & mvm::HashMask) ^ (uintptr_t)getClass(self);
 }
 
 





More information about the vmkit-commits mailing list