[vmkit-commits] [vmkit] r121130 - in /vmkit/branches/multi-vm: include/mvm/SystemThreads.h include/mvm/VMKit.h include/mvm/VirtualMachine.h lib/J3/Classpath/JavaUpcalls.cpp lib/J3/VMCore/Jnjvm.cpp lib/J3/VMCore/Jnjvm.h lib/J3/VMCore/ReferenceQueue.cpp lib/J3/VMCore/ReferenceQueue.h lib/J3/VMCore/VirtualTables.cpp lib/Mvm/CommonThread/ctthread.cpp lib/Mvm/GCMmap2/gccollector.cpp lib/Mvm/Runtime/SystemThreads.cpp lib/Mvm/Runtime/VMKit.cpp mmtk/mmtk-j3/ReferenceProcessor.cpp

Gael Thomas gael.thomas at lip6.fr
Tue Dec 7 03:08:03 PST 2010


Author: gthomas
Date: Tue Dec  7 05:08:02 2010
New Revision: 121130

URL: http://llvm.org/viewvc/llvm-project?rev=121130&view=rev
Log:
move the reference thread in vmkit

Modified:
    vmkit/branches/multi-vm/include/mvm/SystemThreads.h
    vmkit/branches/multi-vm/include/mvm/VMKit.h
    vmkit/branches/multi-vm/include/mvm/VirtualMachine.h
    vmkit/branches/multi-vm/lib/J3/Classpath/JavaUpcalls.cpp
    vmkit/branches/multi-vm/lib/J3/VMCore/Jnjvm.cpp
    vmkit/branches/multi-vm/lib/J3/VMCore/Jnjvm.h
    vmkit/branches/multi-vm/lib/J3/VMCore/ReferenceQueue.cpp
    vmkit/branches/multi-vm/lib/J3/VMCore/ReferenceQueue.h
    vmkit/branches/multi-vm/lib/J3/VMCore/VirtualTables.cpp
    vmkit/branches/multi-vm/lib/Mvm/CommonThread/ctthread.cpp
    vmkit/branches/multi-vm/lib/Mvm/GCMmap2/gccollector.cpp
    vmkit/branches/multi-vm/lib/Mvm/Runtime/SystemThreads.cpp
    vmkit/branches/multi-vm/lib/Mvm/Runtime/VMKit.cpp
    vmkit/branches/multi-vm/mmtk/mmtk-j3/ReferenceProcessor.cpp

