[vmkit-commits] [vmkit] r198179 - First J3Monitor implementation. Not yet used.

Gael Thomas gael.thomas at lip6.fr
Sun Dec 29 14:15:59 PST 2013


Author: gthomas
Date: Sun Dec 29 16:15:59 2013
New Revision: 198179

URL: http://llvm.org/viewvc/llvm-project?rev=198179&view=rev
Log:
First J3Monitor implementation. Not yet used.

Added:
    vmkit/branches/mcjit/include/j3/j3monitor.h
    vmkit/branches/mcjit/lib/j3/vm/j3monitor.cc
Modified:
    vmkit/branches/mcjit/include/j3/j3.h
    vmkit/branches/mcjit/include/j3/j3object.h
    vmkit/branches/mcjit/include/j3/j3thread.h
    vmkit/branches/mcjit/lib/j3/vm/j3.cc

Modified: vmkit/branches/mcjit/include/j3/j3.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/mcjit/include/j3/j3.h?rev=198179&r1=198178&r2=198179&view=diff
==============================================================================
--- vmkit/branches/mcjit/include/j3/j3.h (original)
+++ vmkit/branches/mcjit/include/j3/j3.h Sun Dec 29 16:15:59 2013
@@ -11,7 +11,7 @@
 #include "j3/j3options.h"
 #include "j3/j3typesdef.h"
 #include "j3/j3jni.h"
