[vmkit-commits] [vmkit] r72413 - in /vmkit/trunk: include/mvm/VirtualMachine.h lib/JnJVM/Classpath/ClasspathReflect.h lib/JnJVM/Classpath/ClasspathVMRuntime.cpp lib/JnJVM/VMCore/JavaMetaJIT.cpp lib/JnJVM/VMCore/JavaUpcalls.cpp lib/JnJVM/VMCore/JavaUpcalls.h lib/JnJVM/VMCore/Jnjvm.cpp lib/JnJVM/VMCore/Jnjvm.h lib/Mvm/GCMmap2/gccollector.cpp lib/Mvm/Runtime/Object.cpp

Nicolas Geoffray nicolas.geoffray at lip6.fr
Tue May 26 01:48:29 PDT 2009


Author: geoffray
Date: Tue May 26 03:48:28 2009
New Revision: 72413

URL: http://llvm.org/viewvc/llvm-project?rev=72413&view=rev
Log:
Support for weak/soft/phantom references.


Modified:
    vmkit/trunk/include/mvm/VirtualMachine.h
    vmkit/trunk/lib/JnJVM/Classpath/ClasspathReflect.h
    vmkit/trunk/lib/JnJVM/Classpath/ClasspathVMRuntime.cpp
    vmkit/trunk/lib/JnJVM/VMCore/JavaMetaJIT.cpp
    vmkit/trunk/lib/JnJVM/VMCore/JavaUpcalls.cpp
    vmkit/trunk/lib/JnJVM/VMCore/JavaUpcalls.h
    vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.cpp
    vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.h
    vmkit/trunk/lib/Mvm/GCMmap2/gccollector.cpp
    vmkit/trunk/lib/Mvm/Runtime/Object.cpp

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

==============================================================================
--- vmkit/trunk/include/mvm/VirtualMachine.h (original)
+++ vmkit/trunk/include/mvm/VirtualMachine.h Tue May 26 03:48:28 2009
@@ -36,15 +36,72 @@
 #define INITIAL_QUEUE_SIZE 256
 #define GROW_FACTOR 2
 
