[vmkit-commits] [vmkit] r117226 - in /vmkit/branches/precise: include/mvm/VirtualMachine.h lib/J3/Classpath/ClasspathVMRuntime.inc lib/J3/Classpath/JavaUpcalls.cpp lib/J3/VMCore/JavaMetaJIT.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/GCMmap2/gccollector.cpp lib/Mvm/Runtime/Object.cpp mmtk/mmtk-j3/Collection.cpp

Nicolas Geoffray nicolas.geoffray at lip6.fr
Sun Oct 24 07:37:39 PDT 2010


Author: geoffray
Date: Sun Oct 24 09:37:39 2010
New Revision: 117226

URL: http://llvm.org/viewvc/llvm-project?rev=117226&view=rev
Log:
Refactor code around references and finalizer. Now the VM only has empty stubs for them.


Added:
    vmkit/branches/precise/lib/J3/VMCore/ReferenceQueue.cpp
    vmkit/branches/precise/lib/J3/VMCore/ReferenceQueue.h
Modified:
    vmkit/branches/precise/include/mvm/VirtualMachine.h
    vmkit/branches/precise/lib/J3/Classpath/ClasspathVMRuntime.inc
    vmkit/branches/precise/lib/J3/Classpath/JavaUpcalls.cpp
    vmkit/branches/precise/lib/J3/VMCore/JavaMetaJIT.cpp
    vmkit/branches/precise/lib/J3/VMCore/Jnjvm.cpp
    vmkit/branches/precise/lib/J3/VMCore/Jnjvm.h
    vmkit/branches/precise/lib/J3/VMCore/VirtualTables.cpp
    vmkit/branches/precise/lib/Mvm/GCMmap2/gccollector.cpp
    vmkit/branches/precise/lib/Mvm/Runtime/Object.cpp
    vmkit/branches/precise/mmtk/mmtk-j3/Collection.cpp

Modified: vmkit/branches/precise/include/mvm/VirtualMachine.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/precise/include/mvm/VirtualMachine.h?rev=117226&r1=117225&r2=117226&view=diff
==============================================================================
--- vmkit/branches/precise/include/mvm/VirtualMachine.h (original)
+++ vmkit/branches/precise/include/mvm/VirtualMachine.h Sun Oct 24 09:37:39 2010
@@ -6,11 +6,6 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-//
-// Ultimately, this would be like a generic way of defining a VM. But we're not
-// quite there yet.
-//
-//===----------------------------------------------------------------------===//
 
 #ifndef MVM_VIRTUALMACHINE_H
 #define MVM_VIRTUALMACHINE_H
@@ -30,8 +25,6 @@
   class JnjvmClassLoader;
 }
 
-class gc;
-
 namespace mvm {
 
 class FunctionMap {
@@ -57,84 +50,16 @@
   FunctionMap();
 };
 
-
-// Same values than JikesRVM
-#define INITIAL_QUEUE_SIZE 256
-#define GROW_FACTOR 2
-
 class CompilationUnit;
-class VirtualMachine;
-
-class ReferenceQueue {
-private:
-  gc** References;
-  uint32 QueueLength;
-  uint32 CurrentIndex;
-  mvm::SpinLock QueueLock;
-  uint8_t semantics;
-
-  gc* processReference(gc*, VirtualMachine*, 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 gc*[INITIAL_QUEUE_SIZE];
-    QueueLength = INITIAL_QUEUE_SIZE;
-    CurrentIndex = 0;
-    semantics = s;
-  }
-
-  ~ReferenceQueue() {
-    delete[] References;
-  }
- 
-  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, uintptr_t closure);
-};
 
 /// 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(mvm::BumpPtrAllocator &Alloc) :
-		allocator(Alloc),
-    WeakReferencesQueue(ReferenceQueue::WEAK),
-    SoftReferencesQueue(ReferenceQueue::SOFT), 
-    PhantomReferencesQueue(ReferenceQueue::PHANTOM) {
+		allocator(Alloc) {
 #ifdef SERVICE
     memoryLimit = ~0;
     executionLimit = ~0;
@@ -144,21 +69,14 @@
     status = 1;
     _since_last_collection = 4*1024*1024;
 #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;
-    
     mainThread = 0;
     NumberOfThreads = 0;
   }
+
+  virtual ~VirtualMachine() {
+    if (scanner) delete scanner;
+  }
+
 public:
 
   /// allocator - Bump pointer allocator to allocate permanent memory
@@ -166,6 +84,10 @@
   ///
   mvm::BumpPtrAllocator& allocator;
 
+//===----------------------------------------------------------------------===//
+// (1) Thread-related methods.
+//===----------------------------------------------------------------------===//
+
   /// mainThread - The main thread of this VM.
   ///
   mvm::Thread* mainThread;
@@ -210,227 +132,46 @@
   }
 
 
