[vmkit-commits] [vmkit] r58903 - in /vmkit/trunk: ./ include/mvm/ include/mvm/Threads/ lib/JnJVM/Classpath/ lib/JnJVM/VMCore/ lib/Mvm/CommonThread/ lib/Mvm/GCMmap2/ lib/Mvm/Runtime/ lib/N3/VMCore/ tools/jnjvm/ tools/n3-mono/ tools/n3-pnetlib/ tools/vmjc/ tools/vmkit/
Nicolas Geoffray
nicolas.geoffray at lip6.fr
Sat Nov 8 03:48:09 PST 2008
Author: geoffray
Date: Sat Nov 8 05:48:04 2008
New Revision: 58903
URL: http://llvm.org/viewvc/llvm-project?rev=58903&view=rev
Log:
Revamping threading in VMKit.
Removed:
vmkit/trunk/include/mvm/Threads/Key.h
vmkit/trunk/lib/Mvm/GCMmap2/ctcircular.h
Modified:
vmkit/trunk/Makefile.common.in
vmkit/trunk/include/mvm/JIT.h
vmkit/trunk/include/mvm/Threads/Cond.h
vmkit/trunk/include/mvm/Threads/Locks.h
vmkit/trunk/include/mvm/Threads/Thread.h
vmkit/trunk/include/mvm/VirtualMachine.h
vmkit/trunk/lib/JnJVM/Classpath/ClasspathVMThread.cpp
vmkit/trunk/lib/JnJVM/VMCore/JavaClass.cpp
vmkit/trunk/lib/JnJVM/VMCore/JavaClass.h
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.cpp
vmkit/trunk/lib/JnJVM/VMCore/JavaThread.h
vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.cpp
vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.h
vmkit/trunk/lib/JnJVM/VMCore/JnjvmClassLoader.h
vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.cpp
vmkit/trunk/lib/JnJVM/VMCore/JnjvmModuleProvider.cpp
vmkit/trunk/lib/JnJVM/VMCore/LowerConstantCalls.cpp
vmkit/trunk/lib/JnJVM/VMCore/VirtualTables.cpp
vmkit/trunk/lib/Mvm/CommonThread/ctlock.cpp
vmkit/trunk/lib/Mvm/CommonThread/ctthread.cpp
vmkit/trunk/lib/Mvm/GCMmap2/MvmGC.h
vmkit/trunk/lib/Mvm/GCMmap2/gc.cpp
vmkit/trunk/lib/Mvm/GCMmap2/gccollector.h
vmkit/trunk/lib/Mvm/GCMmap2/gcinit.cpp
vmkit/trunk/lib/Mvm/GCMmap2/gcthread.cpp
vmkit/trunk/lib/Mvm/GCMmap2/gcthread.h
vmkit/trunk/lib/Mvm/Runtime/JIT.cpp
vmkit/trunk/lib/Mvm/Runtime/LLVMRuntime.ll
vmkit/trunk/lib/Mvm/Runtime/Object.cpp
vmkit/trunk/lib/N3/VMCore/CLIJit.cpp
vmkit/trunk/lib/N3/VMCore/LockedMap.h
vmkit/trunk/lib/N3/VMCore/MSCorlib.cpp
vmkit/trunk/lib/N3/VMCore/N3.cpp
vmkit/trunk/lib/N3/VMCore/N3.h
vmkit/trunk/lib/N3/VMCore/N3Initialise.cpp
vmkit/trunk/lib/N3/VMCore/VMCache.cpp
vmkit/trunk/lib/N3/VMCore/VMClass.cpp
vmkit/trunk/lib/N3/VMCore/VMObject.cpp
vmkit/trunk/lib/N3/VMCore/VMObject.h
vmkit/trunk/lib/N3/VMCore/VMThread.cpp
vmkit/trunk/lib/N3/VMCore/VMThread.h
vmkit/trunk/lib/N3/VMCore/VirtualMachine.cpp
vmkit/trunk/lib/N3/VMCore/VirtualMachine.h
vmkit/trunk/lib/N3/VMCore/VirtualTables.cpp
vmkit/trunk/tools/jnjvm/Main.cpp
vmkit/trunk/tools/n3-mono/Main.cpp
vmkit/trunk/tools/n3-pnetlib/Main.cpp
vmkit/trunk/tools/vmjc/vmjc.cpp
vmkit/trunk/tools/vmkit/Launcher.cpp
Modified: vmkit/trunk/Makefile.common.in
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/Makefile.common.in?rev=58903&r1=58902&r2=58903&view=diff
==============================================================================
--- vmkit/trunk/Makefile.common.in (original)
+++ vmkit/trunk/Makefile.common.in Sat Nov 8 05:48:04 2008
@@ -23,7 +23,7 @@
# Include LLVM's Master Makefile.
include $(LLVM_OBJ_ROOT)/Makefile.common
-CXX.Flags += @GC_FLAGS@ @VM_FLAGS@ -Wno-variadic-macros -fno-omit-frame-pointer -ansi
+CXX.Flags += @GC_FLAGS@ @VM_FLAGS@ -Wno-variadic-macros -fno-omit-frame-pointer -ansi -DENABLE_THREADS
# GNU Classpath flags
CLASSPATH_FLAGS = @classpathinclude@
Modified: vmkit/trunk/include/mvm/JIT.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/include/mvm/JIT.h?rev=58903&r1=58902&r2=58903&view=diff
==============================================================================
--- vmkit/trunk/include/mvm/JIT.h (original)
+++ vmkit/trunk/include/mvm/JIT.h Sat Nov 8 05:48:04 2008
@@ -112,7 +112,7 @@
llvm::Function* llvm_atomic_lcs_i64;
static llvm::ExecutionEngine* executionEngine;
- static mvm::Lock* protectEngine;
+ static mvm::LockNormal protectEngine;
static uint64 getTypeSize(const llvm::Type* type);
static void AddStandardCompilePasses(llvm::FunctionPassManager*);
@@ -179,10 +179,6 @@
static uint32 (*llvm_atomic_cmp_swap_i32) ( uint32* ptr, uint32 cmp, uint32 val );
static uint64 (*llvm_atomic_cmp_swap_i64) ( uint64* ptr, uint64 cmp, uint64 val );
- static llvm::GlobalVariable* executionEnvironment;
- static mvm::Thread* (*getExecutionEnvironment)();
- static void (*setExecutionEnvironment)(mvm::Thread*);
-
};
// TODO: find what macro for gcc < 4.2
Modified: vmkit/trunk/include/mvm/Threads/Cond.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/include/mvm/Threads/Cond.h?rev=58903&r1=58902&r2=58903&view=diff
==============================================================================
--- vmkit/trunk/include/mvm/Threads/Cond.h (original)
+++ vmkit/trunk/include/mvm/Threads/Cond.h Sat Nov 8 05:48:04 2008
@@ -10,27 +10,22 @@
#ifndef MVM_COND_H
#define MVM_COND_H
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "mvm/Threads/Locks.h"
-
#include <cstdlib>
+#include <pthread.h>
namespace mvm {
+class Lock;
+
class Cond {
- unsigned int no_barrier;
- unsigned int go;
- unsigned int n_wait;
+ pthread_cond_t internalCond;
public:
- Cond() : no_barrier(0), go(0), n_wait(0) { }
- static Cond *allocCond(void);
+ Cond();
+ ~Cond();
void broadcast(void);
void wait(Lock *l);
- int timed_wait(Lock *l, timeval *tv);
+ int timedWait(Lock *l, timeval *tv);
void signal(void);
};
Removed: vmkit/trunk/include/mvm/Threads/Key.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/include/mvm/Threads/Key.h?rev=58902&view=auto
==============================================================================
--- vmkit/trunk/include/mvm/Threads/Key.h (original)
+++ vmkit/trunk/include/mvm/Threads/Key.h (removed)
@@ -1,54 +0,0 @@
-//===---------------- Key.h - Private thread keys -------------------------===//
-//
-// The Micro Virtual Machine
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef MVM_KEY_H
-#define MVM_KEY_H
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <pthread.h>
-
-namespace mvm {
-
-class ThreadKey {
-public:
- pthread_key_t val;
-
- ThreadKey(void (*_destr)(void *));
- ThreadKey();
- void* get();
- void set(void*);
- void initialise();
-
-};
-
-template <class T>
-class Key {
-public:
- ThreadKey key;
-
- Key() {
- initialise();
- }
-
- void initialise() {
- key.initialise();
- }
-
- T* get() { return (T*)key.get(); }
- void set(T *v) { key.set(v); }
-
-};
-
-
-} // end namespace mvm
-
-#endif // MVM_KEY_H
Modified: vmkit/trunk/include/mvm/Threads/Locks.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/include/mvm/Threads/Locks.h?rev=58903&r1=58902&r2=58903&view=diff
==============================================================================
--- vmkit/trunk/include/mvm/Threads/Locks.h (original)
+++ vmkit/trunk/include/mvm/Threads/Locks.h Sat Nov 8 05:48:04 2008
@@ -10,92 +10,61 @@
#ifndef MVM_LOCKS_H
#define MVM_LOCKS_H
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
+#include <pthread.h>
namespace mvm {
-class SpinLock {
- unsigned int value;
-public:
- SpinLock() { value = 0; }
-
- void slock();
- void sunlock() {
- value = 0;
- }
-};
+class Cond;
+class LockNormal;
+class LockRecursive;
-class Lock : public SpinLock {
+class Lock {
+ friend class Cond;
protected:
- void (*xlock)(Lock *);
- void (*xunlock)(Lock *);
- int (*xtrylock)(Lock *);
-
- int _owner;
+ int owner;
+ pthread_mutex_t internalLock;
public:
- inline Lock() { _owner = 0; }
- inline int owner() { return _owner; }
- inline void owner(int o) { _owner = o; }
-
- void lock() {
- xlock(this);
- }
-
- void unlock() {
- xunlock(this);
- }
-
- int trylock() {
- int res = xtrylock(this);
- return res;
- }
-
- static Lock *allocNormal();
- static Lock *allocRecursive();
- static void destroy(Lock *);
+ Lock(bool rec);
+
+ ~Lock();
+
+ virtual void lock() = 0;
+ virtual void unlock() = 0;
- static bool selfOwner(Lock *);
- static int getOwner(Lock *);
+ bool selfOwner();
+ int getOwner();
};
class LockNormal : public Lock {
- static void my_lock(Lock *);
- static void my_unlock(Lock *);
- static int my_trylock(Lock *);
public:
- LockNormal() {
- xlock = my_lock; xunlock = my_unlock; xtrylock = my_trylock;
- }
+ LockNormal() : Lock(false) {}
+ virtual void lock();
+ virtual void unlock();
- void initialise() {
- xlock = my_lock; xunlock = my_unlock; xtrylock = my_trylock;
- }
};
class LockRecursive : public Lock {
+private:
int n;
- static void my_lock(Lock *);
- static void my_unlock(Lock *);
- static int my_trylock(Lock *);
public:
- LockRecursive() {
- xlock = my_lock; xunlock = my_unlock; xtrylock = my_trylock; n = 0;
+ LockRecursive() : Lock(true) {
+ n = 0;
}
- void initialise() {
- xlock = my_lock; xunlock = my_unlock; xtrylock = my_trylock; n = 0;
- }
+ virtual void lock();
+ virtual void unlock();
- static int recursion_count(Lock *);
- static int my_unlock_all(Lock *);
- static void my_lock_all(Lock *, int count);
+ int recursionCount() {
+ return n;
+ }
+ int unlockAll();
+ void lockAll(int count);
};
+
} // end namespace mvm
#endif // MVM_LOCKS_H
Modified: vmkit/trunk/include/mvm/Threads/Thread.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/include/mvm/Threads/Thread.h?rev=58903&r1=58902&r2=58903&view=diff
==============================================================================
--- vmkit/trunk/include/mvm/Threads/Thread.h (original)
+++ vmkit/trunk/include/mvm/Threads/Thread.h Sat Nov 8 05:48:04 2008
@@ -15,7 +15,6 @@
#include "MvmGC.h"
#include "mvm/JIT.h"
#include "mvm/Object.h"
-#include "mvm/Threads/Key.h"
class Collector;
@@ -24,10 +23,41 @@
class BumpPtrAllocator;
+
+class CircularBase {
+ CircularBase *_next;
+ CircularBase *_prev;
+public:
+ inline CircularBase *next() { return _next; }
+ inline CircularBase *prev() { return _prev; }
+
+ inline void next(CircularBase *n) { _next = n; }
+ inline void prev(CircularBase *p) { _prev = p; }
+
+ inline CircularBase() { alone(); }
+ inline explicit CircularBase(CircularBase *p) { append(p); }
+
+ inline void remove() {
+ _prev->_next = _next;
+ _next->_prev = _prev;
+ alone();
+ }
+
+ inline void append(CircularBase *p) {
+ _prev = p;
+ _next = p->_next;
+ _next->_prev = this;
+ _prev->_next = this;
+ }
+
+ inline void alone() { _prev = _next = this; }
+};
+
+
/// Thread - This class is the base of custom virtual machines' Thread classes.
/// It provides static functions to manage threads. An instance of this class
/// contains all thread-specific informations.
-class Thread : public Object {
+class Thread : public CircularBase {
public:
/// yield - Yield the processor to another thread.
@@ -44,27 +74,22 @@
///
static int self(void);
- /// initialise - Initialise the thread implementation. Used for pthread_key.
- ///
- static void initialise(void);
-
/// kill - Kill the thread with the given pid by sending it a signal.
///
static int kill(int tid, int signo);
+
+ /// kill - Kill the given thread by sending it a signal.
+ ///
+ int kill(int signo);
/// exit - Exit the current thread.
///
static void exit(int value);
- /// start - Start the execution of a thread, creating it and setting its
- /// Thread instance.
+ /// start - Start the execution of a thread.
///
- static int start(int *tid, int (*fct)(void *), void *arg);
+ int start(void (*fct)(mvm::Thread*));
-private:
- /// threadKey - the key for accessing the thread specific data.
- ///
- static mvm::Key<Thread>* threadKey;
public:
@@ -83,29 +108,24 @@
/// threadID - The virtual machine specific thread id.
///
uint32 threadID;
-
+
/// get - Get the thread specific data of the current thread.
///
static Thread* get() {
-#if 1//defined(__PPC__) || defined(__ppc__)
- return (Thread*)Thread::threadKey->get();
-#else
- return (Thread*)mvm::jit::getExecutionEnvironment();
-#endif
+ return (Thread*)((uintptr_t)__builtin_frame_address(0) & IDMask);
}
- /// set - Set the thread specific data of the current thread.
- ///
- static void set(Thread* th) {
-#if 1//defined(__PPC__) || defined(__ppc__)
- Thread::threadKey->set(th);
-#else
- mvm::jit::setExecutionEnvironment(th);
-#endif
- }
-
private:
+ /// internalThreadID - The implementation specific thread id.
+ ///
+ void* internalThreadID;
+
+ /// internalThreadStart - The implementation sepcific thread starter
+ /// function.
+ ///
+ static void internalThreadStart(mvm::Thread* th);
+
/// internalClearException - Clear any pending exception.
virtual void internalClearException() {}
@@ -116,6 +136,13 @@
Thread* th = Thread::get();
th->internalClearException();
}
+
+ static const uint32_t IDMask = 0x7FF00000;
+
+ void* operator new(size_t sz);
+
+ void (*routine)(mvm::Thread*);
+
};
Modified: vmkit/trunk/include/mvm/VirtualMachine.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/include/mvm/VirtualMachine.h?rev=58903&r1=58902&r2=58903&view=diff
==============================================================================
--- vmkit/trunk/include/mvm/VirtualMachine.h (original)
+++ vmkit/trunk/include/mvm/VirtualMachine.h Sat Nov 8 05:48:04 2008
@@ -21,8 +21,7 @@
namespace mvm {
/// VirtualMachine - This class is the root of virtual machine classes. It
-/// defines what a VM should be. Currently, a VM only initializes itself
-/// and runs applications.
+/// defines what a VM should be.
///
class VirtualMachine : public mvm::Object {
public:
@@ -33,7 +32,9 @@
/// compile - Compile a given file to LLVM.
virtual void compile(const char* name) = 0;
-
+
+ /// waitForExit - Wait until the virtual machine stops its execution.
+ virtual void waitForExit() = 0;
static CompilationUnit* initialiseJVM(bool staticCompilation = false);
static VirtualMachine* createJVM(CompilationUnit* C = 0);
Modified: vmkit/trunk/lib/JnJVM/Classpath/ClasspathVMThread.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/Classpath/ClasspathVMThread.cpp?rev=58903&r1=58902&r2=58903&view=diff
==============================================================================
--- vmkit/trunk/lib/JnJVM/Classpath/ClasspathVMThread.cpp (original)
+++ vmkit/trunk/lib/JnJVM/Classpath/ClasspathVMThread.cpp Sat Nov 8 05:48:04 2008
@@ -40,30 +40,25 @@
return (jobject)(JavaThread::currentThread());
}
-static void start(JavaObject* vmThread) {
- // Get the classpath
- Classpath* upcalls = vmThread->classOf->classLoader->bootstrapLoader->upcalls;
-
- // When starting the thread, the creator placed the vm object in the vmThread
- Jnjvm* vm = (Jnjvm*)upcalls->vmdataVMThread->getObjectField(vmThread);
- assert(vm && "Thread Creator did not put the vm");
-
- // Classpath has set this field.
- JavaObject* javaThread = upcalls->assocThread->getObjectField(vmThread);
- assert(javaThread && "VMThread with no Java equivalent");
-
- // Create the Java thread.Allocating it on stack will make it call the
- // destructor when the function exists.
- JavaThread th(javaThread, vm, &upcalls);
-
- // Ok, now we can set the real value of vmdata, which is the JavaThread
- // object.
- vm->upcalls->vmdataVMThread->setObjectField(vmThread, (JavaObject*)(void*)&th);
+static void start(JavaThread* thread) {
+ Jnjvm* vm = thread->isolate;
+
+ // Ok, now that the thread is created we can set the the value of vmdata,
+ // which is the JavaThread object.
+ JavaField* field = vm->upcalls->vmdataVMThread;
+ JavaObject* vmThread = thread->vmThread;
+ assert(vmThread && "Didn't fix the vmThread of a jnjvm thread");
+ JavaObject* javaThread = thread->javaThread;
+ assert(javaThread && "Didn't fix the javaThread of a jnjvm thread");
+ field->setObjectField(vmThread, (JavaObject*)(void*)thread);
+
UserClass* vmthClass = (UserClass*)vmThread->classOf;
ThreadSystem& ts = vm->threadSystem;
+ // If the thread is not a daemon, it is added to the list of threads to
+ // wait until exit.
bool isDaemon = vm->upcalls->daemon->getInt8Field(javaThread);
if (!isDaemon) {
@@ -72,8 +67,10 @@
ts.nonDaemonLock.unlock();
}
- upcalls->runVMThread->invokeIntSpecial(vm, vmthClass, vmThread);
-
+ // Run the VMThread::run function
+ vm->upcalls->runVMThread->invokeIntSpecial(vm, vmthClass, vmThread);
+
+ // Remove the thread from the list.
if (!isDaemon) {
ts.nonDaemonLock.lock();
ts.nonDaemonThreads--;
@@ -91,14 +88,13 @@
Jnjvm* vm = JavaThread::get()->isolate;
JavaObject* vmThread = (JavaObject*)_vmThread;
- // Set the vm in the vmData. We do this to give the vm to the created
- // thread. The created thread will change the field to its JavaThread
- // object.
- vm->upcalls->vmdataVMThread->setObjectField(vmThread, (JavaObject*)vm);
-
- int tid = 0;
-
- mvm::Thread::start(&tid, (int (*)(void *))start, (void*)vmThread);
+ // Classpath has set this field.
+ JavaObject* javaThread = vm->upcalls->assocThread->getObjectField(vmThread);
+ assert(javaThread && "VMThread with no Java equivalent");
+
+ JavaThread* th = new JavaThread(javaThread, vmThread, vm);
+ if (!th) vm->outOfMemoryError(0);
+ th->start((void (*)(mvm::Thread*))start);
}
JNIEXPORT void JNICALL Java_java_lang_VMThread_interrupt(
Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaClass.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JavaClass.cpp?rev=58903&r1=58902&r2=58903&view=diff
==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JavaClass.cpp (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JavaClass.cpp Sat Nov 8 05:48:04 2008
@@ -92,6 +92,7 @@
nbStaticMethods = 0;
nbInterfaces = 0;
access = 0;
+ ownerClass = 0;
}
Class::Class() : CommonClass() {
@@ -276,6 +277,7 @@
virtualFields = 0;
staticFields = 0;
access = 0;
+ ownerClass = 0;
#if !defined(ISOLATE) && !defined(ISOLATE_SHARING)
this->delegatee = 0;
#endif
@@ -520,7 +522,8 @@
JavaObject* UserClass::doNew(Jnjvm* vm) {
assert(this && "No class when allocating.");
- assert((this->isReady() || classLoader->getModule()->isStaticCompiling())
+ assert((this->isInitializing() ||
+ classLoader->getModule()->isStaticCompiling())
&& "Uninitialized class when allocating.");
JavaObject* res =
(JavaObject*)vm->gcAllocator.allocateManagedObject(getVirtualSize(),
Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaClass.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JavaClass.h?rev=58903&r1=58902&r2=58903&view=diff
==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JavaClass.h (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JavaClass.h Sat Nov 8 05:48:04 2008
@@ -52,9 +52,9 @@
classRead = 1, /// The .class file has been read.
prepared = 2, /// The parents of this class has been resolved.
resolved = 3, /// The class has been resolved.
- clinitParent = 4, /// The class is cliniting its parents.
- inClinit = 5, /// The class is cliniting.
- ready = 6, /// The class is ready to be used.
+ inClinit = 4, /// The class is cliniting.
+ ready = 5, /// The class is ready to be used.
+ erroneous = 6, /// The class is in an erroneous state.
dontuseenums = 0xffffffff /// dummy value to force the enum to be int32
}JavaState;
@@ -342,11 +342,9 @@
condVar.broadcast();
}
- /// ownerClass - Is the current thread the owner of this thread?
+ /// ownerClass - Who is initializing this class.
///
- bool ownerClass() {
- return mvm::Lock::selfOwner(&lockVar);
- }
+ uint32 ownerClass;
/// lookupMethodDontThrow - Lookup a method in the method map of this class.
/// Do not throw if the method is not found.
@@ -440,7 +438,11 @@
/// isReady - Has this class been initialized?
///
bool isReady() {
- return status >= clinitParent;
+ return status == ready;
+ }
+
+ bool isInitializing() {
+ return status >= inClinit;
}
/// isResolved - Has this class been resolved?
Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaObject.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JavaObject.cpp?rev=58903&r1=58902&r2=58903&view=diff
==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JavaObject.cpp (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JavaObject.cpp Sat Nov 8 05:48:04 2008
@@ -91,7 +91,7 @@
void JavaObject::overflowThinlock() {
LockObj* obj = LockObj::allocate();
- mvm::LockRecursive::my_lock_all(&obj->lock, 257);
+ obj->lock.lockAll(257);
lock = ((uint32)obj >> 1) | 0x80000000;
}
@@ -151,7 +151,7 @@
LockObj* obj = LockObj::allocate();
uint32 val = (((uint32) obj) >> 1) | 0x80000000;
uint32 count = lock & 0xFF;
- mvm::LockRecursive::my_lock_all(&obj->lock, count + 1);
+ obj->lock.lockAll(count + 1);
lock = val;
return obj;
} else {
@@ -179,22 +179,22 @@
thread->interruptFlag = 0;
thread->isolate->interruptedException(this);
} else {
- unsigned int recur = mvm::LockRecursive::recursion_count(&l->lock);
+ unsigned int recur = l->lock.recursionCount();
bool timeout = false;
- mvm::LockRecursive::my_unlock_all(&l->lock);
+ l->lock.unlockAll();
JavaCond* cond = l->getCond();
cond->wait(thread);
thread->state = JavaThread::StateWaiting;
if (timed) {
- timeout = varcondThread.timed_wait(&mutexThread, info);
+ timeout = varcondThread.timedWait(&mutexThread, info);
} else {
varcondThread.wait(&mutexThread);
}
bool interrupted = (thread->interruptFlag != 0);
mutexThread.unlock();
- mvm::LockRecursive::my_lock_all(&l->lock, recur);
+ l->lock.lockAll(recur);
if (interrupted || timeout) {
cond->remove(thread);
Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaObject.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JavaObject.h?rev=58903&r1=58902&r2=58903&view=diff
==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JavaObject.h (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JavaObject.h Sat Nov 8 05:48:04 2008
@@ -97,7 +97,7 @@
/// owner - Returns if the current thread owns this lock.
///
bool owner() {
- return mvm::Lock::selfOwner(&lock);
+ return lock.selfOwner();
}
/// getCond - Returns the conditation variable of this lock, allocating it
Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaRuntimeJIT.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JavaRuntimeJIT.cpp?rev=58903&r1=58902&r2=58903&view=diff
==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JavaRuntimeJIT.cpp (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JavaRuntimeJIT.cpp Sat Nov 8 05:48:04 2008
@@ -40,7 +40,8 @@
uint32 index = enveloppe->index;
ctpInfo->resolveMethod(index, cl, utf8, sign);
- assert(obj->classOf->isReady() && "Class not ready in a virtual lookup.");
+ assert(obj->classOf->isInitializing() &&
+ "Class not ready in a virtual lookup.");
enveloppe->cacheLock.lock();
CacheNode* rcache = 0;
@@ -62,7 +63,7 @@
JavaMethod* dmeth = ocl->lookupMethod(utf8, sign->keyName, false, true,
&methodCl);
#ifndef ISOLATE_SHARING
- assert(dmeth->classDef->isReady() &&
+ assert(dmeth->classDef->isInitializing() &&
"Class not ready in a virtual lookup.");
#endif
if (cache->methPtr) {
@@ -128,10 +129,13 @@
JavaField* field = cl->lookupField(utf8, sign->keyName, true, true, &fieldCl);
fieldCl->initialiseClass(JavaThread::get()->isolate);
- void* ptr =
- (void*)((uint64)(((UserClass*)fieldCl)->getStaticInstance()) + field->ptrOffset);
- ctpInfo->ctpRes[index] = ptr;
+ JavaObject* obj = ((UserClass*)fieldCl)->getStaticInstance();
+
+ assert(obj && "No static instance in static field lookup");
+ void* ptr = (void*)((uint64)obj + field->ptrOffset);
+ ctpInfo->ctpRes[index] = ptr;
+
return ptr;
}
@@ -219,7 +223,8 @@
va_start(ap, index);
JavaObject* obj = va_arg(ap, JavaObject*);
va_end(ap);
- assert(obj->classOf->isReady() && "Class not ready in a virtual lookup.");
+ assert(obj->classOf->isInitializing() &&
+ "Class not ready in a virtual lookup.");
// Arg, the bytecode is buggy! Perform the lookup on the object class
// and do not update offset.
dmeth = obj->classOf->lookupMethod(utf8, sign->keyName, false, true, 0);
@@ -228,7 +233,8 @@
}
#ifndef ISOLATE_SHARING
- assert(dmeth->classDef->isReady() && "Class not ready in a virtual lookup.");
+ assert(dmeth->classDef->isInitializing() &&
+ "Class not ready in a virtual lookup.");
#endif
return (void*)dmeth->offset;
Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaThread.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JavaThread.cpp?rev=58903&r1=58902&r2=58903&view=diff
==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JavaThread.cpp (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JavaThread.cpp Sat Nov 8 05:48:04 2008
@@ -9,7 +9,6 @@
#include "mvm/JIT.h"
#include "mvm/PrintBuffer.h"
-#include "mvm/Threads/Key.h"
#include "mvm/Threads/Locks.h"
#include "mvm/Threads/Thread.h"
@@ -31,54 +30,24 @@
if (javaThread) javaThread->print(buf);
}
-JavaThread::JavaThread(JavaObject* thread, Jnjvm* vm, void* sp) {
- if (!thread) bootstrap = true;
- else bootstrap = false;
+JavaThread::JavaThread(JavaObject* thread, JavaObject* vmth, Jnjvm* vm) {
javaThread = thread;
+ vmThread = vmth;
isolate = vm;
interruptFlag = 0;
state = StateRunning;
pendingException = 0;
vmAllocator = &isolate->allocator;
- baseSP = sp;
- mvm::Thread::set(this);
- threadID = (mvm::Thread::self() << 8) & 0x7FFFFF00;
-
- if (!bootstrap) {
-#ifdef MULTIPLE_GC
- GC = isolate->GC;
- GC->inject_my_thread(sp);
-#else
- Collector::inject_my_thread(sp);
-#endif
-
#ifdef SERVICE_VM
- ServiceDomain* domain = (ServiceDomain*)vm;
- domain->startExecution();
- domain->lock->lock();
- domain->numThreads++;
- domain->lock->unlock();
+ ServiceDomain* domain = (ServiceDomain*)vm;
+ domain->startExecution();
+ domain->lock->lock();
+ domain->numThreads++;
+ domain->lock->unlock();
#endif
- }
-
-
}
-JavaThread::~JavaThread() {
- if (!bootstrap) {
-#ifdef MULTIPLE_GC
- GC->remove_my_thread();
-#else
- Collector::remove_my_thread();
-#endif
-#ifdef SERVICE_VM
- ServiceDomain* vm = (ServiceDomain*)isolate;
- vm->lock->lock();
- vm->numThreads--;
- vm->lock->unlock();
-#endif
- }
-}
+JavaThread::~JavaThread() {}
// We define these here because gcc compiles the 'throw' keyword
// differently, whether these are defined in a file or not. Since many
Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaThread.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JavaThread.h?rev=58903&r1=58902&r2=58903&view=diff
==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JavaThread.h (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JavaThread.h Sat Nov 8 05:48:04 2008
@@ -14,7 +14,6 @@
#include "mvm/Object.h"
#include "mvm/Threads/Cond.h"
-#include "mvm/Threads/Key.h"
#include "mvm/Threads/Locks.h"
#include "mvm/Threads/Thread.h"
@@ -30,6 +29,7 @@
public:
static VirtualTable *VT;
JavaObject* javaThread;
+ JavaObject* vmThread;
Jnjvm* isolate;
mvm::LockNormal lock;
mvm::Cond varcond;
@@ -38,18 +38,17 @@
uint32 interruptFlag;
uint32 state;
std::vector<jmp_buf*> sjlj_buffers;
- bool bootstrap;
static const unsigned int StateRunning;
static const unsigned int StateWaiting;
static const unsigned int StateInterrupted;
- virtual void print(mvm::PrintBuffer *buf) const;
+ void print(mvm::PrintBuffer *buf) const;
virtual void TRACER;
- JavaThread() { bootstrap = true; }
+ JavaThread() {}
~JavaThread();
- JavaThread(JavaObject* thread, Jnjvm* isolate, void* sp);
+ JavaThread(JavaObject* thread, JavaObject* vmThread, Jnjvm* isolate);
static JavaThread* get() {
return (JavaThread*)mvm::Thread::get();
@@ -94,6 +93,13 @@
longjmp((__jmp_buf_tag*)sjlj_buffers.back(), 1);
#endif
}
+
+ /// printString - Prints the class.
+ char *printString() const {
+ mvm::PrintBuffer *buf = mvm::PrintBuffer::alloc();
+ print(buf);
+ return buf->contents()->cString();
+ }
private:
virtual void internalClearException() {
Modified: vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.cpp?rev=58903&r1=58902&r2=58903&view=diff
==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.cpp (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.cpp Sat Nov 8 05:48:04 2008
@@ -46,82 +46,199 @@
typedef void (*clinit_t)(Jnjvm* vm, UserConstantPool*);
+
+/// initialiseClass - Java class initialisation. Java specification §2.17.5.
+
void UserCommonClass::initialiseClass(Jnjvm* vm) {
- // Primitives are initialized at boot time
+
+ // Assumes that the Class object has already been verified and prepared and
+ // that the Class object contains state that can indicate one of four
+ // situations:
+ //
+ // * This Class object is verified and prepared but not initialized.
+ // * This Class object is being initialized by some particular thread T.
+ // * This Class object is fully initialized and ready for use.
+ // * This Class object is in an erroneous state, perhaps because the
+ // verification step failed or because initialization was attempted and
+ // failed.
+
+ assert(status >= resolved || ownerClass || status == ready ||
+ status == erroneous && "Class in wrong state");
+
+ // Primitives are initialized at boot time, arrays are initialized directly.
if (isArray()) {
status = ready;
} else if (status != ready) {
+
+ // 1. Synchronize on the Class object that represents the class or
+ // interface to be initialized. This involves waiting until the
+ // current thread can obtain the lock for that object
+ // (Java specification §8.13).
acquire();
+ uint32 self = mvm::Thread::get()->threadID;
+
+ if (status == inClinit) {
+ // 2. If initialization by some other thread is in progress for the
+ // class or interface, then wait on this Class object (which
+ // temporarily releases the lock). When the current thread awakens
+ // from the wait, repeat this step.
+ if (ownerClass != self) {
+ while (ownerClass) {
+ waitClass();
+ }
+ release();
+ } else {
+ // 3. If initialization is in progress for the class or interface by
+ // the current thread, then this must be a recursive request for
+ // initialization. Release the lock on the Class object and complete
+ // normally.
+ release();
+ return;
+ }
+ }
+
+ // 4. If the class or interface has already been initialized, then no
+ // further action is required. Release the lock on the Class object
+ // and complete normally.
if (status == ready) {
release();
- } else if (status >= resolved && status != clinitParent &&
- status != inClinit) {
- UserClass* cl = (UserClass*)this;
- status = clinitParent;
+ return;
+ }
+
+ // 5. If the Class object is in an erroneous state, then initialization is
+ // not possible. Release the lock on the Class object and throw a
+ // NoClassDefFoundError.
+ if (status == erroneous) {
release();
- UserCommonClass* super = getSuper();
- if (super) {
+ vm->noClassDefFoundError(name);
+ }
+
+ // 6. Otherwise, record the fact that initialization of the Class object is
+ // now in progress by the current thread and release the lock on the
+ // Class object.
+ ownerClass = self;
+ status = inClinit;
+ release();
+
+
+ // 7. Next, if the Class object represents a class rather than an interface,
+ // and the direct superclass of this class has not yet been initialized,
+ // then recursively perform this entire procedure for the uninitialized
+ // superclass. If the initialization of the direct superclass completes
+ // abruptly because of a thrown exception, then lock this Class object,
+ // label it erroneous, notify all waiting threads, release the lock,
+ // and complete abruptly, throwing the same exception that resulted from
+ // the initializing the superclass.
+ UserCommonClass* super = getSuper();
+ if (super) {
+ JavaObject *exc = 0;
+ try {
super->initialiseClass(vm);
+ } catch(...) {
+ exc = JavaThread::getJavaException();
+ assert(exc && "no exception?");
+ JavaThread::clearException();
}
- cl->resolveStaticClass();
+ if (exc) {
+ acquire();
+ status = erroneous;
+ ownerClass = 0;
+ broadcastClass();
+ release();
+ throw exc;
+ }
+ }
+
+ // 8. Next, execute either the class variable initializers and static
+ // initializers of the class or the field initializers of the interface,
+ // in textual order, as though they were a single block, except that
+ // final static variables and fields of interfaces whose values are
+ // compile-time constants are initialized first.
+
+
+ UserClass* cl = (UserClass*)this;
+ cl->resolveStaticClass();
- status = inClinit;
- JavaMethod* meth = lookupMethodDontThrow(vm->bootstrapLoader->clinitName,
- vm->bootstrapLoader->clinitType,
- true, false, 0);
- PRINT_DEBUG(JNJVM_LOAD, 0, COLOR_NORMAL, "; ", 0);
- PRINT_DEBUG(JNJVM_LOAD, 0, LIGHT_GREEN, "clinit ", 0);
- PRINT_DEBUG(JNJVM_LOAD, 0, COLOR_NORMAL, "%s\n", printString());
+ PRINT_DEBUG(JNJVM_LOAD, 0, COLOR_NORMAL, "; ", 0);
+ PRINT_DEBUG(JNJVM_LOAD, 0, LIGHT_GREEN, "clinit ", 0);
+ PRINT_DEBUG(JNJVM_LOAD, 0, COLOR_NORMAL, "%s\n", printString());
- JavaObject* val =
- (JavaObject*)vm->gcAllocator.allocateManagedObject(cl->getStaticSize(),
+ JavaObject* val =
+ (JavaObject*)vm->gcAllocator.allocateManagedObject(cl->getStaticSize(),
cl->getStaticVT());
- val->initialise(cl);
- JavaField* fields = cl->getStaticFields();
- for (uint32 i = 0; i < cl->nbStaticFields; ++i) {
- fields[i].initField(val, vm);
- }
+ val->initialise(cl);
+ JavaField* fields = cl->getStaticFields();
+ for (uint32 i = 0; i < cl->nbStaticFields; ++i) {
+ fields[i].initField(val, vm);
+ }
- cl->setStaticInstance(val);
-
- if (meth) {
- JavaObject* exc = 0;
- try{
- clinit_t pred = (clinit_t)(intptr_t)meth->compiledPtr();
- pred(vm, cl->getConstantPool());
- } catch(...) {
- exc = JavaThread::getJavaException();
- assert(exc && "no exception?");
- JavaThread::clearException();
- }
- if (exc) {
- if (exc->classOf->isAssignableFrom(vm->upcalls->newException)) {
- vm->initializerError(exc);
- } else {
- JavaThread::throwException(exc);
- }
- }
- }
+ cl->setStaticInstance(val);
+
+ JavaMethod* meth = lookupMethodDontThrow(vm->bootstrapLoader->clinitName,
+ vm->bootstrapLoader->clinitType,
+ true, false, 0);
+
+ JavaObject* exc = 0;
+ if (meth) {
+ try{
+ clinit_t pred = (clinit_t)(intptr_t)meth->compiledPtr();
+ pred(vm, cl->getConstantPool());
+ } catch(...) {
+ exc = JavaThread::getJavaException();
+ assert(exc && "no exception?");
+ JavaThread::clearException();
+ }
+ }
+
+ // 9. If the execution of the initializers completes normally, then lock
+ // this Class object, label it fully initialized, notify all waiting
+ // threads, release the lock, and complete this procedure normally.
+ if (!exc) {
+ acquire();
status = ready;
+ ownerClass = 0;
broadcastClass();
- } else if (status < resolved) {
- release();
- vm->unknownError("try to clinit a not-read class...");
- } else {
- if (!ownerClass()) {
- while (status < ready) waitClass();
- release();
- initialiseClass(vm);
- }
release();
+ return;
}
+
+ // 10. Otherwise, the initializers must have completed abruptly by
+ // throwing some exception E. If the class of E is not Error or one
+ // of its subclasses, then create a new instance of the class
+ // ExceptionInInitializerError, with E as the argument, and use this
+ // object in place of E in the following step. But if a new instance of
+ // ExceptionInInitializerError cannot be created because an
+ // OutOfMemoryError occurs, then instead use an OutOfMemoryError object
+ // in place of E in the following step.
+ if (exc->classOf->isAssignableFrom(vm->upcalls->newException)) {
+ Classpath* upcalls = classLoader->bootstrapLoader->upcalls;
+ UserClass* clExcp = upcalls->ExceptionInInitializerError;
+ Jnjvm* vm = JavaThread::get()->isolate;
+ JavaObject* obj = clExcp->doNew(vm);
+ if (!obj) {
+ fprintf(stderr, "implement me");
+ abort();
+ }
+ JavaMethod* init = upcalls->ErrorWithExcpExceptionInInitializerError;
+ init->invokeIntSpecial(vm, clExcp, obj, exc);
+ exc = obj;
+ }
+
+ // 11. Lock the Class object, label it erroneous, notify all waiting
+ // threads, release the lock, and complete this procedure abruptly
+ // with reason E or its replacement as determined in the previous step.
+ acquire();
+ status = erroneous;
+ ownerClass = 0;
+ broadcastClass();
+ release();
+ throw exc;
}
}
-
-
+
void Jnjvm::errorWithExcp(UserClass* cl, JavaMethod* init, const JavaObject* excp) {
JavaObject* obj = cl->doNew(this);
init->invokeIntSpecial(this, cl, obj, excp);
@@ -338,25 +455,6 @@
extern "C" struct JNINativeInterface JNI_JNIEnvTable;
extern "C" const struct JNIInvokeInterface JNI_JavaVMTable;
-namespace jnjvm {
-
-class ClArgumentsInfo {
-public:
- uint32 appArgumentsPos;
- char* className;
- std::vector< std::pair<char*, char*> > agents;
-
- void readArgs(int argc, char** argv, Jnjvm *vm);
- void extractClassFromJar(Jnjvm* vm, int argc, char** argv, int i);
- void javaAgent(char* cur);
-
- void printInformation();
- void nyi();
- void printVersion();
-};
-
-}
-
void ClArgumentsInfo::javaAgent(char* cur) {
assert(0 && "implement me");
}
@@ -477,7 +575,7 @@
" load Java programming language agent, see java.lang.instrument\n");
}
-void ClArgumentsInfo::readArgs(int argc, char** argv, Jnjvm* vm) {
+void ClArgumentsInfo::readArgs(Jnjvm* vm) {
className = 0;
appArgumentsPos = 0;
sint32 i = 1;
@@ -734,57 +832,71 @@
}
void Jnjvm::waitForExit() {
+
threadSystem.nonDaemonLock.lock();
- --(threadSystem.nonDaemonThreads);
while (threadSystem.nonDaemonThreads) {
threadSystem.nonDaemonVar.wait(&threadSystem.nonDaemonLock);
}
+
+ threadSystem.nonDaemonLock.unlock();
- threadSystem.nonDaemonLock.unlock();
return;
}
-void Jnjvm::runApplication(int argc, char** argv) {
- ClArgumentsInfo info;
-
- info.readArgs(argc, argv, this);
- if (info.className) {
- int pos = info.appArgumentsPos;
-
- argv = argv + pos - 1;
- argc = argc - pos + 1;
-
- mvm::Thread* oldThread = mvm::Thread::get();
- JavaThread thread(0, this, oldThread->baseSP);
- bootstrapThread = &thread;
+void Jnjvm::mainJavaStart(JavaThread* thread) {
+ Jnjvm* vm = thread->isolate;
+ vm->bootstrapThread = thread;
- loadBootstrap();
+ vm->loadBootstrap();
#ifdef SERVICE_VM
- ServiceDomain::initialise((ServiceDomain*)this);
+ ServiceDomain::initialise((ServiceDomain*)vm);
#endif
-
- if (info.agents.size()) {
- assert(0 && "implement me");
- JavaObject* instrumenter = 0;//createInstrumenter();
- for (std::vector< std::pair<char*, char*> >::iterator i =
- info.agents.begin(),
- e = info.agents.end(); i!= e; ++i) {
- JavaString* args = asciizToStr(i->second);
- executePremain(i->first, args, instrumenter);
- }
+
+ ClArgumentsInfo& info = vm->argumentsInfo;
+#if 0
+ if (info.agents.size()) {
+ assert(0 && "implement me");
+ JavaObject* instrumenter = 0;//createInstrumenter();
+ for (std::vector< std::pair<char*, char*> >::iterator i =
+ info.agents.begin(),
+ e = info.agents.end(); i!= e; ++i) {
+ JavaString* args = vm->asciizToStr(i->second);
+ vm->executePremain(i->first, args, instrumenter);
}
+ }
+#endif
- UserClassArray* array = bootstrapLoader->upcalls->ArrayOfString;
- ArrayObject* args = (ArrayObject*)array->doNew(argc - 2, this);
- for (int i = 2; i < argc; ++i) {
- args->elements[i - 2] = (JavaObject*)asciizToStr(argv[i]);
- }
+ UserClassArray* array = vm->bootstrapLoader->upcalls->ArrayOfString;
+ ArrayObject* args = (ArrayObject*)array->doNew(info.argc - 2, vm);
+ for (int i = 2; i < info.argc; ++i) {
+ args->elements[i - 2] = (JavaObject*)vm->asciizToStr(info.argv[i]);
+ }
+
+ vm->executeClass(info.className, args);
+
+ vm->threadSystem.nonDaemonLock.lock();
+ --(vm->threadSystem.nonDaemonThreads);
+ if (vm->threadSystem.nonDaemonThreads == 0)
+ vm->threadSystem.nonDaemonVar.signal();
+ vm->threadSystem.nonDaemonLock.unlock();
+}
- executeClass(info.className, args);
- waitForExit();
- mvm::Thread::set(oldThread);
+void Jnjvm::runApplication(int argc, char** argv) {
+ argumentsInfo.argc = argc;
+ argumentsInfo.argv = argv;
+ argumentsInfo.readArgs(this);
+ if (argumentsInfo.className) {
+ int pos = argumentsInfo.appArgumentsPos;
+
+ argumentsInfo.argv = argumentsInfo.argv + pos - 1;
+ argumentsInfo.argc = argumentsInfo.argc - pos + 1;
+
+ bootstrapThread = new JavaThread(0, 0, this);
+ bootstrapThread->start((void (*)(mvm::Thread*))mainJavaStart);
+ } else {
+ threadSystem.nonDaemonThreads = 0;
}
}
@@ -845,14 +957,14 @@
}
}
+static const char* name;
-void Jnjvm::compile(const char* name) {
- bootstrapLoader->analyseClasspathEnv(classpath);
-
- mvm::Thread* oldThread = mvm::Thread::get();
- JavaThread thread(0, this, oldThread->baseSP);
- bootstrapThread = &thread;
+void Jnjvm::mainCompilerStart(JavaThread* th) {
+ Jnjvm* vm = th->isolate;
+ JnjvmBootstrapLoader* bootstrapLoader = vm->bootstrapLoader;
+
+ bootstrapLoader->analyseClasspathEnv(vm->classpath);
uint32 size = strlen(name);
if (size > 4 &&
@@ -862,7 +974,7 @@
std::vector<Class*> classes;
ArrayUInt8* bytes = Reader::openFile(bootstrapLoader, name);
- if (!bytes) unknownError("Can't find zip file.");
+ if (!bytes) vm->unknownError("Can't find zip file.");
ZipArchive archive(bytes, bootstrapLoader->allocator);
char* realName = (char*)alloca(4096);
@@ -876,7 +988,7 @@
ArrayUInt8* res = (ArrayUInt8*)array->doNew(file->ucsize,
bootstrapLoader->allocator);
int ok = archive.readFile(res, file);
- if (!ok) unknownError("Wrong zip file.");
+ if (!ok) vm->unknownError("Wrong zip file.");
memcpy(realName, file->filename, size);
@@ -914,5 +1026,16 @@
i->setLinkage(llvm::GlobalValue::ExternalLinkage);
}
- mvm::Thread::set(oldThread);
+ vm->threadSystem.nonDaemonLock.lock();
+ --(vm->threadSystem.nonDaemonThreads);
+ if (vm->threadSystem.nonDaemonThreads == 0)
+ vm->threadSystem.nonDaemonVar.signal();
+ vm->threadSystem.nonDaemonLock.unlock();
+
+}
+
+void Jnjvm::compile(const char* n) {
+ name = n;
+ bootstrapThread = new JavaThread(0, 0, this);
+ bootstrapThread->start((void (*)(mvm::Thread*))mainCompilerStart);
}
Modified: vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.h?rev=58903&r1=58902&r2=58903&view=diff
==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.h (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.h Sat Nov 8 05:48:04 2008
@@ -80,6 +80,23 @@
};
+class ClArgumentsInfo {
+public:
+ int argc;
+ char** argv;
+ uint32 appArgumentsPos;
+ char* className;
+ std::vector< std::pair<char*, char*> > agents;
+
+ void readArgs(Jnjvm *vm);
+ void extractClassFromJar(Jnjvm* vm, int argc, char** argv, int i);
+ void javaAgent(char* cur);
+
+ void printInformation();
+ void nyi();
+ void printVersion();
+};
+
/// Jnjvm - A JVM. Each execution of a program allocates a Jnjvm.
///
class Jnjvm : public mvm::VirtualMachine {
@@ -98,7 +115,7 @@
/// bootstrapThread - The initial thread of this JVM.
///
JavaThread* bootstrapThread;
-
+
/// error - Throws an exception in the execution of a JVM for the thread
/// that calls this functions. This is used internally by Jnjvm to control
/// which pair class/method are used.
@@ -135,15 +152,15 @@
///
void executePremain(const char* className, JavaString* args,
JavaObject* instrumenter);
-
- /// waitForExit - Waits that there are no more non-daemon threads in this JVM.
+
+ /// mainJavaStart - Starts the execution of the application in a Java thread.
///
- void waitForExit();
+ static void mainJavaStart(JavaThread* thread);
- /// runMain - Runs the application with the given command line.
+ /// mainCompileStart - Starts the static compilation of classes in a Java
+ /// thread.
///
- void runMain(int argc, char** argv);
-
+ static void mainCompilerStart(JavaThread* thread);
public:
@@ -185,7 +202,11 @@
/// control the end of the JVM's execution.
///
ThreadSystem threadSystem;
-
+
+ /// argumentsInfo - The command line arguments given to the vm
+ ///
+ ClArgumentsInfo argumentsInfo;
+
/// jniEnv - The JNI environment of this JVM.
///
void* jniEnv;
@@ -257,9 +278,7 @@
/// UTF8, thus duplicating the UTF8.
///
JavaString* internalUTF8ToStr(const UTF8* utf8);
-
-
-
+
/// asciizToInternalUTF8 - Constructs an UTF8 out of the asciiz and changes
/// '.' into '/'.
///
@@ -299,7 +318,11 @@
/// compile - Compile the .class, .zip or .jar file to LLVM IR.
///
virtual void compile(const char* name);
-
+
+ /// waitForExit - Waits that there are no more non-daemon threads in this JVM.
+ ///
+ virtual void waitForExit();
+
};
} // end namespace jnjvm
Modified: vmkit/trunk/lib/JnJVM/VMCore/JnjvmClassLoader.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JnjvmClassLoader.h?rev=58903&r1=58902&r2=58903&view=diff
==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JnjvmClassLoader.h (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JnjvmClassLoader.h Sat Nov 8 05:48:04 2008
@@ -51,6 +51,7 @@
/// table for non-isolate environments.
///
class JnjvmClassLoader : public mvm::CompilationUnit {
+ friend class Jnjvm;
private:
Modified: vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.cpp?rev=58903&r1=58902&r2=58903&view=diff
==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.cpp (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.cpp Sat Nov 8 05:48:04 2008
@@ -92,6 +92,7 @@
constant_pool_iterator I = constantPools.find(ctp);
if (I == End) {
void* ptr = ctp->ctpRes;
+ assert(ptr && "No constant pool found");
Constant* cons =
ConstantExpr::getIntToPtr(ConstantInt::get(Type::Int64Ty, uint64(ptr)),
mvm::MvmModule::ptrPtrType);
@@ -112,6 +113,7 @@
varGV = SI->second;
} else {
void* ptr = str;
+ assert(ptr && "No string given");
Constant* cons =
ConstantExpr::getIntToPtr(ConstantInt::get(Type::Int64Ty, uint64(ptr)),
JnjvmModule::JavaObjectType);
@@ -130,6 +132,7 @@
varGV = SI->second;
} else {
void* ptr = enveloppe;
+ assert(ptr && "No enveloppe given");
Constant* cons =
ConstantExpr::getIntToPtr(ConstantInt::get(Type::Int64Ty, uint64(ptr)),
JnjvmModule::EnveloppeType);
@@ -149,6 +152,7 @@
JavaObject* obj = isStaticCompiling() ? 0 :
cl->getClassDelegatee(JavaThread::get()->isolate);
+ assert(obj && "Delegatee not created");
Constant* cons =
ConstantExpr::getIntToPtr(ConstantInt::get(Type::Int64Ty, uint64(obj)),
JnjvmModule::JavaObjectType);
@@ -171,6 +175,7 @@
LLVMClassInfo* LCI = getClassInfo(classDef);
LCI->getStaticType();
JavaObject* obj = ((Class*)classDef)->getStaticInstance();
+ assert(obj && "Getting static instance before it's created!");
Constant* cons =
ConstantExpr::getIntToPtr(ConstantInt::get(Type::Int64Ty,
uint64_t (obj)), JnjvmModule::JavaObjectType);
@@ -196,6 +201,7 @@
LLVMClassInfo* LCI = getClassInfo((Class*)classDef);
LCI->getVirtualType();
}
+ assert(classDef->virtualVT && "Virtual VT not created");
Constant* cons =
ConstantExpr::getIntToPtr(ConstantInt::get(Type::Int64Ty,
uint64_t(classDef->virtualVT)),
@@ -220,6 +226,8 @@
LLVMSignatureInfo* LSI = getSignatureInfo(meth->getSignature());
const llvm::Type* valPtrType = LSI->getNativePtrType();
+
+ assert(ptr && "No native function given");
Constant* cons =
ConstantExpr::getIntToPtr(ConstantInt::get(Type::Int64Ty, uint64_t(ptr)),
@@ -980,7 +988,7 @@
OffsetStatusInClassConstant = mvm::MvmModule::constantFive;
OffsetCtpInClassConstant = mvm::MvmModule::constantSix;
- ClassReadyConstant = ConstantInt::get(Type::Int32Ty, clinitParent);
+ ClassReadyConstant = ConstantInt::get(Type::Int32Ty, ready);
LLVMAssessorInfo::initialise();
}
Modified: vmkit/trunk/lib/JnJVM/VMCore/JnjvmModuleProvider.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JnjvmModuleProvider.cpp?rev=58903&r1=58902&r2=58903&view=diff
==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JnjvmModuleProvider.cpp (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JnjvmModuleProvider.cpp Sat Nov 8 05:48:04 2008
@@ -98,7 +98,7 @@
uint64_t offset = LMI->getOffset()->getZExtValue();
assert(meth->classDef->isResolved() && "Class not resolved");
#ifndef ISOLATE_SHARING
- assert(meth->classDef->isReady() && "Class not ready");
+ assert(meth->classDef->isInitializing() && "Class not ready");
#endif
assert(meth->classDef->virtualVT && "Class has no VT");
assert(meth->classDef->virtualTableSize > offset &&
@@ -247,17 +247,17 @@
JnjvmModuleProvider::JnjvmModuleProvider(JnjvmModule *m) {
TheModule = (Module*)m;
- mvm::MvmModule::protectEngine->lock();
+ mvm::MvmModule::protectEngine.lock();
mvm::MvmModule::executionEngine->addModuleProvider(this);
- mvm::MvmModule::protectEngine->unlock();
+ mvm::MvmModule::protectEngine.unlock();
perFunctionPasses = new llvm::FunctionPassManager(this);
perFunctionPasses->add(new llvm::TargetData(m));
AddStandardCompilePasses(m, perFunctionPasses);
}
JnjvmModuleProvider::~JnjvmModuleProvider() {
- mvm::MvmModule::protectEngine->lock();
+ mvm::MvmModule::protectEngine.lock();
mvm::MvmModule::executionEngine->removeModuleProvider(this);
- mvm::MvmModule::protectEngine->unlock();
+ mvm::MvmModule::protectEngine.unlock();
delete TheModule;
}
Modified: vmkit/trunk/lib/JnJVM/VMCore/LowerConstantCalls.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/LowerConstantCalls.cpp?rev=58903&r1=58902&r2=58903&view=diff
==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/LowerConstantCalls.cpp (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/LowerConstantCalls.cpp Sat Nov 8 05:48:04 2008
@@ -249,7 +249,7 @@
Value* Status = new LoadInst(StatusPtr, "", CI);
- Value* test = new ICmpInst(ICmpInst::ICMP_UGT, Status,
+ Value* test = new ICmpInst(ICmpInst::ICMP_EQ, Status,
jnjvm::JnjvmModule::ClassReadyConstant,
"", CI);
Modified: vmkit/trunk/lib/JnJVM/VMCore/VirtualTables.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/VirtualTables.cpp?rev=58903&r1=58902&r2=58903&view=diff
==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/VirtualTables.cpp (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/VirtualTables.cpp Sat Nov 8 05:48:04 2008
@@ -108,6 +108,12 @@
if (l) l->MARK_AND_TRACE;
}
+static void traceClassMap(ClassMap* classes) {
+ for (ClassMap::iterator i = classes->map.begin(), e = classes->map.end();
+ i!= e; ++i) {
+ i->second->CALL_TRACER;
+ }
+}
void JavaThread::TRACER {
javaThread->MARK_AND_TRACE;
@@ -121,24 +127,7 @@
#if defined(ISOLATE_SHARING)
JnjvmSharedLoader::sharedLoader->MARK_AND_TRACE;
#endif
-}
-
-static void traceClassMap(ClassMap* classes) {
- for (ClassMap::iterator i = classes->map.begin(), e = classes->map.end();
- i!= e; ++i) {
- i->second->CALL_TRACER;
- }
-}
-
-void JnjvmClassLoader::TRACER {
- javaLoader->MARK_AND_TRACE;
- traceClassMap(classes);
- isolate->MARK_AND_TRACE;
- TRACE_VECTOR(JavaString*, gc_allocator, strings);
-}
-
-void JnjvmBootstrapLoader::TRACER {
- traceClassMap(classes);
+ traceClassMap(bootstrapLoader->classes);
#define TRACE_DELEGATEE(prim) \
prim->delegatee->MARK_AND_TRACE
@@ -154,9 +143,25 @@
TRACE_DELEGATEE(upcalls->OfDouble);
#undef TRACE_DELEGATEE
+ TRACE_VECTOR(JavaString*, gc_allocator, bootstrapLoader->strings);
+
+ if (bootstrapThread) {
+ bootstrapThread->CALL_TRACER;
+ for (JavaThread* th = (JavaThread*)bootstrapThread->next();
+ th != bootstrapThread; th = (JavaThread*)th->next())
+ th->CALL_TRACER;
+ }
+}
+
+void JnjvmClassLoader::TRACER {
+ javaLoader->MARK_AND_TRACE;
+ traceClassMap(classes);
+ isolate->MARK_AND_TRACE;
TRACE_VECTOR(JavaString*, gc_allocator, strings);
}
+void JnjvmBootstrapLoader::TRACER {}
+
#if defined(ISOLATE_SHARING)
void UserClass::TRACER {
classLoader->MARK_AND_TRACE;
Modified: vmkit/trunk/lib/Mvm/CommonThread/ctlock.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/Mvm/CommonThread/ctlock.cpp?rev=58903&r1=58902&r2=58903&view=diff
==============================================================================
--- vmkit/trunk/lib/Mvm/CommonThread/ctlock.cpp (original)
+++ vmkit/trunk/lib/Mvm/CommonThread/ctlock.cpp Sat Nov 8 05:48:04 2008
@@ -16,224 +16,110 @@
using namespace mvm;
-inline int atomic_test_and_pass(unsigned int *ptr) {
+Lock::Lock(bool recursive) {
+ pthread_mutexattr_t attr;
-#if defined(__ppc__) || defined(__powerpc__)
- int result;
-# if defined(__MACH__)
- const int val=1;
-
- asm volatile("1:\n"
-#if 0
- " lwz %0,0(%1)\n" /* result <- ptr[0] */
- " cmpwi %0,0\n"
- " bne 1b\n"
+ // Initialize the mutex attributes
+ int errorcode = pthread_mutexattr_init(&attr);
+ assert(errorcode == 0);
+
+ // Initialize the mutex as a recursive mutex, if requested, or normal
+ // otherwise.
+ int kind = ( recursive ? PTHREAD_MUTEX_RECURSIVE : PTHREAD_MUTEX_NORMAL );
+ errorcode = pthread_mutexattr_settype(&attr, kind);
+ assert(errorcode == 0);
+
+#if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__) && \
+ !defined(__DragonFly__)
+ // Make it a process local mutex
+ errorcode = pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_PRIVATE);
#endif
- " lwarx %0,0,%1\n" /* result <- ptr[0] */
- " cmpwi %0,0\n"
- " bne 1b\n"
- " stwcx. %2,0,%1\n" /* ptr[0] <- 1 (si pas d'autre accès) */
- " bne- 1b\n"
- " isync\n" /* empeche toute execution d'instruction après le lock!!! */
- :"=&r"(result): "r"(ptr), "r"(val): "cr0", "memory");
- /* le & empeche gcc d'utiliser le même register pour result et les entrées... */
-# else
- const int val=1;
-
- asm volatile("1:\n"
- " lwarx %0,0,%1\n" /* result <- ptr[0] */
- " cmpwi %0,0\n"
- " bne 1b\n"
- " stwcx. %2,0,%1\n" /* ptr[0] <- 1 (si pas d'autre accès) */
- " bne- 1b\n"
- " isync\n" /* empeche toute execution d'instruction après le lock!!! */
- :"=&r"(result): "r"(ptr), "r"(val): "cr0", "memory");
- /* le & empeche gcc d'utiliser le même register pour result et les entrées... */
-# endif
-
- return result;
-#elif defined(__i386__)
- // asm ("bts $1, %1; sbbl %0, %0":"=r" (result):"m" (*ptr):"memory");
- unsigned int old;
- int c=0;
- do {
- asm volatile("movl $1,%0;"
- "xchgl %0, %1" : "=&r"(old) : "m"(*ptr));
- if(!old)
- return 0;
- if(!(++c & 0xf))
- Thread::yield();
- } while(1);
-#else
-#error "I do not know how to do an atomic test and pass on your machine"
-#endif
-}
-Lock *Lock::allocRecursive() {
- return new LockRecursive();
-}
+ // Initialize the mutex
+ errorcode = pthread_mutex_init(&internalLock, &attr);
+ assert(errorcode == 0);
-Lock *Lock::allocNormal() {
- return new LockNormal();
-}
+ // Destroy the attributes
+ errorcode = pthread_mutexattr_destroy(&attr);
+ assert(errorcode == 0);
-void Lock::destroy(Lock *l) {
+ owner = 0;
}
-bool Lock::selfOwner(Lock *l) {
- return l->owner() == Thread::self();
+Lock::~Lock() {
+ pthread_mutex_destroy((pthread_mutex_t*)&internalLock);
}
-int Lock::getOwner(Lock *l) {
- return l->owner();
+bool Lock::selfOwner() {
+ return owner == Thread::self();
}
-void SpinLock::slock() {
- atomic_test_and_pass(&value);
+int Lock::getOwner() {
+ return owner;
}
-void LockNormal::my_lock(Lock *l) {
- unsigned int c = 0;
-
- l->slock();
-
- while(l->owner()) {
- l->sunlock();
- Thread::yield(&c);
- l->slock();
- }
- l->owner(Thread::self());
- l->sunlock();
+void LockNormal::lock() {
+ pthread_mutex_lock((pthread_mutex_t*)&internalLock);
+ owner = (int)pthread_self();
}
-void LockNormal::my_unlock(Lock *l) {
- l->owner(0);
+void LockNormal::unlock() {
+ owner = 0;
+ pthread_mutex_unlock((pthread_mutex_t*)&internalLock);
}
-int LockNormal::my_trylock(Lock *) {
- ctfatal("not implemented");
- return -1;
+void LockRecursive::lock() {
+ pthread_mutex_lock((pthread_mutex_t*)&internalLock);
+ if (!owner) owner = (int)pthread_self();
+ ++n;
}
-void LockRecursive::my_lock(Lock *l) {
- unsigned int c = 0;
-
- int self = Thread::self();
-
- l->slock();
- while(l->owner() && (l->owner() != self)) {
- l->sunlock();
- Thread::yield(&c);
- l->slock();
- }
- l->owner(self);
- ((LockRecursive *)l)->n++;
- l->sunlock();
+void LockRecursive::unlock() {
+ --n;
+ owner = 0;
+ pthread_mutex_unlock((pthread_mutex_t*)&internalLock);
}
- void LockRecursive::my_unlock(Lock *l) {
- if(!--((LockRecursive *)l)->n)
- l->owner(0);
- }
-
-int LockRecursive::my_trylock(Lock *) {
- ctfatal("not implemented");
- return -1;
+int LockRecursive::unlockAll() {
+ int res = n;
+ while (n) unlock();
+ return res;
}
-int LockRecursive::recursion_count(Lock *l){
- return ((LockRecursive*)l)->n;
+void LockRecursive::lockAll(int count) {
+ for (int i = 0; i < count; ++i) lock();
}
-int LockRecursive::my_unlock_all(Lock *l){
- int count = ((LockRecursive*)l)->n;
- ((LockRecursive*)l)->n = 0;
- l->owner(0);
- return count;
+Cond::Cond() {
+ int errorcode = pthread_cond_init((pthread_cond_t*)&internalCond, NULL);
+ assert(errorcode == 0);
}
-void LockRecursive::my_lock_all(Lock *l, int count){
- LockRecursive::my_lock(l);
- ((LockRecursive*)l)->n = count;
-}
-
-
-
-
-void Cond::wait(Lock *l) {
- unsigned int n=0;
- unsigned int my_barrier = no_barrier;
-
- n_wait++; /* un attente de plus */
- while(1) {
- if(no_barrier == my_barrier) /* pas de broadcast */
- if(go) { /* un signal? */
- n_wait--; /* pus une attente en moins */
- go--; /* pour le pochain */
- return;
- } else { /* à l'ouest rien de nouveau */
- l->unlock(); /* je rend gentillement le lock */
- Thread::yield(&n); /* j'attends qu'on me libère... */
- l->lock(); /* je reprends mon lock */
- }
- else /* on a eu un broadcast */
- return;
- }
-}
-
-int Cond::timed_wait(Lock *l, struct timeval *ref) {
- unsigned int n=0;
- unsigned int my_barrier = no_barrier;
- struct timeval max, cur;
-
- gettimeofday(&max, 0);
- timeradd(&max, ref, &max);
-
- n_wait++;
- while(1) {
- if(no_barrier == my_barrier) /* pas de broadcast */
- if(go) { /* un signal? */
- n_wait--; /* puis une attente en moins */
- go--; /* pour le pochain */
- return 0;
- } else { /* à l'ouest rien de nouveau */
- gettimeofday(&cur, 0);
- if(timercmp(&cur, &max, >=)) {/* timesout écoulé */
- n_wait--; /* on n'attend plus */
- return 1; /* c'est nif */
- }
-
- l->unlock();
- timersub(&max, &cur, &cur); /* le reste */
- if(!cur.tv_sec && (cur.tv_usec <= 2))
- Thread::yield(); /* j'attends qu'on me libère... */
- else
- Thread::yield(&n); /* j'attends qu'on me libère... */
- l->lock(); /* je reprends mon lock */
- }
- else /* on a eu un broadcast */
- return 0;
- }
+Cond::~Cond() {
+ pthread_cond_destroy((pthread_cond_t*)&internalCond);
}
void Cond::broadcast() {
- no_barrier++;
- n_wait = 0;
-}
-
-void Cond::signal() {
- if(n_wait>go) go++;
+ pthread_cond_broadcast((pthread_cond_t*)&internalCond);
}
-
-extern "C" void lock_C(Lock* l) {
- return l->lock();
+void Cond::wait(Lock* l) {
+ pthread_cond_wait((pthread_cond_t*)&internalCond,
+ (pthread_mutex_t*)&(l->internalLock));
}
-extern "C" void unlock_C(Lock* l) {
- return l->unlock();
+void Cond::signal() {
+ pthread_cond_signal((pthread_cond_t*)&internalCond);
}
-Cond* Cond::allocCond() {
- return new Cond();
+int Cond::timedWait(Lock* l, struct timeval *ref) {
+
+ struct timespec timeout;
+ struct timeval now;
+ struct timezone tz;
+ gettimeofday(&now, &tz);
+ timeout.tv_sec = now.tv_sec + ref->tv_sec;
+ timeout.tv_nsec = now.tv_usec + ref->tv_usec;
+ return pthread_cond_timedwait((pthread_cond_t*)&internalCond,
+ (pthread_mutex_t*)&(l->internalLock), &timeout);
}
Modified: vmkit/trunk/lib/Mvm/CommonThread/ctthread.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/Mvm/CommonThread/ctthread.cpp?rev=58903&r1=58902&r2=58903&view=diff
==============================================================================
--- vmkit/trunk/lib/Mvm/CommonThread/ctthread.cpp (original)
+++ vmkit/trunk/lib/Mvm/CommonThread/ctthread.cpp Sat Nov 8 05:48:04 2008
@@ -7,12 +7,12 @@
//
//===----------------------------------------------------------------------===//
-#include "mvm/Threads/Key.h"
#include "mvm/Threads/Thread.h"
#include <pthread.h>
#include <signal.h>
#include <time.h>
+#include <sys/mman.h>
using namespace mvm;
@@ -20,11 +20,7 @@
sched_yield();
}
-int Thread::self() {
- return (int)pthread_self();
-}
-
-void Thread::yield(unsigned int *c) {
+ void Thread::yield(unsigned int *c) {
if(++(*c) & 3)
sched_yield();
else {
@@ -35,44 +31,152 @@
}
}
+int Thread::self() {
+ return (int)pthread_self();
+}
+
int Thread::kill(int tid, int signo) {
return pthread_kill((pthread_t)tid, signo);
}
+int Thread::kill(int signo) {
+ return pthread_kill((pthread_t)internalThreadID, signo);
+}
+
void Thread::exit(int value) {
pthread_exit((void*)value);
}
-void* ThreadKey::get() {
- pthread_key_t k = (pthread_key_t)val;
- return (void *)pthread_getspecific(k);
-}
+// These could be set at runtime.
+#define STACK_SIZE 0x100000
+#define NR_THREADS 255
-void ThreadKey::set(void *v) {
- pthread_key_t k = (pthread_key_t)val;
- pthread_setspecific(k, v);
-}
-ThreadKey::ThreadKey(void (*_destr)(void *)) {
- pthread_key_create((pthread_key_t*)&val, _destr);
-}
+/// StackThreadManager - This class allocates all stacks for threads. Because
+/// we want fast access to thread local data, and can not rely on platform
+/// dependent thread local storage (eg pthread keys are inefficient, tls is
+/// specific to Linux), we put thread local data at the bottom of the
+/// stack. A simple mask computes the thread local data , based on the current
+/// stack pointer.
+//
+/// The stacks are allocated at boot time. They must all be in the memory range
+/// 0x?0000000 and Ox(?+1)0000000, so that the thread local data can be computed
+/// and threads have a unique ID.
+///
+class StackThreadManager {
+public:
+ uintptr_t baseAddr;
+ uint32 allocPtr;
+ uint32 used[NR_THREADS];
+ LockNormal lock;
+
+ StackThreadManager() {
+ baseAddr = 0;
+ uintptr_t ptr = 0x00000000;
+
+ // Do an mmap at a fixed address. If the mmap fails for a given address
+ // use the next one.
+ while (!baseAddr && ptr != 0xF0000000) {
+ ptr = ptr + 0x10000000;
+#if defined (__MACH__)
+ uint32 flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED;
+#else
+ uint32 flags = MAP_PRIVATE | MAP_ANON | MAP_FIXED;
+#endif
+ baseAddr = (uintptr_t)mmap((void*)ptr, STACK_SIZE * NR_THREADS,
+ PROT_READ | PROT_WRITE, flags, 0, 0);
+ if (baseAddr == (uintptr_t)MAP_FAILED) baseAddr = 0;
+ }
+ if (!baseAddr) {
+ fprintf(stderr, "Can not allocate thread memory\n");
+ abort();
+ }
+
+ // Protect the page after the first page. The first page contains thread
+ // specific data. The second page has no access rights to catch stack
+ // overflows.
+ uint32 pagesize = getpagesize();
+ for (uint32 i = 0; i < NR_THREADS; ++i) {
+ uintptr_t addr = baseAddr + (i * STACK_SIZE) + pagesize;
+ mprotect((void*)addr, pagesize, PROT_NONE);
+ }
-ThreadKey::ThreadKey() {
- pthread_key_create((pthread_key_t*)&val, NULL);
-}
+ memset((void*)used, 0, NR_THREADS);
+ allocPtr = 0;
+ }
-void ThreadKey::initialise() {
- pthread_key_create((pthread_key_t*)&val, NULL);
-}
+ uintptr_t allocate() {
+ uint32 start = allocPtr;
+ bool found = false;
+ uint32 myAllocPtr = allocPtr;
+ do {
+ found = __sync_bool_compare_and_swap(&used[myAllocPtr], 0, 1);
+ myAllocPtr++;
+ if (myAllocPtr == NR_THREADS) myAllocPtr = 0;
+ } while (myAllocPtr != start && !found);
+
+ if (found) {
+ allocPtr = myAllocPtr;
+ return baseAddr + (myAllocPtr - 1) * STACK_SIZE;
+ }
+
+ return 0;
+ }
+
+};
+
+
+/// Static allocate a stack manager. In the future, this should be virtual
+/// machine specific.
+StackThreadManager TheStackManager;
+
+/// internalThreadStart - The initial function called by a thread. Sets some
+/// thread specific data, registers the thread to the GC and calls the
+/// given routine of th.
+///
+void Thread::internalThreadStart(mvm::Thread* th) {
+ th->internalThreadID = (void*)pthread_self();
+ th->threadID = (int)th & mvm::Thread::IDMask;
+ th->baseSP = &th;
+
+#ifdef MULTIPLE_GC
+ GC->inject_my_thread(th);
+#else
+ Collector::inject_my_thread(th);
+#endif
+
+
+ th->routine(th);
+
+#ifdef MULTIPLE_GC
+ GC->remove_my_thread(th);
+#else
+ Collector::remove_my_thread(th);
+#endif
-void Thread::initialise() {
- Thread::threadKey = new mvm::Key<Thread>();
- Thread* th = new Thread();
- mvm::Thread::set(th);
}
-int Thread::start(int *tid, int (*fct)(void *), void *arg) {
- int res = pthread_create((pthread_t *)tid, 0, (void * (*)(void *))fct, arg);
+/// start - Called by the creator of the thread to run the new thread.
+/// The thread is in a detached state, because each virtual machine has
+/// its own way of waiting for created threads.
+int Thread::start(void (*fct)(mvm::Thread*)) {
+ pthread_attr_t attributs;
+ pthread_attr_init(&attributs);
+ pthread_attr_setstack(&attributs, this, STACK_SIZE);
+ pthread_t tid;
+ routine = fct;
+ int res = pthread_create(&tid, &attributs,
+ (void* (*)(void *))internalThreadStart, this);
pthread_detach(*(pthread_t *)tid);
+ pthread_attr_destroy(&attributs);
return res;
}
+
+
+/// operator new - Get a stack from the stack manager. The Thread object
+/// will be placed in the first page at the bottom of the stack. Hence
+/// Thread objects can not exceed a page.
+void* Thread::operator new(size_t sz) {
+ assert(sz < (size_t)getpagesize() && "Thread local data too big");
+ return (void*)TheStackManager.allocate();
+}
Modified: vmkit/trunk/lib/Mvm/GCMmap2/MvmGC.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/Mvm/GCMmap2/MvmGC.h?rev=58903&r1=58902&r2=58903&view=diff
==============================================================================
--- vmkit/trunk/lib/Mvm/GCMmap2/MvmGC.h (original)
+++ vmkit/trunk/lib/Mvm/GCMmap2/MvmGC.h Sat Nov 8 05:48:04 2008
@@ -32,6 +32,10 @@
#define MARK_AND_TRACE markAndTrace()
#endif
+namespace mvm {
+ class Thread;
+}
+
class Collector;
class gc : public gcRoot {
@@ -74,7 +78,7 @@
#endif
typedef void (*markerFn)(void*);
- static void initialise(markerFn mark, void *base_sp);
+ static void initialise(markerFn mark);
STATIC void destroy();
STATIC void die_if_sigsegv_occured_during_collection(void *addr);
@@ -84,8 +88,8 @@
STATIC void gcStats(size_t &no, size_t &nbb);
STATIC void maybeCollect();
STATIC void collect(void);
- STATIC void inject_my_thread(void *sp);
- STATIC void remove_my_thread();
+ STATIC void inject_my_thread(mvm::Thread* th);
+ STATIC void remove_my_thread(mvm::Thread* th);
#ifdef MULTIPLE_GC
static Collector* allocate();
#endif
Removed: vmkit/trunk/lib/Mvm/GCMmap2/ctcircular.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/Mvm/GCMmap2/ctcircular.h?rev=58902&view=auto
==============================================================================
--- vmkit/trunk/lib/Mvm/GCMmap2/ctcircular.h (original)
+++ vmkit/trunk/lib/Mvm/GCMmap2/ctcircular.h (removed)
@@ -1,57 +0,0 @@
-//===------------- ctcircular.h - Mvm Garbage Collector -------------------===//
-//
-// Mvm
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef _CT_CIRCULAR_H_
-#define _CT_CIRCULAR_H_
-
-#include "ctosdep.h"
-
-
-class CircularBase {
- CircularBase *_next;
- CircularBase *_prev;
-public:
- inline CircularBase *next() { return _next; }
- inline CircularBase *prev() { return _prev; }
-
- inline void next(CircularBase *n) { _next = n; }
- inline void prev(CircularBase *p) { _prev = p; }
-
- inline CircularBase() { alone(); }
- inline explicit CircularBase(CircularBase *p) { append(p); }
-
- inline void remove() {
- _prev->_next = _next;
- _next->_prev = _prev;
- alone();
- }
-
- inline void append(CircularBase *p) {
- _prev = p;
- _next = p->_next;
- _next->_prev = this;
- _prev->_next = this;
- }
-
- inline void alone() { _prev = _next = this; }
-};
-
-class Circular : public CircularBase, public TObj {
-public:
- inline Circular() : CircularBase() {}
- inline Circular(Circular *p) : CircularBase(p) {}
- inline ~Circular() {
- if(prev() != this) {
- next()->prev(prev());
- delete next();
- }
- }
-};
-
-#endif
Modified: vmkit/trunk/lib/Mvm/GCMmap2/gc.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/Mvm/GCMmap2/gc.cpp?rev=58903&r1=58902&r2=58903&view=diff
==============================================================================
--- vmkit/trunk/lib/Mvm/GCMmap2/gc.cpp (original)
+++ vmkit/trunk/lib/Mvm/GCMmap2/gc.cpp Sat Nov 8 05:48:04 2008
@@ -111,29 +111,18 @@
COLLECTOR gcStats(&no, &nbb);
}
-void Collector::initialise(markerFn marker, void *base_sp) {
-#ifdef MULTIPLE_GC
- GCCollector* GC = new GCCollector();
- GCCollector::bootstrapGC = GC;
- mvm::Thread::get()->GC = GC;
- GC->initialise(marker);
- GC->inject_my_thread(base_sp);
-#else
+void Collector::initialise(markerFn marker) {
GCCollector::initialise(marker);
- GCCollector::inject_my_thread(base_sp);
-#endif
- mvm::Thread::get()->baseSP = base_sp;
}
void Collector::destroy() {
COLLECTOR destroy();
}
-void Collector::inject_my_thread(void *base_sp) {
+void Collector::inject_my_thread(mvm::Thread* th) {
#ifdef HAVE_PTHREAD
- COLLECTOR inject_my_thread(base_sp);
+ COLLECTOR inject_my_thread(th);
#endif
- mvm::Thread::get()->baseSP = base_sp;
}
void Collector::maybeCollect() {
@@ -182,9 +171,9 @@
//onMemoryError = &COLLECTOR defaultMemoryError;
}
-void Collector::remove_my_thread() {
+void Collector::remove_my_thread(mvm::Thread* th) {
#ifdef HAVE_PTHREAD
- COLLECTOR remove_thread(COLLECTOR threads->myloc());
+ COLLECTOR remove_thread(th);
#endif
}
@@ -200,9 +189,10 @@
#else
#define COLLECTOR GCCollector::
#endif
+ mvm::Thread* th = mvm::Thread::get();
unsigned int cm = COLLECTOR current_mark;
- if(Thread::self() != collector_tid) {
+ if(th != current_collector) {
collectorGo();
while((COLLECTOR current_mark == cm) &&
(COLLECTOR status == COLLECTOR stat_collect))
@@ -224,18 +214,18 @@
#else
#define COLLECTOR GCCollector::
#endif
- GCThreadCollector *loc = COLLECTOR threads->myloc();
-
+ mvm::Thread* th = mvm::Thread::get();
+
jmp_buf buf;
setjmp(buf);
COLLECTOR threads->stackLock();
- if(!loc) /* a key is being destroyed */
+ if(!th) /* The thread is being destroyed */
COLLECTOR threads->another_mark();
else {
register unsigned int **cur = (unsigned int**)(void*)&buf;
- register unsigned int **max = loc->base_sp();
+ register unsigned int **max = (unsigned int**)th->baseSP;
GCChunkNode *node;
Modified: vmkit/trunk/lib/Mvm/GCMmap2/gccollector.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/Mvm/GCMmap2/gccollector.h?rev=58903&r1=58902&r2=58903&view=diff
==============================================================================
--- vmkit/trunk/lib/Mvm/GCMmap2/gccollector.h (original)
+++ vmkit/trunk/lib/Mvm/GCMmap2/gccollector.h Sat Nov 8 05:48:04 2008
@@ -113,9 +113,9 @@
static int siggc();
#ifdef HAVE_PTHREAD
- STATIC void inject_my_thread(void *base_sp);
- STATIC inline void remove_thread(GCThreadCollector *loc) {
- threads->remove(loc);
+ STATIC void inject_my_thread(mvm::Thread* th);
+ STATIC inline void remove_thread(mvm::Thread* th) {
+ threads->remove(th);
}
STATIC inline int isStable(gc_lock_recovery_fct_t fct, int a0, int a1, int a2,
int a3, int a4, int a5, int a6, int a7) {
Modified: vmkit/trunk/lib/Mvm/GCMmap2/gcinit.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/Mvm/GCMmap2/gcinit.cpp?rev=58903&r1=58902&r2=58903&view=diff
==============================================================================
--- vmkit/trunk/lib/Mvm/GCMmap2/gcinit.cpp (original)
+++ vmkit/trunk/lib/Mvm/GCMmap2/gcinit.cpp Sat Nov 8 05:48:04 2008
@@ -80,42 +80,9 @@
allocator = 0;
}
-
-static void *get_curr_fp(void)
-{
- register void *fp;
- asm(
-# if defined(__ppc__) || defined(__PPC__)
-# if defined(__MACH__)
- "mr %0, r1"
-# else
- "mr %0, 1"
-# endif
-# elif defined(__i386__)
- "movl %%ebp, %0"
-# elif defined(__amd64__)
- "movq %%rbp, %0"
-# else
-# error:
-# error: I do not know how to read the frame pointer on this machine
-# error:
-# endif
- :"=r"(fp):);
- return fp;
-}
-
-static void *get_base_sp(void)
-{
- void *fp= 0;
- for (fp= get_curr_fp(); (*(void **)fp); fp= *(void **)fp) {}
- return fp;
-}
-
#ifdef HAVE_PTHREAD
-void GCCollector::inject_my_thread(void *base_sp) {
- if(!base_sp)
- base_sp = get_base_sp();
- threads->inject(base_sp, current_mark);
+void GCCollector::inject_my_thread(mvm::Thread* th) {
+ threads->inject(th);
}
#endif
Modified: vmkit/trunk/lib/Mvm/GCMmap2/gcthread.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/Mvm/GCMmap2/gcthread.cpp?rev=58903&r1=58902&r2=58903&view=diff
==============================================================================
--- vmkit/trunk/lib/Mvm/GCMmap2/gcthread.cpp (original)
+++ vmkit/trunk/lib/Mvm/GCMmap2/gcthread.cpp Sat Nov 8 05:48:04 2008
@@ -19,27 +19,27 @@
}
void GCThread::synchronize() {
- GCThreadCollector *cur;
int signo = GCCollector::siggc();
- int reached = 0;
- collector_tid = Thread::self();
-
+ mvm::Thread* self = mvm::Thread::get();
+ assert(self && "No thread local data for this thread");
+ current_collector = self;
_nb_collected = 0;
- for(cur=(GCThreadCollector *)base.next(); cur!=&base; cur=(GCThreadCollector *)cur->next()) {
- int t = cur->tid();
- if(t != Thread::self())
- Thread::kill(cur->tid(), signo);
- else
- reached = 1;
+
+ for(mvm::Thread* cur = (mvm::Thread*)self->next(); cur != self;
+ cur = (mvm::Thread*)cur->next()) {
+ cur->kill(signo);
}
- if(reached) /* moi aussi je dois collecter... */
- GCCollector::siggc_handler(signo);
- waitStacks();
+
+ GCCollector::siggc_handler(signo);
+
+ waitStacks();
}
-int GCLockRecovery::verify_recall(gc_lock_recovery_fct_t fct, int a0, int a1, int a2, int a3, int a4, int a5, int a6, int a7) {
- if(owner() == Thread::self()) {
- _fct = fct; _args[0] = a0; _args[1] = a1; _args[2] = a2; _args[3] = a3;
+int GCLockRecovery::verify_recall(gc_lock_recovery_fct_t fct, int a0, int a1,
+ int a2, int a3, int a4, int a5, int a6,
+ int a7) {
+ if(selfOwner()) {
+ _fct = fct; _args[0] = a0; _args[1] = a1; _args[2] = a2; _args[3] = a3;
_args[4] = a4; _args[5] = a5; _args[6] = a6; _args[7] = a7;
return 0;
} else
Modified: vmkit/trunk/lib/Mvm/GCMmap2/gcthread.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/Mvm/GCMmap2/gcthread.h?rev=58903&r1=58902&r2=58903&view=diff
==============================================================================
--- vmkit/trunk/lib/Mvm/GCMmap2/gcthread.h (original)
+++ vmkit/trunk/lib/Mvm/GCMmap2/gcthread.h Sat Nov 8 05:48:04 2008
@@ -10,43 +10,12 @@
#ifndef _GC_THREAD_H_
#define _GC_THREAD_H_
-#include "ctcircular.h"
#include "mvm/Threads/Cond.h"
-#include "mvm/Threads/Key.h"
#include "mvm/Threads/Locks.h"
-#include "mvm/Threads/Thread.h" // only for self
-
-// class GCAllocator;
+#include "mvm/Threads/Thread.h"
namespace mvm {
-class GCThreadCollector : public CircularBase {
- void *_base_sp;
- int _tid;
-
-public:
-#ifdef SERVICE_GC
- void* meta;
-#endif
- inline GCThreadCollector() {}
- inline GCThreadCollector(GCThreadCollector *pred, int t, void *p, int m) : CircularBase(pred) {
- _base_sp = p;
- _tid = t;
-#ifdef SERVICE_GC
- meta = 0;
-#endif
- }
-
- /* This function is only called in two cases:
- * 1) When a thread quits, in which case everything is already done.
- * 2) When the collector quits, in which case all memory is freed.
- */
- inline ~GCThreadCollector() {}
-
- inline int tid() { return _tid; }
- inline unsigned int **base_sp() { return (unsigned int **)_base_sp; }
-};
-
class GCLockRecovery : public LockNormal {
gc_lock_recovery_fct_t _fct;
int _args[8];
@@ -54,10 +23,11 @@
public:
inline GCLockRecovery() { _fct = 0; }
- int verify_recall(gc_lock_recovery_fct_t fct, int a0, int a1, int a2, int a3, int a4, int a5, int a6, int a7);
+ int verify_recall(gc_lock_recovery_fct_t fct, int a0, int a1, int a2, int a3,
+ int a4, int a5, int a6, int a7);
inline void unlock_dont_recovery() {
- if(owner() == Thread::self()) {
+ if(selfOwner()) {
LockNormal::unlock();
}
}
@@ -66,8 +36,8 @@
if(_fct) {
gc_lock_recovery_fct_t tmp = _fct;
int l[8];
- l[0] = _args[0]; l[1] = _args[1]; l[2] = _args[2]; l[3] = _args[3];
- l[4] = _args[4]; l[5] = _args[5]; l[6] = _args[6]; l[7] = _args[7];
+ l[0] = _args[0]; l[1] = _args[1]; l[2] = _args[2]; l[3] = _args[3];
+ l[4] = _args[4]; l[5] = _args[5]; l[6] = _args[6]; l[7] = _args[7];
_fct = 0;
LockNormal::unlock();
tmp(l[0], l[1], l[2], l[3], l[4], l[5], l[6], l[7]);
@@ -77,28 +47,44 @@
};
class GCThread {
- GCLockRecovery _globalLock; /* global lock for gcmalloc */
- LockNormal _stackLock; /* stack lock for synchronization */
- Cond _stackCond; /* condition for unlocking other tasks (write protect) */
- Cond _collectionCond;/* condition for unblocking the collecter */
- unsigned int _nb_threads; /* number of active threads */
- unsigned int _nb_collected; /* number of threads collected */
- int collector_tid; /* don't synchonize this one */
+ /// _globalLoc - Global lock for gcmalloc.
+ GCLockRecovery _globalLock;
+
+ /// _stackLock - Stack lock for synchronization.
+ LockNormal _stackLock;
+
+ /// _stackCond - Condition for unlocking other tasks (write protect).
+ Cond _stackCond;
+
+ /// _collectionCond - Condition for unblocking the collector.
+ Cond _collectionCond;
+
+ /// _nb_threads - Number of active threads.
+ unsigned int _nb_threads;
+
+ /// _nb_collected - Number of threads collected.
+ unsigned int _nb_collected;
+
+ /// current_collector - The initiating thread for collection. Don't
+ /// synchonize this one.
+ mvm::Thread* current_collector;
public:
- GCThreadCollector base;
- Key<GCThreadCollector> _loc;
+ mvm::Thread* base;
+
GCThread() {
_nb_threads = 0;
_nb_collected = 0;
- collector_tid = 0;
+ current_collector = 0;
+ base = 0;
}
inline void lock() { _globalLock.lock(); }
inline void unlock() { _globalLock.unlock(); }
inline void unlock_dont_recovery() { _globalLock.unlock_dont_recovery(); }
- inline int isStable(gc_lock_recovery_fct_t fct, int a0, int a1, int a2, int a3, int a4, int a5, int a6, int a7) {
+ inline int isStable(gc_lock_recovery_fct_t fct, int a0, int a1, int a2,
+ int a3, int a4, int a5, int a6, int a7) {
return _globalLock.verify_recall(fct, a0, a1, a2, a3, a4, a5, a6, a7);
}
@@ -110,34 +96,34 @@
inline void collectionFinished() { _collectionCond.broadcast(); }
inline void collectorGo() { _stackCond.broadcast(); }
- inline void cancel() {
- _nb_collected = _nb_threads; /* all stacks have been collected */
- collectorGo(); /* unblock all threads in stack collection */
- collectionFinished(); /* unblock mutators */
+ inline void cancel() {
+ // all stacks have been collected
+ _nb_collected = _nb_threads;
+ // unblock all threads in stack collection
+ collectorGo();
+ // unblock mutators
+ collectionFinished();
}
- inline GCThreadCollector *myloc() { return _loc.get(); }
-
inline void another_mark() { _nb_collected++; }
void synchronize();
- inline void remove(GCThreadCollector *loc) {
+ inline void remove(mvm::Thread* th) {
lock();
- loc->remove();
+ th->remove();
_nb_threads--;
- delete loc;
+ if (!_nb_threads) base = 0;
unlock();
}
- inline void inject(void *sp, int m) {
- GCThreadCollector *me = _loc.get();
- if(me)
- gcfatal("thread %d is already in pool for allocator %p", Thread::self(), this);
- lock(); /* the new should be protected */
- me = new GCThreadCollector(&base, Thread::self(), sp, m);
+ inline void inject(mvm::Thread* th) {
+ lock();
+ if (base)
+ th->append(base);
+ else
+ base = th;
_nb_threads++;
- _loc.set(me);
unlock();
}
};
Modified: vmkit/trunk/lib/Mvm/Runtime/JIT.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/Mvm/Runtime/JIT.cpp?rev=58903&r1=58902&r2=58903&view=diff
==============================================================================
--- vmkit/trunk/lib/Mvm/Runtime/JIT.cpp (original)
+++ vmkit/trunk/lib/Mvm/Runtime/JIT.cpp Sat Nov 8 05:48:04 2008
@@ -78,14 +78,6 @@
(uintptr_t)executionEngine->getPointerToFunction(
module.getFunction("runtime.llvm.atomic.cmp.swap.i64"));
- executionEnvironment = module.getGlobalVariable("executionEnvironment");
- getExecutionEnvironment = (mvm::Thread* (*)())
- (uintptr_t)executionEngine->getPointerToFunction(
- module.getFunction("getExecutionEnvironment"));
- setExecutionEnvironment = (void (*)(mvm::Thread*))
- (uintptr_t)executionEngine->getPointerToFunction(
- module.getFunction("setExecutionEnvironment"));
-
// Type declaration
ptrType = PointerType::getUnqual(Type::Int8Ty);
ptr32Type = PointerType::getUnqual(Type::Int32Ty);
@@ -134,8 +126,6 @@
constantPtrNull = Constant::getNullValue(ptrType);
constantPtrSize = ConstantInt::get(Type::Int32Ty, sizeof(void*));
arrayPtrType = PointerType::getUnqual(ArrayType::get(Type::Int8Ty, 0));
-
- protectEngine = mvm::Lock::allocNormal();
}
@@ -203,7 +193,7 @@
}
llvm::ExecutionEngine* MvmModule::executionEngine;
-mvm::Lock* MvmModule::protectEngine;
+mvm::LockNormal MvmModule::protectEngine;
llvm::ConstantInt* MvmModule::constantInt8Zero;
llvm::ConstantInt* MvmModule::constantZero;
@@ -264,10 +254,6 @@
uint64 val);
-llvm::GlobalVariable* MvmModule::executionEnvironment;
-mvm::Thread* (*MvmModule::getExecutionEnvironment)();
-void (*MvmModule::setExecutionEnvironment)(mvm::Thread*);
-
uint64 MvmModule::getTypeSize(const llvm::Type* type) {
return executionEngine->getTargetData()->getABITypeSize(type);
}
Modified: vmkit/trunk/lib/Mvm/Runtime/LLVMRuntime.ll
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/Mvm/Runtime/LLVMRuntime.ll?rev=58903&r1=58902&r2=58903&view=diff
==============================================================================
--- vmkit/trunk/lib/Mvm/Runtime/LLVMRuntime.ll (original)
+++ vmkit/trunk/lib/Mvm/Runtime/LLVMRuntime.ll Sat Nov 8 05:48:04 2008
@@ -100,21 +100,3 @@
%A = call i64 @llvm.atomic.cmp.swap.i64.p0i64( i64* %ptr, i64 %cmp, i64 %swap)
ret i64 %A
}
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;;;;;;;;;;;;;;;;;;;; TLS for the execution environment ;;;;;;;;;;;;;;;;;;;;;;;;
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-%Thread = type {%VT*, i32}
-
- at executionEnvironment = thread_local global %Thread* null
-
-define %Thread* @getExecutionEnvironment() nounwind readnone {
- %E = load %Thread** @executionEnvironment
- ret %Thread* %E
-}
-
-define void @setExecutionEnvironment(%Thread* %E) nounwind {
- store %Thread* %E, %Thread** @executionEnvironment
- ret void
-}
Modified: vmkit/trunk/lib/Mvm/Runtime/Object.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/Mvm/Runtime/Object.cpp?rev=58903&r1=58902&r2=58903&view=diff
==============================================================================
--- vmkit/trunk/lib/Mvm/Runtime/Object.cpp (original)
+++ vmkit/trunk/lib/Mvm/Runtime/Object.cpp Sat Nov 8 05:48:04 2008
@@ -14,7 +14,6 @@
#include "mvm/Method.h"
#include "mvm/Object.h"
#include "mvm/PrintBuffer.h"
-#include "mvm/Threads/Key.h"
#include "mvm/Threads/Thread.h"
using namespace mvm;
@@ -23,8 +22,6 @@
VirtualTable *NativeString::VT = 0;
VirtualTable *PrintBuffer::VT = 0;
-mvm::Key<mvm::Thread>* mvm::Thread::threadKey = 0;
-
void Object::initialise() {
# define INIT(X) { \
Modified: vmkit/trunk/lib/N3/VMCore/CLIJit.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/N3/VMCore/CLIJit.cpp?rev=58903&r1=58902&r2=58903&view=diff
==============================================================================
--- vmkit/trunk/lib/N3/VMCore/CLIJit.cpp (original)
+++ vmkit/trunk/lib/N3/VMCore/CLIJit.cpp Sat Nov 8 05:48:04 2008
@@ -1503,9 +1503,9 @@
}
void CLIJit::initialiseAppDomain(N3* vm) {
- mvm::MvmModule::protectEngine->lock();
+ mvm::MvmModule::protectEngine.lock();
mvm::MvmModule::executionEngine->addModuleProvider(vm->TheModuleProvider);
- mvm::MvmModule::protectEngine->unlock();
+ mvm::MvmModule::protectEngine.unlock();
}
namespace n3 {
@@ -1517,9 +1517,9 @@
void CLIJit::initialiseBootstrapVM(N3* vm) {
mvm::MvmModule* module = vm->module;
- module->protectEngine->lock();
+ module->protectEngine.lock();
module->executionEngine->addModuleProvider(vm->TheModuleProvider);
- module->protectEngine->unlock();
+ module->protectEngine.unlock();
n3::llvm_runtime::makeLLVMModuleContents(module);
Modified: vmkit/trunk/lib/N3/VMCore/LockedMap.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/N3/VMCore/LockedMap.h?rev=58903&r1=58902&r2=58903&view=diff
==============================================================================
--- vmkit/trunk/lib/N3/VMCore/LockedMap.h (original)
+++ vmkit/trunk/lib/N3/VMCore/LockedMap.h Sat Nov 8 05:48:04 2008
@@ -123,7 +123,7 @@
static VirtualTable* VT;
static ClassNameMap* allocate() {
ClassNameMap* map = gc_new(ClassNameMap)();
- map->lock = mvm::Lock::allocNormal();
+ map->lock = new mvm::LockNormal();
return map;
}
};
@@ -134,7 +134,7 @@
static VirtualTable* VT;
static ClassTokenMap* allocate() {
ClassTokenMap* map = gc_new(ClassTokenMap)();
- map->lock = mvm::Lock::allocNormal();
+ map->lock = new mvm::LockNormal();
return map;
}
@@ -146,7 +146,7 @@
static VirtualTable* VT;
static FieldTokenMap* allocate() {
FieldTokenMap* map = gc_new(FieldTokenMap)();
- map->lock = mvm::Lock::allocNormal();
+ map->lock = new mvm::LockNormal();
return map;
}
};
@@ -157,7 +157,7 @@
static VirtualTable* VT;
static MethodTokenMap* allocate() {
MethodTokenMap* map = gc_new(MethodTokenMap)();
- map->lock = mvm::Lock::allocNormal();
+ map->lock = new mvm::LockNormal();
return map;
}
};
@@ -168,7 +168,7 @@
static VirtualTable* VT;
static AssemblyMap* allocate() {
AssemblyMap* map = gc_new(AssemblyMap)();
- map->lock = mvm::Lock::allocNormal();
+ map->lock = new mvm::LockNormal();
return map;
}
};
@@ -180,7 +180,7 @@
static VirtualTable* VT;
static StringMap* allocate() {
StringMap* map = gc_new(StringMap)();
- map->lock = mvm::Lock::allocRecursive();
+ map->lock = new mvm::LockRecursive();
return map;
}
};
@@ -191,7 +191,7 @@
static VirtualTable* VT;
static FunctionMap* allocate() {
FunctionMap* map = gc_new(FunctionMap)();
- map->lock = mvm::Lock::allocNormal();
+ map->lock = new mvm::LockNormal();
return map;
}
};
@@ -222,7 +222,7 @@
static UTF8Map* allocate() {
UTF8Map* map = gc_new(UTF8Map)();
- map->lock = mvm::Lock::allocNormal();
+ map->lock = new mvm::LockNormal();
return map;
}
Modified: vmkit/trunk/lib/N3/VMCore/MSCorlib.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/N3/VMCore/MSCorlib.cpp?rev=58903&r1=58902&r2=58903&view=diff
==============================================================================
--- vmkit/trunk/lib/N3/VMCore/MSCorlib.cpp (original)
+++ vmkit/trunk/lib/N3/VMCore/MSCorlib.cpp Sat Nov 8 05:48:04 2008
@@ -195,7 +195,7 @@
extern "C" void System_GC_Collect() {
#ifdef MULTIPLE_GC
- mvm::Thread::get()->GC->collect();
+ VMThread::get()->GC->collect();
#else
Collector::collect();
#endif
Modified: vmkit/trunk/lib/N3/VMCore/N3.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/N3/VMCore/N3.cpp?rev=58903&r1=58902&r2=58903&view=diff
==============================================================================
--- vmkit/trunk/lib/N3/VMCore/N3.cpp (original)
+++ vmkit/trunk/lib/N3/VMCore/N3.cpp Sat Nov 8 05:48:04 2008
@@ -60,28 +60,16 @@
N3* N3::allocateBootstrap() {
N3 *vm= gc_new(N3)();
-#ifdef MULTIPLE_GC
- Collector* GC = Collector::allocate();
-#endif
-
std::string str =
mvm::MvmModule::executionEngine->getTargetData()->getStringRepresentation();
vm->module = new mvm::MvmModule("Bootstrap N3");
vm->module->setDataLayout(str);
- vm->protectModule = mvm::Lock::allocNormal();
+ vm->protectModule = new mvm::LockNormal();
vm->functions = FunctionMap::allocate();
vm->TheModuleProvider = new N3ModuleProvider(vm->module, vm->functions);
CLIJit::initialiseBootstrapVM(vm);
- vm->bootstrapThread = VMThread::allocate(0, vm);
- vm->bootstrapThread->baseSP = mvm::Thread::get()->baseSP;
-#ifdef MULTIPLE_GC
- vm->bootstrapThread->GC = GC;
- mvm::MvmModule::memoryManager->addGCForModule(vm->module, GC);
-#endif
- VMThread::set(vm->bootstrapThread);
-
vm->name = "bootstrapN3";
vm->hashUTF8 = UTF8Map::allocate();
vm->hashStr = StringMap::allocate();
@@ -95,26 +83,15 @@
N3* N3::allocate(const char* name, N3* parent) {
N3 *vm= gc_new(N3)();
-#ifdef MULTIPLE_GC
- Collector* GC = Collector::allocate();
-#endif
-
std::string str =
mvm::MvmModule::executionEngine->getTargetData()->getStringRepresentation();
vm->module = new mvm::MvmModule("App Domain");
vm->module->setDataLayout(str);
- vm->protectModule = mvm::Lock::allocNormal();
+ vm->protectModule = new mvm::LockNormal();
vm->functions = FunctionMap::allocate();
vm->TheModuleProvider = new N3ModuleProvider(vm->module, vm->functions);
CLIJit::initialiseAppDomain(vm);
- vm->bootstrapThread = VMThread::allocate(0, vm);
- vm->bootstrapThread->baseSP = mvm::Thread::get()->baseSP;
-#ifdef MULTIPLE_GC
- vm->bootstrapThread->GC = GC;
- mvm::MvmModule::memoryManager->addGCForModule(vm->module, GC);
-#endif
- VMThread::set(vm->bootstrapThread);
vm->threadSystem = ThreadSystem::allocateThreadSystem();
vm->name = name;
@@ -153,22 +130,6 @@
return res;
}
-namespace n3 {
-
-class ClArgumentsInfo {
-public:
- uint32 appArgumentsPos;
- char* assembly;
-
- void readArgs(int argc, char** argv, N3 *vm);
-
- void printInformation();
- void nyi();
- void printVersion();
-};
-
-}
-
void ClArgumentsInfo::nyi() {
fprintf(stdout, "Not yet implemented\n");
}
@@ -203,7 +164,6 @@
void N3::waitForExit() {
threadSystem->nonDaemonLock->lock();
- --(threadSystem->nonDaemonThreads);
while (threadSystem->nonDaemonThreads) {
threadSystem->nonDaemonVar->wait(threadSystem->nonDaemonLock);
@@ -249,25 +209,43 @@
}
void N3::runMain(int argc, char** argv) {
- ClArgumentsInfo info;
+ ClArgumentsInfo& info = argumentsInfo;
info.readArgs(argc, argv, this);
if (info.assembly) {
- argv = argv + info.appArgumentsPos - 1;
- argc = argc - info.appArgumentsPos + 1;
+ info.argv = argv + info.appArgumentsPos - 1;
+ info.argc = argc - info.appArgumentsPos + 1;
- MSCorlib::loadBootstrap(this);
- ArrayObject* args = ArrayObject::acons(argc - 2, MSCorlib::arrayString);
- for (int i = 2; i < argc; ++i) {
- args->setAt(i - 2, (VMObject*)asciizToStr(argv[i]));
- }
- try{
- executeAssembly(info.assembly, args);
- }catch(...) {
- VMObject* exc = VMThread::get()->pendingException;
- printf("N3 caught %s\n", exc->printString());
- }
- waitForExit();
+ bootstrapThread = VMThread::TheThread;
+ bootstrapThread->vm = this;
+ bootstrapThread->start((void (*)(mvm::Thread*))mainCLIStart);
+
+ } else {
+ --(threadSystem->nonDaemonThreads);
}
}
+
+void N3::mainCLIStart(VMThread* th) {
+ N3* vm = (N3*)th->vm;
+ MSCorlib::loadBootstrap(vm);
+
+ ClArgumentsInfo& info = vm->argumentsInfo;
+ ArrayObject* args = ArrayObject::acons(info.argc - 2, MSCorlib::arrayString);
+ for (int i = 2; i < info.argc; ++i) {
+ args->setAt(i - 2, (VMObject*)vm->asciizToStr(info.argv[i]));
+ }
+
+ try{
+ vm->executeAssembly(info.assembly, args);
+ }catch(...) {
+ VMObject* exc = th->pendingException;
+ printf("N3 caught %s\n", exc->printString());
+ }
+
+ vm->threadSystem->nonDaemonLock->lock();
+ --(vm->threadSystem->nonDaemonThreads);
+ if (vm->threadSystem->nonDaemonThreads == 0)
+ vm->threadSystem->nonDaemonVar->signal();
+ vm->threadSystem->nonDaemonLock->unlock();
+}
Modified: vmkit/trunk/lib/N3/VMCore/N3.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/N3/VMCore/N3.h?rev=58903&r1=58902&r2=58903&view=diff
==============================================================================
--- vmkit/trunk/lib/N3/VMCore/N3.h (original)
+++ vmkit/trunk/lib/N3/VMCore/N3.h Sat Nov 8 05:48:04 2008
@@ -22,6 +22,7 @@
class Assembly;
class AssemblyMap;
class FunctionMap;
+class N3;
class N3ModuleProvider;
class StringMap;
class UTF8;
@@ -32,6 +33,21 @@
class VMField;
class VMMethod;
+class ClArgumentsInfo {
+public:
+ int argc;
+ char** argv;
+ uint32 appArgumentsPos;
+ char* assembly;
+
+ void readArgs(int argc, char** argv, N3 *vm);
+
+ void printInformation();
+ void nyi();
+ void printVersion();
+};
+
+
class N3 : public VirtualMachine {
public:
static VirtualTable* VT;
@@ -43,6 +59,7 @@
Assembly* constructAssembly(const UTF8* name);
Assembly* lookupAssembly(const UTF8* name);
+ ClArgumentsInfo argumentsInfo;
const char* name;
StringMap * hashStr;
AssemblyMap* loadedAssemblies;
@@ -58,7 +75,8 @@
Assembly* loadAssembly(const UTF8* name, const char* extension);
void executeAssembly(const char* name, ArrayObject* args);
void runMain(int argc, char** argv);
- void waitForExit();
+ virtual void waitForExit();
+ static void mainCLIStart(VMThread* th);
static N3* bootstrapVM;
Modified: vmkit/trunk/lib/N3/VMCore/N3Initialise.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/N3/VMCore/N3Initialise.cpp?rev=58903&r1=58902&r2=58903&view=diff
==============================================================================
--- vmkit/trunk/lib/N3/VMCore/N3Initialise.cpp (original)
+++ vmkit/trunk/lib/N3/VMCore/N3Initialise.cpp Sat Nov 8 05:48:04 2008
@@ -220,14 +220,15 @@
}
+VMThread* VMThread::TheThread = 0;
static void initialiseStatics() {
CLIJit::initialise();
- VMObject::globalLock = mvm::Lock::allocNormal();
+ VMObject::globalLock = new mvm::LockNormal();
N3* vm = N3::bootstrapVM = N3::allocateBootstrap();
-
+ VMThread::TheThread = VMThread::allocate(0, vm);
vm->assemblyPath.push_back("");
@@ -337,7 +338,6 @@
}
void VirtualMachine::runApplication(int argc, char** argv) {
- mvm::Thread::set(this->bootstrapThread);
((N3*)this)->runMain(argc, argv);
}
Modified: vmkit/trunk/lib/N3/VMCore/VMCache.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/N3/VMCore/VMCache.cpp?rev=58903&r1=58902&r2=58903&view=diff
==============================================================================
--- vmkit/trunk/lib/N3/VMCore/VMCache.cpp (original)
+++ vmkit/trunk/lib/N3/VMCore/VMCache.cpp Sat Nov 8 05:48:04 2008
@@ -61,7 +61,7 @@
Enveloppe* enveloppe = gc_new(Enveloppe)();
enveloppe->firstCache = CacheNode::allocate();
enveloppe->firstCache->enveloppe = enveloppe;
- enveloppe->cacheLock = mvm::Lock::allocNormal();
+ enveloppe->cacheLock = new mvm::LockNormal();
enveloppe->originalMethod = meth;
return enveloppe;
}
Modified: vmkit/trunk/lib/N3/VMCore/VMClass.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/N3/VMCore/VMClass.cpp?rev=58903&r1=58902&r2=58903&view=diff
==============================================================================
--- vmkit/trunk/lib/N3/VMCore/VMClass.cpp (original)
+++ vmkit/trunk/lib/N3/VMCore/VMClass.cpp Sat Nov 8 05:48:04 2008
@@ -56,7 +56,7 @@
}
bool VMCommonClass::ownerClass() {
- return mvm::Lock::selfOwner(lockVar);
+ return lockVar->selfOwner();
}
@@ -160,8 +160,8 @@
void VMCommonClass::initialise(VirtualMachine* vm, bool isArray) {
- this->lockVar = mvm::Lock::allocRecursive();
- this->condVar = mvm::Cond::allocCond();
+ this->lockVar = new mvm::LockRecursive();
+ this->condVar = new mvm::Cond();
this->delegatee = 0;
this->status = hashed;
this->vm = vm;
Modified: vmkit/trunk/lib/N3/VMCore/VMObject.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/N3/VMCore/VMObject.cpp?rev=58903&r1=58902&r2=58903&view=diff
==============================================================================
--- vmkit/trunk/lib/N3/VMCore/VMObject.cpp (original)
+++ vmkit/trunk/lib/N3/VMCore/VMObject.cpp Sat Nov 8 05:48:04 2008
@@ -77,7 +77,7 @@
LockObj* LockObj::allocate() {
LockObj* res = gc_new(LockObj)();
- res->lock = mvm::Lock::allocRecursive();
+ res->lock = new mvm::LockRecursive();
res->varcond = VMCond::allocate();
return res;
}
@@ -91,7 +91,7 @@
}
bool LockObj::owner() {
- return mvm::Lock::selfOwner(lock);
+ return lock->selfOwner();
}
void VMObject::print(mvm::PrintBuffer* buf) const {
@@ -142,21 +142,21 @@
thread->interruptFlag = 0;
thread->vm->interruptedException(this);
} else {
- unsigned int recur = mvm::LockRecursive::recursion_count(l->lock);
+ unsigned int recur = l->lock->recursionCount();
bool timeout = false;
- mvm::LockRecursive::my_unlock_all(l->lock);
+ l->lock->unlockAll();
l->varcond->wait(thread);
thread->state = VMThread::StateWaiting;
if (timed) {
- timeout = varcondThread->timed_wait(mutexThread, info);
+ timeout = varcondThread->timedWait(mutexThread, info);
} else {
varcondThread->wait(mutexThread);
}
bool interrupted = (thread->interruptFlag != 0);
mutexThread->unlock();
- mvm::LockRecursive::my_lock_all(l->lock, recur);
+ l->lock->lockAll(recur);
if (interrupted || timeout) {
l->varcond->remove(thread);
Modified: vmkit/trunk/lib/N3/VMCore/VMObject.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/N3/VMCore/VMObject.h?rev=58903&r1=58902&r2=58903&view=diff
==============================================================================
--- vmkit/trunk/lib/N3/VMCore/VMObject.h (original)
+++ vmkit/trunk/lib/N3/VMCore/VMObject.h Sat Nov 8 05:48:04 2008
@@ -48,7 +48,7 @@
class LockObj : public mvm::Object {
public:
static VirtualTable* VT;
- mvm::Lock *lock;
+ mvm::LockRecursive *lock;
VMCond* varcond;
virtual void print(mvm::PrintBuffer* buf) const;
Modified: vmkit/trunk/lib/N3/VMCore/VMThread.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/N3/VMCore/VMThread.cpp?rev=58903&r1=58902&r2=58903&view=diff
==============================================================================
--- vmkit/trunk/lib/N3/VMCore/VMThread.cpp (original)
+++ vmkit/trunk/lib/N3/VMCore/VMThread.cpp Sat Nov 8 05:48:04 2008
@@ -11,7 +11,6 @@
#include "mvm/JIT.h"
#include "mvm/PrintBuffer.h"
-#include "mvm/Threads/Key.h"
#include "mvm/Threads/Locks.h"
#include "mvm/Threads/Thread.h"
@@ -42,18 +41,14 @@
perFunctionPasses = 0;
}
-VMThread* VMThread::get() {
- return (VMThread*)mvm::Thread::get();
-}
-
extern void AddStandardCompilePasses(llvm::FunctionPassManager*);
VMThread* VMThread::allocate(VMObject* thread, VirtualMachine* vm) {
- VMThread* key = gc_new(VMThread)();
+ VMThread* key = new VMThread();
key->vmThread = thread;
key->vm = vm;
- key->lock = mvm::Lock::allocNormal();
- key->varcond = mvm::Cond::allocCond();
+ key->lock = new mvm::LockNormal();
+ key->varcond = new mvm::Cond();
key->interruptFlag = 0;
key->state = StateRunning;
key->self = mvm::Thread::self();
Modified: vmkit/trunk/lib/N3/VMCore/VMThread.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/N3/VMCore/VMThread.h?rev=58903&r1=58902&r2=58903&view=diff
==============================================================================
--- vmkit/trunk/lib/N3/VMCore/VMThread.h (original)
+++ vmkit/trunk/lib/N3/VMCore/VMThread.h Sat Nov 8 05:48:04 2008
@@ -16,7 +16,6 @@
#include "mvm/Object.h"
#include "mvm/Threads/Cond.h"
-#include "mvm/Threads/Key.h"
#include "mvm/Threads/Locks.h"
#include "mvm/Threads/Thread.h"
@@ -50,7 +49,12 @@
~VMThread();
VMThread();
- static VMThread* get();
+ // Temporary solution until N3 can cleanly bootstrap itself and
+ // implement threads.
+ static VMThread* TheThread;
+ static VMThread* get() {
+ return TheThread;
+ }
static VMThread* allocate(VMObject* thread, VirtualMachine* vm);
static VMObject* currentThread();
Modified: vmkit/trunk/lib/N3/VMCore/VirtualMachine.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/N3/VMCore/VirtualMachine.cpp?rev=58903&r1=58902&r2=58903&view=diff
==============================================================================
--- vmkit/trunk/lib/N3/VMCore/VirtualMachine.cpp (original)
+++ vmkit/trunk/lib/N3/VMCore/VirtualMachine.cpp Sat Nov 8 05:48:04 2008
@@ -78,8 +78,8 @@
ThreadSystem* ThreadSystem::allocateThreadSystem() {
ThreadSystem* res = gc_new(ThreadSystem)();
res->nonDaemonThreads = 1;
- res->nonDaemonLock = mvm::Lock::allocNormal();
- res->nonDaemonVar = mvm::Cond::allocCond();
+ res->nonDaemonLock = new mvm::LockNormal();
+ res->nonDaemonVar = new mvm::Cond();
return res;
}
Modified: vmkit/trunk/lib/N3/VMCore/VirtualMachine.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/N3/VMCore/VirtualMachine.h?rev=58903&r1=58902&r2=58903&view=diff
==============================================================================
--- vmkit/trunk/lib/N3/VMCore/VirtualMachine.h (original)
+++ vmkit/trunk/lib/N3/VMCore/VirtualMachine.h Sat Nov 8 05:48:04 2008
@@ -128,6 +128,9 @@
virtual void runApplication(int argc, char** argv);
virtual void compile(const char* name);
+ virtual void waitForExit() {
+ // Currently unimplemented.
+ }
};
Modified: vmkit/trunk/lib/N3/VMCore/VirtualTables.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/N3/VMCore/VirtualTables.cpp?rev=58903&r1=58902&r2=58903&view=diff
==============================================================================
--- vmkit/trunk/lib/N3/VMCore/VirtualTables.cpp (original)
+++ vmkit/trunk/lib/N3/VMCore/VirtualTables.cpp Sat Nov 8 05:48:04 2008
@@ -209,7 +209,10 @@
}
void VMCond::TRACER {
- TRACE_VECTOR(VMThread*, threads, std::allocator);
+ for (std::vector<VMThread*, std::allocator<VMThread*> >::iterator i = threads.begin(), e = threads.end();
+ i!= e; ++i) {
+ (*i)->CALL_TRACER;
+ }
}
void LockObj::TRACER {
@@ -234,8 +237,12 @@
threadSystem->MARK_AND_TRACE;
hashUTF8->MARK_AND_TRACE;
functions->MARK_AND_TRACE;
- //protectModule->MARK_AND_TRACE;
- bootstrapThread->MARK_AND_TRACE;
+ if (bootstrapThread) {
+ bootstrapThread->CALL_TRACER;
+ for (VMThread* th = (VMThread*)bootstrapThread->next();
+ th != bootstrapThread; th = (VMThread*)th->next())
+ th->CALL_TRACER;
+ }
}
void Param::TRACER {
Modified: vmkit/trunk/tools/jnjvm/Main.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/tools/jnjvm/Main.cpp?rev=58903&r1=58902&r2=58903&view=diff
==============================================================================
--- vmkit/trunk/tools/jnjvm/Main.cpp (original)
+++ vmkit/trunk/tools/jnjvm/Main.cpp Sat Nov 8 05:48:04 2008
@@ -19,16 +19,15 @@
int main(int argc, char **argv, char **envp) {
llvm::llvm_shutdown_obj X;
- int base;
MvmModule::initialise();
Object::initialise();
- Thread::initialise();
- Collector::initialise(0, &base);
+ Collector::initialise(0);
CompilationUnit* CU = VirtualMachine::initialiseJVM();
VirtualMachine* vm = VirtualMachine::createJVM(CU);
vm->runApplication(argc, argv);
+ vm->waitForExit();
return 0;
}
Modified: vmkit/trunk/tools/n3-mono/Main.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/tools/n3-mono/Main.cpp?rev=58903&r1=58902&r2=58903&view=diff
==============================================================================
--- vmkit/trunk/tools/n3-mono/Main.cpp (original)
+++ vmkit/trunk/tools/n3-mono/Main.cpp Sat Nov 8 05:48:04 2008
@@ -19,16 +19,15 @@
int main(int argc, char **argv, char **envp) {
llvm::llvm_shutdown_obj X;
- int base;
MvmModule::initialise();
Object::initialise();
- Thread::initialise();
- Collector::initialise(0, &base);
+ Collector::initialise(0);
VirtualMachine::initialiseCLIVM();
VirtualMachine* vm = VirtualMachine::createCLIVM();
vm->runApplication(argc, argv);
+ vm->waitForExit();
return 0;
}
Modified: vmkit/trunk/tools/n3-pnetlib/Main.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/tools/n3-pnetlib/Main.cpp?rev=58903&r1=58902&r2=58903&view=diff
==============================================================================
--- vmkit/trunk/tools/n3-pnetlib/Main.cpp (original)
+++ vmkit/trunk/tools/n3-pnetlib/Main.cpp Sat Nov 8 05:48:04 2008
@@ -19,16 +19,15 @@
int main(int argc, char **argv, char **envp) {
llvm::llvm_shutdown_obj X;
- int base;
MvmModule::initialise();
Object::initialise();
- Thread::initialise();
- Collector::initialise(0, &base);
+ Collector::initialise(0);
VirtualMachine::initialiseCLIVM();
VirtualMachine* vm = VirtualMachine::createCLIVM();
vm->runApplication(argc, argv);
+ vm->waitForExit();
return 0;
}
Modified: vmkit/trunk/tools/vmjc/vmjc.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/tools/vmjc/vmjc.cpp?rev=58903&r1=58902&r2=58903&view=diff
==============================================================================
--- vmkit/trunk/tools/vmjc/vmjc.cpp (original)
+++ vmkit/trunk/tools/vmjc/vmjc.cpp Sat Nov 8 05:48:04 2008
@@ -54,7 +54,6 @@
int main(int argc, char **argv) {
llvm_shutdown_obj X; // Call llvm_shutdown() on exit.
- int base;
try {
cl::ParseCommandLineOptions(argc, argv, "vmkit .class -> .ll compiler\n");
sys::PrintStackTraceOnErrorSignal();
@@ -70,14 +69,13 @@
mvm::MvmModule::initialise();
mvm::Object::initialise();
- mvm::Thread::initialise();
- Collector::initialise(0, &base);
+ Collector::initialise(0);
Collector::enable(0);
mvm::CompilationUnit* CU = mvm::VirtualMachine::initialiseJVM(true);
mvm::VirtualMachine* vm = mvm::VirtualMachine::createJVM(CU);
vm->compile(InputFilename.c_str());
-
+ vm->waitForExit();
if (DontPrint) {
// Just use stdout. We won't actually print anything on it.
Modified: vmkit/trunk/tools/vmkit/Launcher.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/tools/vmkit/Launcher.cpp?rev=58903&r1=58902&r2=58903&view=diff
==============================================================================
--- vmkit/trunk/tools/vmkit/Launcher.cpp (original)
+++ vmkit/trunk/tools/vmkit/Launcher.cpp Sat Nov 8 05:48:04 2008
@@ -47,7 +47,6 @@
int main(int argc, char** argv) {
llvm::llvm_shutdown_obj X;
- int base;
int pos = found(argv, argc, "-java");
if (pos) {
@@ -63,8 +62,7 @@
mvm::MvmModule::initialise(Fast);
mvm::Object::initialise();
- mvm::Thread::initialise();
- Collector::initialise(0, &base);
+ Collector::initialise(0);
Collector::enable(0);
if (VMToRun == RunJava) {
More information about the vmkit-commits
mailing list