[vmkit-commits] [vmkit] r85279 - in /vmkit/trunk: include/mvm/Threads/Locks.h lib/JnJVM/Compiler/JavaJIT.cpp

Nicolas Geoffray nicolas.geoffray at lip6.fr
Tue Oct 27 12:50:31 PDT 2009


Author: geoffray
Date: Tue Oct 27 14:50:31 2009
New Revision: 85279

URL: http://llvm.org/viewvc/llvm-project?rev=85279&view=rev
Log:
Fix implementation of thin locks, in the presence of used bits for the GC.


Modified:
    vmkit/trunk/include/mvm/Threads/Locks.h
    vmkit/trunk/lib/JnJVM/Compiler/JavaJIT.cpp

Modified: vmkit/trunk/include/mvm/Threads/Locks.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/include/mvm/Threads/Locks.h?rev=85279&r1=85278&r2=85279&view=diff

==============================================================================
--- vmkit/trunk/include/mvm/Threads/Locks.h (original)
+++ vmkit/trunk/include/mvm/Threads/Locks.h Tue Oct 27 14:50:31 2009
@@ -183,8 +183,9 @@
   static const uint64_t FatMask = 0x80000000;
 #endif
 
-  static const uint64_t ThinMask = 0x7FFFFF00;
-  static const uint64_t ThinCountMask = 0xFF;
+  static const uint64_t ThinCountMask = 0xFF000;
+  static const uint64_t ThinCountAdd = 0x1000;
+  static const uint64_t GCMask = 0x3;
 
 
 
@@ -251,7 +252,8 @@
       TFatLock* obj = TFatLock::allocate(O);
       uint32 count = lock & ThinCountMask;
       obj->acquireAll(count + 1);
-      lock = obj->getID();
+      uintptr_t oldLock = lock;
+      lock = obj->getID() | (oldLock & GCMask);
       return obj;
     } else {
       TFatLock* res = TFatLock::getFromID(lock);
@@ -265,14 +267,17 @@
     IsGC::gcroot(O, 0);
 start:
     uint64_t id = mvm::Thread::get()->getThreadID();
-    uintptr_t val = __sync_val_compare_and_swap(&lock, 0, id);
+    uintptr_t oldValue = lock;
+    uintptr_t newValue = id | (lock & GCMask);
+    uintptr_t val = __sync_val_compare_and_swap(&lock, oldValue & GCMask,
+                                                newValue);
 
-    if (val != 0) {
+    if (val != (oldValue & GCMask)) {
       //fat!
       if (!(val & FatMask)) {
-        if ((val & ThinMask) == id) {
+        if ((val & Thread::IDMask) == id) {
           if ((val & ThinCountMask) != ThinCountMask) {
-            lock++;
+            lock += ThinCountAdd;
           } else {
             overflowThinLock(O);
           }
@@ -288,8 +293,11 @@
             else mvm::Thread::yield();
           }
         
-          uintptr_t test = __sync_val_compare_and_swap((uintptr_t*)&lock, 0, val);
-          if (test) goto loop;
+          oldValue = lock;
+          newValue = val | (lock & GCMask);
+          uintptr_t test = __sync_val_compare_and_swap(&lock, oldValue & GCMask,
+                                                       newValue);
+          if (test != (oldValue & GCMask)) goto loop;
           if (!obj->acquire(O)) goto start;
         }
       } else {
@@ -312,14 +320,14 @@
     IsGC::gcroot(O, 0);
     assert(owner() && "Not owner when entering release!");
     uint64 id = mvm::Thread::get()->getThreadID();
-    if (lock == id) {
-      lock = 0;
+    if ((lock & ~GCMask) == id) {
+      lock = lock & GCMask;
     } else if (lock & FatMask) {
       TFatLock* obj = TFatLock::getFromID(lock);
       assert(obj && "Lock deallocated while held.");
       obj->release(O);
     } else {
-      lock--;
+      lock -= ThinCountAdd;
     }
   }
 
@@ -345,12 +353,12 @@
   /// owner - Returns true if the curren thread is the owner of this object's
   /// lock.
   bool owner() {
-    uint64 id = mvm::Thread::get()->getThreadID();
-    if (id == lock) return true;
-    if ((lock & ThinMask) == id) return true;
     if (lock & FatMask) {
       TFatLock* obj = TFatLock::getFromID(lock);
       if (obj) return obj->owner();
+    } else {
+      uint64 id = mvm::Thread::get()->getThreadID();
+      if ((lock & Thread::IDMask) == id) return true;
     }
     return false;
   }
@@ -361,7 +369,7 @@
       if (obj) return obj->getOwner();
       return 0;
     } else {
-      return (mvm::Thread*)(lock & ThinMask);
+      return (mvm::Thread*)(lock & mvm::Thread::IDMask);
     }
   }
 

Modified: vmkit/trunk/lib/JnJVM/Compiler/JavaJIT.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/Compiler/JavaJIT.cpp?rev=85279&r1=85278&r2=85279&view=diff

==============================================================================
--- vmkit/trunk/lib/JnJVM/Compiler/JavaJIT.cpp (original)
+++ vmkit/trunk/lib/JnJVM/Compiler/JavaJIT.cpp Tue Oct 27 14:50:31 2009
@@ -496,16 +496,25 @@
   gep.push_back(module->JavaObjectLockOffsetConstant);
   Value* lockPtr = GetElementPtrInst::Create(obj, gep.begin(), gep.end(), "",
                                              currentBlock);
+  
+  Value* lock = new LoadInst(lockPtr, "", currentBlock);
+  lock = new PtrToIntInst(lock, module->pointerSizeType, "", currentBlock);
+  Value* GCMask = ConstantInt::get(module->pointerSizeType,
+                                   mvm::GCMask);
+
+  lock = BinaryOperator::CreateAnd(lock, GCMask, "", currentBlock);
+
   lockPtr = new BitCastInst(lockPtr, 
                             PointerType::getUnqual(module->pointerSizeType),
                             "", currentBlock);
   Value* threadId = getCurrentThread(module->MutatorThreadType);
   threadId = new PtrToIntInst(threadId, module->pointerSizeType, "",
                               currentBlock);
+  threadId = BinaryOperator::CreateOr(threadId, lock, "", currentBlock);
 
   std::vector<Value*> atomicArgs;
   atomicArgs.push_back(lockPtr);
-  atomicArgs.push_back(module->constantPtrZero);
+  atomicArgs.push_back(lock);
   atomicArgs.push_back(threadId);
 
   // Do the atomic compare and swap.
@@ -514,7 +523,7 @@
                                    currentBlock);
   
   Value* cmp = new ICmpInst(*currentBlock, ICmpInst::ICMP_EQ, atomic,
-                            module->constantPtrZero, "");
+                            lock, "");
   
   BasicBlock* OK = createBasicBlock("synchronize passed");
   BasicBlock* NotOK = createBasicBlock("synchronize did not pass");