-  virtual void tracer(uintptr_t closure);
-
-  virtual ~VirtualMachine() {
-    if (scanner) delete scanner;
-    delete[] FinalizationQueue;
-    delete[] ToBeFinalized;
-    delete[] ToEnqueue;
-  }
-
-  /// runApplication - Run an application. The application name is in
-  /// the arguments, hence it is the virtual machine's job to parse them.
-  virtual void runApplication(int argc, char** argv) = 0;
-  
-  /// waitForExit - Wait until the virtual machine stops its execution.
-  virtual void waitForExit() = 0;
-
-  static j3::JnjvmClassLoader* initialiseJVM(j3::JavaCompiler* C,
-                                                bool dlLoad = true);
-  static VirtualMachine* createJVM(j3::JnjvmClassLoader* C = 0);
-  
-  static CompilationUnit* initialiseCLIVM();
-  static VirtualMachine* createCLIVM(CompilationUnit* C = 0);
-
-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;
-
-  /// finalizationQueue - A list of allocated objets that contain a finalize
-  /// method.
-  ///
-  gc** FinalizationQueue;
-
-  /// CurrentIndex - Current index in the queue of finalizable objects.
-  ///
-  uint32 CurrentIndex;
-
-  /// QueueLength - Current length of the queue of finalizable objects.
-  ///
-  uint32 QueueLength;
-
-  /// growFinalizationQueue - Grow the queue of finalizable objects.
-  ///
-  void growFinalizationQueue();
-  
-  /// ToBeFinalized - List of objects that are scheduled to be finalized.
-  ///
-  gc** ToBeFinalized;
-  
-  /// ToBeFinalizedLength - Current length of the queue of objects scheduled
-  /// for finalization.
-  ///
-  uint32 ToBeFinalizedLength;
-
-  /// CurrentFinalizedIndex - The current index in the ToBeFinalized queue
-  /// that will be sceduled for finalization.
-  ///
-  uint32 CurrentFinalizedIndex;
-  
-  /// growToBeFinalizedQueue - Grow the queue of the to-be finalized objects.
-  ///
-  void growToBeFinalizedQueue();
-  
-  /// finalizationCond - Condition variable to wake up finalization threads.
-  ///
-  mvm::Cond FinalizationCond;
-
-  /// 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 < ToEnqueueLength; ++i) {
-        newQueue[i] = ToEnqueue[i];
-      }
-      delete[] ToEnqueue;
-      ToEnqueue = newQueue;
-      ToEnqueueLength = newLength;
-    }
-    ToEnqueue[ToEnqueueIndex++] = obj;
-  }
-
-public:
-  /// invokeFinalizer - Invoke the finalizer of the object. This may involve
-  /// changing the environment, e.g. going to native to Java.
-  ///
-  virtual void invokeFinalizer(gc*) {}
-  
-  /// enqueueReference - Calls the enqueue method. Should be overriden
-  /// by the VM.
-  ///
-  virtual bool enqueueReference(gc*) { return false; }
-  
-  /// finalizerStart - The start function of a finalizer. Will poll the
-  /// 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.
-  ///
-  void addFinalizationCandidate(gc*);
-  
-  /// scanFinalizationQueue - Scan objets with a finalized method and schedule
-  /// them for finalization if they are not live.
-  ///
-  void scanFinalizationQueue(uintptr_t closure);
+//===----------------------------------------------------------------------===//
+// (2) GC-related methods.
+//===----------------------------------------------------------------------===//
 
-  /// wakeUpFinalizers - Wake the finalizers.
+  /// startCollection - Preliminary code before starting a GC.
   ///
-  void wakeUpFinalizers() { FinalizationCond.broadcast(); }
+  virtual void startCollection() {}
   
-  /// wakeUpEnqueue - Wake the threads for enqueueing.
+  /// endCollection - Code after running a GC.
   ///
-  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();
-  }
+  virtual void endCollection() {}
   
   /// scanWeakReferencesQueue - Scan all weak references. Called by the GC
   /// before scanning the finalization queue.
   /// 
-  void scanWeakReferencesQueue(uintptr_t closure) {
-    WeakReferencesQueue.scan(this, closure);
-  }
+  virtual void scanWeakReferencesQueue(uintptr_t closure) {}
   
   /// scanSoftReferencesQueue - Scan all soft references. Called by the GC
   /// before scanning the finalization queue.
   ///
-  void scanSoftReferencesQueue(uintptr_t closure) {
-    SoftReferencesQueue.scan(this, closure);
-  }
+  virtual void scanSoftReferencesQueue(uintptr_t closure) {}
   
   /// scanPhantomReferencesQueue - Scan all phantom references. Called by the GC
   /// after the finalization queue.
   ///
-  void scanPhantomReferencesQueue(uintptr_t closure) {
-    PhantomReferencesQueue.scan(this, closure);
-  }
-  
-  /// 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);
-  }
+  virtual void scanPhantomReferencesQueue(uintptr_t closure) {}
 
-  /// clearReferent - Clear the referent in a reference. Should be overriden
-  /// by the VM.
-  ///
-  virtual void clearReferent(gc*) {}
+  /// scanFinalizationQueue - Scan objets with a finalized method and schedule
+  /// them for finalization if they are not live.
+  /// 
+  virtual void scanFinalizationQueue(uintptr_t closure) {}
 
-  /// getReferent - Get the referent of the reference. Should be overriden
-  /// by the VM.
-  //
-  virtual gc** getReferentPtr(gc*) { return 0; }
-  
-  /// setReferent - Set the referent of the reference. Should be overriden
-  /// by the VM.
-  virtual void setReferent(gc* reference, gc* referent) { }
+  /// addFinalizationCandidate - Add an object to the queue of objects with
+  /// a finalization method.
+  ///
+  virtual void addFinalizationCandidate(gc* object) {}
 
-public:
+  /// tracer - Trace this virtual machine's GC-objects.
+  ///
+  virtual void tracer(uintptr_t closure) {}
 
   /// scanner - Scanner of threads' stacks.
   ///
@@ -448,10 +189,32 @@
   UncooperativeCollectionRV rendezvous;
 #endif
 
+//===----------------------------------------------------------------------===//
+// (3) Backtrace-related methods.
+//===----------------------------------------------------------------------===//
+
   FunctionMap FunctionsCache;
   MethodInfo* IPToMethodInfo(void* ip) {
     return FunctionsCache.IPToMethodInfo(ip);
   }
+  
+//===----------------------------------------------------------------------===//
+// (4) Launch-related methods.
+//===----------------------------------------------------------------------===//
+
+  /// runApplication - Run an application. The application name is in
+  /// the arguments, hence it is the virtual machine's job to parse them.
+  virtual void runApplication(int argc, char** argv) = 0;
+  
+  /// waitForExit - Wait until the virtual machine stops its execution.
+  virtual void waitForExit() = 0;
+
+  static j3::JnjvmClassLoader* initialiseJVM(j3::JavaCompiler* C,
+                                                bool dlLoad = true);
+  static VirtualMachine* createJVM(j3::JnjvmClassLoader* C = 0);
+  
+  static CompilationUnit* initialiseCLIVM();
+  static VirtualMachine* createCLIVM(CompilationUnit* C = 0);
 
 #ifdef ISOLATE
   size_t IsolateID;
@@ -477,6 +240,5 @@
 
 };
 
-
 } // end namespace mvm
 #endif // MVM_VIRTUALMACHINE_H