-
+#include "j3/j3monitor.h"
 
 namespace j3 {
 	class J3InitialClassLoader;
@@ -30,7 +30,7 @@ namespace j3 {
 
 		static vmkit::T_ptr_less_t<J3ObjectHandle*> charArrayLess;
 
-		J3Options                          _options;
+		J3Options                            _options;
 
 		pthread_mutex_t                      stringsMutex;
 		vmkit::NameMap<J3ObjectHandle*>::map nameToCharArrays;
@@ -50,6 +50,8 @@ namespace j3 {
 		onJavaTypes(defPrimitive)
 #undef defPrimitive
 
+		J3MonitorManager monitorManager;
+
 		void*            interfaceTrampoline;
 
 		J3Type**         arrayInterfaces;
@@ -117,6 +119,8 @@ namespace j3 {
 		static void    arrayStoreException() __attribute__((noreturn));
 		static void    arrayIndexOutOfBoundsException() __attribute__((noreturn));
 
+		static void    illegalMonitorStateException() __attribute__((noreturn));
+
 		static void    printStackTrace();
 
 		void forceSymbolDefinition();

Added: vmkit/branches/mcjit/include/j3/j3monitor.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/mcjit/include/j3/j3monitor.h?rev=198179&view=auto
==============================================================================
--- vmkit/branches/mcjit/include/j3/j3monitor.h (added)
+++ vmkit/branches/mcjit/include/j3/j3monitor.h Sun Dec 29 16:15:59 2013
@@ -0,0 +1,57 @@
+#ifndef _J3_MONITOR_H_
+#define _J3_MONITOR_H_
+
+#include <pthread.h>
+#include <stdint.h>
+
+namespace vmkit {
+	class BumpAllocator;
+}
+
+namespace j3 {
+	class J3Thread;
+	class J3Object;
+
+	class J3Monitor {
+		friend class J3MonitorManager;
+
+		J3Monitor*      _next;
+
+		J3Thread*       owner;
+		uint32_t        recursiveCount;
+		pthread_mutex_t mutex;
+		pthread_cond_t  cond;
+		uintptr_t       header;
+		J3Object*       object;
+
+		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 lock();
+		void unlock();
+
+		void wait();
+		void timed_wait(uint64_t ms, uint32_t ns);
+
+		void notify();
+		void notifyAll();
+	};
+
+	class J3MonitorManager {
+		static const uint32_t monitorsBucket = 256;
+		pthread_mutex_t       mutex;
+		vmkit::BumpAllocator* allocator;
+		J3Monitor*            head;
+
+	public:
+		J3MonitorManager(vmkit::BumpAllocator* _allocator);
+
+		J3Monitor* allocate();
+		void       release(J3Monitor* monitor); 
+	};
+
+}
+
+#endif

Modified: vmkit/branches/mcjit/include/j3/j3object.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/mcjit/include/j3/j3object.h?rev=198179&r1=198178&r2=198179&view=diff
==============================================================================
--- vmkit/branches/mcjit/include/j3/j3object.h (original)
+++ vmkit/branches/mcjit/include/j3/j3object.h Sun Dec 29 16:15:59 2013
@@ -86,10 +86,18 @@ namespace j3 {
 		friend class J3ObjectHandle;
 	public:
 		static const uint32_t gepVT = 0;
+		static const uint32_t gepHeader = 1;
 
 	private:
 		J3VirtualTable* _vt;
 		uintptr_t       _header;
+		/* 
+		 *     biased (not yet implemented):  0         | epoch | age        | 101
+		 *                                    thread_id | epoch | age        | 101
+		 *     not locked:                    hash-code 24 bits | age 5 bits | 001
+		 *     stack locked:                      pointer to lock record      | 00
+		 *     inflated:                          pointer to monitor          | 01
+		 */
 
 		J3Object(); /* never directly allocate an object */
 

Modified: vmkit/branches/mcjit/include/j3/j3thread.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/mcjit/include/j3/j3thread.h?rev=198179&r1=198178&r2=198179&view=diff
==============================================================================
--- vmkit/branches/mcjit/include/j3/j3thread.h (original)
+++ vmkit/branches/mcjit/include/j3/j3thread.h Sun Dec 29 16:15:59 2013
@@ -14,6 +14,8 @@ namespace j3 {
 	class J3;
 
 	class J3Thread : public vmkit::Thread {
+		friend class J3Monitor;
+
 	public:
 		static const uint32_t gepInterfaceMethodIndex = 1;
 
@@ -24,6 +26,7 @@ namespace j3 {
 		J3LocalReferences          _localReferences;
 		J3ObjectHandle*            _pendingException;
 		J3ObjectHandle*            _javaThread;
+		J3Thread*                  _nextLocked;
 
 		virtual void run();
 		static void doRun();

Modified: vmkit/branches/mcjit/lib/j3/vm/j3.cc
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/mcjit/lib/j3/vm/j3.cc?rev=198179&r1=198178&r2=198179&view=diff
==============================================================================
--- vmkit/branches/mcjit/lib/j3/vm/j3.cc (original)
+++ vmkit/branches/mcjit/lib/j3/vm/j3.cc Sun Dec 29 16:15:59 2013
@@ -25,7 +25,8 @@ J3::J3(vmkit::BumpAllocator* allocator)
 	VMKit(allocator),
 	nameToCharArrays(vmkit::Name::less, allocator),
 	charArrayToStrings(charArrayLess, allocator),
-	_names(allocator) {
+	_names(allocator),
+	monitorManager(allocator) {
 	pthread_mutex_init(&stringsMutex, 0);
 	constantValueAttr = names()->get(J3Cst::constantValueAttr);
 	codeAttr =          names()->get(J3Cst::codeAttr);
@@ -189,6 +190,10 @@ void J3::arrayIndexOutOfBoundsException(
 	internalError(L"array bound check exception");
 }
 
+void J3::illegalMonitorStateException() {
+	internalError(L"illegal monitor state exception");
+}
+
 void J3::vinternalError(const wchar_t* msg, va_list va) {
 	wchar_t buf[65536];
 	vswprintf(buf, 65536, msg, va);

Added: vmkit/branches/mcjit/lib/j3/vm/j3monitor.cc
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/mcjit/lib/j3/vm/j3monitor.cc?rev=198179&view=auto
==============================================================================
--- vmkit/branches/mcjit/lib/j3/vm/j3monitor.cc (added)
+++ vmkit/branches/mcjit/lib/j3/vm/j3monitor.cc Sun Dec 29 16:15:59 2013
@@ -0,0 +1,124 @@
+#include "j3/j3monitor.h"
+#include "j3/j3thread.h"
+#include "j3/j3.h"
+
+#include <sys/time.h>
+
+using namespace j3;
+
+void J3Monitor::init(J3Monitor* next) {
+	pthread_mutex_init(&mutex, 0);
+	pthread_cond_init(&cond, 0);
+	pthread_mutex_lock(&mutex);
+}
+
+bool J3Monitor::isDeflatable() {
+	return pthread_mutex_trylock(&mutex) == 0;
+}
+
+void J3Monitor::prepare(J3Object* _object, J3Thread* _owner, uint32_t _recursiveCount, uintptr_t _header) {
+	object = _object;
+	owner = _owner;
+	recursiveCount = _recursiveCount;
+	header = _header;
+}
+
+void J3Monitor::lock() {
+	J3Thread* self = J3Thread::get();
+	if(owner == self) {
+		recursiveCount++;
+	} else {
+		pthread_mutex_lock(&mutex);
+		recursiveCount++;
+		owner = self;
+	}
+}
+
+void J3Monitor::unlock() {
+	J3Thread* self = J3Thread::get();
+	if(owner != self)
+		J3::illegalMonitorStateException();
+	if(!--recursiveCount) {
+		owner = 0;
+		pthread_mutex_unlock(&mutex);
+	} else
+		__sync_synchronize(); /* JMM */
+}
+		
+void J3Monitor::wait() {
+	timed_wait(0, 0);
+}
+
+void J3Monitor::timed_wait(uint64_t ms, uint32_t ns) {
+	J3Thread* self = J3Thread::get();
+
+	if(owner != self)
+		J3::illegalMonitorStateException();
+
+	uint32_t r = recursiveCount;
+	owner = 0;
+
+	if(ms || ns) {
+		struct timeval tv;
+		struct timespec ts;
+		gettimeofday(&tv, 0);
+		ts.tv_sec = tv.tv_sec + ms / 1000;
+		ts.tv_nsec = tv.tv_usec*1000 + ms % 1000 + ns;
+		if(ts.tv_nsec > 1e9) {
+			ts.tv_sec++;
+			ts.tv_nsec -= 1e9;
+		}
+		pthread_cond_timedwait(&cond, &mutex, &ts);
+	} else
+		pthread_cond_wait(&cond, &mutex);
+
+	owner = self;
+	recursiveCount = r;
+}
+
+void J3Monitor::notify() {
+	if(owner != J3Thread::get())
+		J3::illegalMonitorStateException();
+	pthread_cond_signal(&cond);
+}
+
+void J3Monitor::notifyAll() {
+	if(owner != J3Thread::get())
+		J3::illegalMonitorStateException();
+	pthread_cond_broadcast(&cond);
+}
+
+
+J3MonitorManager::J3MonitorManager(vmkit::BumpAllocator* _allocator) {
+	pthread_mutex_init(&mutex, 0);
+	allocator = _allocator;
+}
+
+J3Monitor* J3MonitorManager::allocate() {
+	pthread_mutex_lock(&mutex);
+
+	J3Monitor* res = head;
+
+	if(!res) {
+		uint32_t n = monitorsBucket;
+		J3Monitor* bucket = (J3Monitor*)allocator->allocate(sizeof(J3Monitor)*n);
+
+		for(uint32_t i=0; i<n; i++)
+			bucket[i].init(bucket+i-1);
+
+		bucket[0]._next = head;
+		head = bucket + n - 1;
+		res = head;
+	}
+	head = res->_next;
+	pthread_mutex_unlock(&mutex);
+	return res;
+}
+
+void J3MonitorManager::release(J3Monitor* monitor) {
+	pthread_mutex_lock(&mutex);
+	monitor->_next = head;
+	head = monitor;
+	pthread_mutex_unlock(&mutex);
+}
+





More information about the vmkit-commits mailing list