[vmkit-commits] [vmkit] r84625 - in /vmkit/trunk: include/mvm/Threads/Locks.h lib/JnJVM/Classpath/ClasspathVMThread.inc lib/JnJVM/VMCore/JavaClass.h lib/JnJVM/VMCore/JavaLocks.h lib/JnJVM/VMCore/JavaObject.cpp lib/JnJVM/VMCore/JavaObject.h lib/JnJVM/VMCore/Jnjvm.cpp

Nicolas Geoffray nicolas.geoffray at lip6.fr
Tue Oct 20 01:58:38 PDT 2009


Author: geoffray
Date: Tue Oct 20 03:58:38 2009
New Revision: 84625

URL: http://llvm.org/viewvc/llvm-project?rev=84625&view=rev
Log:
Internally recycle JavaLocks when they are released and
no-one is waiting on them.


Modified:
    vmkit/trunk/include/mvm/Threads/Locks.h
    vmkit/trunk/lib/JnJVM/Classpath/ClasspathVMThread.inc
    vmkit/trunk/lib/JnJVM/VMCore/JavaClass.h
    vmkit/trunk/lib/JnJVM/VMCore/JavaLocks.h
    vmkit/trunk/lib/JnJVM/VMCore/JavaObject.cpp
    vmkit/trunk/lib/JnJVM/VMCore/JavaObject.h
    vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.cpp

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

==============================================================================
--- vmkit/trunk/include/mvm/Threads/Locks.h (original)
+++ vmkit/trunk/include/mvm/Threads/Locks.h Tue Oct 20 03:58:38 2009
@@ -215,17 +215,17 @@
 ///
 template <class TFatLock, class Owner, class IsGC>
 class ThinLock {
+public:
   uintptr_t lock;
 
-public:
 
 
 
   /// overflowThinlock - Change the lock of this object to a fat lock because
   /// we have reached 0xFF locks.
   void overflowThinLock(Owner* O = 0) {
+    IsGC::gcroot(O, 0);
     TFatLock* obj = TFatLock::allocate(O);
-    IsGC::gcroot(obj, 0);
     obj->acquireAll(257);
     lock = obj->getID();
   }
@@ -246,20 +246,24 @@
   /// changeToFatlock - Change the lock of this object to a fat lock. The lock
   /// may be in a thin lock or fat lock state.
   TFatLock* changeToFatlock(Owner* O) {
+    IsGC::gcroot(O, 0);
     if (!(lock & FatMask)) {
       TFatLock* obj = TFatLock::allocate(O);
-      IsGC::gcroot(obj, 0);
       uint32 count = lock & ThinCountMask;
       obj->acquireAll(count + 1);
       lock = obj->getID();
       return obj;
     } else {
-      return TFatLock::getFromID(lock);
+      TFatLock* res = TFatLock::getFromID(lock);
+      assert(res && "Lock deallocated while held.");
+      return res;
     }
   }
 
   /// acquire - Acquire the lock.
-  void acquire(Owner* O = 0) {
+  void acquire(Owner* O) {
+    IsGC::gcroot(O, 0);
+start:
     uint64_t id = mvm::Thread::get()->getThreadID();
     uintptr_t val = __sync_val_compare_and_swap(&lock, 0, id);
 
@@ -274,7 +278,6 @@
           }
         } else {
           TFatLock* obj = TFatLock::allocate(O);
-          IsGC::gcroot(obj, 0);
           uintptr_t val = obj->getID();
 loop:
           while (lock) {
@@ -287,13 +290,17 @@
         
           uintptr_t test = __sync_val_compare_and_swap((uintptr_t*)&lock, 0, val);
           if (test) goto loop;
-          obj->acquire();
+          if (!obj->acquire(O)) goto start;
         }
       } else {
 
 end:
         TFatLock* obj = TFatLock::getFromID(lock);
-        obj->acquire();
+        if (obj) {
+          if (!obj->acquire(O)) goto start;
+        } else {
+          goto start;
+        }
       }
     }
 
@@ -301,15 +308,16 @@
   }
 
   /// release - Release the lock.