Modified: vmkit/branches/precise/lib/J3/Classpath/ClasspathVMRuntime.inc
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/precise/lib/J3/Classpath/ClasspathVMRuntime.inc?rev=117226&r1=117225&r2=117226&view=diff
==============================================================================
--- vmkit/branches/precise/lib/J3/Classpath/ClasspathVMRuntime.inc (original)
+++ vmkit/branches/precise/lib/J3/Classpath/ClasspathVMRuntime.inc Sun Oct 24 09:37:39 2010
@@ -150,8 +150,7 @@
 jclass clazz,
 #endif
 ) {
-  Jnjvm* vm = JavaThread::get()->getJVM();
-  vm->wakeUpFinalizers();
+  mvm::Collector::collect();
   // Sleep a bit.
   sleep(1);
   return;

Modified: vmkit/branches/precise/lib/J3/Classpath/JavaUpcalls.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/precise/lib/J3/Classpath/JavaUpcalls.cpp?rev=117226&r1=117225&r2=117226&view=diff
==============================================================================
--- vmkit/branches/precise/lib/J3/Classpath/JavaUpcalls.cpp (original)
+++ vmkit/branches/precise/lib/J3/Classpath/JavaUpcalls.cpp Sun Oct 24 09:37:39 2010
@@ -15,6 +15,7 @@
 #include "JavaThread.h"
 #include "JavaUpcalls.h"
 #include "Jnjvm.h"
+#include "ReferenceQueue.h"
 
 #define COMPILE_METHODS(cl) \
   for (CommonClass::method_iterator i = cl->virtualMethods.begin(), \
@@ -292,8 +293,8 @@
   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);
+  assert(vm->getReferenceThread() && "VM did not set its enqueue thread");
+  CreateJavaThread(vm, vm->getReferenceThread(), "Reference", SystemGroup);
 }
 
 extern "C" void Java_java_lang_ref_WeakReference__0003Cinit_0003E__Ljava_lang_Object_2(
@@ -304,7 +305,7 @@
   BEGIN_NATIVE_EXCEPTION(0)
   
   JavaObjectReference::init(reference, referent, 0);
-  JavaThread::get()->getJVM()->addWeakReference(reference);
+  JavaThread::get()->getJVM()->getReferenceThread()->addWeakReference(reference);
 
   END_NATIVE_EXCEPTION
 
@@ -321,7 +322,7 @@
   BEGIN_NATIVE_EXCEPTION(0)
   
   JavaObjectReference::init(reference, referent, queue);
-  JavaThread::get()->getJVM()->addWeakReference(reference);
+  JavaThread::get()->getJVM()->getReferenceThread()->addWeakReference(reference);
   
   END_NATIVE_EXCEPTION
 
@@ -335,7 +336,7 @@
   BEGIN_NATIVE_EXCEPTION(0)
   
   JavaObjectReference::init(reference, referent, 0);
-  JavaThread::get()->getJVM()->addSoftReference(reference);
+  JavaThread::get()->getJVM()->getReferenceThread()->addSoftReference(reference);
   
   END_NATIVE_EXCEPTION
 
@@ -352,7 +353,7 @@
   BEGIN_NATIVE_EXCEPTION(0)
 
   JavaObjectReference::init(reference, referent, queue);
-  JavaThread::get()->getJVM()->addSoftReference(reference);
+  JavaThread::get()->getJVM()->getReferenceThread()->addSoftReference(reference);
   
   END_NATIVE_EXCEPTION
 
@@ -369,7 +370,7 @@
   BEGIN_NATIVE_EXCEPTION(0)
   
   JavaObjectReference::init(reference, referent, queue);
-  JavaThread::get()->getJVM()->addPhantomReference(reference);
+  JavaThread::get()->getJVM()->getReferenceThread()->addPhantomReference(reference);
 
   END_NATIVE_EXCEPTION
 }
@@ -1059,25 +1060,6 @@
   initPhantomReference->setNative();
 }
 
-gc** Jnjvm::getReferentPtr(gc* _obj) {
-  JavaObjectReference* obj = (JavaObjectReference*)_obj;
-  llvm_gcroot(obj, 0);
-  return (gc**)JavaObjectReference::getReferentPtr(obj);
-}
-
-void Jnjvm::setReferent(gc* _obj, gc* val) {
-  JavaObjectReference* obj = (JavaObjectReference*)_obj;
-  llvm_gcroot(obj, 0);
-  llvm_gcroot(val, 0);
-  JavaObjectReference::setReferent(obj, (JavaObject*)val);
-}
- 
-void Jnjvm::clearReferent(gc* _obj) {
-  JavaObjectReference* obj = (JavaObjectReference*)_obj;
-  llvm_gcroot(obj, 0);
-  JavaObjectReference::setReferent(obj, NULL);
-}
-
 #include "ClasspathConstructor.inc"
 #include "Classpath.inc"
 #include "ClasspathField.inc"

Modified: vmkit/branches/precise/lib/J3/VMCore/JavaMetaJIT.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/precise/lib/J3/VMCore/JavaMetaJIT.cpp?rev=117226&r1=117225&r2=117226&view=diff
==============================================================================
--- vmkit/branches/precise/lib/J3/VMCore/JavaMetaJIT.cpp (original)
+++ vmkit/branches/precise/lib/J3/VMCore/JavaMetaJIT.cpp Sun Oct 24 09:37:39 2010
@@ -289,19 +289,3 @@
 INVOKE(float,  Float, float_virtual_ap,  float_static_ap,  float_virtual_buf,  float_static_buf)
 INVOKE(double, Double, double_virtual_ap, double_static_ap, double_virtual_buf, double_static_buf)
 INVOKE(JavaObject*, JavaObject, object_virtual_ap, object_static_ap, object_virtual_buf, object_static_buf)
-
-void Jnjvm::invokeFinalizer(gc* _obj) {
-  JavaObject* obj = (JavaObject*)_obj;
-  llvm_gcroot(obj, 0);
-  JavaMethod* meth = upcalls->FinalizeObject;
-  UserClass* cl = JavaObject::getClass(obj)->asClass();
-  meth->invokeIntVirtualBuf(this, cl, obj, 0);
-}
-
-bool Jnjvm::enqueueReference(gc* _obj) {
-  JavaObject* obj = (JavaObject*)_obj;
-  llvm_gcroot(obj, 0);
-  JavaMethod* meth = upcalls->EnqueueReference;
-  UserClass* cl = JavaObject::getClass(obj)->asClass();
-  return (bool)meth->invokeIntSpecialBuf(this, cl, obj, 0);
-}