+class VirtualMachine;
+
+class ReferenceQueue {
+private:
+  gc** References;
+  uint32 QueueLength;
+  uint32 CurrentIndex;
+  mvm::SpinLock QueueLock;
+  uint8_t semantics;
+
+  gc* processReference(gc*, VirtualMachine*);
+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 gc*[INITIAL_QUEUE_SIZE];
+    QueueLength = INITIAL_QUEUE_SIZE;
+    CurrentIndex = 0;
+    semantics = s;
+  }
+ 
+  void addReference(gc* ref) {
+    QueueLock.acquire();
+    if (CurrentIndex >= QueueLength) {
+      uint32 newLength = QueueLength * GROW_FACTOR;
+      gc** newQueue = new gc*[newLength];
+      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(VirtualMachine* vm);
+};
 
 
 /// VirtualMachine - This class is the root of virtual machine classes. It
 /// defines what a VM should be.
 ///
 class VirtualMachine : public mvm::PermanentObject {
+  friend class ReferenceQueue;
+
 protected:
 
-  VirtualMachine() {
+  VirtualMachine() :
+    WeakReferencesQueue(ReferenceQueue::WEAK),
+    SoftReferencesQueue(ReferenceQueue::SOFT), 
+    PhantomReferencesQueue(ReferenceQueue::PHANTOM) {
 #ifdef SERVICE
     memoryLimit = ~0;
     executionLimit = ~0;
@@ -56,9 +113,15 @@
 #endif
     FinalizationQueue = new gc*[INITIAL_QUEUE_SIZE];
     QueueLength = INITIAL_QUEUE_SIZE;
+    CurrentIndex = 0;
 
     ToBeFinalized = new gc*[INITIAL_QUEUE_SIZE];
     ToBeFinalizedLength = INITIAL_QUEUE_SIZE;
+    CurrentFinalizedIndex = 0;
+    
+    ToEnqueue = new gc*[INITIAL_QUEUE_SIZE];
+    ToEnqueueLength = INITIAL_QUEUE_SIZE;
+    ToEnqueueIndex = 0;
   }
 public:
 
@@ -82,6 +145,19 @@
 
     
 private:
+  /// WeakReferencesQueue - The queue of weak references.
+  ///
+  ReferenceQueue WeakReferencesQueue;
+
+  /// SoftReferencesQueue - The queue of soft references.
+  ///
+  ReferenceQueue SoftReferencesQueue;
+
+  /// PhantomReferencesQueue - The queue of phantom references.
+  ///
+  ReferenceQueue PhantomReferencesQueue;
+
+  
   /// FinalizationQueueLock - A lock to protect access to the queue.
   ///
   mvm::SpinLock FinalizationQueueLock;
@@ -128,6 +204,32 @@
   /// finalizationLock - Lock for the condition variable.
   ///
   mvm::LockNormal FinalizationLock;
+  
+  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(gc* obj) {
+    if (ToEnqueueIndex >= ToEnqueueLength) {
+      uint32 newLength = ToEnqueueLength * GROW_FACTOR;
+      gc** newQueue = new gc*[newLength];
+      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] = ToEnqueue[i];
+      delete[] ToEnqueue;
+      ToEnqueue = newQueue;
+      ToEnqueueLength = newLength;
+    }
+    ToEnqueue[ToEnqueueIndex++] = obj;
+  }
 
 protected:
   /// invokeFinalizer - Invoke the finalizer of the object. This may involve
@@ -141,6 +243,11 @@
   /// finalizationQueue.
   ///
   static void finalizerStart(mvm::Thread*);
+  
+  /// enqueueStart - The start function of a thread for references. Will poll
+  /// ToEnqueue.
+  ///
+  static void enqueueStart(mvm::Thread*);
 
   /// addFinalizationCandidate - Add an object to the queue of objects with
   /// a finalization method.
@@ -155,14 +262,81 @@
   /// wakeUpFinalizers - Wake the finalizers.
   ///
   void wakeUpFinalizers() { FinalizationCond.broadcast(); }
+  
+  /// wakeUpEnqueue - Wake the threads for enqueueing.
+  ///
+  void wakeUpEnqueue() { EnqueueCond.broadcast(); }
 
   virtual void startCollection() {
     FinalizationQueueLock.acquire();
+    ToEnqueueLock.acquire();
+    SoftReferencesQueue.acquire();
+    WeakReferencesQueue.acquire();
+    PhantomReferencesQueue.acquire();
   }
   
   virtual void endCollection() {
     FinalizationQueueLock.release();
+    ToEnqueueLock.release();
+    SoftReferencesQueue.release();
+    WeakReferencesQueue.release();
+    PhantomReferencesQueue.release();
+  }
+  
+  /// scanWeakReferencesQueue - Scan all weak references. Called by the GC
+  /// before scanning the finalization queue.
+  /// 
+  void scanWeakReferencesQueue() {
+    WeakReferencesQueue.scan(this);
   }
+  
+  /// scanSoftReferencesQueue - Scan all soft references. Called by the GC
+  /// before scanning the finalization queue.
+  ///
+  void scanSoftReferencesQueue() {
+    SoftReferencesQueue.scan(this);
+  }
+  
+  /// scanPhantomReferencesQueue - Scan all phantom references. Called by the GC
+  /// after the finalization queue.
+  ///
+  void scanPhantomReferencesQueue() {
+    PhantomReferencesQueue.scan(this);
+  }
+  
+  /// addWeakReference - Add a weak reference to the queue.
+  ///
+  void addWeakReference(gc* ref) {
+    WeakReferencesQueue.addReference(ref);
+  }
+  
+  /// addSoftReference - Add a weak reference to the queue.
+  ///
+  void addSoftReference(gc* ref) {
+    SoftReferencesQueue.addReference(ref);
+  }
+  
+  /// addPhantomReference - Add a weak reference to the queue.
+  ///
+  void addPhantomReference(gc* ref) {
+    PhantomReferencesQueue.addReference(ref);
+  }
+
+  /// clearReferent - Clear the referent in a reference. Should be overriden
+  /// by the VM.
+  ///
+  virtual void clearReferent(gc*) {}
+
+  /// getReferent - Get the referent of the reference. Should be overriden
+  /// by the VM.
+  //
+  virtual gc* getReferent(gc*) { return 0; }
+
+  /// enqueueReference - Calls the enqueue method. Should be overriden
+  /// by the VM.
+  ///
+  virtual bool enqueueReference(gc*) { return false; }
+
 
 protected:
 

Modified: vmkit/trunk/lib/JnJVM/Classpath/ClasspathReflect.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/Classpath/ClasspathReflect.h?rev=72413&r1=72412&r2=72413&view=diff

==============================================================================
--- vmkit/trunk/lib/JnJVM/Classpath/ClasspathReflect.h (original)
+++ vmkit/trunk/lib/JnJVM/Classpath/ClasspathReflect.h Tue May 26 03:48:28 2009
@@ -153,6 +153,27 @@
   }
 };
 
