[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