[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