+class JavaObjectReference : public JavaObject {
+private:
+  JavaObject* referent;
+  JavaObject* queue;
+  JavaObject* nextOnQueue;
+
+public:
+  void init(JavaObject* r, JavaObject* q) {
+    referent = r;
+    queue = q;
+  }
+
+  JavaObject* getReferent() const { return referent; }
+  void setReferent(JavaObject* r) { referent = r; }
+  
+  static void STATIC_TRACER(JavaObjectReference) {
+    obj->queue->MARK_AND_TRACE;
+    obj->nextOnQueue->MARK_AND_TRACE;
+  }
+};
+
 }
 
 #endif

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

==============================================================================
--- vmkit/trunk/lib/JnJVM/Classpath/ClasspathVMRuntime.cpp (original)
+++ vmkit/trunk/lib/JnJVM/Classpath/ClasspathVMRuntime.cpp Tue May 26 03:48:28 2009
@@ -143,6 +143,10 @@
 jclass clazz,
 #endif
 ) {
+  Jnjvm* vm = JavaThread::get()->getJVM();
+  vm->wakeUpFinalizers();
+  // Sleep a bit.
+  sleep(1);
   return;
 }
 

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

==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JavaMetaJIT.cpp (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JavaMetaJIT.cpp Tue May 26 03:48:28 2009
@@ -634,3 +634,9 @@
   meth->invokeIntVirtualBuf(this, cl, obj, 0);
 }
 
+bool Jnjvm::enqueueReference(gc* _obj) {
+  JavaObject* obj = (JavaObject*)_obj;
+  JavaMethod* meth = upcalls->EnqueueReference;
+  UserClass* cl = obj->getClass()->asClass();
+  return (bool)meth->invokeIntSpecialBuf(this, cl, obj, 0);
+}

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

