[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