[vmkit-commits] [vmkit] r57487 - in /vmkit/trunk: include/mvm/Allocator.h include/mvm/Threads/Thread.h lib/JnJVM/Classpath/ClasspathVMRuntime.cpp lib/JnJVM/Classpath/ClasspathVMThread.cpp lib/JnJVM/VMCore/JavaThread.cpp lib/JnJVM/VMCore/JavaThread.h lib/JnJVM/VMCore/Jnjvm.cpp lib/Mvm/Runtime/Object.cpp lib/N3/VMCore/VMThread.cpp lib/N3/VMCore/VMThread.h

Nicolas Geoffray nicolas.geoffray at lip6.fr
Tue Oct 14 07:08:50 PDT 2008


Author: geoffray
Date: Tue Oct 14 09:08:49 2008
New Revision: 57487

URL: http://llvm.org/viewvc/llvm-project?rev=57487&view=rev
Log:
Code cleanup for thread creation.
Add two new constructors for STL containers. The first allocator
is vm-specific, the second is class-loader specific, ie it is set
by the current class loader in Java.


Modified:
    vmkit/trunk/include/mvm/Allocator.h
    vmkit/trunk/include/mvm/Threads/Thread.h
    vmkit/trunk/lib/JnJVM/Classpath/ClasspathVMRuntime.cpp
    vmkit/trunk/lib/JnJVM/Classpath/ClasspathVMThread.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/Mvm/Runtime/Object.cpp
    vmkit/trunk/lib/N3/VMCore/VMThread.cpp
    vmkit/trunk/lib/N3/VMCore/VMThread.h

Modified: vmkit/trunk/include/mvm/Allocator.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/include/mvm/Allocator.h?rev=57487&r1=57486&r2=57487&view=diff

==============================================================================
--- vmkit/trunk/include/mvm/Allocator.h (original)
+++ vmkit/trunk/include/mvm/Allocator.h Tue Oct 14 09:08:49 2008
@@ -11,6 +11,7 @@
 #define MVM_ALLOCATOR_H
 
 #include <cstdlib>
+#include <limits>
 
 #include "llvm/Support/Allocator.h"
 
@@ -25,7 +26,6 @@
 
 namespace mvm {
 
-
 class Allocator {
 private:
 #ifdef MULTIPLE_GC
@@ -74,8 +74,154 @@
   }
 
   void Deallocate(void* obj) {}
+
+  static void* ThreadAllocate(size_t sz);
+  static void* VMAllocate(size_t sz);
+};
+
+template <class T>
+class STLVMAllocator {
+public:
+  // type definitions
+  typedef T        value_type;
+  typedef T*       pointer;
+  typedef const T* const_pointer;
+  typedef T&       reference;
+  typedef const T& const_reference;
+  typedef std::size_t    size_type;
+  typedef std::ptrdiff_t difference_type;
+
+  // rebind allocator to type U
+  template <class U>
+  struct rebind {
+    typedef STLVMAllocator<U> other;
+  };
+
+  // return address of values
+  pointer address (reference value) const {
+    return &value;
+  }
+  const_pointer address (const_reference value) const {
+    return &value;
+  }
+
+  
+  STLVMAllocator() {}
+  template<class T2> STLVMAllocator(STLVMAllocator<T2>&) {}
+  
+  ~STLVMAllocator() {}
+
+  size_type max_size () const {
+    return std::numeric_limits<std::size_t>::max() / sizeof(T);
+  }
+
+  // allocate but don't initialize num elements of type T
+  pointer allocate (size_type num, const void* = 0) { 
+    pointer ret = (pointer)mvm::BumpPtrAllocator::VMAllocate(num*sizeof(T));
+    return ret;
+  }
+
+  // initialize elements of allocated storage p with value value
+  void construct (pointer p, const T& value) {
+    // initialize memory with placement new
+    new((void*)p)T(value);
+  }
+
+  // destroy elements of initialized storage p
+  void destroy (pointer p) {
+    // destroy objects by calling their destructor
+    p->~T();
+  }
+
+  // deallocate storage p of deleted elements
+  void deallocate (pointer p, size_type num) {}
 };
 