==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JavaUpcalls.cpp (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JavaUpcalls.cpp Tue May 26 03:48:28 2009
@@ -18,12 +18,12 @@
 
 #define COMPILE_METHODS(cl) \
   for (CommonClass::method_iterator i = cl->virtualMethods.begin(), \
-            e = cl->virtualMethods.end(); i!= e; +i) { \
+            e = cl->virtualMethods.end(); i!= e; ++i) { \
     i->second->compiledPtr(); \
   } \
   \
   for (CommonClass::method_iterator i = cl->staticMethods.begin(), \
-            e = cl->staticMethods.end(); i!= e; +i) { \
+            e = cl->staticMethods.end(); i!= e; ++i) { \
     i->second->compiledPtr(); \
   }
 
@@ -216,6 +216,9 @@
 JavaField* Classpath::fieldClass;
 JavaField* Classpath::constructorClass;
 
+JavaMethod* Classpath::EnqueueReference;
+Class*      Classpath::newReference;
+
 #endif
 
 void Classpath::CreateJavaThread(Jnjvm* vm, JavaThread* myth,
@@ -262,9 +265,51 @@
   JavaObject* systemName = (JavaObject*)vm->asciizToStr("system");
   groupName->setObjectField(SystemGroup, systemName);
 
-  // And create the finalizer thread.
+  // Create the finalizer thread.
   assert(vm->getFinalizerThread() && "VM did not set its finalizer thread");
   CreateJavaThread(vm, vm->getFinalizerThread(), "Finalizer", SystemGroup);
+  
+  // Create the enqueue thread.
+  assert(vm->getEnqueueThread() && "VM did not set its enqueue thread");
+  CreateJavaThread(vm, vm->getEnqueueThread(), "Reference", SystemGroup);
+}
+
+extern "C" void nativeInitWeakReference(JavaObjectReference* reference,
+                                        JavaObject* referent) {
+  reference->init(referent, 0);
+  JavaThread::get()->getJVM()->addWeakReference(reference);
+
+}
+
+extern "C" void nativeInitWeakReferenceQ(JavaObjectReference* reference,
+                                         JavaObject* referent,
+                                         JavaObject* queue) {
+  reference->init(referent, queue);
+  JavaThread::get()->getJVM()->addWeakReference(reference);
+
+}
+
+extern "C" void nativeInitSoftReference(JavaObjectReference* reference,
+                                        JavaObject* referent) {
+  reference->init(referent, 0);
+  JavaThread::get()->getJVM()->addSoftReference(reference);
+
+}
+
+extern "C" void nativeInitSoftReferenceQ(JavaObjectReference* reference,
+                                         JavaObject* referent,
+                                         JavaObject* queue) {
+  reference->init(referent, queue);
+  JavaThread::get()->getJVM()->addSoftReference(reference);
+
+}
+
+extern "C" void nativeInitPhantomReferenceQ(JavaObjectReference* reference,
+                                            JavaObject* referent,
+                                            JavaObject* queue) {
+  reference->init(referent, queue);
+  JavaThread::get()->getJVM()->addPhantomReference(reference);
+
 }
 
 extern "C" JavaString* nativeInternString(JavaString* obj) {
@@ -359,6 +404,10 @@
   JavaObjectConstructor::staticTracer(obj);
 }
 
+extern "C" void nativeJavaObjectReferenceTracer(JavaObjectReference* obj) {
+  JavaObjectReference::staticTracer(obj);
+}
+
 extern "C" void nativeJavaObjectVMThreadDestructor(JavaObjectVMThread* obj) {
   JavaObjectVMThread::staticDestructor(obj);
 }
@@ -833,4 +882,63 @@
    newVMThread->getVirtualVT()->setNativeDestructor(
       (uintptr_t)nativeJavaObjectVMThreadDestructor,
       "nativeJavaObjectVMThreadDestructor");
+
+   
+  newReference = UPCALL_CLASS(loader, "java/lang/ref/Reference");
+    
+  newReference->getVirtualVT()->setNativeTracer(
+      (uintptr_t)nativeJavaObjectReferenceTracer,
+      "nativeJavaObjectReferenceTracer");
+  
+  EnqueueReference = 
+    UPCALL_METHOD(loader, "java/lang/ref/Reference",  "enqueue", "()Z",
+                  ACC_VIRTUAL);
+ 
+  JavaMethod* initWeakReference =
+    UPCALL_METHOD(loader, "java/lang/ref/WeakReference", "<init>",
+                  "(Ljava/lang/Object;)V",
+                  ACC_VIRTUAL);
+  initWeakReference->setCompiledPtr((void*)(intptr_t)nativeInitWeakReference,
+                                    "nativeInitWeakReference");
+  
+  initWeakReference =
+    UPCALL_METHOD(loader, "java/lang/ref/WeakReference", "<init>",
+                  "(Ljava/lang/Object;Ljava/lang/ref/ReferenceQueue;)V",
+                  ACC_VIRTUAL);
+  initWeakReference->setCompiledPtr((void*)(intptr_t)nativeInitWeakReferenceQ,
+                                    "nativeInitWeakReferenceQ");
+  
+  JavaMethod* initSoftReference =
+    UPCALL_METHOD(loader, "java/lang/ref/SoftReference", "<init>",
+                  "(Ljava/lang/Object;)V",
+                  ACC_VIRTUAL);
+  initSoftReference->setCompiledPtr((void*)(intptr_t)nativeInitSoftReference,
+                                    "nativeInitSoftReference");
+  
+  initSoftReference =
+    UPCALL_METHOD(loader, "java/lang/ref/WeakReference", "<init>",
+                  "(Ljava/lang/Object;Ljava/lang/ref/ReferenceQueue;)V",
+                  ACC_VIRTUAL);
+  initSoftReference->setCompiledPtr((void*)(intptr_t)nativeInitSoftReferenceQ,
+                                    "nativeInitSoftReferenceQ");
+  
+  JavaMethod* initPhantomReference =
+    UPCALL_METHOD(loader, "java/lang/ref/PhantomReference", "<init>",
+                  "(Ljava/lang/Object;Ljava/lang/ref/ReferenceQueue;)V",
+                  ACC_VIRTUAL);
+  initPhantomReference->setCompiledPtr(
+      (void*)(intptr_t)nativeInitPhantomReferenceQ,
+      "nativeInitPhantomReferenceQ");
+  
+
+}
+
+gc* Jnjvm::getReferent(gc* _obj) {
+  JavaObjectReference* obj = (JavaObjectReference*)_obj;
+  return obj->getReferent();
+ }
+ 
+void Jnjvm::clearReferent(gc* _obj) {
+  JavaObjectReference* obj = (JavaObjectReference*)_obj;
+  obj->setReferent(0);
 }

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

