[llvm-commits] [vmkit] r51994 - in /vmkit/trunk: include/mvm/ include/mvm/Threads/ lib/JnJVM/Classpath/ lib/JnJVM/LLVMRuntime/ lib/JnJVM/VMCore/ lib/Mvm/

Nicolas Geoffray nicolas.geoffray at lip6.fr
Thu Jun 5 05:46:06 PDT 2008


Author: geoffray
Date: Thu Jun  5 07:45:58 2008
New Revision: 51994

URL: http://llvm.org/viewvc/llvm-project?rev=51994&view=rev
Log:
A thin lock implementation on JnJVM. A few things still need to be improved:
1) Make class info locks protected by thin locks.
2) Create "real" IDs for threads.
3) Create a compiler dependent file for builtins (e.g. compare and swap)


Modified:
    vmkit/trunk/include/mvm/JIT.h
    vmkit/trunk/include/mvm/Threads/Thread.h
    vmkit/trunk/lib/JnJVM/Classpath/ClasspathVMObject.cpp
    vmkit/trunk/lib/JnJVM/Classpath/ClasspathVMThread.cpp
    vmkit/trunk/lib/JnJVM/LLVMRuntime/runtime-default.ll
    vmkit/trunk/lib/JnJVM/VMCore/JavaInitialise.cpp
    vmkit/trunk/lib/JnJVM/VMCore/JavaIsolate.cpp
    vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.cpp
    vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.h
    vmkit/trunk/lib/JnJVM/VMCore/JavaJITOpcodes.cpp
    vmkit/trunk/lib/JnJVM/VMCore/JavaObject.cpp
    vmkit/trunk/lib/JnJVM/VMCore/JavaObject.h
    vmkit/trunk/lib/JnJVM/VMCore/JavaRuntimeJIT.cpp
    vmkit/trunk/lib/JnJVM/VMCore/JavaThread.h
    vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.cpp
    vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.h
    vmkit/trunk/lib/JnJVM/VMCore/VirtualTables.cpp
    vmkit/trunk/lib/Mvm/JIT.cpp
    vmkit/trunk/lib/Mvm/Main.cpp

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

==============================================================================
--- vmkit/trunk/include/mvm/JIT.h (original)
+++ vmkit/trunk/include/mvm/JIT.h Thu Jun  5 07:45:58 2008
@@ -93,6 +93,7 @@
 
 extern llvm::Function* llvm_memcpy_i32;
 extern llvm::Function* llvm_memset_i32;
+extern llvm::Function* llvm_atomic_lcs_i32;
 
 extern llvm::ExecutionEngine* executionEngine;
 

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

==============================================================================
--- vmkit/trunk/include/mvm/Threads/Thread.h (original)
+++ vmkit/trunk/include/mvm/Threads/Thread.h Thu Jun  5 07:45:58 2008
@@ -10,6 +10,8 @@
 #ifndef MVM_THREAD_H
 #define MVM_THREAD_H
 
+#include "types.h"
+
 #include "MvmGC.h"
 #include "mvm/Threads/Key.h"
 
@@ -31,6 +33,7 @@
   static mvm::Key<Thread>* threadKey;
   Collector* GC;
   void* baseSP;
+  uint32 threadID;
   static Thread* get() {
     return (Thread*)Thread::threadKey->get();
   }

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

==============================================================================
--- vmkit/trunk/lib/JnJVM/Classpath/ClasspathVMObject.cpp (original)
+++ vmkit/trunk/lib/JnJVM/Classpath/ClasspathVMObject.cpp Thu Jun  5 07:45:58 2008
@@ -31,10 +31,11 @@
                                                         jobject _src) {
   
   JavaObject* src = (JavaObject*)_src;
-  uint64 size = src->objectSize() + 4; // + VT
+  uint64 size = src->objectSize() + sizeof(void*); // + VT
   JavaObject* res = (JavaObject*)
     JavaThread::get()->isolate->allocateObject(size, src->getVirtualTable());
   memcpy(res, src, size);
+  res->lock = 0;
   return (jobject)res;
 } 
 

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

==============================================================================
--- vmkit/trunk/lib/JnJVM/Classpath/ClasspathVMThread.cpp (original)
+++ vmkit/trunk/lib/JnJVM/Classpath/ClasspathVMThread.cpp Thu Jun  5 07:45:58 2008
@@ -62,6 +62,8 @@
   JavaIsolate* isolate = (JavaIsolate*)(intern->isolate);
   ThreadSystem* ts = isolate->threadSystem;
   bool isDaemon = ClasspathThread::daemon->getVirtualInt8Field(thread);