Modified: vmkit/branches/precise/lib/J3/VMCore/Jnjvm.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/precise/lib/J3/VMCore/Jnjvm.cpp?rev=117226&r1=117225&r2=117226&view=diff
==============================================================================
--- vmkit/branches/precise/lib/J3/VMCore/Jnjvm.cpp (original)
+++ vmkit/branches/precise/lib/J3/VMCore/Jnjvm.cpp Sun Oct 24 09:37:39 2010
@@ -34,6 +34,7 @@
 #include "LinkJavaRuntime.h"
 #include "LockedMap.h"
 #include "Reader.h"
+#include "ReferenceQueue.h"
 #include "Zip.h"
 
 using namespace j3;
@@ -1088,11 +1089,13 @@
   JnjvmClassLoader* loader = bootstrapLoader;
   
   // First create system threads.
-  finalizerThread = new JavaThread(0, 0, this);
-  finalizerThread->start((void (*)(mvm::Thread*))finalizerStart);
+  finalizerThread = new FinalizerThread(this);
+  finalizerThread->start(
+      (void (*)(mvm::Thread*))FinalizerThread::finalizerStart);
     
-  enqueueThread = new JavaThread(0, 0, this);
-  enqueueThread->start((void (*)(mvm::Thread*))enqueueStart);
+  referenceThread = new ReferenceThread(this);
+  referenceThread->start(
+      (void (*)(mvm::Thread*))ReferenceThread::enqueueStart);
   
   // Initialise the bootstrap class loader if it's not
   // done already.
@@ -1491,6 +1494,45 @@
 }
 
 
+void Jnjvm::startCollection() {
+  finalizerThread->FinalizationQueueLock.acquire();
+  referenceThread->ToEnqueueLock.acquire();
+  referenceThread->SoftReferencesQueue.acquire();
+  referenceThread->WeakReferencesQueue.acquire();
+  referenceThread->PhantomReferencesQueue.acquire();
+}
+  
+void Jnjvm::endCollection() {
+  finalizerThread->FinalizationQueueLock.release();
+  referenceThread->ToEnqueueLock.release();
+  referenceThread->SoftReferencesQueue.release();
+  referenceThread->WeakReferencesQueue.release();
+  referenceThread->PhantomReferencesQueue.release();
+  finalizerThread->FinalizationCond.broadcast();
+  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);
+}
+
+void Jnjvm::scanFinalizationQueue(uintptr_t closure) {
+  finalizerThread->scanFinalizationQueue(closure);
+}
+
+void Jnjvm::addFinalizationCandidate(gc* object) {
+  llvm_gcroot(object, 0);
+  finalizerThread->addFinalizationCandidate(object);
+}
+
 /// JavaStaticCompiler - Compiler for AOT-compiled programs that
 /// do not use the JIT.
 class JavaStaticCompiler : public JavaCompiler {

Modified: vmkit/branches/precise/lib/J3/VMCore/Jnjvm.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/precise/lib/J3/VMCore/Jnjvm.h?rev=117226&r1=117225&r2=117226&view=diff
==============================================================================
--- vmkit/branches/precise/lib/J3/VMCore/Jnjvm.h (original)
+++ vmkit/branches/precise/lib/J3/VMCore/Jnjvm.h Sun Oct 24 09:37:39 2010
@@ -30,6 +30,7 @@
 class ArrayObject;
 class Classpath;
 class CommonClass;
+class FinalizerThread;
 class JavaField;
 class JavaMethod;
 class JavaObject;
@@ -38,6 +39,7 @@
 class JavaVirtualTable;
 class JnjvmBootstrapLoader;
 class JnjvmClassLoader;
+class ReferenceThread;
 class UserClass;
 class UserClassArray;
 class UserClassPrimitive;
@@ -120,11 +122,19 @@
   
   /// finalizerThread - The thread that finalizes Java objects.
   ///
-  JavaThread* finalizerThread;
+  FinalizerThread* finalizerThread;
  
   /// enqueueThread - The thread that enqueue Java references.
   ///
-  JavaThread* enqueueThread;
+  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 void scanFinalizationQueue(uintptr_t closure);
+  virtual void addFinalizationCandidate(gc* obj);
 
   /// CreateError - Creates a Java object of the specified exception class
   /// and calling its <init> function.
@@ -300,19 +310,19 @@
   
   /// setFinalizerThread - Set the finalizer thread of this VM.
   ///
-  void setFinalizerThread(JavaThread* th) { finalizerThread = th; }
+  void setFinalizerThread(FinalizerThread* th) { finalizerThread = th; }
   
   /// getFinalizerThread - Get the finalizer thread of this VM.
   ///
-  JavaThread* getFinalizerThread() const { return finalizerThread; }
+  FinalizerThread* getFinalizerThread() const { return finalizerThread; }
   
-  /// setEnqueueThread - Set the enqueue thread of this VM.
+  /// setReferenceThread - Set the enqueue thread of this VM.
   ///
-  void setEnqueueThread(JavaThread* th) { enqueueThread = th; }
+  void setReferenceThread(ReferenceThread* th) { referenceThread = th; }
   
-  /// getEnqueueThread - Get the enqueue thread of this VM.
+  /// getReferenceThread - Get the enqueue thread of this VM.
   ///
-  JavaThread* getEnqueueThread() const { return enqueueThread; }
+  ReferenceThread* getReferenceThread() const { return referenceThread; }
 
   /// ~Jnjvm - Destroy the JVM.
   ///
@@ -367,15 +377,6 @@
 #ifdef SERVICE
   virtual void stopService();
 #endif
-
-  virtual void clearReferent(gc*);
-  virtual gc** getReferentPtr(gc*);
-  virtual void setReferent(gc*, gc*);
-  virtual bool enqueueReference(gc*);
-
-protected:
-  virtual void invokeFinalizer(gc*);
-
 };
 
 } // end namespace j3