==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JavaUpcalls.h (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JavaUpcalls.h Tue May 26 03:48:28 2009
@@ -252,6 +252,9 @@
   ISOLATE_STATIC JavaField* fieldClass;
   ISOLATE_STATIC JavaField* constructorClass;
   
+  ISOLATE_STATIC JavaMethod* EnqueueReference;
+  ISOLATE_STATIC Class*      newReference;
+
 private:
   ISOLATE_STATIC void CreateJavaThread(Jnjvm* vm, JavaThread* myth,
                                        const char* name, JavaObject* Group);

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

==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.cpp (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.cpp Tue May 26 03:48:28 2009
@@ -1205,6 +1205,9 @@
     finalizerThread = new JavaThread(0, 0, this);
     finalizerThread->start((void (*)(mvm::Thread*))finalizerStart);
     
+    enqueueThread = new JavaThread(0, 0, this);
+    enqueueThread->start((void (*)(mvm::Thread*))enqueueStart);
+    
     mainThread = new JavaThread(0, 0, this);
     mainThread->start((void (*)(mvm::Thread*))mainJavaStart);
   } else {

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

==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.h (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.h Tue May 26 03:48:28 2009
@@ -120,7 +120,11 @@
   /// finalizerThread - The thread that finalizes Java objects.
   ///
   JavaThread* finalizerThread;
-  
+ 
+  /// enqueueThread - The thread that enqueue Java references.
+  ///
+  JavaThread* enqueueThread;
+
   /// CreateError - Creates a Java object of the specified exception class
   /// and calling its <init> function.
   ///
@@ -315,6 +319,14 @@
   /// getFinalizerThread - Get the finalizer thread of this VM.
   ///
   JavaThread* getFinalizerThread() const { return finalizerThread; }
+  
+  /// setEnqueueThread - Set the enqueue thread of this VM.
+  ///
+  void setEnqueueThread(JavaThread* th) { enqueueThread = th; }
+  
+  /// getEnqueueThread - Get the enqueue thread of this VM.
+  ///
+  JavaThread* getEnqueueThread() const { return enqueueThread; }
 
   /// ~Jnjvm - Destroy the JVM.
   ///
@@ -367,6 +379,10 @@
     hashStr.lock.unlock();
   }
 
+  virtual void clearReferent(gc*);
+  virtual gc* getReferent(gc*);
+  virtual bool enqueueReference(gc*);
+
 protected:
   virtual void invokeFinalizer(gc*);
 

Modified: vmkit/trunk/lib/Mvm/GCMmap2/gccollector.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/Mvm/GCMmap2/gccollector.cpp?rev=72413&r1=72412&r2=72413&view=diff

==============================================================================
--- vmkit/trunk/lib/Mvm/GCMmap2/gccollector.cpp (original)
+++ vmkit/trunk/lib/Mvm/GCMmap2/gccollector.cpp Tue May 26 03:48:28 2009
@@ -58,22 +58,31 @@
 
   mvm::Thread* tcur = th;
 
-  // First, trace the VM.
+  // (1) Trace the VM.
   th->MyVM->tracer();
 
-  // Second, trace the threads.
+  // (2) Trace the threads.
   do {
     th->tracer();
     tcur = (mvm::Thread*)tcur->next();
   } while (tcur != th);
 
-  // Third, trace stack objects.
+  // (3) Trace stack objects.
   for(cur=used_nodes->next(); cur!=used_nodes; cur=cur->next())
     trace(cur);
 
-  // Fourth, trace the finalization queue.
+  // (4) Trace the weak reference queue.
+  th->MyVM->scanWeakReferencesQueue();
+
+  // (5) Trace the soft reference queue.
+  th->MyVM->scanSoftReferencesQueue();
+  
+  // (6) Trace the finalization queue.
   th->MyVM->scanFinalizationQueue();
 
+  // (7) Trace the phantom reference queue.
+  th->MyVM->scanPhantomReferencesQueue();
+
   if(_marker)
     _marker(0);
   status = stat_finalize;
@@ -104,6 +113,7 @@
   threads->collectionFinished();
 #endif
   th->MyVM->wakeUpFinalizers();
+  th->MyVM->wakeUpEnqueue();
 }
 
 void GCCollector::collect_unprotect() {

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

==============================================================================
--- vmkit/trunk/lib/Mvm/Runtime/Object.cpp (original)
+++ vmkit/trunk/lib/Mvm/Runtime/Object.cpp Tue May 26 03:48:28 2009
@@ -145,6 +145,34 @@
   }
 }
 