Modified: vmkit/branches/multi-vm/include/mvm/SystemThreads.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/multi-vm/include/mvm/SystemThreads.h?rev=121130&r1=121129&r2=121130&view=diff
==============================================================================
--- vmkit/branches/multi-vm/include/mvm/SystemThreads.h (original)
+++ vmkit/branches/multi-vm/include/mvm/SystemThreads.h Tue Dec  7 05:08:02 2010
@@ -11,6 +11,126 @@
 namespace mvm {
 class VirtualMachine;
 
+class ReferenceThread;
+class Jnjvm;
+
+class ReferenceQueue {
+private:
+	mvm::gc** References;
+  uint32 QueueLength;
+  uint32 CurrentIndex;
+  mvm::SpinLock QueueLock;
+  uint8_t semantics;
+
+	mvm::gc* processReference(mvm::gc*, ReferenceThread*, uintptr_t closure);
+public:
+
+  static const uint8_t WEAK = 1;
+  static const uint8_t SOFT = 2;
+  static const uint8_t PHANTOM = 3;
+
+
+  ReferenceQueue(uint8_t s) {
+    References = new mvm::gc*[INITIAL_QUEUE_SIZE];
+    memset(References, 0, INITIAL_QUEUE_SIZE * sizeof(mvm::gc*));
+    QueueLength = INITIAL_QUEUE_SIZE;
+    CurrentIndex = 0;
+    semantics = s;
+  }
+
+  ~ReferenceQueue() {
+    delete[] References;
+  }
+ 
+  void addReference(mvm::gc* ref) {
+    llvm_gcroot(ref, 0);
+    QueueLock.acquire();
+    if (CurrentIndex >= QueueLength) {
+      uint32 newLength = QueueLength * GROW_FACTOR;
+			mvm::gc** newQueue = new mvm::gc*[newLength];
+      memset(newQueue, 0, newLength * sizeof(mvm::gc*));
+      if (!newQueue) {
+        fprintf(stderr, "I don't know how to handle reference overflow yet!\n");
+        abort();
+      }
+      for (uint32 i = 0; i < QueueLength; ++i) newQueue[i] = References[i];
+      delete[] References;
+      References = newQueue;
+      QueueLength = newLength;
+    }
+    References[CurrentIndex++] = ref;
+    QueueLock.release();
+  }
+  
+  void acquire() {
+    QueueLock.acquire();
+  }
+
+  void release() {
+    QueueLock.release();
+  }
+
+  void scan(ReferenceThread* thread, uintptr_t closure);
+};
+
+class ReferenceThread : public mvm::MutatorThread {
+public:
+  /// WeakReferencesQueue - The queue of weak references.
+  ///
+  ReferenceQueue WeakReferencesQueue;
+
+  /// SoftReferencesQueue - The queue of soft references.
+  ///
+  ReferenceQueue SoftReferencesQueue;
+
+  /// PhantomReferencesQueue - The queue of phantom references.
+  ///
+  ReferenceQueue PhantomReferencesQueue;
+
+	mvm::gc** ToEnqueue;
+  uint32 ToEnqueueLength;
+  uint32 ToEnqueueIndex;
+  
+  /// ToEnqueueLock - A lock to protect access to the queue.
+  ///
+  mvm::LockNormal EnqueueLock;
+  mvm::Cond EnqueueCond;
+  mvm::SpinLock ToEnqueueLock;
+
+  void addToEnqueue(mvm::gc* obj);
+
+  static void enqueueStart(ReferenceThread*);
+
+  /// addWeakReference - Add a weak reference to the queue.
+  ///
+  void addWeakReference(mvm::gc* ref) {
+    llvm_gcroot(ref, 0);
+    WeakReferencesQueue.addReference(ref);
+  }
+  
+  /// addSoftReference - Add a weak reference to the queue.
+  ///
+  void addSoftReference(mvm::gc* ref) {
+    llvm_gcroot(ref, 0);
+    SoftReferencesQueue.addReference(ref);
+  }
+  
+  /// addPhantomReference - Add a weak reference to the queue.
+  ///
+  void addPhantomReference(mvm::gc* ref) {
+    llvm_gcroot(ref, 0);
+    PhantomReferencesQueue.addReference(ref);
+  }
+
+  ReferenceThread(mvm::VMKit* vmkit);
+
+	virtual ~ReferenceThread() {
+    delete[] ToEnqueue;
+  }
+
+  virtual void tracer(uintptr_t closure);
+};
+
 class FinalizerThread : public mvm::MutatorThread {
 public:
     /// FinalizationQueueLock - A lock to protect access to the queue.

Modified: vmkit/branches/multi-vm/include/mvm/VMKit.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/multi-vm/include/mvm/VMKit.h?rev=121130&r1=121129&r2=121130&view=diff
==============================================================================
--- vmkit/branches/multi-vm/include/mvm/VMKit.h (original)
+++ vmkit/branches/multi-vm/include/mvm/VMKit.h Tue Dec  7 05:08:02 2010
@@ -10,6 +10,7 @@
 class VMKit;
 class gc;
 class FinalizerThread;
+class ReferenceThread;
 
 class FunctionMap {
 public:
@@ -92,7 +93,13 @@
 	void registerRunningThread(mvm::Thread* th);  
 	void unregisterRunningThread(mvm::Thread* th);
 
+  /// enqueueThread - The thread that finalizes references.
+  ///
 	FinalizerThread*             finalizerThread;
+  
+  /// enqueueThread - The thread that enqueues references.
+  ///
+  ReferenceThread* referenceThread;
 
   /// scanFinalizationQueue - Scan objets with a finalized method and schedule
   /// them for finalization if they are not live.
@@ -103,6 +110,21 @@
   /// a finalization method.
   ///
   void addFinalizationCandidate(gc* object);
+  
+  /// scanWeakReferencesQueue - Scan all weak references. Called by the GC
+  /// before scanning the finalization queue.
+  /// 
+  void scanWeakReferencesQueue(uintptr_t closure);
+  
+  /// scanSoftReferencesQueue - Scan all soft references. Called by the GC
+  /// before scanning the finalization queue.
+  ///
+  void scanSoftReferencesQueue(uintptr_t closure);
+  
+  /// scanPhantomReferencesQueue - Scan all phantom references. Called by the GC
+  /// after the finalization queue.
+  ///
+  void scanPhantomReferencesQueue(uintptr_t closure);
 
 	/// ------------------------------------------------- ///
 	/// ---             collection managment          --- ///

Modified: vmkit/branches/multi-vm/include/mvm/VirtualMachine.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/multi-vm/include/mvm/VirtualMachine.h?rev=121130&r1=121129&r2=121130&view=diff
==============================================================================
--- vmkit/branches/multi-vm/include/mvm/VirtualMachine.h (original)
+++ vmkit/branches/multi-vm/include/mvm/VirtualMachine.h Tue Dec  7 05:08:02 2010
@@ -79,23 +79,6 @@
   ///
 	virtual bool enqueueReference(mvm::gc* _obj) { abort(); }
 
-
-  
-  /// scanWeakReferencesQueue - Scan all weak references. Called by the GC
-  /// before scanning the finalization queue.
-  /// 
-  virtual void scanWeakReferencesQueue(uintptr_t closure) {}
-  
-  /// scanSoftReferencesQueue - Scan all soft references. Called by the GC
-  /// before scanning the finalization queue.
-  ///
-  virtual void scanSoftReferencesQueue(uintptr_t closure) {}
-  
-  /// scanPhantomReferencesQueue - Scan all phantom references. Called by the GC
-  /// after the finalization queue.
-  ///
-  virtual void scanPhantomReferencesQueue(uintptr_t closure) {}
-
   /// tracer - Trace this virtual machine's GC-objects. 
 	///    Called once by vm. If you have GC-objects in a thread specific data, redefine the tracer of your VMThreadData.
   ///

Modified: vmkit/branches/multi-vm/lib/J3/Classpath/JavaUpcalls.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/multi-vm/lib/J3/Classpath/JavaUpcalls.cpp?rev=121130&r1=121129&r2=121130&view=diff
==============================================================================
--- vmkit/branches/multi-vm/lib/J3/Classpath/JavaUpcalls.cpp (original)
+++ vmkit/branches/multi-vm/lib/J3/Classpath/JavaUpcalls.cpp Tue Dec  7 05:08:02 2010
@@ -15,7 +15,8 @@
 #include "JavaThread.h"
 #include "JavaUpcalls.h"
 #include "Jnjvm.h"
-#include "ReferenceQueue.h"
+#include "mvm/SystemThreads.h"
+#include "mvm/VMKit.h"
 
 #define COMPILE_METHODS(cl) \
   for (CommonClass::method_iterator i = cl->virtualMethods.begin(), \
@@ -307,7 +308,7 @@
   BEGIN_NATIVE_EXCEPTION(0)
   
   JavaObjectReference::init(reference, referent, 0);
-  JavaThread::get()->getJVM()->getReferenceThread()->addWeakReference(reference);
+  mvm::Thread::get()->vmkit->referenceThread->addWeakReference(reference);
 
   END_NATIVE_EXCEPTION
 
@@ -324,7 +325,7 @@
   BEGIN_NATIVE_EXCEPTION(0)
   
   JavaObjectReference::init(reference, referent, queue);
-  JavaThread::get()->getJVM()->getReferenceThread()->addWeakReference(reference);
+  mvm::Thread::get()->vmkit->referenceThread->addWeakReference(reference);
   
   END_NATIVE_EXCEPTION
 
@@ -338,7 +339,7 @@
   BEGIN_NATIVE_EXCEPTION(0)
   
   JavaObjectReference::init(reference, referent, 0);
-  JavaThread::get()->getJVM()->getReferenceThread()->addSoftReference(reference);
+  mvm::Thread::get()->vmkit->referenceThread->addSoftReference(reference);
   
   END_NATIVE_EXCEPTION
 
@@ -355,7 +356,7 @@
   BEGIN_NATIVE_EXCEPTION(0)
 
   JavaObjectReference::init(reference, referent, queue);
-  JavaThread::get()->getJVM()->getReferenceThread()->addSoftReference(reference);
+  mvm::Thread::get()->vmkit->referenceThread->addSoftReference(reference);
   
   END_NATIVE_EXCEPTION
 
@@ -372,7 +373,7 @@
   BEGIN_NATIVE_EXCEPTION(0)
   
   JavaObjectReference::init(reference, referent, queue);
-  JavaThread::get()->getJVM()->getReferenceThread()->addPhantomReference(reference);
+  mvm::Thread::get()->vmkit->referenceThread->addPhantomReference(reference);
 
   END_NATIVE_EXCEPTION
 }

Modified: vmkit/branches/multi-vm/lib/J3/VMCore/Jnjvm.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/multi-vm/lib/J3/VMCore/Jnjvm.cpp?rev=121130&r1=121129&r2=121130&view=diff
==============================================================================
--- vmkit/branches/multi-vm/lib/J3/VMCore/Jnjvm.cpp (original)
+++ vmkit/branches/multi-vm/lib/J3/VMCore/Jnjvm.cpp Tue Dec  7 05:08:02 2010
@@ -35,7 +35,6 @@
 #include "LinkJavaRuntime.h"
 #include "LockedMap.h"
 #include "Reader.h"
-#include "ReferenceQueue.h"
 #include "Zip.h"
 
 using namespace j3;
@@ -1076,10 +1075,6 @@
   llvm_gcroot(javaLoader, 0);
   JnjvmClassLoader* loader = bootstrapLoader;
   
-  referenceThread = new ReferenceThread(vmkit);
-  referenceThread->start(
-      (void (*)(mvm::Thread*))ReferenceThread::enqueueStart);
-  
   // Initialise the bootstrap class loader if it's not
   // done already.
   if (bootstrapLoader->upcalls->newString == NULL) {
@@ -1425,34 +1420,7 @@
   UserClass* cl = JavaObject::getClass(obj)->asClass();
   return (bool)meth->invokeIntSpecialBuf(this, cl, obj, 0);
 }
-
-void Jnjvm::startCollection() {
-  referenceThread->ToEnqueueLock.acquire();
-  referenceThread->SoftReferencesQueue.acquire();
-  referenceThread->WeakReferencesQueue.acquire();
-  referenceThread->PhantomReferencesQueue.acquire();
-}
   
-void Jnjvm::endCollection() {
-  referenceThread->ToEnqueueLock.release();
-  referenceThread->SoftReferencesQueue.release();
-  referenceThread->WeakReferencesQueue.release();
-  referenceThread->PhantomReferencesQueue.release();
-  referenceThread->EnqueueCond.broadcast();
-}
-  
-void Jnjvm::scanWeakReferencesQueue(uintptr_t closure) {
-  referenceThread->WeakReferencesQueue.scan(referenceThread, closure);
-}
-  
-void Jnjvm::scanSoftReferencesQueue(uintptr_t closure) {
-  referenceThread->SoftReferencesQueue.scan(referenceThread, closure);
-}
-  
-void Jnjvm::scanPhantomReferencesQueue(uintptr_t closure) {
-  referenceThread->PhantomReferencesQueue.scan(referenceThread, closure);
-}
-
 size_t Jnjvm::getObjectSize(mvm::gc* object) {
   // TODO: because this is called during GC, there is no need to do
   // llvm_gcroot. For clarity, it may be useful to have a special type

Modified: vmkit/branches/multi-vm/lib/J3/VMCore/Jnjvm.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/multi-vm/lib/J3/VMCore/Jnjvm.h?rev=121130&r1=121129&r2=121130&view=diff
==============================================================================
--- vmkit/branches/multi-vm/lib/J3/VMCore/Jnjvm.h (original)
+++ vmkit/branches/multi-vm/lib/J3/VMCore/Jnjvm.h Tue Dec  7 05:08:02 2010
@@ -121,16 +121,7 @@
   UserClass* throwable;
 
 private:
-  
-  /// enqueueThread - The thread that enqueue Java references.
-  ///
-  ReferenceThread* referenceThread;
 
-  virtual void startCollection();
-  virtual void endCollection();
-  virtual void scanWeakReferencesQueue(uintptr_t closure);
-  virtual void scanSoftReferencesQueue(uintptr_t closure);
-  virtual void scanPhantomReferencesQueue(uintptr_t closure);
   virtual size_t getObjectSize(mvm::gc* obj);
   virtual const char* getObjectTypeName(mvm::gc* obj);
 
@@ -322,14 +313,6 @@
   /// enqueueReference - enqueue the reference
   ///
 	virtual bool enqueueReference(mvm::gc* _obj);
-  
-  /// setReferenceThread - Set the enqueue thread of this VM.
-  ///
-  void setReferenceThread(ReferenceThread* th) { referenceThread = th; }
-  
-  /// getReferenceThread - Get the enqueue thread of this VM.
-  ///
-  ReferenceThread* getReferenceThread() const { return referenceThread; }
 
   /// ~Jnjvm - Destroy the JVM.
   ///

Modified: vmkit/branches/multi-vm/lib/J3/VMCore/ReferenceQueue.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/multi-vm/lib/J3/VMCore/ReferenceQueue.cpp?rev=121130&r1=121129&r2=121130&view=diff
==============================================================================
--- vmkit/branches/multi-vm/lib/J3/VMCore/ReferenceQueue.cpp (original)
+++ vmkit/branches/multi-vm/lib/J3/VMCore/ReferenceQueue.cpp Tue Dec  7 05:08:02 2010
@@ -12,138 +12,3 @@
 #include "JavaUpcalls.h"
 #include "Jnjvm.h"
 #include "ReferenceQueue.h"
-
-using namespace j3;
-
-ReferenceThread::ReferenceThread(mvm::VMKit* vmkit) :
-	MutatorThread(vmkit),
-	WeakReferencesQueue(ReferenceQueue::WEAK),
-	SoftReferencesQueue(ReferenceQueue::SOFT), 
-	PhantomReferencesQueue(ReferenceQueue::PHANTOM) {
-
-  ToEnqueue = new mvm::gc*[INITIAL_QUEUE_SIZE];
-  ToEnqueueLength = INITIAL_QUEUE_SIZE;
-  ToEnqueueIndex = 0;
-}
-
-mvm::gc** getReferent(mvm::gc* obj) {
-  llvm_gcroot(obj, 0);
-	mvm::VirtualMachine* vm = obj->getVirtualTable()->vm;
-	mvm::Thread::get()->attach(vm);
-	return vm->getReferent(obj);
-}
-
-void setReferent(mvm::gc* obj, mvm::gc* val) {
-	printf("set referent: %p %p\n", obj, val);
-  llvm_gcroot(obj, 0);
-  llvm_gcroot(val, 0);
-	mvm::VirtualMachine* vm = obj->getVirtualTable()->vm;
-	mvm::Thread::get()->attach(vm);
-	vm->setReferent(obj, val);
-}
- 
-void invokeEnqueue(mvm::gc* obj) {
-  llvm_gcroot(obj, 0);
-  TRY {
-		mvm::VirtualMachine* vm = obj->getVirtualTable()->vm;
-		mvm::Thread::get()->attach(vm);
-		
-		printf("enqueue reference: %p\n", obj);
-    vm->enqueueReference(obj);
-  } IGNORE;
-  mvm::Thread::get()->clearPendingException();
-}
-
-void ReferenceThread::enqueueStart(ReferenceThread* th) {
-	mvm::gc* res = NULL;
-  llvm_gcroot(res, 0);
-
-  while (true) {
-    th->EnqueueLock.lock();
-    while (th->ToEnqueueIndex == 0) {
-      th->EnqueueCond.wait(&th->EnqueueLock);
-    }
-    th->EnqueueLock.unlock();
-
-    while (true) {
-      th->ToEnqueueLock.acquire();
-      if (th->ToEnqueueIndex != 0) {
-        res = th->ToEnqueue[th->ToEnqueueIndex - 1];
-        --th->ToEnqueueIndex;
-      }
-      th->ToEnqueueLock.release();
-      if (!res) break;
-
-      invokeEnqueue(res);
-      res = NULL;
-    }
-  }
-}
-
-
-void ReferenceThread::addToEnqueue(mvm::gc* obj) {
-  llvm_gcroot(obj, 0);
-  if (ToEnqueueIndex >= ToEnqueueLength) {
-    uint32 newLength = ToEnqueueLength * GROW_FACTOR;
-		mvm::gc** newQueue = new mvm::gc*[newLength];
-    if (!newQueue) {
-      fprintf(stderr, "I don't know how to handle reference overflow yet!\n");
-      abort();
-    }   
-    for (uint32 i = 0; i < ToEnqueueLength; ++i) {
-      newQueue[i] = ToEnqueue[i];
-    }   
-    delete[] ToEnqueue;
-    ToEnqueue = newQueue;
-    ToEnqueueLength = newLength;
-  }
-  ToEnqueue[ToEnqueueIndex++] = obj;
-}
-
-mvm::gc* ReferenceQueue::processReference(mvm::gc* reference, ReferenceThread* th, uintptr_t closure) {
-  if (!mvm::Collector::isLive(reference, closure)) {
-    setReferent(reference, 0);
-    return NULL;
-  }
-
-	mvm::gc* referent = *(getReferent(reference));
-
-  if (!referent) {
-    return NULL;
-  }
-
-  if (semantics == SOFT) {
-    // TODO: are we are out of memory? Consider that we always are for now.
-    if (false) {
-      mvm::Collector::retainReferent(referent, closure);
-    }
-  } else if (semantics == PHANTOM) {
-    // Nothing to do.
-  }
-
-	mvm::gc* newReference =
-      mvm::Collector::getForwardedReference(reference, closure);
-  if (mvm::Collector::isLive(referent, closure)) {
-		mvm::gc* newReferent = mvm::Collector::getForwardedReferent(referent, closure);
-    setReferent(newReference, newReferent);
-    return newReference;
-  } else {
-    setReferent(newReference, 0);
-    th->addToEnqueue(newReference);
-    return NULL;
-  }
-}
-
-
-void ReferenceQueue::scan(ReferenceThread* th, uintptr_t closure) {
-  uint32 NewIndex = 0;
-
-  for (uint32 i = 0; i < CurrentIndex; ++i) {
-		mvm::gc* obj = References[i];
-		mvm::gc* res = processReference(obj, th, closure);
-    if (res) References[NewIndex++] = res;
-  }
-
-  CurrentIndex = NewIndex;
-}
-

Modified: vmkit/branches/multi-vm/lib/J3/VMCore/ReferenceQueue.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/multi-vm/lib/J3/VMCore/ReferenceQueue.h?rev=121130&r1=121129&r2=121130&view=diff
==============================================================================
--- vmkit/branches/multi-vm/lib/J3/VMCore/ReferenceQueue.h (original)
+++ vmkit/branches/multi-vm/lib/J3/VMCore/ReferenceQueue.h Tue Dec  7 05:08:02 2010
@@ -20,124 +20,6 @@
 
 namespace j3 {
 
-class ReferenceThread;
-class Jnjvm;
-
-class ReferenceQueue {
-private:
-	mvm::gc** References;
-  uint32 QueueLength;
-  uint32 CurrentIndex;
-  mvm::SpinLock QueueLock;
-  uint8_t semantics;
-
-	mvm::gc* processReference(mvm::gc*, ReferenceThread*, uintptr_t closure);
-public:
-
-  static const uint8_t WEAK = 1;
-  static const uint8_t SOFT = 2;
-  static const uint8_t PHANTOM = 3;
-
-
-  ReferenceQueue(uint8_t s) {
-    References = new mvm::gc*[INITIAL_QUEUE_SIZE];
-    memset(References, 0, INITIAL_QUEUE_SIZE * sizeof(mvm::gc*));
-    QueueLength = INITIAL_QUEUE_SIZE;
-    CurrentIndex = 0;
-    semantics = s;
-  }
-
-  ~ReferenceQueue() {
-    delete[] References;
-  }
- 
-  void addReference(mvm::gc* ref) {
-    llvm_gcroot(ref, 0);
-    QueueLock.acquire();
-    if (CurrentIndex >= QueueLength) {
-      uint32 newLength = QueueLength * GROW_FACTOR;
-			mvm::gc** newQueue = new mvm::gc*[newLength];
-      memset(newQueue, 0, newLength * sizeof(mvm::gc*));
-      if (!newQueue) {
-        fprintf(stderr, "I don't know how to handle reference overflow yet!\n");
-        abort();
-      }
-      for (uint32 i = 0; i < QueueLength; ++i) newQueue[i] = References[i];
-      delete[] References;
-      References = newQueue;
-      QueueLength = newLength;
-    }
-    References[CurrentIndex++] = ref;
-    QueueLock.release();
-  }
-  
-  void acquire() {
-    QueueLock.acquire();
-  }
-
-  void release() {
-    QueueLock.release();
-  }
-
-  void scan(ReferenceThread* thread, uintptr_t closure);
-};
-
-class ReferenceThread : public mvm::MutatorThread {
-public:
-  /// WeakReferencesQueue - The queue of weak references.
-  ///
-  ReferenceQueue WeakReferencesQueue;
-
-  /// SoftReferencesQueue - The queue of soft references.
-  ///
-  ReferenceQueue SoftReferencesQueue;
-
-  /// PhantomReferencesQueue - The queue of phantom references.
-  ///
-  ReferenceQueue PhantomReferencesQueue;
-
-	mvm::gc** ToEnqueue;
-  uint32 ToEnqueueLength;
-  uint32 ToEnqueueIndex;
-  
-  /// ToEnqueueLock - A lock to protect access to the queue.
-  ///
-  mvm::LockNormal EnqueueLock;
-  mvm::Cond EnqueueCond;
-  mvm::SpinLock ToEnqueueLock;
-
-  void addToEnqueue(mvm::gc* obj);
-
-  static void enqueueStart(ReferenceThread*);
-
-  /// addWeakReference - Add a weak reference to the queue.
-  ///
-  void addWeakReference(mvm::gc* ref) {
-    llvm_gcroot(ref, 0);
-    WeakReferencesQueue.addReference(ref);
-  }
-  
-  /// addSoftReference - Add a weak reference to the queue.
-  ///
-  void addSoftReference(mvm::gc* ref) {
-    llvm_gcroot(ref, 0);
-    SoftReferencesQueue.addReference(ref);
-  }
-  
-  /// addPhantomReference - Add a weak reference to the queue.
-  ///
-  void addPhantomReference(mvm::gc* ref) {
-    llvm_gcroot(ref, 0);
-    PhantomReferencesQueue.addReference(ref);
-  }
-
-  ReferenceThread(mvm::VMKit* vmkit);
-
-	virtual ~ReferenceThread() {
-    delete[] ToEnqueue;
-  }
-};
-
 } // namespace j3
 
 #endif  //J3_REFERENCE_QUEUE_H

Modified: vmkit/branches/multi-vm/lib/J3/VMCore/VirtualTables.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/multi-vm/lib/J3/VMCore/VirtualTables.cpp?rev=121130&r1=121129&r2=121130&view=diff
==============================================================================
--- vmkit/branches/multi-vm/lib/J3/VMCore/VirtualTables.cpp (original)
+++ vmkit/branches/multi-vm/lib/J3/VMCore/VirtualTables.cpp Tue Dec  7 05:08:02 2010
@@ -291,11 +291,6 @@
     mvm::Collector::markAndTraceRoot(key, closure);
   }
   
-  // (6) Trace the reference queue
-  for (uint32 i = 0; i < referenceThread->ToEnqueueIndex; ++i) {
-    mvm::Collector::markAndTraceRoot(referenceThread->ToEnqueue + i, closure);
-  }
- 
   // (7) Trace the locks and their associated object.
   uint32 i = 0;
   for (; i < mvm::LockSystem::GlobalSize; i++) {

Modified: vmkit/branches/multi-vm/lib/Mvm/CommonThread/ctthread.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/multi-vm/lib/Mvm/CommonThread/ctthread.cpp?rev=121130&r1=121129&r2=121130&view=diff
==============================================================================
--- vmkit/branches/multi-vm/lib/Mvm/CommonThread/ctthread.cpp (original)
+++ vmkit/branches/multi-vm/lib/Mvm/CommonThread/ctthread.cpp Tue Dec  7 05:08:02 2010
@@ -518,14 +518,12 @@
 }
 
 void Thread::operator delete(void* th) {
-	printf("deleting %p\n", th);
   uintptr_t index = ((uintptr_t)th & Thread::IDMask);
   index = (index & ~TheStackManager.baseAddr) >> 20;
   TheStackManager.used[index] = 0;
 }
 
 Thread::~Thread() {
-	printf("destroying %p\n", this);
   // It seems like the pthread implementation in Linux is clearing with NULL
   // the stack of the thread. So we have to get the thread id before
   // calling pthread_join.

Modified: vmkit/branches/multi-vm/lib/Mvm/GCMmap2/gccollector.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/multi-vm/lib/Mvm/GCMmap2/gccollector.cpp?rev=121130&r1=121129&r2=121130&view=diff
==============================================================================
--- vmkit/branches/multi-vm/lib/Mvm/GCMmap2/gccollector.cpp (original)
+++ vmkit/branches/multi-vm/lib/Mvm/GCMmap2/gccollector.cpp Tue Dec  7 05:08:02 2010
@@ -9,6 +9,7 @@
 
 #include "mvm/GC.h"
 #include "mvm/VMKit.h"
+#include "mvm/SystemThreads.h"
 
 using namespace mvm;
 
@@ -63,16 +64,16 @@
 		cur = cur->prev();
 
 		// (4) Trace the weak reference queue.
-		th->MyVM->scanWeakReferencesQueue(0);
+		th->vmkit->scanWeakReferencesQueue(0);
 
 		// (5) Trace the soft reference queue.
-		th->MyVM->scanSoftReferencesQueue(0);
+		th->vmkit->scanSoftReferencesQueue(0);
   
 		// (6) Trace the finalization queue.
 		th->vmkit->scanFinalizationQueue(0);
 
 		// (7) Trace the phantom reference queue.
-		th->MyVM->scanPhantomReferencesQueue(0);
+		th->vmkit->scanPhantomReferencesQueue(0);
 
 		// (8) Trace the new objects added by queues.
 		for(cur = cur->next(); cur != used_nodes; cur = cur->next())

Modified: vmkit/branches/multi-vm/lib/Mvm/Runtime/SystemThreads.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/multi-vm/lib/Mvm/Runtime/SystemThreads.cpp?rev=121130&r1=121129&r2=121130&view=diff
==============================================================================
--- vmkit/branches/multi-vm/lib/Mvm/Runtime/SystemThreads.cpp (original)
+++ vmkit/branches/multi-vm/lib/Mvm/Runtime/SystemThreads.cpp Tue Dec  7 05:08:02 2010
@@ -4,6 +4,144 @@
 
 using namespace mvm;
 
+ReferenceThread::ReferenceThread(mvm::VMKit* vmkit) :
+	MutatorThread(vmkit),
+	WeakReferencesQueue(ReferenceQueue::WEAK),
+	SoftReferencesQueue(ReferenceQueue::SOFT), 
+	PhantomReferencesQueue(ReferenceQueue::PHANTOM) {
+
+  ToEnqueue = new mvm::gc*[INITIAL_QUEUE_SIZE];
+  ToEnqueueLength = INITIAL_QUEUE_SIZE;
+  ToEnqueueIndex = 0;
+}
+
+mvm::gc** getReferent(mvm::gc* obj) {
+  llvm_gcroot(obj, 0);
+	mvm::VirtualMachine* vm = obj->getVirtualTable()->vm;
+	mvm::Thread::get()->attach(vm);
+	return vm->getReferent(obj);
+}
+
+void setReferent(mvm::gc* obj, mvm::gc* val) {
+  llvm_gcroot(obj, 0);
+  llvm_gcroot(val, 0);
+	mvm::VirtualMachine* vm = obj->getVirtualTable()->vm;
+	mvm::Thread::get()->attach(vm);
+	vm->setReferent(obj, val);
+}
+ 
+void invokeEnqueue(mvm::gc* obj) {
+  llvm_gcroot(obj, 0);
+  TRY {
+		mvm::VirtualMachine* vm = obj->getVirtualTable()->vm;
+		mvm::Thread::get()->attach(vm);
+		
+    vm->enqueueReference(obj);
+  } IGNORE;
+  mvm::Thread::get()->clearPendingException();
+}
+
+void ReferenceThread::enqueueStart(ReferenceThread* th) {
+	mvm::gc* res = NULL;
+  llvm_gcroot(res, 0);
+
+  while (true) {
+    th->EnqueueLock.lock();
+    while (th->ToEnqueueIndex == 0) {
+      th->EnqueueCond.wait(&th->EnqueueLock);
+    }
+    th->EnqueueLock.unlock();
+
+    while (true) {
+      th->ToEnqueueLock.acquire();
+      if (th->ToEnqueueIndex != 0) {
+        res = th->ToEnqueue[th->ToEnqueueIndex - 1];
+        --th->ToEnqueueIndex;
+      }
+      th->ToEnqueueLock.release();
+      if (!res) break;
+
+      invokeEnqueue(res);
+      res = NULL;
+    }
+  }
+}
+
+
+void ReferenceThread::addToEnqueue(mvm::gc* obj) {
+  llvm_gcroot(obj, 0);
+  if (ToEnqueueIndex >= ToEnqueueLength) {
+    uint32 newLength = ToEnqueueLength * GROW_FACTOR;
+		mvm::gc** newQueue = new mvm::gc*[newLength];
+    if (!newQueue) {
+      fprintf(stderr, "I don't know how to handle reference overflow yet!\n");
+      abort();
+    }   
+    for (uint32 i = 0; i < ToEnqueueLength; ++i) {
+      newQueue[i] = ToEnqueue[i];
+    }   
+    delete[] ToEnqueue;
+    ToEnqueue = newQueue;
+    ToEnqueueLength = newLength;
+  }
+  ToEnqueue[ToEnqueueIndex++] = obj;
+}
+
+mvm::gc* ReferenceQueue::processReference(mvm::gc* reference, ReferenceThread* th, uintptr_t closure) {
+  if (!mvm::Collector::isLive(reference, closure)) {
+    setReferent(reference, 0);
+    return NULL;
+  }
+
+	mvm::gc* referent = *(getReferent(reference));
+
+  if (!referent) {
+    return NULL;
+  }
+
+  if (semantics == SOFT) {
+    // TODO: are we are out of memory? Consider that we always are for now.
+    if (false) {
+      mvm::Collector::retainReferent(referent, closure);
+    }
+  } else if (semantics == PHANTOM) {
+    // Nothing to do.
+  }
+
+	mvm::gc* newReference =
+      mvm::Collector::getForwardedReference(reference, closure);
+  if (mvm::Collector::isLive(referent, closure)) {
+		mvm::gc* newReferent = mvm::Collector::getForwardedReferent(referent, closure);
+    setReferent(newReference, newReferent);
+    return newReference;
+  } else {
+    setReferent(newReference, 0);
+    th->addToEnqueue(newReference);
+    return NULL;
+  }
+}
+
+
+void ReferenceQueue::scan(ReferenceThread* th, uintptr_t closure) {
+  uint32 NewIndex = 0;
+
+  for (uint32 i = 0; i < CurrentIndex; ++i) {
+		mvm::gc* obj = References[i];
+		mvm::gc* res = processReference(obj, th, closure);
+    if (res) References[NewIndex++] = res;
+  }
+
+  CurrentIndex = NewIndex;
+}
+
+void ReferenceThread::tracer(uintptr_t closure) {
+  for (uint32 i = 0; i < ToEnqueueIndex; ++i) {
+    mvm::Collector::markAndTraceRoot(ToEnqueue + i, closure);
+  } 
+	MutatorThread::tracer(closure);
+}
+
+
 FinalizerThread::FinalizerThread(VMKit* vmkit) : MutatorThread(vmkit) {
   FinalizationQueue = new mvm::gc*[INITIAL_QUEUE_SIZE];
   QueueLength = INITIAL_QUEUE_SIZE;
@@ -125,7 +263,6 @@
 }
 
 void FinalizerThread::tracer(uintptr_t closure) {
-  // (5) Trace the finalization queue.
   for (uint32 i = 0; i < CurrentFinalizedIndex; ++i) {
     mvm::Collector::markAndTraceRoot(ToBeFinalized + i, closure);
   }

Modified: vmkit/branches/multi-vm/lib/Mvm/Runtime/VMKit.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/multi-vm/lib/Mvm/Runtime/VMKit.cpp?rev=121130&r1=121129&r2=121130&view=diff
==============================================================================
--- vmkit/branches/multi-vm/lib/Mvm/Runtime/VMKit.cpp (original)
+++ vmkit/branches/multi-vm/lib/Mvm/Runtime/VMKit.cpp Tue Dec  7 05:08:02 2010
@@ -17,6 +17,21 @@
   // First create system threads.
   finalizerThread = new FinalizerThread(this);
   finalizerThread->start((void (*)(mvm::Thread*))FinalizerThread::finalizerStart);
+
+  referenceThread = new ReferenceThread(this);
+  referenceThread->start((void (*)(mvm::Thread*))ReferenceThread::enqueueStart);
+}
+
+void VMKit::scanWeakReferencesQueue(uintptr_t closure) {
+  referenceThread->WeakReferencesQueue.scan(referenceThread, closure);
+}
+  
+void VMKit::scanSoftReferencesQueue(uintptr_t closure) {
+  referenceThread->SoftReferencesQueue.scan(referenceThread, closure);
+}
+  
+void VMKit::scanPhantomReferencesQueue(uintptr_t closure) {
+  referenceThread->PhantomReferencesQueue.scan(referenceThread, closure);
 }
 
 void VMKit::scanFinalizationQueue(uintptr_t closure) {
@@ -51,6 +66,10 @@
 		vmkitLock();
 
 		finalizerThread->FinalizationQueueLock.acquire();
+		referenceThread->ToEnqueueLock.acquire();
+		referenceThread->SoftReferencesQueue.acquire();
+		referenceThread->WeakReferencesQueue.acquire();
+		referenceThread->PhantomReferencesQueue.acquire();
 
 		// call first startCollection on each vm to avoid deadlock. 
 		// indeed, a vm could want to execute applicative code
@@ -74,6 +93,11 @@
 			vms[i]->endCollection();
 
   finalizerThread->FinalizationQueueLock.release();
+  referenceThread->ToEnqueueLock.release();
+  referenceThread->SoftReferencesQueue.release();
+  referenceThread->WeakReferencesQueue.release();
+  referenceThread->PhantomReferencesQueue.release();
+  referenceThread->EnqueueCond.broadcast();
   finalizerThread->FinalizationCond.broadcast();
 
 	vmkitUnlock();

Modified: vmkit/branches/multi-vm/mmtk/mmtk-j3/ReferenceProcessor.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/multi-vm/mmtk/mmtk-j3/ReferenceProcessor.cpp?rev=121130&r1=121129&r2=121130&view=diff
==============================================================================
--- vmkit/branches/multi-vm/mmtk/mmtk-j3/ReferenceProcessor.cpp (original)
+++ vmkit/branches/multi-vm/mmtk/mmtk-j3/ReferenceProcessor.cpp Tue Dec  7 05:08:02 2010
@@ -10,6 +10,8 @@
 
 #include "debug.h"
 #include "mvm/VirtualMachine.h"
+#include "mvm/VMKit.h"
+#include "mvm/SystemThreads.h"
 #include "MMTkObject.h"
 
 namespace mmtk {
@@ -19,12 +21,12 @@
   uint32_t val = RP->ordinal;
 
   if (val == 0) {
-    th->MyVM->scanSoftReferencesQueue(TL);
+    th->vmkit->scanSoftReferencesQueue(TL);
   } else if (val == 1) {
-    th->MyVM->scanWeakReferencesQueue(TL);
+    th->vmkit->scanWeakReferencesQueue(TL);
   } else {
     assert(val == 2);
-    th->MyVM->scanPhantomReferencesQueue(TL);
+    th->vmkit->scanPhantomReferencesQueue(TL);
   }
 }
 





More information about the vmkit-commits mailing list