Added: vmkit/branches/precise/lib/J3/VMCore/ReferenceQueue.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/precise/lib/J3/VMCore/ReferenceQueue.cpp?rev=117226&view=auto
==============================================================================
--- vmkit/branches/precise/lib/J3/VMCore/ReferenceQueue.cpp (added)
+++ vmkit/branches/precise/lib/J3/VMCore/ReferenceQueue.cpp Sun Oct 24 09:37:39 2010
@@ -0,0 +1,281 @@
+//===--ReferenceQueue.cpp - Implementation of soft/weak/phantom references-===//
+//
+//                            The VMKit project
+//
+// This file is distributed under the University of Pierre et Marie Curie 
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "ClasspathReflect.h"
+#include "JavaClass.h"
+#include "JavaUpcalls.h"
+#include "Jnjvm.h"
+#include "ReferenceQueue.h"
+
+using namespace j3;
+
+ReferenceThread::ReferenceThread(Jnjvm* vm) : JavaThread(NULL, NULL, vm),
+    WeakReferencesQueue(ReferenceQueue::WEAK),
+    SoftReferencesQueue(ReferenceQueue::SOFT), 
+    PhantomReferencesQueue(ReferenceQueue::PHANTOM) {
+
+  ToEnqueue = new gc*[INITIAL_QUEUE_SIZE];
+  ToEnqueueLength = INITIAL_QUEUE_SIZE;
+  ToEnqueueIndex = 0;
+}
+
+
+bool enqueueReference(gc* _obj) {
+  Jnjvm* vm = JavaThread::get()->getJVM();
+  JavaObject* obj = (JavaObject*)_obj;
+  llvm_gcroot(obj, 0);
+  JavaMethod* meth = vm->upcalls->EnqueueReference;
+  UserClass* cl = JavaObject::getClass(obj)->asClass();
+  return (bool)meth->invokeIntSpecialBuf(vm, cl, obj, 0);
+}
+
+void invokeEnqueue(gc* res) {
+  llvm_gcroot(res, 0);
+  TRY {
+    enqueueReference(res);
+  } IGNORE;
+  mvm::Thread::get()->clearException();
+}
+
+void ReferenceThread::enqueueStart(ReferenceThread* th) {
+  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(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 < ToEnqueueLength; ++i) {
+      newQueue[i] = ToEnqueue[i];
+    }   
+    delete[] ToEnqueue;
+    ToEnqueue = newQueue;
+    ToEnqueueLength = newLength;
+  }   
+  ToEnqueue[ToEnqueueIndex++] = obj;
+}
+
+gc** getReferentPtr(gc* _obj) {
+  JavaObjectReference* obj = (JavaObjectReference*)_obj;
+  llvm_gcroot(obj, 0);
+  return (gc**)JavaObjectReference::getReferentPtr(obj);
+}
+
+void setReferent(gc* _obj, gc* val) {
+  JavaObjectReference* obj = (JavaObjectReference*)_obj;
+  llvm_gcroot(obj, 0);
+  llvm_gcroot(val, 0);
+  JavaObjectReference::setReferent(obj, (JavaObject*)val);
+}
+ 
+void clearReferent(gc* _obj) {
+  JavaObjectReference* obj = (JavaObjectReference*)_obj;
+  llvm_gcroot(obj, 0);
+  JavaObjectReference::setReferent(obj, NULL);
+}
+
+gc* ReferenceQueue::processReference(gc* reference, ReferenceThread* th, uintptr_t closure) {
+  if (!mvm::Collector::isLive(reference, closure)) {
+    clearReferent(reference);
+    return NULL;
+  }
+
+  gc* referent = *(getReferentPtr(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.
+  }
+
+  gc* newReference =
+      mvm::Collector::getForwardedReference(reference, closure);
+  if (mvm::Collector::isLive(referent, closure)) {
+    gc* newReferent = mvm::Collector::getForwardedReferent(referent, closure);
+    setReferent(newReference, newReferent);
+    return newReference;
+  } else {
+    clearReferent(newReference);
+    th->addToEnqueue(newReference);
+    return NULL;
+  }
+}
+
+
+void ReferenceQueue::scan(ReferenceThread* th, uintptr_t closure) {
+  uint32 NewIndex = 0;
+
+  for (uint32 i = 0; i < CurrentIndex; ++i) {
+    gc* obj = References[i];
+    gc* res = processReference(obj, th, closure);
+    if (res) References[NewIndex++] = res;
+  }
+
+  CurrentIndex = NewIndex;
+}
+
+
+FinalizerThread::FinalizerThread(Jnjvm* vm) : JavaThread(NULL, NULL, vm) {
+  FinalizationQueue = new gc*[INITIAL_QUEUE_SIZE];
+  QueueLength = INITIAL_QUEUE_SIZE;
+  CurrentIndex = 0;
+
+  ToBeFinalized = new gc*[INITIAL_QUEUE_SIZE];
+  ToBeFinalizedLength = INITIAL_QUEUE_SIZE;
+  CurrentFinalizedIndex = 0;
+}
+
+void FinalizerThread::growFinalizationQueue() {
+  if (CurrentIndex >= QueueLength) {
+    uint32 newLength = QueueLength * GROW_FACTOR;
+    gc** newQueue = new gc*[newLength];
+    if (!newQueue) {
+      fprintf(stderr, "I don't know how to handle finalizer overflows yet!\n");
+      abort();
+    }
+    for (uint32 i = 0; i < QueueLength; ++i) newQueue[i] = FinalizationQueue[i];
+    delete[] FinalizationQueue;
+    FinalizationQueue = newQueue;
+    QueueLength = newLength;
+  }
+}
+
+void FinalizerThread::growToBeFinalizedQueue() {
+  if (CurrentFinalizedIndex >= ToBeFinalizedLength) {
+    uint32 newLength = ToBeFinalizedLength * GROW_FACTOR;
+    gc** newQueue = new gc*[newLength];
+    if (!newQueue) {
+      fprintf(stderr, "I don't know how to handle finalizer overflows yet!\n");
+      abort();
+    }
+    for (uint32 i = 0; i < ToBeFinalizedLength; ++i) newQueue[i] = ToBeFinalized[i];
+    delete[] ToBeFinalized;
+    ToBeFinalized = newQueue;
+    ToBeFinalizedLength = newLength;
+  }
+}
+
+
+void FinalizerThread::addFinalizationCandidate(gc* obj) {
+  FinalizationQueueLock.acquire();
+ 
+  if (CurrentIndex >= QueueLength) {
+    growFinalizationQueue();
+  }
+  
+  FinalizationQueue[CurrentIndex++] = obj;
+  FinalizationQueueLock.release();
+}
+  
+
+void FinalizerThread::scanFinalizationQueue(uintptr_t closure) {
+  uint32 NewIndex = 0;
+  for (uint32 i = 0; i < CurrentIndex; ++i) {
+    gc* obj = FinalizationQueue[i];
+
+    if (!mvm::Collector::isLive(obj, closure)) {
+      obj = mvm::Collector::retainForFinalize(FinalizationQueue[i], closure);
+      
+      if (CurrentFinalizedIndex >= ToBeFinalizedLength)
+        growToBeFinalizedQueue();
+      
+      /* Add to object table */
+      ToBeFinalized[CurrentFinalizedIndex++] = obj;
+    } else {
+      FinalizationQueue[NewIndex++] =
+        mvm::Collector::getForwardedFinalizable(obj, closure);
+    }
+  }
+  CurrentIndex = NewIndex;
+}
+
+typedef void (*destructor_t)(void*);
+
+void invokeFinalizer(gc* _obj) {
+  Jnjvm* vm = JavaThread::get()->getJVM();
+  JavaObject* obj = (JavaObject*)_obj;
+  llvm_gcroot(obj, 0);
+  JavaMethod* meth = vm->upcalls->FinalizeObject;
+  UserClass* cl = JavaObject::getClass(obj)->asClass();
+  meth->invokeIntVirtualBuf(vm, cl, obj, 0);
+}
+
+void invokeFinalize(gc* res) {
+  llvm_gcroot(res, 0);
+  TRY {
+    invokeFinalizer(res);
+  } IGNORE;
+  mvm::Thread::get()->clearException();
+}
+
+void FinalizerThread::finalizerStart(FinalizerThread* th) {
+  gc* res = NULL;
+  llvm_gcroot(res, 0);
+
+  while (true) {
+    th->FinalizationLock.lock();
+    while (th->CurrentFinalizedIndex == 0) {
+      th->FinalizationCond.wait(&th->FinalizationLock);
+    }
+    th->FinalizationLock.unlock();
+
+    while (true) {
+      th->FinalizationQueueLock.acquire();
+      if (th->CurrentFinalizedIndex != 0) {
+        res = th->ToBeFinalized[th->CurrentFinalizedIndex - 1];
+        --th->CurrentFinalizedIndex;
+      }
+      th->FinalizationQueueLock.release();
+      if (!res) break;
+
+      VirtualTable* VT = res->getVirtualTable();
+      if (VT->operatorDelete) {
+        destructor_t dest = (destructor_t)VT->destructor;
+        dest(res);
+      } else {
+        invokeFinalize(res);
+      }
+      res = NULL;
+    }
+  }
+}

Added: vmkit/branches/precise/lib/J3/VMCore/ReferenceQueue.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/precise/lib/J3/VMCore/ReferenceQueue.h?rev=117226&view=auto
==============================================================================
--- vmkit/branches/precise/lib/J3/VMCore/ReferenceQueue.h (added)
+++ vmkit/branches/precise/lib/J3/VMCore/ReferenceQueue.h Sun Oct 24 09:37:39 2010
@@ -0,0 +1,207 @@
+//===---ReferenceQueue.h - Implementation of soft/weak/phantom references--===//
+//
+//                            The VMKit project
+//
+// This file is distributed under the University of Pierre et Marie Curie 
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef J3_REFERENCE_QUEUE_H
+#define J3_REFERENCE_QUEUE_H
+
+#include "mvm/Threads/Locks.h"
+
+#include "JavaThread.h"
+
+// Same values than JikesRVM
+#define INITIAL_QUEUE_SIZE 256
+#define GROW_FACTOR 2
+
+namespace j3 {
+
+class ReferenceThread;
+class Jnjvm;
+
+class ReferenceQueue {
+private:
+  gc** References;
+  uint32 QueueLength;
+  uint32 CurrentIndex;
+  mvm::SpinLock QueueLock;
+  uint8_t semantics;
+
+  gc* processReference(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 gc*[INITIAL_QUEUE_SIZE];
+    QueueLength = INITIAL_QUEUE_SIZE;
+    CurrentIndex = 0;
+    semantics = s;
+  }
+
+  ~ReferenceQueue() {
+    delete[] References;
+  }
+ 
+  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(ReferenceThread* thread, uintptr_t closure);
+};
+
+class ReferenceThread : public JavaThread {
+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;
+
+  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);
+
+  static void enqueueStart(ReferenceThread*);
+
+  /// 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);
+  }
+
+  ReferenceThread(Jnjvm* vm);
+
+  ~ReferenceThread() {
+    delete[] ToEnqueue;
+  }
+};
+
+class FinalizerThread : public JavaThread {
+public:
+    /// FinalizationQueueLock - A lock to protect access to the queue.
+  ///
+  mvm::SpinLock FinalizationQueueLock;
+
+  /// finalizationQueue - A list of allocated objets that contain a finalize
+  /// method.
+  ///
+  gc** FinalizationQueue;
+
+  /// CurrentIndex - Current index in the queue of finalizable objects.
+  ///
+  uint32 CurrentIndex;
+
+  /// QueueLength - Current length of the queue of finalizable objects.
+  ///
+  uint32 QueueLength;
+
+  /// growFinalizationQueue - Grow the queue of finalizable objects.
+  ///
+  void growFinalizationQueue();
+  
+  /// ToBeFinalized - List of objects that are scheduled to be finalized.
+  ///
+  gc** ToBeFinalized;
+  
+  /// ToBeFinalizedLength - Current length of the queue of objects scheduled
+  /// for finalization.
+  ///
+  uint32 ToBeFinalizedLength;
+
+  /// CurrentFinalizedIndex - The current index in the ToBeFinalized queue
+  /// that will be sceduled for finalization.
+  ///
+  uint32 CurrentFinalizedIndex;
+  
+  /// growToBeFinalizedQueue - Grow the queue of the to-be finalized objects.
+  ///
+  void growToBeFinalizedQueue();
+  
+  /// finalizationCond - Condition variable to wake up finalization threads.
+  ///
+  mvm::Cond FinalizationCond;
+
+  /// finalizationLock - Lock for the condition variable.
+  ///
+  mvm::LockNormal FinalizationLock;
+
+  static void finalizerStart(FinalizerThread*);
+
+  /// addFinalizationCandidate - Add an object to the queue of objects with
+  /// a finalization method.
+  ///
+  void addFinalizationCandidate(gc*);
+
+  /// scanFinalizationQueue - Scan objets with a finalized method and schedule
+  /// them for finalization if they are not live.
+  ///
+  void scanFinalizationQueue(uintptr_t closure);
+
+  FinalizerThread(Jnjvm* vm);
+
+  ~FinalizerThread() {
+    delete[] FinalizationQueue;
+    delete[] ToBeFinalized;
+  }
+
+};
+
+} // namespace j3
+
+#endif  //J3_REFERENCE_QUEUE_H