+void VirtualMachine::enqueueStart(mvm::Thread* th) {
+  VirtualMachine* vm = th->MyVM;
+
+  while (true) {
+    vm->EnqueueLock.lock();
+    while (vm->ToEnqueueIndex == 0) {
+      vm->EnqueueCond.wait(&vm->EnqueueLock);
+    }
+    vm->EnqueueLock.unlock();
+
+    while (true) {
+      vm->ToEnqueueLock.acquire();
+      gc* res = 0;
+      if (vm->ToEnqueueIndex != 0) {
+        res = vm->ToEnqueue[--vm->ToEnqueueIndex];
+      }
+      vm->ToEnqueueLock.release();
+      if (!res) break;
+
+      try {
+        vm->enqueueReference(res);
+      } catch(...) {
+      }
+      th->clearException();
+    }
+  }
+}
+
 void VirtualMachine::growFinalizationQueue() {
   if (CurrentIndex >= QueueLength) {
     uint32 newLength = QueueLength * GROW_FACTOR;
@@ -212,3 +240,44 @@
     obj->markAndTrace();
   }
 }
+
+gc* ReferenceQueue::processReference(gc* reference, VirtualMachine* vm) {
+  if (!Collector::isLive(reference)) {
+    vm->clearReferent(reference);
+    return 0;
+  }
+
+  gc* referent = vm->getReferent(reference);
+
+  if (!referent) return 0;
+
+  if (semantics == SOFT) {
+    // TODO: are we are out of memory? Consider that we always are for now.
+    if (false) {
+      referent->markAndTrace();
+    }
+  } else if (semantics == PHANTOM) {
+    // Nothing to do.
+  }
+
+  if (Collector::isLive(referent)) {
+    return reference;
+  } else {
+    vm->clearReferent(reference);
+    vm->addToEnqueue(reference);
+    return 0;
+  }
+}
+
+
+void ReferenceQueue::scan(VirtualMachine* vm) {
+  uint32 NewIndex = 0;
+
+  for (uint32 i = 0; i < CurrentIndex; ++i) {
+    gc* obj = References[i];
+    gc* res = processReference(obj, vm);
+    if (res) References[NewIndex++] = res;
+  }
+
+  CurrentIndex = NewIndex;
+}





More information about the vmkit-commits mailing list