+// return that all specializations of this allocator are interchangeable
+template <class T1, class T2>
+bool operator== (const STLVMAllocator<T1>&,
+                 const STLVMAllocator<T2>&) {
+  return true;
+}
+
+template <class T1, class T2>
+bool operator!= (const STLVMAllocator<T1>&,
+                 const STLVMAllocator<T2>&) {
+  return false;
+}
+
+template <class T>
+class STLThreadAllocator {
+public:
+  // type definitions
+  typedef T        value_type;
+  typedef T*       pointer;
+  typedef const T* const_pointer;
+  typedef T&       reference;
+  typedef const T& const_reference;
+  typedef std::size_t    size_type;
+  typedef std::ptrdiff_t difference_type;
+
+  // rebind allocator to type U
+  template <class U>
+  struct rebind {
+    typedef STLThreadAllocator<U> other;
+  };
+
+  // return address of values
+  pointer address (reference value) const {
+    return &value;
+  }
+  const_pointer address (const_reference value) const {
+    return &value;
+  }
+
+  
+  STLThreadAllocator() {}
+  template<class T2> STLThreadAllocator(STLThreadAllocator<T2>&) {}
+  
+  ~STLThreadAllocator() {}
+
+  size_type max_size () const {
+    return std::numeric_limits<std::size_t>::max() / sizeof(T);
+  }
+
+  // allocate but don't initialize num elements of type T
+  pointer allocate (size_type num, const void* = 0) {
+    pointer ret = (pointer)mvm::BumpPtrAllocator::ThreadAllocate(num*sizeof(T));
+    return ret;
+  }
+
+  // initialize elements of allocated storage p with value value
+  void construct (pointer p, const T& value) {
+    // initialize memory with placement new
+    new((void*)p)T(value);
+  }
+
+  // destroy elements of initialized storage p
+  void destroy (pointer p) {
+    // destroy objects by calling their destructor
+    p->~T();
+  }
+
+  // deallocate storage p of deleted elements
+  void deallocate (pointer p, size_type num) {}
+};
+
+// return that all specializations of this allocator are interchangeable
+template <class T1, class T2>
+bool operator== (const STLThreadAllocator<T1>&,
+                 const STLThreadAllocator<T2>&) {
+  return true;
+}
+
+template <class T1, class T2>
+bool operator!= (const STLThreadAllocator<T1>&,
+                 const STLThreadAllocator<T2>&) {
+  return false;
+}
+
+
 
 class PermanentObject {
 public:

Modified: vmkit/trunk/include/mvm/Threads/Thread.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/include/mvm/Threads/Thread.h?rev=57487&r1=57486&r2=57487&view=diff

==============================================================================
--- vmkit/trunk/include/mvm/Threads/Thread.h (original)
+++ vmkit/trunk/include/mvm/Threads/Thread.h Tue Oct 14 09:08:49 2008
@@ -14,18 +14,20 @@
 
 #include "MvmGC.h"
 #include "mvm/JIT.h"
+#include "mvm/Object.h"
 #include "mvm/Threads/Key.h"
 
 
-class Allocator;
 class Collector;
 
 namespace mvm {
 
+class BumpPtrAllocator;
+
 /// 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 gc {
+class Thread : public Object {
 public:
   
   /// yield - Yield the processor to another thread.
@@ -65,7 +67,14 @@
   static mvm::Key<Thread>* threadKey;
  
 public:
-  Allocator* allocator;
+  
+  /// vmAllocator - Virtual machine specific allocator.
+  ///
+  mvm::BumpPtrAllocator* vmAllocator;
+
+  /// threadAllocator - Current allocator for the thread. Useful for things
+  /// like class loaders which do not allocate per-vm.
+  mvm::BumpPtrAllocator* threadAllocator;
   
   /// baseSP - The base stack pointer.
   ///
@@ -98,8 +107,7 @@
 private:
   
   /// internalClearException - Clear any pending exception.
-  virtual void internalClearException() {
-  }
+  virtual void internalClearException() {}
 
 public:
 

Modified: vmkit/trunk/lib/JnJVM/Classpath/ClasspathVMRuntime.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/Classpath/ClasspathVMRuntime.cpp?rev=57487&r1=57486&r2=57487&view=diff

==============================================================================
--- vmkit/trunk/lib/JnJVM/Classpath/ClasspathVMRuntime.cpp (original)
+++ vmkit/trunk/lib/JnJVM/Classpath/ClasspathVMRuntime.cpp Tue Oct 14 09:08:49 2008
@@ -21,6 +21,7 @@
 #include "JavaTypes.h"
 #include "JavaThread.h"
 #include "Jnjvm.h"
+#include "LockedMap.h"
 #include "NativeUtil.h"
 
 
@@ -54,8 +55,7 @@
   memmove(&(elements[lgPre + lgLib]), vm->postlib->elements,
            lgPost * sizeof(uint16));
   
-  // TODO: find a better place to store the UTF8
-  const UTF8* res = vm->bootstrapLoader->readerConstructUTF8(elements, size);
+  const UTF8* res = vm->hashUTF8->lookupOrCreateReader(elements, size);
 
   return (jobject)(vm->UTF8ToStr(res));
   

Modified: vmkit/trunk/lib/JnJVM/Classpath/ClasspathVMThread.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/Classpath/ClasspathVMThread.cpp?rev=57487&r1=57486&r2=57487&view=diff

==============================================================================
--- vmkit/trunk/lib/JnJVM/Classpath/ClasspathVMThread.cpp (original)
+++ vmkit/trunk/lib/JnJVM/Classpath/ClasspathVMThread.cpp Tue Oct 14 09:08:49 2008
@@ -41,22 +41,30 @@
 }
 
 static void start(JavaObject* vmThread) {
-  int argc;
+  // Get the classpath
   Classpath* upcalls = vmThread->classOf->classLoader->bootstrapLoader->upcalls;
-  JavaThread* intern = (JavaThread*)upcalls->vmdataVMThread->getObjectField(vmThread);
-  Jnjvm* isolate = intern->isolate;
-  mvm::Thread::set(intern);
-#ifdef MULTIPLE_GC
-  intern->GC->inject_my_thread(&argc);
-#else
-  Collector::inject_my_thread(&argc);
-#endif
-  UserClass* vmthClass = (UserClass*)vmThread->classOf;
-  JavaObject* thread = isolate->upcalls->assocThread->getObjectField(vmThread);
-  ThreadSystem& ts = isolate->threadSystem;
-  bool isDaemon = isolate->upcalls->daemon->getInt8Field(thread);
-  intern->threadID = (mvm::Thread::self() << 8) & 0x7FFFFF00;
 
+  // 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);
+
+  UserClass* vmthClass = (UserClass*)vmThread->classOf;
+  ThreadSystem& ts = vm->threadSystem;
+  
+  
+  bool isDaemon = vm->upcalls->daemon->getInt8Field(javaThread);
 
   if (!isDaemon) {
     ts.nonDaemonLock.lock();
@@ -64,15 +72,7 @@
     ts.nonDaemonLock.unlock();
   }
   
-#ifdef SERVICE_VM
-  ServiceDomain* vm = (ServiceDomain*)isolate;
-  vm->startExecution();
-  vm->lock->lock();
-  vm->numThreads++;
-  vm->lock->unlock();
-#endif
-  
-  isolate->upcalls->runVMThread->invokeIntSpecial(isolate, vmthClass, vmThread);
+  upcalls->runVMThread->invokeIntSpecial(vm, vmthClass, vmThread);
   
   if (!isDaemon) {
     ts.nonDaemonLock.lock();
@@ -81,18 +81,6 @@
       ts.nonDaemonVar.signal();
     ts.nonDaemonLock.unlock();
   }
-
-#ifdef SERVICE_VM
-  vm->lock->lock();
-  vm->numThreads--;
-  vm->lock->unlock();
-#endif
-
-#ifdef MULTIPLE_GC
-  intern->GC->remove_my_thread();
-#else
-  Collector::remove_my_thread();
-#endif
 }
 
 JNIEXPORT void JNICALL Java_java_lang_VMThread_start(
@@ -102,16 +90,13 @@
 jobject _vmThread, sint64 stackSize) {
   Jnjvm* vm = JavaThread::get()->isolate;
   JavaObject* vmThread = (JavaObject*)_vmThread;
-  JavaObject* javaThread = vm->upcalls->assocThread->getObjectField(vmThread);
-  assert(javaThread);
+  
+  // 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);
 
-  JavaThread* th = allocator_new(vm->allocator, JavaThread)();
-  th->initialise(javaThread, vm);
-  vm->upcalls->vmdataVMThread->setObjectField(vmThread, (JavaObject*)th);
   int tid = 0;
-#ifdef MULTIPLE_GC
-  th->GC = mvm::Thread::get()->GC;
-#endif
 
   mvm::Thread::start(&tid, (int (*)(void *))start, (void*)vmThread);
 }
@@ -123,11 +108,12 @@
 jobject _vmthread) {
   Jnjvm* vm = JavaThread::get()->isolate;
   JavaObject* vmthread = (JavaObject*)_vmthread;
-
-  while (vm->upcalls->vmdataVMThread->getObjectField(vmthread) == 0)
+  JavaField* field = vm->upcalls->vmdataVMThread; 
+  // It's possible that the thread to be interrupted has not finished
+  // its initialization. Wait until the initialization is done.
+  while (field->getObjectField(vmthread) == 0)
     mvm::Thread::yield();
   
-  JavaField* field = vm->upcalls->vmdataVMThread;
   JavaThread* th = (JavaThread*)field->getObjectField(vmthread);
   th->lock.lock();
   th->interruptFlag = 1;

Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaThread.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JavaThread.cpp?rev=57487&r1=57486&r2=57487&view=diff

==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JavaThread.cpp (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JavaThread.cpp Tue Oct 14 09:08:49 2008
@@ -27,5 +27,54 @@
 
 void JavaThread::print(mvm::PrintBuffer* buf) const {
   buf->write("Thread:");
-  javaThread->print(buf);
+  if (javaThread) javaThread->print(buf);
+}
+
+JavaThread::JavaThread(JavaObject* thread, Jnjvm* vm, void* sp) {
+  if (!thread) bootstrap = true;
+  else bootstrap = false;
+  javaThread = thread;
+  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();
+#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
+  }
 }

Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaThread.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JavaThread.h?rev=57487&r1=57486&r2=57487&view=diff

==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JavaThread.h (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JavaThread.h Tue Oct 14 09:08:49 2008
@@ -41,6 +41,7 @@
   uint32 interruptFlag;
   uint32 state;
   std::vector<jmp_buf*> sjlj_buffers;
+  bool bootstrap;
 
   static const unsigned int StateRunning;
   static const unsigned int StateWaiting;
@@ -48,16 +49,10 @@
 
   virtual void print(mvm::PrintBuffer *buf) const;
   virtual void TRACER;
-  ~JavaThread() {}
-  JavaThread() {}
+  JavaThread() { bootstrap = true; }
+  ~JavaThread();
   
-  void initialise(JavaObject* thread, Jnjvm* isolate) {
-    this->javaThread = thread;
-    this->isolate = isolate;
-    this->interruptFlag = 0;
-    this->state = StateRunning;
-    this->pendingException = 0;
-  }
+  JavaThread(JavaObject* thread, Jnjvm* isolate, void* sp);
 
   static JavaThread* get() {
     return (JavaThread*)mvm::Thread::get();

Modified: vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.cpp?rev=57487&r1=57486&r2=57487&view=diff

==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.cpp (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.cpp Tue Oct 14 09:08:49 2008
@@ -776,11 +776,7 @@
     argv = argv + pos - 1;
     argc = argc - pos + 1;
   
-    bootstrapThread = allocator_new(allocator, JavaThread)();
-    bootstrapThread->initialise(0, this);
-    bootstrapThread->baseSP = mvm::Thread::get()->baseSP;
-    JavaThread::set(bootstrapThread); 
-    bootstrapThread->threadID = (mvm::Thread::self() << 8) & 0x7FFFFF00;
+    bootstrapThread = gc_new(JavaThread)(0, this, mvm::Thread::get()->baseSP);
 
     loadBootstrap();
 

Modified: vmkit/trunk/lib/Mvm/Runtime/Object.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/Mvm/Runtime/Object.cpp?rev=57487&r1=57486&r2=57487&view=diff

==============================================================================
--- vmkit/trunk/lib/Mvm/Runtime/Object.cpp (original)
+++ vmkit/trunk/lib/Mvm/Runtime/Object.cpp Tue Oct 14 09:08:49 2008
@@ -10,6 +10,7 @@
 #include <stdlib.h>
 
 #include "MvmGC.h"
+#include "mvm/Allocator.h"
 #include "mvm/Method.h"
 #include "mvm/Object.h"
 #include "mvm/PrintBuffer.h"
@@ -114,3 +115,13 @@
   }
   buf->write("\"");
 }
+
+void* mvm::BumpPtrAllocator::VMAllocate(size_t sz) {
+  mvm::BumpPtrAllocator* allocator = mvm::Thread::get()->vmAllocator;
+  return allocator->Allocate(sz);
+}
+
+void* mvm::BumpPtrAllocator::ThreadAllocate(size_t sz) {
+  mvm::BumpPtrAllocator* allocator = mvm::Thread::get()->threadAllocator;
+  return allocator->Allocate(sz);
+}

Modified: vmkit/trunk/lib/N3/VMCore/VMThread.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/N3/VMCore/VMThread.cpp?rev=57487&r1=57486&r2=57487&view=diff

==============================================================================
--- vmkit/trunk/lib/N3/VMCore/VMThread.cpp (original)
+++ vmkit/trunk/lib/N3/VMCore/VMThread.cpp Tue Oct 14 09:08:49 2008
@@ -29,7 +29,7 @@
 const unsigned int VMThread::StateWaiting = 1;
 const unsigned int VMThread::StateInterrupted = 2;
 
-void VMThread::print(mvm::PrintBuffer* buf) {
+void VMThread::print(mvm::PrintBuffer* buf) const {
   buf->write("Thread:");
   vmThread->print(buf);
 }

Modified: vmkit/trunk/lib/N3/VMCore/VMThread.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/N3/VMCore/VMThread.h?rev=57487&r1=57486&r2=57487&view=diff

==============================================================================
--- vmkit/trunk/lib/N3/VMCore/VMThread.h (original)
+++ vmkit/trunk/lib/N3/VMCore/VMThread.h Tue Oct 14 09:08:49 2008
@@ -45,7 +45,7 @@
   static const unsigned int StateWaiting;
   static const unsigned int StateInterrupted;
 
-  virtual void print(mvm::PrintBuffer *buf);
+  virtual void print(mvm::PrintBuffer *buf) const;
   virtual void TRACER;
   ~VMThread();
   VMThread();





More information about the vmkit-commits mailing list