@@ -535,8 +544,8 @@
 
   // It's a thin lock. Look if we're the owner of this lock.
   currentBlock = ThinLockBB;
-  Value* idMask = ConstantInt::get(module->pointerSizeType, 0x7FFFFF00);
-  Value* cptMask = ConstantInt::get(module->pointerSizeType, 0xFF);
+  Value* idMask = ConstantInt::get(module->pointerSizeType, mvm::Thread::IDMask);
+  Value* cptMask = ConstantInt::get(module->pointerSizeType, mvm::ThinCountMask);
   Value* IdInLock = BinaryOperator::CreateAnd(atomic, idMask, "", currentBlock);
   Value* owner = new ICmpInst(*currentBlock, ICmpInst::ICMP_EQ, threadId,
                               IdInLock, "");
@@ -557,8 +566,8 @@
   currentBlock = IncCounterBB;
   
   // The counter will not overflow, increment it.
-  Value* Add = BinaryOperator::CreateAdd(module->constantPtrOne, atomic, "",
-                                         currentBlock);
+  Value* One = ConstantInt::get(module->pointerSizeType, mvm::ThinCountAdd);
+  Value* Add = BinaryOperator::CreateAdd(One, atomic, "", currentBlock);
   new StoreInst(Add, lockPtr, false, currentBlock);
   BranchInst::Create(OK, currentBlock);
 
@@ -623,8 +632,8 @@
   currentBlock = ThinLockBB;
 
   // Decrement the counter.
-  Value* Sub = BinaryOperator::CreateSub(lock, module->constantPtrOne, "",
-                                         currentBlock);
+  Value* One = ConstantInt::get(module->pointerSizeType, mvm::ThinCountAdd);
+  Value* Sub = BinaryOperator::CreateSub(lock, One, "", currentBlock);
   new StoreInst(Sub, lockPtr, false, currentBlock);
   BranchInst::Create(EndUnlock, currentBlock);
 





More information about the vmkit-commits mailing list