[vmkit-commits] [vmkit] r58999 - in /vmkit/trunk: include/mvm/JIT.h lib/JnJVM/Classpath/ClasspathVMObject.cpp lib/JnJVM/VMCore/JavaJIT.cpp lib/JnJVM/VMCore/JavaJITOpcodes.cpp lib/JnJVM/VMCore/JavaObject.cpp lib/JnJVM/VMCore/JavaObject.h lib/Mvm/Runtime/JIT.cpp

Nicolas Geoffray nicolas.geoffray at lip6.fr
Mon Nov 10 12:38:05 PST 2008


Author: geoffray
Date: Mon Nov 10 14:38:05 2008
New Revision: 58999

URL: http://llvm.org/viewvc/llvm-project?rev=58999&view=rev
Log:
Implement biased-locking.


Modified:
    vmkit/trunk/include/mvm/JIT.h
    vmkit/trunk/lib/JnJVM/Classpath/ClasspathVMObject.cpp
    vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.cpp
    vmkit/trunk/lib/JnJVM/VMCore/JavaJITOpcodes.cpp
    vmkit/trunk/lib/JnJVM/VMCore/JavaObject.cpp
    vmkit/trunk/lib/JnJVM/VMCore/JavaObject.h
    vmkit/trunk/lib/Mvm/Runtime/JIT.cpp

Modified: vmkit/trunk/include/mvm/JIT.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/include/mvm/JIT.h?rev=58999&r1=58998&r2=58999&view=diff

==============================================================================
--- vmkit/trunk/include/mvm/JIT.h (original)
+++ vmkit/trunk/include/mvm/JIT.h Mon Nov 10 14:38:05 2008
@@ -160,6 +160,8 @@
   static llvm::Constant*    constantPtrNull;
   static llvm::ConstantInt* constantPtrSize;
   static llvm::ConstantInt* constantThreadIDMask;
+  static llvm::ConstantInt* constantLockedMask;
+  static llvm::ConstantInt* constantThreadFreeMask;
   static const llvm::PointerType* ptrType;
   static const llvm::PointerType* ptr32Type;
   static const llvm::PointerType* ptrPtrType;

Modified: vmkit/trunk/lib/JnJVM/Classpath/ClasspathVMObject.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/Classpath/ClasspathVMObject.cpp?rev=58999&r1=58998&r2=58999&view=diff

==============================================================================
--- vmkit/trunk/lib/JnJVM/Classpath/ClasspathVMObject.cpp (original)
+++ vmkit/trunk/lib/JnJVM/Classpath/ClasspathVMObject.cpp Mon Nov 10 14:38:05 2008
@@ -43,7 +43,7 @@
   JavaObject* res = (JavaObject*)
     vm->gcAllocator.allocateManagedObject(size, src->getVirtualTable());
   memcpy(res, src, size);
-  res->lock = 0;
+  res->lock = JavaThread::get()->threadID;;
   return (jobject)res;
 } 
 

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

