[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