+  intern->threadID = (mvm::Thread::self() << 8) & 0x7FFFFF00;
+
 
   if (!isDaemon) {
     ts->nonDaemonLock->lock();

Modified: vmkit/trunk/lib/JnJVM/LLVMRuntime/runtime-default.ll
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/LLVMRuntime/runtime-default.ll?rev=51994&r1=51993&r2=51994&view=diff

==============================================================================
--- vmkit/trunk/lib/JnJVM/LLVMRuntime/runtime-default.ll (original)
+++ vmkit/trunk/lib/JnJVM/LLVMRuntime/runtime-default.ll Thu Jun  5 07:45:58 2008
@@ -15,7 +15,7 @@
 %JavaClass = type { %VT, i32, %VT ,%JavaClass**, i32}
 
 ;;; The root of all Java Objects: a VT, a class and a lock.
-%JavaObject = type { %VT, %JavaClass*, i8* }
+%JavaObject = type { %VT, %JavaClass*, i32 }
 
 ;;; Types for Java arrays. A size of 0 means an undefined size.
 %JavaArray = type { %JavaObject, i32 }
@@ -53,9 +53,12 @@
 ;;; getVT - Get the VT of the object.
 declare %VT @getVT(%JavaObject*) readnone 
 
-;;; getClass - Get the class of an object
+;;; getClass - Get the class of an object.
 declare %JavaClass* @getClass(%JavaObject*) readnone 
 
+;;; getLock - Get the lock of an object.
+declare i32* @getLock(%JavaObject*)
+
 ;;; getVTFromClass - Get the VT of a class from its runtime representation.
 declare %VT @getVTFromClass(%JavaClass*) readnone 
 
@@ -112,6 +115,10 @@
 ;;; block or method.
 declare void @JavaObjectRelease(%JavaObject*)
 
+;;; overflowThinLock - Change a thin lock to a fat lock when the thin lock
+;;; overflows
+declare void @overflowThinLock(%JavaObject*)
+
 ;;; isAssignableFrom - Returns if the objet's class implements the given class.
 declare i1 @instanceOf(%JavaObject*, %JavaClass*) readnone 
 
@@ -128,6 +135,10 @@
 ;;; class.
 declare %JavaObject* @getClassDelegatee(%JavaClass*) readnone 
 
+;;; getThreadID - Returns the thread ID of the current thread. Used for thin
+;;; locks.
+declare i32 @getThreadID() readnone
+
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Exception methods ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

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

==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JavaInitialise.cpp (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JavaInitialise.cpp Thu Jun  5 07:45:58 2008
@@ -78,8 +78,7 @@
 }
 
 static void initialiseStatics() {
-  JavaObject::globalLock = mvm::Lock::allocNormal();
-
+  
   Jnjvm* vm = JavaIsolate::bootstrapVM = JavaIsolate::allocateBootstrap();
   
   // Array initialization
@@ -192,7 +191,8 @@
 extern "C" void ClasspathBoot();
 
 void handler(int val, siginfo_t* info, void* addr) {
-  printf("Crash in JnJVM at %p\n", addr);
+  printf("[%d] Crash in JnJVM at %p\n", mvm::Thread::self(), addr);
+  JavaJIT::printBacktrace();
   assert(0);
 }
 

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

==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JavaIsolate.cpp (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JavaIsolate.cpp Thu Jun  5 07:45:58 2008
@@ -450,6 +450,8 @@
   isolate->bootstrapThread = vm_new(isolate, JavaThread)();
   isolate->bootstrapThread->initialise(0, isolate);
   void* baseSP = mvm::Thread::get()->baseSP;
+  isolate->bootstrapThread->threadID = (mvm::Thread::self() << 8) & 0x7FFFFF00;
+  
 #ifdef MULTIPLE_GC
   isolate->bootstrapThread->GC = isolate->GC;
   isolate->GC->inject_my_thread(baseSP);
@@ -508,6 +510,7 @@
   isolate->bootstrapThread = vm_new(isolate, JavaThread)();
   isolate->bootstrapThread->initialise(0, isolate);
   void* baseSP = mvm::Thread::get()->baseSP;
+  isolate->bootstrapThread->threadID = (mvm::Thread::self() << 8) & 0x7FFFFF00;
 #ifdef MULTIPLE_GC
   isolate->bootstrapThread->GC = isolate->GC;
 #endif 

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

==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.cpp (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.cpp Thu Jun  5 07:45:58 2008
@@ -276,44 +276,186 @@
   return llvmFunction;
 }
 
+void JavaJIT::monitorEnter(Value* obj) {
+  std::vector<Value*> gep;
+  gep.push_back(mvm::jit::constantZero);
+  gep.push_back(JnjvmModule::JavaObjectLockOffsetConstant);
+  Value* lockPtr = GetElementPtrInst::Create(obj, gep.begin(), gep.end(), "",
+                                             currentBlock);
+  Value* threadId = CallInst::Create(JnjvmModule::GetThreadIDFunction, "",
+                                     currentBlock);
+  std::vector<Value*> atomicArgs;
+  atomicArgs.push_back(lockPtr);
+  atomicArgs.push_back(mvm::jit::constantZero);
+  atomicArgs.push_back(threadId);
+
+  // Do the atomic compare and swap.
+  Value* atomic = CallInst::Create(mvm::jit::llvm_atomic_lcs_i32,
+                                   atomicArgs.begin(), atomicArgs.end(), "",
+                                   currentBlock);
+  
+  Value* cmp = new ICmpInst(ICmpInst::ICMP_EQ, atomic, mvm::jit::constantZero, 
+                            "", currentBlock);
+  
+  BasicBlock* OK = createBasicBlock("synchronize passed");
+  BasicBlock* NotOK = createBasicBlock("synchronize did not pass");
+  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, mvm::jit::constantZero, "",
+                     currentBlock);
+  
+  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);
+
+  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(mvm::jit::constantOne, atomic, "",
+                                         currentBlock);
+  new StoreInst(Add, lockPtr, "", 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(JnjvmModule::OverflowThinLockFunction, obj, "",
+                   currentBlock);
+  BranchInst::Create(OK, currentBlock);
+  
+  currentBlock = FatLockBB;
+
+  // Either it's a fat lock or there is contention.
+  CallInst::Create(JnjvmModule::AquireObjectFunction, obj, "", currentBlock);
+  BranchInst::Create(OK, currentBlock);
+  currentBlock = OK;
+}
+
+void JavaJIT::monitorExit(Value* obj) {
+  std::vector<Value*> gep;
+  gep.push_back(mvm::jit::constantZero);
+  gep.push_back(JnjvmModule::JavaObjectLockOffsetConstant);
+  Value* lockPtr = GetElementPtrInst::Create(obj, gep.begin(), gep.end(), "",
+                                             currentBlock);
+  Value* lock = new LoadInst(lockPtr, "", currentBlock);
+  Value* threadId = CallInst::Create(JnjvmModule::GetThreadIDFunction, "",
+                                     currentBlock);
+  
+  Value* cmp = new ICmpInst(ICmpInst::ICMP_EQ, lock, threadId, "",
+                            currentBlock);
+  
+  
+  BasicBlock* EndUnlock = createBasicBlock("end unlock");
+  BasicBlock* LockedOnceBB = createBasicBlock("desynchronize thin lock");
+  BasicBlock* NotLockedOnceBB = 
+    createBasicBlock("simple desynchronize did not pass");
+  BasicBlock* FatLockBB = createBasicBlock("fat lock");
+  BasicBlock* ThinLockBB = createBasicBlock("thin lock");
+  
+  BranchInst::Create(LockedOnceBB, NotLockedOnceBB, cmp, currentBlock);
+  
+  // Locked once, set zero
+  currentBlock = LockedOnceBB;
+  new StoreInst(mvm::jit::constantZero, lockPtr, 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, mvm::jit::constantZero, "",
+                     currentBlock);
+  
+  BranchInst::Create(ThinLockBB, FatLockBB, cmp, currentBlock);
+  
+  currentBlock = ThinLockBB;
+
+  // Decrement the counter.
+  Value* Sub = BinaryOperator::createSub(lock, mvm::jit::constantOne, "",
+                                         currentBlock);
+  new StoreInst(Sub, lockPtr, currentBlock);
+  BranchInst::Create(EndUnlock, currentBlock);
+
+  currentBlock = FatLockBB;
+
+  // Either it's a fat lock or there is contention.
+  CallInst::Create(JnjvmModule::ReleaseObjectFunction, obj, "", currentBlock);
+  BranchInst::Create(EndUnlock, currentBlock);
+  currentBlock = EndUnlock;
+}
+
 void JavaJIT::beginSynchronize() {
-  std::vector<Value*> argsSync;
+  Value* obj = 0;
   if (isVirtual(compilingMethod->access)) {
-    argsSync.push_back(llvmFunction->arg_begin());
+    obj = llvmFunction->arg_begin();
   } else {
     LLVMClassInfo* LCI = 
       (LLVMClassInfo*)module->getClassInfo(compilingClass);
-    Value* arg = LCI->getStaticVar(this);
-    argsSync.push_back(arg);
+    obj = LCI->getStaticVar(this);
   }
-#ifdef SERVICE_VM
-  if (ServiceDomain::isLockableDomain(compilingClass->isolate))
+#ifndef SERVICE_VM
+  monitorEnter(obj);
+#else
+  if (ServiceDomain::isLockableDomain(compilingClass->isolate)) {
     llvm::CallInst::Create(JnjvmModule::AquireObjectInSharedDomainFunction,
-                           argsSync.begin(), argsSync.end(), "", currentBlock);
-  else
+                           obj, "", currentBlock);
+  } else {
+    llvm::CallInst::Create(JnjvmModule::AquireObjectFunction,
+                           obj, "", currentBlock);
+  }
 #endif
-  llvm::CallInst::Create(JnjvmModule::AquireObjectFunction, argsSync.begin(),
-                         argsSync.end(), "", currentBlock);
 }
 
 void JavaJIT::endSynchronize() {
-  std::vector<Value*> argsSync;
+  Value* obj = 0;
   if (isVirtual(compilingMethod->access)) {
-    argsSync.push_back(llvmFunction->arg_begin());
+    obj = llvmFunction->arg_begin();
   } else {
     LLVMClassInfo* LCI = 
       (LLVMClassInfo*)module->getClassInfo(compilingClass);
-    Value* arg = LCI->getStaticVar(this);
-    argsSync.push_back(arg);
+    obj = LCI->getStaticVar(this);
   }
-#ifdef SERVICE_VM
-  if (ServiceDomain::isLockableDomain(compilingClass->isolate))
+#ifndef SERVICE_VM
+  monitorExit(obj);
+#else
+  if (ServiceDomain::isLockableDomain(compilingClass->isolate)) {
     llvm::CallInst::Create(JnjvmModule::ReleaseObjectInSharedDomainFunction,
                            argsSync.begin(), argsSync.end(), "", currentBlock);
-  else
+  } else {
+    llvm::CallInst::Create(JnjvmModule::ReleaseObjectFunction, argsSync.begin(),
+                           argsSync.end(), "", currentBlock);    
+  }
 #endif
-  llvm::CallInst::Create(JnjvmModule::ReleaseObjectFunction, argsSync.begin(),
-                         argsSync.end(), "", currentBlock);    
 }
 
 

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

==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.h (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.h Thu Jun  5 07:45:58 2008
@@ -193,6 +193,8 @@
   // synchronize
   void beginSynchronize();
   void endSynchronize();
+  void monitorEnter(llvm::Value* obj);
+  void monitorExit(llvm::Value* obj);
 
   // fields invoke
   void getStaticField(uint16 index);

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

==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JavaJITOpcodes.cpp (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JavaJITOpcodes.cpp Thu Jun  5 07:45:58 2008
@@ -2029,11 +2029,15 @@
         Value* obj = pop();
 #ifdef SERVICE_VM
         if (ServiceDomain::isLockableDomain(compilingClass->isolate))
-        invoke(JnjvmModule::AquireObjectInSharedDomainFunction, obj, "",
-               currentBlock); 
+          invoke(JnjvmModule::AquireObjectInSharedDomainFunction, obj, "",
+                 currentBlock); 
         else
+          invoke(JnjvmModule::AquireObjectFunction, obj, "",
+                 currentBlock); 
+#else
+        JITVerifyNull(obj);
+        monitorEnter(obj);
 #endif
-        invoke(JnjvmModule::AquireObjectFunction, obj, "", currentBlock); 
         break;
       }
 
@@ -2041,11 +2045,15 @@
         Value* obj = pop();
 #ifdef SERVICE_VM
         if (ServiceDomain::isLockableDomain(compilingClass->isolate))
-        invoke(JnjvmModule::ReleaseObjectInSharedDomainFunction, obj, "",
-               currentBlock); 
+          invoke(JnjvmModule::ReleaseObjectInSharedDomainFunction, obj, "",
+                 currentBlock); 
         else
+          invoke(JnjvmModule::ReleaseObjectFunction, obj, "",
+                 currentBlock); 
+#else
+        JITVerifyNull(obj);
+        monitorExit(obj);
 #endif
-        invoke(JnjvmModule::ReleaseObjectFunction, obj, "", currentBlock); 
         break;
       }
 

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

==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JavaObject.cpp (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JavaObject.cpp Thu Jun  5 07:45:58 2008
@@ -22,8 +22,6 @@
 
 using namespace jnjvm;
 
-mvm::Lock* JavaObject::globalLock = 0;
-
 void JavaCond::notify() {
   for (std::vector<JavaThread*>::iterator i = threads.begin(), 
             e = threads.end(); i!= e;) {
@@ -75,22 +73,95 @@
 }
 
 LockObj* LockObj::allocate() {
+#ifdef USE_GC_BOEHM
+  LockObj* res = new LockObj();
+#else
   LockObj* res = vm_new(JavaThread::get()->isolate, LockObj)();
+#endif
   res->lock = mvm::Lock::allocRecursive();
   res->varcond = 0;
   return res;
 }
 
-void LockObj::aquire() {
-  lock->lock();
+bool JavaObject::owner() {
+  uint32 id = mvm::Thread::get()->threadID;
+  if (id == lock) return true;
+  if ((lock & 0x7FFFFF00) == id) return true;
+  if (lock & 0x80000000) {
+    LockObj* obj = (LockObj*)(lock << 1);
+    return obj->owner();
+  }
+  return false;
+}
+
+void JavaObject::overflowThinlock() {
+  LockObj* obj = LockObj::allocate();
+  mvm::LockRecursive::my_lock_all(obj->lock, 257);
+  lock = ((uint32)obj >> 1) | 0x80000000;
+}
+
+void JavaObject::release() {
+  uint32 id = mvm::Thread::get()->threadID;
+  if (lock == id) {
+    lock = 0;
+  } else if (lock & 0x80000000) {
+    LockObj* obj = (LockObj*)(lock << 1);
+    obj->release();
+  } else {
+    lock--;
+  }
 }
 
-void LockObj::release() {
-  lock->unlock();
+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();
+        }
+      } else {
+        LockObj* obj = LockObj::allocate();
+        uint32 val = ((uint32)obj >> 1) | 0x80000000;
+loop:
+        uint32 count = 0;
+        while (lock) {
+          if (lock & 0x80000000) {
+#ifdef USE_GC_BOEHM
+            delete obj;
+#endif
+            goto end;
+          }
+          else mvm::Thread::yield(&count);
+        }
+        
+        uint32 test = __sync_val_compare_and_swap((uint32*)&lock, 0, val);
+        if (test) goto loop;
+        obj->acquire();
+      }
+    } else {
+end:
+      LockObj* obj = (LockObj*)(lock << 1);
+      obj->acquire();
+    }
+  }
 }
 