-  void release() {
+  void release(Owner* O) {
+    IsGC::gcroot(O, 0);
     assert(owner() && "Not owner when entering release!");
     uint64 id = mvm::Thread::get()->getThreadID();
     if (lock == id) {
       lock = 0;
     } else if (lock & FatMask) {
       TFatLock* obj = TFatLock::getFromID(lock);
-      IsGC::gcroot(obj, 0);
-      obj->release();
+      assert(obj && "Lock deallocated while held.");
+      obj->release(O);
     } else {
       lock--;
     }
@@ -320,7 +328,7 @@
   void broadcast() {
     if (lock & FatMask) {
       TFatLock* obj = TFatLock::getFromID(lock);
-      IsGC::gcroot(obj, 0);
+      assert(obj && "Lock deallocated while held.");
       obj->broadcast();
     }
   }
@@ -329,7 +337,7 @@
   void signal() {
     if (lock & FatMask) {
       TFatLock* obj = TFatLock::getFromID(lock);
-      IsGC::gcroot(obj, 0);
+      assert(obj && "Lock deallocated while held.");
       obj->signal();
     }
   }
@@ -342,8 +350,7 @@
     if ((lock & ThinMask) == id) return true;
     if (lock & FatMask) {
       TFatLock* obj = TFatLock::getFromID(lock);
-      IsGC::gcroot(obj, 0);
-      return obj->owner();
+      if (obj) return obj->owner();
     }
     return false;
   }
@@ -351,8 +358,8 @@
   mvm::Thread* getOwner() {
     if (lock & FatMask) {
       TFatLock* obj = TFatLock::getFromID(lock);
-      IsGC::gcroot(obj, 0);
-      return obj->getOwner();
+      if (obj) return obj->getOwner();
+      return 0;
     } else {
       return (mvm::Thread*)(lock & ThinMask);
     }

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

==============================================================================
--- vmkit/trunk/lib/JnJVM/Classpath/ClasspathVMThread.inc (original)
+++ vmkit/trunk/lib/JnJVM/Classpath/ClasspathVMThread.inc Tue Oct 20 03:58:38 2009
@@ -140,7 +140,7 @@
     th->varcond.signal();
 
     // Release the lock if we acquired it.
-    if (locked) lock->release();
+    if (locked) lock->release(lock->getAssociatedObject());
   }
 
   // Here we could also raise a signal for interrupting I/O

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

==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JavaClass.h (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JavaClass.h Tue Oct 20 03:58:38 2009
@@ -425,15 +425,16 @@
       // Too bad, I can't deallocate it because it is in permanent memory.
     }
 
-    void acquire() {
+    bool acquire(CommonClass* cl) {
       lockVar.lock();
+      return true;
     }
 
     void acquireAll(uint32 nb) {
       lockVar.lockAll(nb);
     }
 
-    void release() {
+    void release(CommonClass* cl) {
       lockVar.unlock();
     }
 
@@ -746,7 +747,7 @@
   /// release - Release this class lock.
   ///
   void release() {
-    lock.release();  
+    lock.release(this); 
   }
 
   /// waitClass - Wait for the class to be loaded/initialized/resolved.

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

==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JavaLocks.h (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JavaLocks.h Tue Oct 20 03:58:38 2009
@@ -30,7 +30,9 @@
 
 private:
   mvm::LockRecursive internalLock;
-  mvm::Thread* waitingThread;
+  mvm::SpinLock spinLock;
+  uint32_t waitingThreads;
+  uint32_t lockingThreads;
   JavaThread* firstThread;
   JavaObject* associatedObject;
   uint32_t index;
@@ -38,12 +40,30 @@
 
 public:
 
+  JavaObject* getAssociatedObject() {
+    return associatedObject;
+  }
+
   /// acquire - Acquires the internalLock.
   ///
-  void acquire() {
-    waitingThread = mvm::Thread::get();
+  bool acquire(JavaObject* obj) {
+    llvm_gcroot(obj, 0);
+    
+    spinLock.lock();
+    lockingThreads++;
+    spinLock.unlock();
+    
     internalLock.lock();
-    waitingThread = 0;
+    
+    spinLock.lock();
+    lockingThreads--;
+    spinLock.unlock();
+
+    if (associatedObject != obj) {
+      internalLock.unlock();
+      return false;
+    }
+    return true;
   }
  
   /// tryAcquire - Tries to acquire the lock.
@@ -55,16 +75,12 @@
  
   /// acquireAll - Acquires the lock nb times.
   void acquireAll(uint32 nb) {
-    waitingThread = mvm::Thread::get();
     internalLock.lockAll(nb);
-    waitingThread = 0;
   }
 
   /// release - Releases the internalLock.
   ///
-  void release() {
-    internalLock.unlock();
-  }
+  void release(JavaObject* obj);
   
   /// owner - Returns if the current thread owns this internalLock.
   ///
@@ -80,10 +96,12 @@
   
   /// JavaLock - Default constructor.
   JavaLock(uint32_t i, JavaObject* a) {
+    llvm_gcroot(a, 0);
     firstThread = 0;
     index = i;
     associatedObject = a;
-    waitingThread = 0;
+    waitingThreads = 0;
+    lockingThreads = 0;
   }
 
   static JavaLock* allocate(JavaObject*);

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

==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JavaObject.cpp (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JavaObject.cpp Tue Oct 20 03:58:38 2009
@@ -57,6 +57,10 @@
       
       bool timeout = false;
 
+      l->spinLock.lock();
+      l->waitingThreads++;
+      l->spinLock.unlock();
+
       while (!thread->interruptFlag && thread->nextWaiting) {
         if (timed) {
           timeout = varcondThread.timedWait(&l->internalLock, info);
@@ -65,6 +69,10 @@
           varcondThread.wait(&l->internalLock);
         }
       }
+      
+      l->spinLock.lock();
+      l->waitingThreads--;
+      l->spinLock.unlock();
      
       assert((!l->firstThread || (l->firstThread->prevWaiting && 
              l->firstThread->nextWaiting)) && "Inconsistent list");
@@ -112,6 +120,7 @@
   } else {
     JavaThread::get()->getJVM()->illegalMonitorStateException(self);
   }
+  
   assert(owner() && "Not owner after wait");
 }
 

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

==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JavaObject.h (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JavaObject.h Tue Oct 20 03:58:38 2009
@@ -198,7 +198,7 @@
 
   /// lock - The monitor of this object. Most of the time null.
   ///
-  mvm::ThinLock<JavaLock, JavaObject, mvm::FatLockNoGC> lock;
+  mvm::ThinLock<JavaLock, JavaObject, mvm::FatLockWithGC> lock;
 
   /// wait - Java wait. Makes the current thread waiting on a monitor.
   ///
@@ -233,12 +233,14 @@
   void acquire() {
     JavaObject* self = this;
     llvm_gcroot(self, 0);
-    self->lock.acquire();
+    self->lock.acquire(self);
   }
 
   /// release - Release the lock on this object
   void release() {
-    lock.release();
+    JavaObject* self = this;
+    llvm_gcroot(self, 0);
+    lock.release(self);
   }
 
   /// owner - Returns true if the current thread is the owner of this object's

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

==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.cpp (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.cpp Tue Oct 20 03:58:38 2009
@@ -1456,6 +1456,22 @@
 
 JavaLock* JavaLock::getFromID(uintptr_t ID) {
   Jnjvm* vm = JavaThread::get()->getJVM();
-  JavaLock* res = vm->lockSystem.getLock(ID & ~mvm::FatMask);
-  return res;
+  if (ID & mvm::FatMask) {
+    JavaLock* res = vm->lockSystem.getLock(ID & ~mvm::FatMask);
+    return res;
+  } else {
+    return 0;
+  }
+}
+
+void JavaLock::release(JavaObject* obj) {
+  assert(associatedObject == obj && "Mismatch object in lock");
+  llvm_gcroot(obj, 0);
+  if (!waitingThreads && !lockingThreads &&
+      internalLock.recursionCount() == 1) {
+    assert(associatedObject && "No associated object when releasing");
+    associatedObject->lock.initialise();
+    deallocate();
+  }
+  internalLock.unlock();
 }





More information about the vmkit-commits mailing list