[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