-bool LockObj::owner() {
-  return mvm::Lock::selfOwner(lock);
+LockObj* JavaObject::changeToFatlock() {
+  if (!(lock & 0x80000000)) {
+    LockObj* obj = LockObj::allocate();
+    uint32 val = (((uint32) obj) >> 1) | 0x80000000;
+    uint32 count = lock & 0xFF;
+    mvm::LockRecursive::my_lock_all(obj->lock, count + 1);
+    lock = val;
+    return obj;
+  } else {
+    return (LockObj*)(lock << 1);
+  }
 }
 
 void JavaObject::print(mvm::PrintBuffer* buf) const {
@@ -99,23 +170,10 @@
   buf->write(">");
 }
 
-LockObj* LockObj::myLock(JavaObject* obj) {
-  verifyNull(obj);
-  if (obj->lockObj == 0) {
-    JavaObject::globalLock->lock();
-    if (obj->lockObj == 0) {
-      obj->lockObj = LockObj::allocate();
-    }
-    JavaObject::globalLock->unlock();
-  }
-  return obj->lockObj;
-}
-
 void JavaObject::waitIntern(struct timeval* info, bool timed) {
-  LockObj * l = LockObj::myLock(this);
-  bool owner = l->owner();
 
-  if (owner) {
+  if (owner()) {
+    LockObj * l = changeToFatlock();
     JavaThread* thread = JavaThread::get();
     mvm::Lock* mutexThread = thread->lock;
     mvm::Cond* varcondThread = thread->varcond;
@@ -168,8 +226,8 @@
 }
 
 void JavaObject::notify() {
-  LockObj* l = LockObj::myLock(this);
-  if (l->owner()) {
+  if (owner()) {
+    LockObj * l = changeToFatlock();
     l->getCond()->notify();
   } else {
     JavaThread::get()->isolate->illegalMonitorStateException(this);
@@ -177,8 +235,8 @@
 }
 
 void JavaObject::notifyAll() {
-  LockObj* l = LockObj::myLock(this);
-  if (l->owner()) {
+  if (owner()) {
+    LockObj * l = changeToFatlock();
     l->getCond()->notifyAll();
   } else {
     JavaThread::get()->isolate->illegalMonitorStateException(this);
@@ -189,3 +247,9 @@
   if (varcond) delete varcond;
   delete lock;
 }
+
+#ifdef USE_GC_BOEHM
+void JavaObject::destroyer(size_t sz) {
+  if (lockObj()) delete lockObj();
+}
+#endif

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

==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JavaObject.h (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JavaObject.h Thu Jun  5 07:45:58 2008
@@ -59,9 +59,11 @@
 /// LockObj - This class represents a Java monitor.
 ///
 class LockObj : public mvm::Object {
-public:
 
-  static VirtualTable* VT;
+  friend class JavaObject;
+
+private:
+
 
   /// lock - The internal lock of this object lock.
   ///
@@ -80,16 +82,23 @@
   ///
   static LockObj* myLock(JavaObject* obj);
 
-  /// aquire - Acquires the lock.
+  /// acquire - Acquires the lock.
   ///
-  void aquire();
+  void acquire() {
+    lock->lock();
+  }
 
   /// release - Releases the lock.
   ///
-  void release();
-
-  /// owner - Returns true if the curren thread is the owner of this lock.
-  bool owner();
+  void release() {
+    lock->unlock();
+  }
+  
+  /// owner - Returns if the current thread owns this lock.
+  ///
+  bool owner() {
+    return mvm::Lock::selfOwner(lock);
+  }
   
   /// getCond - Returns the conditation variable of this lock, allocating it
   /// if non-existant.
@@ -98,7 +107,9 @@
     if (!varcond) varcond = new JavaCond();
     return varcond;
   }
-  
+
+public:
+  static VirtualTable* VT;
   virtual void print(mvm::PrintBuffer* buf) const;
   virtual void TRACER;
   virtual void destroyer(size_t sz);
@@ -114,6 +125,7 @@
   ///
   void waitIntern(struct timeval *info, bool timed);
 
+  
 public:
   static VirtualTable* VT;
 
@@ -121,14 +133,10 @@
   ///
   CommonClass* classOf;
 
-  /// lockObj - The monitor of this object. Most of the time null.
-  ///
-  LockObj* lockObj;
-  
-  /// globalLock - The global lock to allocate monitors.
+  /// lock - The monitor of this object. Most of the time null.
   ///
-  static mvm::Lock* globalLock;
-   
+  uint32 lock;
+
   /// wait - Java wait. Makes the current thread waiting on a monitor.
   ///
   void wait();
@@ -152,7 +160,7 @@
   ///
   void initialise(CommonClass* cl) {
     this->classOf = cl; 
-    this->lockObj = 0;
+    this->lock = 0;
   }
 
   /// instanceOfString - Is this object's class of type the given name?
@@ -169,6 +177,24 @@
     else return this->classOf->isAssignableFrom(cl);
   }
 
+  /// acquire - Acquire the lock on this object.
+  void acquire();
+
+  /// release - Release the lock on this object
+  void release();
+
+  /// changeToFatlock - Change the lock of this object to a fat lock. The lock
+  /// may be in thin lock or in fat lock.
+  LockObj* changeToFatlock();
+
+  /// overflowThinlock -Change the lock of this object to a fat lock because
+  /// we have reached 0xFF locks.
+  void overflowThinlock();
+  
+  /// owner - Returns true if the curren thread is the owner of this object's
+  /// lock.
+  bool owner();
+
 #ifdef SIGSEGV_THROW_NULL
   #define verifyNull(obj) {}
 #else
@@ -178,7 +204,18 @@
   
   virtual void print(mvm::PrintBuffer* buf) const;
   virtual void TRACER;
-  
+
+#ifdef USE_GC_BOEHM
+  virtual void destroyer(size_t sz);
+#endif
+
+  LockObj* lockObj() {
+    if (lock & 0x80000000) {
+      return (LockObj*)(lock << 1);
+    } else {
+      return 0;
+    }
+  }
 };
 
 

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

==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JavaRuntimeJIT.cpp (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JavaRuntimeJIT.cpp Thu Jun  5 07:45:58 2008
@@ -286,7 +286,7 @@
     vm->serviceError(vm, "I'm locking an object I don't own");
   }
 #endif
-  LockObj::myLock(obj)->aquire();
+  obj->acquire();
 }
 
 
@@ -298,17 +298,18 @@
     vm->serviceError(vm, "I'm unlocking an object I don't own");
   }
 #endif
-  obj->lockObj->release();
+  obj->release();
 }
 
 #ifdef SERVICE_VM
 extern "C" void JavaObjectAquireInSharedDomain(JavaObject* obj) {
-  LockObj::myLock(obj)->aquire();
+  verifyNull(obj);
+  obj->acquire();
 }
 
 extern "C" void JavaObjectReleaseInSharedDomain(JavaObject* obj) {
   verifyNull(obj);
-  obj->lockObj->release();
+  obj->release();
 }
 #endif
 
@@ -347,3 +348,11 @@
 extern "C" void JavaThreadClearException() {
   return JavaThread::clearException();
 }
+
+extern "C" uint32 getThreadID() {
+  return JavaThread::get()->threadID;
+}
+
+extern "C" void overflowThinLock(JavaObject* obj) {
+  obj->overflowThinlock();
+}

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

==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JavaThread.h (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JavaThread.h Thu Jun  5 07:45:58 2008
@@ -38,9 +38,8 @@
   mvm::Cond* varcond;
   JavaObject* pendingException;
   void* internalPendingException;
-  unsigned int self;
-  unsigned int interruptFlag;
-  unsigned int state;
+  uint32 interruptFlag;
+  uint32 state;
   std::vector<jmp_buf*> sjlj_buffers;
 
   static const unsigned int StateRunning;
@@ -58,7 +57,6 @@
     this->varcond = mvm::Cond::allocCond();
     this->interruptFlag = 0;
     this->state = StateRunning;
-    this->self = mvm::Thread::self();
     this->pendingException = 0;
   }
 

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

==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.cpp (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.cpp Thu Jun  5 07:45:58 2008
@@ -111,7 +111,7 @@
 llvm::Function* JnjvmModule::GetObjectSizeFromClassFunction = 0;
 
 #ifdef MULTIPLE_GC
-llvm::Function* JnjvmModule::FetCollectorFunction = 0;
+llvm::Function* JnjvmModule::GetCollectorFunction = 0;
 #endif
 
 #ifdef SERVICE_VM
@@ -121,6 +121,10 @@
 llvm::Function* JnjvmModule::ServiceCallStopFunction = 0;
 #endif
 
+llvm::Function* JnjvmModule::GetThreadIDFunction = 0;
+llvm::Function* JnjvmModule::GetLockFunction = 0;
+llvm::Function* JnjvmModule::OverflowThinLockFunction = 0;
+
 
 
 Value* LLVMCommonClassInfo::getVar(JavaJIT* jit) {
@@ -967,6 +971,7 @@
   GetClassInDisplayFunction = module->getFunction("getClassInDisplay");
   AquireObjectFunction = module->getFunction("JavaObjectAquire");
   ReleaseObjectFunction = module->getFunction("JavaObjectRelease");
+  OverflowThinLockFunction = module->getFunction("overflowThinLock");
 
   FieldLookupFunction = module->getFunction("fieldLookup");
   
@@ -1023,7 +1028,9 @@
 #ifdef MULTIPLE_GC
   GetCollectorFunction = module->getFunction("getCollector");
 #endif
-
+  
+  GetThreadIDFunction = module->getFunction("getThreadID");
+  GetLockFunction = module->getFunction("getLock");
   
   UTF8NullConstant = Constant::getNullValue(JavaArrayUInt16Type); 
   JavaClassNullConstant = Constant::getNullValue(JavaClassType); 

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

==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.h (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.h Thu Jun  5 07:45:58 2008
@@ -326,6 +326,11 @@
 #endif
   static llvm::Function* GetVTFromClassFunction;
   static llvm::Function* GetObjectSizeFromClassFunction;
+
+  static llvm::Function* GetLockFunction;
+  static llvm::Function* GetThreadIDFunction;
+  static llvm::Function* OverflowThinLockFunction;
+
   static llvm::ConstantInt* OffsetObjectSizeInClassConstant;
   static llvm::ConstantInt* OffsetVTInClassConstant;
   static llvm::ConstantInt* OffsetDepthInClassConstant;

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

==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/VirtualTables.cpp (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/VirtualTables.cpp Thu Jun  5 07:45:58 2008
@@ -57,7 +57,7 @@
 
 void ArrayObject::TRACER {
   classOf->MARK_AND_TRACE;
-  if (lockObj) lockObj->MARK_AND_TRACE;
+  if (lockObj()) lockObj()->MARK_AND_TRACE;
   for (sint32 i = 0; i < size; i++) {
     if (elements[i]) elements[i]->MARK_AND_TRACE;
   }
@@ -65,8 +65,8 @@
 
 #define ARRAYTRACER(name)         \
   void name::TRACER {             \
-    if (lockObj)                  \
-      lockObj->MARK_AND_TRACE;    \
+    if (lockObj())                \
+      lockObj()->MARK_AND_TRACE;  \
   }
   
 
@@ -112,7 +112,7 @@
 
 void JavaObject::TRACER {
   classOf->MARK_AND_TRACE;
-  if (lockObj) lockObj->MARK_AND_TRACE;
+  if (lockObj()) lockObj()->MARK_AND_TRACE;
 }
 
 #ifdef MULTIPLE_GC
@@ -121,7 +121,7 @@
 extern "C" void JavaObjectTracer(JavaObject* obj) {
 #endif
   obj->classOf->MARK_AND_TRACE;
-  if (obj->lockObj) obj->lockObj->MARK_AND_TRACE;
+  if (obj->lockObj()) obj->lockObj()->MARK_AND_TRACE;
 }
 
 

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

==============================================================================
--- vmkit/trunk/lib/Mvm/JIT.cpp (original)
+++ vmkit/trunk/lib/Mvm/JIT.cpp Thu Jun  5 07:45:58 2008
@@ -513,6 +513,23 @@
       /*Linkage=*/GlobalValue::ExternalLinkage,
       /*Name=*/"llvm.memset.i32", module); // (external, no body)
   }
+    
+  /* Create atomic cas i32 */
+  {
+    std::vector<const Type*>FuncTy_4_args;
+    FuncTy_4_args.push_back(ptr32Type);
+    FuncTy_4_args.push_back(IntegerType::get(32));
+    FuncTy_4_args.push_back(IntegerType::get(32));
+    FunctionType* FuncTy_4 = FunctionType::get(
+      /*Result=*/Type::Int32Ty,
+      /*Params=*/FuncTy_4_args,
+      /*isVarArg=*/false);
+    llvm_atomic_lcs_i32 = Function::Create(
+      /*Type=*/FuncTy_4,
+      /*Linkage=*/GlobalValue::ExternalLinkage,
+      /*Name=*/"llvm.atomic.lcs.i32", module); // (external, no body)
+  }
+  
 
   
     // Constant declaration
@@ -565,6 +582,8 @@
 llvm::Function* mvm::jit::llvm_memcpy_i32;
 llvm::Function* mvm::jit::llvm_memset_i32;
 
+llvm::Function* mvm::jit::llvm_atomic_lcs_i32;
+
 llvm::Function* mvm::jit::exceptionEndCatch;
 llvm::Function* mvm::jit::exceptionBeginCatch;
 llvm::Function* mvm::jit::unwindResume;

Modified: vmkit/trunk/lib/Mvm/Main.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/Mvm/Main.cpp?rev=51994&r1=51993&r2=51994&view=diff

==============================================================================
--- vmkit/trunk/lib/Mvm/Main.cpp (original)
+++ vmkit/trunk/lib/Mvm/Main.cpp Thu Jun  5 07:45:58 2008
@@ -46,7 +46,7 @@
   jit::initialise();
   Object::initialise();
   Thread::initialise();
-  Collector::initialise(Object::markAndTraceRoots, &base);
+  Collector::initialise(0, &base);
   
   CommandLine cl;
   cl.start();





More information about the llvm-commits mailing list