==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.cpp (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.cpp Mon Nov 10 14:38:05 2008
@@ -321,90 +321,45 @@
 }
 
 void JavaJIT::monitorEnter(Value* obj) {
+
   std::vector<Value*> gep;
   gep.push_back(module->constantZero);
   gep.push_back(module->JavaObjectLockOffsetConstant);
   Value* lockPtr = GetElementPtrInst::Create(obj, gep.begin(), gep.end(), "",
                                              currentBlock);
+  Value* lock = new LoadInst(lockPtr, "", currentBlock);
+  Value* lockMask = BinaryOperator::CreateAnd(lock, 
+                                              module->constantThreadFreeMask,
+                                              "", currentBlock);
   Value* threadId = CallInst::Create(module->llvm_frameaddress,
                                      module->constantZero, "", currentBlock);
   threadId = new PtrToIntInst(threadId, Type::Int32Ty, "", currentBlock);
   threadId = BinaryOperator::CreateAnd(threadId, module->constantThreadIDMask,
                                        "", currentBlock);
-  std::vector<Value*> atomicArgs;
-  atomicArgs.push_back(lockPtr);
-  atomicArgs.push_back(module->constantZero);
-  atomicArgs.push_back(threadId);
-
-  // Do the atomic compare and swap.
-  Value* atomic = CallInst::Create(module->llvm_atomic_lcs_i32,
-                                   atomicArgs.begin(), atomicArgs.end(), "",
-                                   currentBlock);
   
-  Value* cmp = new ICmpInst(ICmpInst::ICMP_EQ, atomic, module->constantZero, 
-                            "", currentBlock);
+  Value* cmp = new ICmpInst(ICmpInst::ICMP_EQ, lockMask, threadId, "",
+                            currentBlock);
   
-  BasicBlock* OK = createBasicBlock("synchronize passed");
-  BasicBlock* NotOK = createBasicBlock("synchronize did not pass");
+  BasicBlock* ThinLockBB = createBasicBlock("thread local");
   BasicBlock* FatLockBB = createBasicBlock("fat lock");
-  BasicBlock* ThinLockBB = createBasicBlock("thin lock");
-
-  BranchInst::Create(OK, NotOK, cmp, currentBlock);
-
-  currentBlock = NotOK;
-  
-  // The compare and swap did not pass, look if it's a thin lock
-  Value* thinMask = ConstantInt::get(Type::Int32Ty, 0x80000000);
-  Value* isThin = BinaryOperator::CreateAnd(atomic, thinMask, "",
-                                            currentBlock);
-  cmp = new ICmpInst(ICmpInst::ICMP_EQ, isThin, module->constantZero, "",
-                     currentBlock);
+  BasicBlock* EndLockBB = createBasicBlock("End lock");
   
   BranchInst::Create(ThinLockBB, FatLockBB, cmp, currentBlock);
 
-  // It's a thin lock. Look if we're the owner of this lock.
   currentBlock = ThinLockBB;
-  Value* idMask = ConstantInt::get(Type::Int32Ty, 0x7FFFFF00);
-  Value* cptMask = ConstantInt::get(Type::Int32Ty, 0xFF);
-  Value* IdInLock = BinaryOperator::CreateAnd(atomic, idMask, "", currentBlock);
-  Value* owner = new ICmpInst(ICmpInst::ICMP_EQ, threadId, IdInLock, "",
-                              currentBlock);
+  Value* increment = BinaryOperator::CreateAdd(lock, module->constantOne, "",
+                                               currentBlock);
+  new StoreInst(increment, lockPtr, false, currentBlock);
+  BranchInst::Create(EndLockBB, currentBlock);
 
-  BasicBlock* OwnerBB = createBasicBlock("owner thread");
-
-  BranchInst::Create(OwnerBB, FatLockBB, owner, currentBlock);
-  currentBlock = OwnerBB;
-
-  // OK, we are the owner, now check if the counter will overflow.
-  Value* count = BinaryOperator::CreateAnd(atomic, cptMask, "", currentBlock);
-  cmp = new ICmpInst(ICmpInst::ICMP_ULT, count, cptMask, "", currentBlock);
-
-  BasicBlock* IncCounterBB = createBasicBlock("Increment counter");
-  BasicBlock* OverflowCounterBB = createBasicBlock("Overflow counter");
-
-  BranchInst::Create(IncCounterBB, OverflowCounterBB, cmp, currentBlock);
-  currentBlock = IncCounterBB;
-  
-  // The counter will not overflow, increment it.
-  Value* Add = BinaryOperator::CreateAdd(module->constantOne, atomic, "",
-                                         currentBlock);
-  new StoreInst(Add, lockPtr, false, currentBlock);
-  BranchInst::Create(OK, currentBlock);
-
-  currentBlock = OverflowCounterBB;
-
-  // The counter will overflow, call this function to create a new lock,
-  // lock it 0x101 times, and pass.
-  CallInst::Create(module->OverflowThinLockFunction, obj, "",
-                   currentBlock);
-  BranchInst::Create(OK, currentBlock);
-  
   currentBlock = FatLockBB;
 
-  // Either it's a fat lock or there is contention.
+  // Either it's a fat lock or there is contention or it's not thread local or
+  // it's locked at least once.
   CallInst::Create(module->AquireObjectFunction, obj, "", currentBlock);
-  BranchInst::Create(OK, currentBlock);
-  currentBlock = OK;
+
+  BranchInst::Create(EndLockBB, currentBlock);
+  currentBlock = EndLockBB;
 }
 
 void JavaJIT::monitorExit(Value* obj) {
@@ -414,51 +369,33 @@
   Value* lockPtr = GetElementPtrInst::Create(obj, gep.begin(), gep.end(), "",
                                              currentBlock);
   Value* lock = new LoadInst(lockPtr, "", currentBlock);
+  Value* lockMask = BinaryOperator::CreateAnd(lock, module->constantLockedMask,
+                                              "", currentBlock);
   Value* threadId = CallInst::Create(module->llvm_frameaddress,
                                      module->constantZero, "", currentBlock);
   threadId = new PtrToIntInst(threadId, Type::Int32Ty, "", currentBlock);
   threadId = BinaryOperator::CreateAnd(threadId, module->constantThreadIDMask,
                                        "", currentBlock);
   
-  Value* cmp = new ICmpInst(ICmpInst::ICMP_EQ, lock, threadId, "",
+  Value* cmp = new ICmpInst(ICmpInst::ICMP_EQ, lockMask, threadId, "",
                             currentBlock);
   
   
   BasicBlock* EndUnlock = createBasicBlock("end unlock");
-  BasicBlock* LockedOnceBB = createBasicBlock("desynchronize thin lock");
-  BasicBlock* NotLockedOnceBB = 
-    createBasicBlock("simple desynchronize did not pass");
+  BasicBlock* ThinLockBB = createBasicBlock("desynchronize thin lock");
   BasicBlock* FatLockBB = createBasicBlock("fat lock");
-  BasicBlock* ThinLockBB = createBasicBlock("thin lock");
-  
-  BranchInst::Create(LockedOnceBB, NotLockedOnceBB, cmp, currentBlock);
-  
-  // Locked once, set zero
-  currentBlock = LockedOnceBB;
-  new StoreInst(module->constantZero, lockPtr, false, currentBlock);
-  BranchInst::Create(EndUnlock, currentBlock);
-
-  currentBlock = NotLockedOnceBB;
-  // Look if the lock is thin.
-  Value* thinMask = ConstantInt::get(Type::Int32Ty, 0x80000000);
-  Value* isThin = BinaryOperator::CreateAnd(lock, thinMask, "",
-                                            currentBlock);
-  cmp = new ICmpInst(ICmpInst::ICMP_EQ, isThin, module->constantZero, "",
-                     currentBlock);
   
   BranchInst::Create(ThinLockBB, FatLockBB, cmp, currentBlock);
   
+  // Locked by the thread, decrement.
   currentBlock = ThinLockBB;
-
-  // Decrement the counter.
-  Value* Sub = BinaryOperator::CreateSub(lock, module->constantOne, "",
-                                         currentBlock);
-  new StoreInst(Sub, lockPtr, false, currentBlock);
+  Value* decrement = BinaryOperator::CreateSub(lock, module->constantOne, "",
+                                               currentBlock);
+  new StoreInst(decrement, lockPtr, false, currentBlock);
   BranchInst::Create(EndUnlock, currentBlock);
 
+  // Either it's a fat lock or there is contention or it's not thread local.
   currentBlock = FatLockBB;
-
-  // Either it's a fat lock or there is contention.
   CallInst::Create(module->ReleaseObjectFunction, obj, "", currentBlock);
   BranchInst::Create(EndUnlock, currentBlock);
   currentBlock = EndUnlock;
@@ -1817,7 +1754,18 @@
   Value* GEP = GetElementPtrInst::Create(val, gep.begin(), gep.end(), "",
                                          currentBlock);
   new StoreInst(Cl, GEP, currentBlock);
-
+  
+  gep.clear();
+  gep.push_back(module->constantZero);
+  gep.push_back(module->JavaObjectLockOffsetConstant);
+  Value* lockPtr = GetElementPtrInst::Create(val, gep.begin(), gep.end(), "",
+                                             currentBlock);
+  Value* threadId = CallInst::Create(module->llvm_frameaddress,
+                                     module->constantZero, "", currentBlock);
+  threadId = new PtrToIntInst(threadId, Type::Int32Ty, "", currentBlock);
+  threadId = BinaryOperator::CreateAnd(threadId, module->constantThreadIDMask,
+                                       "", currentBlock);
+  new StoreInst(threadId, lockPtr, currentBlock);
 
   push(val, false);
 }

Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaJITOpcodes.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JavaJITOpcodes.cpp?rev=58999&r1=58998&r2=58999&view=diff

==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JavaJITOpcodes.cpp (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JavaJITOpcodes.cpp Mon Nov 10 14:38:05 2008
@@ -1955,6 +1955,18 @@
                                         currentBlock);
         new StoreInst(valCl, GEP, currentBlock);
         
+        gep.clear();
+        gep.push_back(module->constantZero);
+        gep.push_back(module->JavaObjectLockOffsetConstant);
+        Value* lockPtr = GetElementPtrInst::Create(res, gep.begin(), gep.end(), "",
+                                                   currentBlock);
+        Value* threadId = CallInst::Create(module->llvm_frameaddress,
+                                           module->constantZero, "", currentBlock);
+        threadId = new PtrToIntInst(threadId, Type::Int32Ty, "", currentBlock);
+        threadId = BinaryOperator::CreateAnd(threadId, module->constantThreadIDMask,
+                                             "", currentBlock);
+        new StoreInst(threadId, lockPtr, currentBlock);
+
         push(res, false);
 
         break;

Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaObject.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JavaObject.cpp?rev=58999&r1=58998&r2=58999&view=diff

==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JavaObject.cpp (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JavaObject.cpp Mon Nov 10 14:38:05 2008
@@ -79,8 +79,7 @@
 }
 
 bool JavaObject::owner() {
-  uint32 id = mvm::Thread::get()->threadID;
-  if (id == lock) return true;
+  uint32 id = (uint32)mvm::Thread::get();
   if ((lock & 0x7FFFFF00) == id) return true;
   if (lock & 0x80000000) {
     LockObj* obj = (LockObj*)(lock << 1);
@@ -91,57 +90,61 @@
 
 void JavaObject::overflowThinlock() {
   LockObj* obj = LockObj::allocate();
-  obj->lock.lockAll(257);
+  obj->lock.lockAll(256);
   lock = ((uint32)obj >> 1) | 0x80000000;
 }
 
 void JavaObject::release() {
-  uint32 id = mvm::Thread::get()->threadID;
-  if (lock == id) {
-    lock = 0;
-  } else if (lock & 0x80000000) {
+  uint32 id = (uint32)mvm::Thread::get();
+  if ((lock & 0x7FFFFF00) == id) {
+    --lock;
+  } else {
     LockObj* obj = (LockObj*)(lock << 1);
     obj->release();
-  } else {
-    lock--;
-  }
+  } 
 }
 
 void JavaObject::acquire() {
-  uint32 id = mvm::Thread::get()->threadID;
-  uint32 val = __sync_val_compare_and_swap((uint32*)&lock, 0, id);
-  if (val != 0) {
-    //fat!
-    if (!(val & 0x80000000)) {
-      if ((val & 0x7FFFFF00) == id) {
-        if ((val & 0xFF) != 0xFF) {
-          lock++;
-        } else {
-          overflowThinlock();
-        }
+  uint32 id = (uint32)mvm::Thread::get();
+  if ((lock & 0x7FFFFFFF) == id) {
+    lock |= 1;
+  } else if ((lock & 0x7FFFFF00) == id) {
+    if ((lock & 0xFF) == 0xFF) {
+      overflowThinlock();
+    } else {
+      ++lock;
+    }
+  } else {
+    uint32 currentLock = lock & 0x7FFFFF00;
+    uint32 val = __sync_val_compare_and_swap((uint32*)&lock, currentLock, (id + 1));
+    if (val != currentLock) {
+      //fat!
+      if (val & 0x80000000) {
+end:
+        LockObj* obj = (LockObj*)(lock << 1);
+        obj->acquire();
       } else {
         LockObj* obj = LockObj::allocate();
         uint32 val = ((uint32)obj >> 1) | 0x80000000;
-loop:
         uint32 count = 0;
-        while (lock) {
+loop:
+        while ((lock & 0xFF) != 0) {
           if (lock & 0x80000000) {
 #ifdef USE_GC_BOEHM
             delete obj;
 #endif
             goto end;
           }
-          else mvm::Thread::yield(&count);
+          else {
+            mvm::Thread::yield(&count);
+          }
         }
         
-        uint32 test = __sync_val_compare_and_swap((uint32*)&lock, 0, val);
-        if (test) goto loop;
+        currentLock = lock & 0x7FFFFF00;
+        uint32 test = __sync_val_compare_and_swap(&lock, currentLock, val);
+        if (test != currentLock) goto loop;
         obj->acquire();
       }
-    } else {
-end:
-      LockObj* obj = (LockObj*)(lock << 1);
-      obj->acquire();
     }
   }
 }
@@ -151,7 +154,7 @@
     LockObj* obj = LockObj::allocate();
     uint32 val = (((uint32) obj) >> 1) | 0x80000000;
     uint32 count = lock & 0xFF;
-    obj->lock.lockAll(count + 1);
+    obj->lock.lockAll(count);
     lock = val;
     return obj;
   } else {

Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaObject.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JavaObject.h?rev=58999&r1=58998&r2=58999&view=diff

==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JavaObject.h (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JavaObject.h Mon Nov 10 14:38:05 2008
@@ -14,6 +14,7 @@
 
 #include "mvm/Object.h"
 #include "mvm/Threads/Locks.h"
+#include "mvm/Threads/Thread.h"
 
 #include "types.h"
 
@@ -160,7 +161,7 @@
   ///
   void initialise(UserCommonClass* cl) {
     this->classOf = cl; 
-    this->lock = 0;
+    this->lock = (uint32)mvm::Thread::get();
   }
 
   /// instanceOf - Is this object's class of type the given class?

Modified: vmkit/trunk/lib/Mvm/Runtime/JIT.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/Mvm/Runtime/JIT.cpp?rev=58999&r1=58998&r2=58999&view=diff

==============================================================================
--- vmkit/trunk/lib/Mvm/Runtime/JIT.cpp (original)
+++ vmkit/trunk/lib/Mvm/Runtime/JIT.cpp Mon Nov 10 14:38:05 2008
@@ -123,6 +123,8 @@
   constantDoubleMinusZero = ConstantFP::get(Type::DoubleTy, -0.0);
   constantFloatMinusZero = ConstantFP::get(Type::FloatTy, -0.0f);
   constantThreadIDMask = ConstantInt::get(Type::Int32Ty, mvm::Thread::IDMask);
+  constantLockedMask = ConstantInt::get(Type::Int32Ty, 0x7FFFFF00);
+  constantThreadFreeMask = ConstantInt::get(Type::Int32Ty, 0x7FFFFFFF);
 
   constantPtrNull = Constant::getNullValue(ptrType); 
   constantPtrSize = ConstantInt::get(Type::Int32Ty, sizeof(void*));
@@ -237,6 +239,8 @@
 llvm::Constant*    MvmModule::constantPtrNull;
 llvm::ConstantInt* MvmModule::constantPtrSize;
 llvm::ConstantInt* MvmModule::constantThreadIDMask;
+llvm::ConstantInt* MvmModule::constantLockedMask;
+llvm::ConstantInt* MvmModule::constantThreadFreeMask;
 const llvm::PointerType* MvmModule::ptrType;
 const llvm::PointerType* MvmModule::ptr32Type;
 const llvm::PointerType* MvmModule::ptrPtrType;





More information about the vmkit-commits mailing list