Modified: vmkit/branches/precise/lib/J3/VMCore/VirtualTables.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/precise/lib/J3/VMCore/VirtualTables.cpp?rev=117226&r1=117225&r2=117226&view=diff
==============================================================================
--- vmkit/branches/precise/lib/J3/VMCore/VirtualTables.cpp (original)
+++ vmkit/branches/precise/lib/J3/VMCore/VirtualTables.cpp Sun Oct 24 09:37:39 2010
@@ -30,6 +30,7 @@
 #include "Jnjvm.h"
 #include "JnjvmClassLoader.h"
 #include "LockedMap.h"
+#include "ReferenceQueue.h"
 #include "Zip.h"
 
 using namespace j3;
@@ -264,15 +265,16 @@
 
 
 void Jnjvm::tracer(uintptr_t closure) {
-  
-  VirtualMachine::tracer(closure);
+  // (1) Trace the bootrap loader.
   bootstrapLoader->tracer(closure);
   
+  // (2) Trace the application class loader.
   if (appClassLoader != NULL) {
     mvm::Collector::markAndTraceRoot(
         appClassLoader->getJavaClassLoaderPtr(), closure);
   }
   
+  // (3) Trace JNI global references.
   JNIGlobalReferences* start = &globalRefs;
   while (start != NULL) {
     for (uint32 i = 0; i < start->length; ++i) {
@@ -282,6 +284,7 @@
     start = start->next;
   }
   
+  // (4) Trace the interned strings.
   for (StringMap::iterator i = hashStr.map.begin(), e = hashStr.map.end();
        i!= e; ++i) {
     JavaString** str = &(i->second);
@@ -289,7 +292,13 @@
     ArrayUInt16** key = const_cast<ArrayUInt16**>(&(i->first));
     mvm::Collector::markAndTraceRoot(key, closure);
   }
+
+  // (5) Trace the finalization queue.
+  for (uint32 i = 0; i < finalizerThread->CurrentFinalizedIndex; ++i) {
+    mvm::Collector::markAndTraceRoot(finalizerThread->ToBeFinalized + i, closure);
+  }
  
+  // (6) Trace the locks and their associated object.
   uint32 i = 0;
   for (; i < mvm::LockSystem::GlobalSize; i++) {
     mvm::FatLock** array = lockSystem.LockTable[i];
@@ -307,6 +316,8 @@
   for (i = i + 1; i < mvm::LockSystem::GlobalSize; i++) {
     assert(lockSystem.LockTable[i] == NULL);
   }
+
+
 #if defined(ISOLATE_SHARING)
   mvm::Collector::markAndTraceRoot(&JnjvmSharedLoader::sharedLoader, closure);
 #endif

Modified: vmkit/branches/precise/lib/Mvm/GCMmap2/gccollector.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/precise/lib/Mvm/GCMmap2/gccollector.cpp?rev=117226&r1=117225&r2=117226&view=diff
==============================================================================
--- vmkit/branches/precise/lib/Mvm/GCMmap2/gccollector.cpp (original)
+++ vmkit/branches/precise/lib/Mvm/GCMmap2/gccollector.cpp Sun Oct 24 09:37:39 2010
@@ -94,10 +94,8 @@
   status = stat_alloc;
   
   // Wake up all threads.
-  th->MyVM->endCollection();
   th->MyVM->rendezvous.finishRV();
-  th->MyVM->wakeUpFinalizers();
-  th->MyVM->wakeUpEnqueue();
+  th->MyVM->endCollection();
   
   // Kill unreachable objects.
   GCChunkNode *next = 0;

Modified: vmkit/branches/precise/lib/Mvm/Runtime/Object.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/precise/lib/Mvm/Runtime/Object.cpp?rev=117226&r1=117225&r2=117226&view=diff
==============================================================================
--- vmkit/branches/precise/lib/Mvm/Runtime/Object.cpp (original)
+++ vmkit/branches/precise/lib/Mvm/Runtime/Object.cpp Sun Oct 24 09:37:39 2010
@@ -59,202 +59,6 @@
   buf->write(">");
 }
 
-typedef void (*destructor_t)(void*);
-
-void invokeFinalize(mvm::Thread* th, gc* res) {
-  llvm_gcroot(res, 0);
-  TRY {
-    th->MyVM->invokeFinalizer(res);
-  } IGNORE;
-  th->clearException();
-}
-
-void invokeEnqueue(mvm::Thread* th, gc* res) {
-  llvm_gcroot(res, 0);
-  TRY {
-    th->MyVM->enqueueReference(res);
-  } IGNORE;
-  th->clearException();
-}
-
-void VirtualMachine::finalizerStart(mvm::Thread* th) {
-  VirtualMachine* vm = th->MyVM;
-  gc* res = 0;
-  llvm_gcroot(res, 0);
-
-  while (true) {
-    vm->FinalizationLock.lock();
-    while (vm->CurrentFinalizedIndex == 0) {
-      vm->FinalizationCond.wait(&vm->FinalizationLock);
-    }
-    vm->FinalizationLock.unlock();
-
-    while (true) {
-      vm->FinalizationQueueLock.acquire();
-      if (vm->CurrentFinalizedIndex != 0) {
-        res = vm->ToBeFinalized[vm->CurrentFinalizedIndex - 1];
-        --vm->CurrentFinalizedIndex;
-      }
-      vm->FinalizationQueueLock.release();
-      if (!res) break;
-
-      VirtualTable* VT = res->getVirtualTable();
-      if (VT->operatorDelete) {
-        destructor_t dest = (destructor_t)VT->destructor;
-        dest(res);
-      } else {
-        invokeFinalize(th, res);
-      }
-      res = 0;
-    }
-  }
-}
-
-void VirtualMachine::enqueueStart(mvm::Thread* th) {
-  VirtualMachine* vm = th->MyVM;
-  gc* res = 0;
-  llvm_gcroot(res, 0);
-
-  while (true) {
-    vm->EnqueueLock.lock();
-    while (vm->ToEnqueueIndex == 0) {
-      vm->EnqueueCond.wait(&vm->EnqueueLock);
-    }
-    vm->EnqueueLock.unlock();
-
-    while (true) {
-      vm->ToEnqueueLock.acquire();
-      if (vm->ToEnqueueIndex != 0) {
-        res = vm->ToEnqueue[vm->ToEnqueueIndex - 1];
-        --vm->ToEnqueueIndex;
-      }
-      vm->ToEnqueueLock.release();
-      if (!res) break;
-
-      invokeEnqueue(th, res);
-      res = 0;
-    }
-  }
-}
-
-void VirtualMachine::growFinalizationQueue() {
-  if (CurrentIndex >= QueueLength) {
-    uint32 newLength = QueueLength * GROW_FACTOR;
-    gc** newQueue = new gc*[newLength];
-    if (!newQueue) {
-      fprintf(stderr, "I don't know how to handle finalizer overflows yet!\n");
-      abort();
-    }
-    for (uint32 i = 0; i < QueueLength; ++i) newQueue[i] = FinalizationQueue[i];
-    delete[] FinalizationQueue;
-    FinalizationQueue = newQueue;
-    QueueLength = newLength;
-  }
-}
-
-void VirtualMachine::growToBeFinalizedQueue() {
-  if (CurrentFinalizedIndex >= ToBeFinalizedLength) {
-    uint32 newLength = ToBeFinalizedLength * GROW_FACTOR;
-    gc** newQueue = new gc*[newLength];
-    if (!newQueue) {
-      fprintf(stderr, "I don't know how to handle finalizer overflows yet!\n");
-      abort();
-    }
-    for (uint32 i = 0; i < ToBeFinalizedLength; ++i) newQueue[i] = ToBeFinalized[i];
-    delete[] ToBeFinalized;
-    ToBeFinalized = newQueue;
-    ToBeFinalizedLength = newLength;
-  }
-}
-
-
-void VirtualMachine::addFinalizationCandidate(gc* obj) {
-  FinalizationQueueLock.acquire();
- 
-  if (CurrentIndex >= QueueLength) {
-    growFinalizationQueue();
-  }
-  
-  FinalizationQueue[CurrentIndex++] = obj;
-  FinalizationQueueLock.release();
-}
-  
-
-void VirtualMachine::scanFinalizationQueue(uintptr_t closure) {
-  uint32 NewIndex = 0;
-  for (uint32 i = 0; i < CurrentIndex; ++i) {
-    gc* obj = FinalizationQueue[i];
-
-    if (!Collector::isLive(obj, closure)) {
-      obj = Collector::retainForFinalize(FinalizationQueue[i], closure);
-      
-      if (CurrentFinalizedIndex >= ToBeFinalizedLength)
-        growToBeFinalizedQueue();
-      
-      /* Add to object table */
-      ToBeFinalized[CurrentFinalizedIndex++] = obj;
-    } else {
-      FinalizationQueue[NewIndex++] =
-        Collector::getForwardedFinalizable(obj, closure);
-    }
-  }
-  CurrentIndex = NewIndex;
-}
-
-void VirtualMachine::tracer(uintptr_t closure) {
-  for (uint32 i = 0; i < CurrentFinalizedIndex; ++i) {
-    Collector::markAndTraceRoot(ToBeFinalized + i, closure);
-  }
-}
-
-gc* ReferenceQueue::processReference(
-    gc* reference, VirtualMachine* vm, uintptr_t closure) {
-  if (!Collector::isLive(reference, closure)) {
-    vm->clearReferent(reference);
-    return NULL;
-  }
-
-  gc* referent = *(vm->getReferentPtr(reference));
-
-  if (!referent) {
-    return NULL;
-  }
-
-  if (semantics == SOFT) {
-    // TODO: are we are out of memory? Consider that we always are for now.
-    if (false) {
-      Collector::retainReferent(referent, closure);
-    }
-  } else if (semantics == PHANTOM) {
-    // Nothing to do.
-  }
-
-  gc* newReference =
-      mvm::Collector::getForwardedReference(reference, closure);
-  if (Collector::isLive(referent, closure)) {
-    gc* newReferent = mvm::Collector::getForwardedReferent(referent, closure);
-    vm->setReferent(newReference, newReferent);
-    return newReference;
-  } else {
-    vm->clearReferent(newReference);
-    vm->addToEnqueue(newReference);
-    return NULL;
-  }
-}
-
-
-void ReferenceQueue::scan(VirtualMachine* vm, uintptr_t closure) {
-  uint32 NewIndex = 0;
-
-  for (uint32 i = 0; i < CurrentIndex; ++i) {
-    gc* obj = References[i];
-    gc* res = processReference(obj, vm, closure);
-    if (res) References[NewIndex++] = res;
-  }
-
-  CurrentIndex = NewIndex;
-}
-
 void PreciseStackScanner::scanStack(mvm::Thread* th, uintptr_t closure) {
   StackWalker Walker(th);
 

Modified: vmkit/branches/precise/mmtk/mmtk-j3/Collection.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/precise/mmtk/mmtk-j3/Collection.cpp?rev=117226&r1=117225&r2=117226&view=diff
==============================================================================
--- vmkit/branches/precise/mmtk/mmtk-j3/Collection.cpp (original)
+++ vmkit/branches/precise/mmtk/mmtk-j3/Collection.cpp Sun Oct 24 09:37:39 2010
@@ -81,10 +81,6 @@
     }
 
     th->MyVM->rendezvous.finishRV();
-  
-    th->MyVM->wakeUpFinalizers();
-    th->MyVM->wakeUpEnqueue();
-    
     th->MyVM->endCollection();
   }
 





More information about the vmkit-commits mailing list