[vmkit-commits] [vmkit] r198211 - hashCode and wait are working with my stack locking/thin lock algorithm.
Gael Thomas
gael.thomas at lip6.fr
Mon Dec 30 07:35:03 PST 2013
Author: gthomas
Date: Mon Dec 30 09:35:02 2013
New Revision: 198211
URL: http://llvm.org/viewvc/llvm-project?rev=198211&view=rev
Log:
hashCode and wait are working with my stack locking/thin lock algorithm.
Modified:
vmkit/branches/mcjit/include/j3/j3monitor.h
vmkit/branches/mcjit/include/j3/j3object.h
vmkit/branches/mcjit/include/j3/j3thread.h
vmkit/branches/mcjit/include/vmkit/thread.h
vmkit/branches/mcjit/lib/j3/openjdk/j3openjdk.cc
vmkit/branches/mcjit/lib/j3/vm/j3codegen.cc
vmkit/branches/mcjit/lib/j3/vm/j3monitor.cc
vmkit/branches/mcjit/lib/j3/vm/j3object.cc
vmkit/branches/mcjit/lib/j3/vm/j3thread.cc
vmkit/branches/mcjit/lib/vmkit/thread.cc
Modified: vmkit/branches/mcjit/include/j3/j3monitor.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/mcjit/include/j3/j3monitor.h?rev=198211&r1=198210&r2=198211&view=diff
==============================================================================
--- vmkit/branches/mcjit/include/j3/j3monitor.h (original)
+++ vmkit/branches/mcjit/include/j3/j3monitor.h Mon Dec 30 09:35:02 2013
@@ -23,20 +23,24 @@ namespace j3 {
class J3Monitor {
friend class J3MonitorManager;
+ friend class J3Object;
J3Monitor* _next;
J3Thread* owner;
- uint32_t recursiveCount;
+ uint32_t lockCount;
pthread_mutex_t mutex;
pthread_cond_t cond;
uintptr_t header;
J3Object* object;
+ J3LockRecord* record;
+
+ void checkRecord();
void init(J3Monitor* next); /* acquire the lock for the next inflate */
public:
bool isDeflatable(); /* acquire the lock for the next inflate */
- void prepare(J3Object* _object, J3Thread* _owner, uint32_t _recursiveCount, uintptr_t _header);
+ void prepare(J3Object* _object, uintptr_t header, J3LockRecord* _record);
void lock();
void unlock();
Modified: vmkit/branches/mcjit/include/j3/j3object.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/mcjit/include/j3/j3object.h?rev=198211&r1=198210&r2=198211&view=diff
==============================================================================
--- vmkit/branches/mcjit/include/j3/j3object.h (original)
+++ vmkit/branches/mcjit/include/j3/j3object.h Mon Dec 30 09:35:02 2013
@@ -22,6 +22,7 @@ namespace j3 {
class J3VirtualTable;
class J3FixedPoint;
class J3Method;
+ class J3Monitor;
// see: Cliff Click and John Rose. 2002. Fast subtype checking in the HotSpot JVM.
// In Proceedings of the 2002 joint ACM-ISCOPE conference on Java Grande (JGI '02). ACM, New York, NY, USA, 96-107.
@@ -89,8 +90,8 @@ namespace j3 {
static const uint32_t gepHeader = 1;
private:
- J3VirtualTable* _vt;
- uintptr_t _header;
+ J3VirtualTable* _vt;
+ volatile uintptr_t _header;
/*
* biasable (not yet implemented): 0 | epoch | age | 101
* biased (not yet implemented): thread_id | epoch | age | 101
@@ -101,6 +102,9 @@ namespace j3 {
J3Object(); /* never directly allocate an object */
+ J3Monitor* monitor();
+ uint32_t hashCode();
+
static void monitorEnter(J3Object* obj);
static void monitorExit(J3Object* obj);
@@ -109,8 +113,8 @@ namespace j3 {
static J3Object* doNew(J3Class* cl);
public:
- J3VirtualTable* vt();
- uintptr_t* header();
+ J3VirtualTable* vt();
+ volatile uintptr_t* header();
};
class J3ArrayObject : public J3Object {
@@ -151,6 +155,8 @@ namespace j3 {
static J3ObjectHandle* doNewObject(J3Class* cl);
static J3ObjectHandle* doNewArray(J3ArrayClass* cl, uint32_t length);
+ void wait();
+
bool isSame(J3ObjectHandle* handle) { return obj() == handle->obj(); }
void harakiri() { _obj = 0; }
Modified: vmkit/branches/mcjit/include/j3/j3thread.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/mcjit/include/j3/j3thread.h?rev=198211&r1=198210&r2=198211&view=diff
==============================================================================
--- vmkit/branches/mcjit/include/j3/j3thread.h (original)
+++ vmkit/branches/mcjit/include/j3/j3thread.h Mon Dec 30 09:35:02 2013
@@ -25,7 +25,6 @@ namespace j3 {
J3LocalReferences _localReferences;
J3ObjectHandle* _pendingException;
J3ObjectHandle* _javaThread;
- J3Thread* _nextLocked;
virtual void run();
static void doRun();
@@ -57,6 +56,7 @@ namespace j3 {
JNIEnv* jniEnv() { return &_jniEnv; }
static J3Thread* get();
+ static J3Thread* get(void* ptr);
static void start(J3ObjectHandle* handle);
};
Modified: vmkit/branches/mcjit/include/vmkit/thread.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/mcjit/include/vmkit/thread.h?rev=198211&r1=198210&r2=198211&view=diff
==============================================================================
--- vmkit/branches/mcjit/include/vmkit/thread.h (original)
+++ vmkit/branches/mcjit/include/vmkit/thread.h Mon Dec 30 09:35:02 2013
@@ -26,12 +26,13 @@ namespace vmkit {
VMKit* vm() { return _vm; }
+ static uintptr_t getThreadMask();
+ static Thread* get(void* ptr);
static Thread* get();
void start();
void join();
- static uintptr_t getThreadMask();
};
class StackWalker {
Modified: vmkit/branches/mcjit/lib/j3/openjdk/j3openjdk.cc
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/mcjit/lib/j3/openjdk/j3openjdk.cc?rev=198211&r1=198210&r2=198211&view=diff
==============================================================================
--- vmkit/branches/mcjit/lib/j3/openjdk/j3openjdk.cc (original)
+++ vmkit/branches/mcjit/lib/j3/openjdk/j3openjdk.cc Mon Dec 30 09:35:02 2013
@@ -33,7 +33,12 @@ jint JNICALL JVM_IHashCode(JNIEnv* env,
return res;
}
-void JNICALL JVM_MonitorWait(JNIEnv* env, jobject obj, jlong ms) { enterJVM(); NYI(); leaveJVM(); }
+void JNICALL JVM_MonitorWait(JNIEnv* env, jobject obj, jlong ms) {
+ enterJVM();
+ obj->wait();
+ leaveJVM();
+}
+
void JNICALL JVM_MonitorNotify(JNIEnv* env, jobject obj) { enterJVM(); NYI(); leaveJVM(); }
void JNICALL JVM_MonitorNotifyAll(JNIEnv* env, jobject obj) { enterJVM(); NYI(); leaveJVM(); }
jobject JNICALL JVM_Clone(JNIEnv* env, jobject obj) { enterJVM(); NYI(); leaveJVM(); }
Modified: vmkit/branches/mcjit/lib/j3/vm/j3codegen.cc
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/mcjit/lib/j3/vm/j3codegen.cc?rev=198211&r1=198210&r2=198211&view=diff
==============================================================================
--- vmkit/branches/mcjit/lib/j3/vm/j3codegen.cc (original)
+++ vmkit/branches/mcjit/lib/j3/vm/j3codegen.cc Mon Dec 30 09:35:02 2013
@@ -197,6 +197,8 @@ void J3CodeGen::monitorEnter(llvm::Value
builder->CreateStore(record, recordPtr);
llvm::Value* gepR[] = { builder->getInt32(0), builder->getInt32(J3LockRecord::gepHeader) };
builder->CreateStore(header, builder->CreateGEP(record, gepR));
+ llvm::Value* gepC[] = { builder->getInt32(0), builder->getInt32(J3LockRecord::gepLockCount) };
+ builder->CreateStore(builder->getInt32(0), builder->CreateGEP(record, gepC));
llvm::Value* orig = builder->CreateOr(builder->CreateAnd(header, llvm::ConstantInt::get(uintPtrTy, ~6)),
llvm::ConstantInt::get(uintPtrTy, 1)); /* ...001 */
llvm::Value* res = builder->CreateAtomicCmpXchg(headerPtr,
@@ -208,7 +210,6 @@ void J3CodeGen::monitorEnter(llvm::Value
/* stack locked, increment the counter */
builder->SetInsertPoint(stackLocked);
- llvm::Value* gepC[] = { builder->getInt32(0), builder->getInt32(J3LockRecord::gepLockCount) };
llvm::Value* countPtr = builder->CreateGEP(builder->CreateLoad(recordPtr), gepC);
builder->CreateStore(builder->CreateAdd(builder->CreateLoad(countPtr), builder->getInt32(1)), countPtr);
builder->CreateBr(ok);
Modified: vmkit/branches/mcjit/lib/j3/vm/j3monitor.cc
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/mcjit/lib/j3/vm/j3monitor.cc?rev=198211&r1=198210&r2=198211&view=diff
==============================================================================
--- vmkit/branches/mcjit/lib/j3/vm/j3monitor.cc (original)
+++ vmkit/branches/mcjit/lib/j3/vm/j3monitor.cc Mon Dec 30 09:35:02 2013
@@ -16,29 +16,39 @@ bool J3Monitor::isDeflatable() {
return pthread_mutex_trylock(&mutex) == 0;
}
-void J3Monitor::prepare(J3Object* _object, J3Thread* _owner, uint32_t _recursiveCount, uintptr_t _header) {
+void J3Monitor::prepare(J3Object* _object, uintptr_t _header, J3LockRecord* _record) {
object = _object;
- owner = _owner;
- recursiveCount = _recursiveCount;
+ record = _record;
header = _header;
+ owner = _record ? J3Thread::get(_record) : 0;
+}
+
+void J3Monitor::checkRecord() {
+ if(record) {
+ lockCount = record->lockCount;
+ record = 0;
+ }
}
void J3Monitor::lock() {
J3Thread* self = J3Thread::get();
- if(owner == self) {
- recursiveCount++;
- } else {
+
+ if(owner == self)
+ checkRecord();
+ else {
pthread_mutex_lock(&mutex);
- recursiveCount++;
owner = self;
}
+ lockCount++;
}
void J3Monitor::unlock() {
J3Thread* self = J3Thread::get();
if(owner != self)
J3::illegalMonitorStateException();
- if(!--recursiveCount) {
+
+ checkRecord();
+ if(!--lockCount) {
owner = 0;
pthread_mutex_unlock(&mutex);
} else
@@ -55,7 +65,9 @@ void J3Monitor::timed_wait(uint64_t ms,
if(owner != self)
J3::illegalMonitorStateException();
- uint32_t r = recursiveCount;
+ checkRecord();
+
+ uint32_t r = lockCount;
owner = 0;
if(ms || ns) {
@@ -69,11 +81,12 @@ void J3Monitor::timed_wait(uint64_t ms,
ts.tv_nsec -= 1e9;
}
pthread_cond_timedwait(&cond, &mutex, &ts);
+
} else
pthread_cond_wait(&cond, &mutex);
owner = self;
- recursiveCount = r;
+ lockCount = r;
}
void J3Monitor::notify() {
Modified: vmkit/branches/mcjit/lib/j3/vm/j3object.cc
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/mcjit/lib/j3/vm/j3object.cc?rev=198211&r1=198210&r2=198211&view=diff
==============================================================================
--- vmkit/branches/mcjit/lib/j3/vm/j3object.cc (original)
+++ vmkit/branches/mcjit/lib/j3/vm/j3object.cc Mon Dec 30 09:35:02 2013
@@ -13,6 +13,7 @@
#include "j3/j3.h"
#include "j3/j3constants.h"
#include "j3/j3thread.h"
+#include "j3/j3monitor.h"
using namespace j3;
@@ -267,7 +268,7 @@ J3VirtualTable* J3Object::vt() {
return _vt;
}
-uintptr_t* J3Object::header() {
+volatile uintptr_t* J3Object::header() {
return &_header;
}
@@ -295,6 +296,73 @@ void J3Object::monitorExit(J3Object* obj
J3::internalError(L"implement me: monitorexit");
}
+uint32_t J3Object::hashCode() {
+ static uint32_t curHashCode = 0;
+
+ while(1) {
+ uintptr_t header = _header;
+ if((header & 0x7) == 1) { /* not locked, not inflated */
+ uint32_t res = header >> 8;
+ if(res)
+ return res;
+ do {
+ res = __sync_add_and_fetch(&curHashCode, 1) & 0xffffff;
+ } while(!res);
+
+ if(__sync_val_compare_and_swap(&_header, header, res<<8 | (header & 0xff)) == header)
+ return res;
+ } else {
+ /* if stack locked, force the inflation because I can not modify the stack of the owner */
+ J3Monitor* m = monitor();
+
+ header = m->header;
+
+ uint32_t res = header >> 8;
+ if(res)
+ return res;
+ do {
+ res = __sync_add_and_fetch(&curHashCode, 1) & 0xffffff;
+ } while(!res);
+
+ if(__sync_val_compare_and_swap(&m->header, header, res<<8 | (header & 0xff)) == header)
+ return res;
+ }
+ }
+}
+
+J3Monitor* J3Object::monitor() {
+ uintptr_t header = _header;
+
+ while(1) {
+ uintptr_t header = _header;
+
+ if((header & 0x3) == 2) { /* already inflated */
+ J3Monitor* res = (J3Monitor*)(header & -2);
+ if(res)
+ return res;
+ else
+ sched_yield(); /* another guy is trying to inflate this monitor */
+ } else if(__sync_val_compare_and_swap(&_header, header, 2) == header) {
+ /* ok, I'm the boss */
+ J3Monitor* monitor = J3Thread::get()->vm()->monitorManager.allocate();
+
+ if(!(header & 3)) { /* stack locked */
+ J3LockRecord* record = (J3LockRecord*)header;
+ fprintf(stderr, " preparing monitor with %p\n", record);
+ /* I can read record->header because, in the worst case, the owner is blocked in the sched_yield loop */
+ monitor->prepare(this, record->header, record);
+ } else { /* not locked at all */
+ if((header & 7) != 1)
+ J3::internalError(L"should not happen");
+ monitor->prepare(this, header, 0);
+ }
+ _header = (uintptr_t)monitor | 2;
+
+ return monitor;
+ }
+ }
+}
+
/*
* --- J3ArrayObject ---
*/
@@ -313,15 +381,12 @@ J3Object* J3ArrayObject::doNew(J3ArrayCl
/*
* J3ObjectHandle
*/
+void J3ObjectHandle::wait() {
+ obj()->monitor()->wait();
+}
+
uint32_t J3ObjectHandle::hashCode() {
- do {
- uintptr_t oh = *obj()->header();
- uintptr_t res = oh;
- if(res)
- return res;
- uintptr_t nh = oh + 256;
- __sync_val_compare_and_swap(obj()->header(), oh, nh);
- } while(1);
+ return obj()->hashCode();
}
J3ObjectHandle* J3ObjectHandle::allocate(J3VirtualTable* vt, size_t n) {
Modified: vmkit/branches/mcjit/lib/j3/vm/j3thread.cc
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/mcjit/lib/j3/vm/j3thread.cc?rev=198211&r1=198210&r2=198211&view=diff
==============================================================================
--- vmkit/branches/mcjit/lib/j3/vm/j3thread.cc (original)
+++ vmkit/branches/mcjit/lib/j3/vm/j3thread.cc Mon Dec 30 09:35:02 2013
@@ -87,6 +87,10 @@ void J3Thread::restore(J3ObjectHandle* p
_localReferences.restore(ptr);
}
+J3Thread* J3Thread::get(void* ptr) {
+ return (J3Thread*)Thread::get(ptr);
+}
+
J3Thread* J3Thread::get() {
return (J3Thread*)Thread::get();
}
Modified: vmkit/branches/mcjit/lib/vmkit/thread.cc
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/mcjit/lib/vmkit/thread.cc?rev=198211&r1=198210&r2=198211&view=diff
==============================================================================
--- vmkit/branches/mcjit/lib/vmkit/thread.cc (original)
+++ vmkit/branches/mcjit/lib/vmkit/thread.cc Mon Dec 30 09:35:02 2013
@@ -17,7 +17,11 @@ void Thread::operator delete(void* p) {
}
Thread* Thread::get() {
- return (Thread*)((uintptr_t)__builtin_frame_address(0) & getThreadMask());
+ return get(__builtin_frame_address(0));
+}
+
+Thread* Thread::get(void* ptr) {
+ return (Thread*)((uintptr_t)ptr & getThreadMask());
}
uintptr_t Thread::getThreadMask() {
More information about the vmkit-commits
mailing list