[vmkit-commits] [vmkit] r72171 - in /vmkit/trunk: include/mvm/VirtualMachine.h lib/JnJVM/Compiler/JavaAOTCompiler.cpp lib/JnJVM/VMCore/JavaMetaJIT.cpp lib/JnJVM/VMCore/JavaString.cpp lib/JnJVM/VMCore/JavaUpcalls.cpp lib/JnJVM/VMCore/JavaUpcalls.h lib/JnJVM/VMCore/Jnjvm.cpp lib/JnJVM/VMCore/Jnjvm.h lib/Mvm/BoehmGC/MvmGC.h lib/Mvm/GCMmap2/MvmGC.h lib/Mvm/GCMmap2/gc.cpp lib/Mvm/GCMmap2/gccollector.h lib/Mvm/Runtime/Object.cpp

Nicolas Geoffray nicolas.geoffray at lip6.fr
Wed May 20 08:46:55 PDT 2009


Author: geoffray
Date: Wed May 20 10:46:54 2009
New Revision: 72171

URL: http://llvm.org/viewvc/llvm-project?rev=72171&view=rev
Log:
Put back the basic infrastructure for finalization support.


Modified:
    vmkit/trunk/include/mvm/VirtualMachine.h
    vmkit/trunk/lib/JnJVM/Compiler/JavaAOTCompiler.cpp
    vmkit/trunk/lib/JnJVM/VMCore/JavaMetaJIT.cpp
    vmkit/trunk/lib/JnJVM/VMCore/JavaString.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/BoehmGC/MvmGC.h
    vmkit/trunk/lib/Mvm/GCMmap2/MvmGC.h
    vmkit/trunk/lib/Mvm/GCMmap2/gc.cpp
    vmkit/trunk/lib/Mvm/GCMmap2/gccollector.h
    vmkit/trunk/lib/Mvm/Runtime/Object.cpp

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

==============================================================================
--- vmkit/trunk/include/mvm/VirtualMachine.h (original)
+++ vmkit/trunk/include/mvm/VirtualMachine.h Wed May 20 10:46:54 2009
@@ -18,6 +18,7 @@
 #include "mvm/Allocator.h"
 #include "mvm/CompilationUnit.h"
 #include "mvm/Object.h"
+#include "mvm/Threads/Cond.h"
 #include "mvm/Threads/Locks.h"
 
 #include <cassert>
@@ -30,6 +31,13 @@
 
 namespace mvm {
 
+
+// Same values than JikesRVM
+#define INITIAL_QUEUE_SIZE 256
+#define GROW_FACTOR 2
+
+
+
 /// VirtualMachine - This class is the root of virtual machine classes. It
 /// defines what a VM should be.
 ///
@@ -46,6 +54,11 @@
     status = 1;
     _since_last_collection = 4*1024*1024;
 #endif
+    FinalizationQueue = new gc*[INITIAL_QUEUE_SIZE];
+    QueueLength = INITIAL_QUEUE_SIZE;
+
+    ToBeFinalized = new gc*[INITIAL_QUEUE_SIZE];
+    ToBeFinalizedLength = INITIAL_QUEUE_SIZE;
   }
 public:
 
@@ -66,7 +79,92 @@
   
   static CompilationUnit* initialiseCLIVM();
   static VirtualMachine* createCLIVM(CompilationUnit* C = 0);
- 
+
+    
+private:
+  /// 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;
+
+  /// growQueue - Grow the queue of finalizable objects.
+  ///
+  void growQueue();
+  
+  /// 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;
+  
+  /// LastFinalizedIndex - The last index in the ToBeFinalized queue whose
+  /// finalize method has been called.
+  ///
+  uint32 LastFinalizedIndex;
+  
+  /// finalizationCond - Condition variable to wake up finalization threads.
+  ///
+  mvm::Cond FinalizationCond;
+
+  /// finalizationLock - Lock for the condition variable.
+  ///
+  mvm::LockNormal FinalizationLock;
+
+protected:
+  /// invokeFinalizer - Invoke the finalizer of the object. This may involve
+  /// changing the environment, e.g. going to native to Java.
+  ///
+  virtual void invokeFinalizer(gc*) {}
+
+
+public:
+  /// finalizerStart - The start function of a finalizer. Will poll the
+  /// finalizationQueue.
+  ///
+  static void finalizerStart(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();
+
+  /// wakeUpFinalizers - Wake the finalizers.
+  ///
+  void wakeUpFinalizers() { FinalizationCond.broadcast(); }
+
+  void startCollection() {
+    FinalizationQueueLock.acquire();
+  }
+  
+  void endCollection() {
+    FinalizationQueueLock.release();
+  }
+
 protected:
 
   /// JavaFunctionMap - Map of Java method to function pointers. This map is

Modified: vmkit/trunk/lib/JnJVM/Compiler/JavaAOTCompiler.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/Compiler/JavaAOTCompiler.cpp?rev=72171&r1=72170&r2=72171&view=diff

==============================================================================
--- vmkit/trunk/lib/JnJVM/Compiler/JavaAOTCompiler.cpp (original)
+++ vmkit/trunk/lib/JnJVM/Compiler/JavaAOTCompiler.cpp Wed May 20 10:46:54 2009
@@ -1699,7 +1699,7 @@
   mvm::BumpPtrAllocator A;
   Jnjvm* vm = new(A) Jnjvm(A, (JnjvmBootstrapLoader*)JCL);
   JavaThread* th = new JavaThread(0, 0, vm);
-  vm->setBootstrapThread(th);
+  vm->setMainThread(th);
   th->start((void (*)(mvm::Thread*))mainCompilerStart);
   vm->waitForExit();
 }

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

==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JavaMetaJIT.cpp (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JavaMetaJIT.cpp Wed May 20 10:46:54 2009
@@ -11,10 +11,12 @@
 #include <cstring>
 
 #include "debug.h"
+
 #include "JavaClass.h"
 #include "JavaObject.h"
 #include "JavaThread.h"
 #include "JavaTypes.h"
+#include "JavaUpcalls.h"
 #include "Jnjvm.h"
 
 using namespace jnjvm;
@@ -624,3 +626,11 @@
 INVOKE(JavaObject*, JavaObject, object_virtual_ap, object_static_ap, object_virtual_buf, object_static_buf)
 
 #undef INVOKE
+
+void Jnjvm::invokeFinalizer(gc* _obj) {
+  JavaObject* obj = (JavaObject*)_obj;
+  JavaMethod* meth = upcalls->FinalizeObject;
+  UserClass* cl = obj->getClass()->asClass();
+  meth->invokeIntVirtualBuf(this, cl, obj, 0);
+}
+

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

==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JavaString.cpp (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JavaString.cpp Wed May 20 10:46:54 2009
@@ -24,7 +24,7 @@
   JavaString* res = (JavaString*)cl->doNew(vm);
   
   // It's a hashed string, set the destructor so that the string
-  // removes itself from the vm string map. Do this ony if
+  // removes itself from the vm string map. Do this only if
   // internStringVT exists (in case of AOT).
   if (internStringVT) res->setVirtualTable(internStringVT);
 

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

==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JavaUpcalls.cpp (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JavaUpcalls.cpp Wed May 20 10:46:54 2009
@@ -38,7 +38,9 @@
 JavaMethod* Classpath::finaliseCreateInitialThread;
 JavaMethod* Classpath::initVMThread;
 JavaMethod* Classpath::groupAddThread;
-JavaField*  Classpath::name;
+JavaField*  Classpath::threadName;
+JavaField*  Classpath::groupName;
+JavaMethod* Classpath::initGroup;
 JavaField*  Classpath::priority;
 JavaField*  Classpath::daemon;
 JavaField*  Classpath::group;
@@ -177,6 +179,7 @@
 JavaMethod* Classpath::InitClassNotFoundException;
 JavaMethod* Classpath::InitArithmeticException;
 JavaMethod* Classpath::InitObject;
+JavaMethod* Classpath::FinalizeObject;
 JavaMethod* Classpath::IntToString;
 
 JavaMethod* Classpath::ErrorWithExcpNoClassDefFoundError;
@@ -217,7 +220,7 @@
   myth->javaThread = th;
   JavaObject* vmth = newVMThread->doNew(vm);
   
-  name->setObjectField(th, (JavaObject*)vm->asciizToStr(thName));
+  threadName->setObjectField(th, (JavaObject*)vm->asciizToStr(thName));
   priority->setInt32Field(th, (uint32)1);
   daemon->setInt8Field(th, (uint32)0);
   vmThread->setObjectField(th, vmth);
@@ -245,8 +248,18 @@
   // Create the main thread
   void* Stat = threadGroup->getStaticInstance();
   JavaObject* RG = rootGroup->getObjectField(Stat);
-  assert(vm->getBootstrapThread() && "VM did not set its bootstrap thread");
-  CreateJavaThread(vm, vm->getBootstrapThread(), "main", RG);
+  assert(vm->getMainThread() && "VM did not set its main thread");
+  CreateJavaThread(vm, vm->getMainThread(), "main", RG);
+
+  // Create the "system" group.
+  JavaObject* SystemGroup = threadGroup->doNew(vm);
+  initGroup->invokeIntSpecial(vm, threadGroup, SystemGroup);
+  JavaObject* systemName = (JavaObject*)vm->asciizToStr("system");
+  groupName->setObjectField(SystemGroup, systemName);
+
+  // And create the finalizer thread.
+  assert(vm->getFinalizerThread() && "VM did not set its finalizer thread");
+  CreateJavaThread(vm, vm->getFinalizerThread(), "Finalizer", SystemGroup);
 }
 
 extern "C" JavaString* nativeInternString(JavaString* obj) {
@@ -614,6 +627,9 @@
   InitObject = UPCALL_METHOD(loader, "java/lang/Object", "<init>", "()V",
                              ACC_VIRTUAL);
   
+  FinalizeObject = UPCALL_METHOD(loader, "java/lang/Object", "finalize", "()V",
+                                 ACC_VIRTUAL);
+  
   IntToString = UPCALL_METHOD(loader, "java/lang/Integer", "toString",
                               "(II)Ljava/lang/String;", ACC_STATIC);
 
@@ -650,10 +666,19 @@
     UPCALL_METHOD(loader, "java/lang/ThreadGroup", "addThread",
                   "(Ljava/lang/Thread;)V", ACC_VIRTUAL);
   
-  name = 
-    UPCALL_FIELD(loader, "java/lang/Thread", "name", "Ljava/lang/String;",
+  initGroup = 
+    UPCALL_METHOD(loader, "java/lang/ThreadGroup", "<init>",
+                  "()V", ACC_VIRTUAL);
+  
+  groupName = 
+    UPCALL_FIELD(loader, "java/lang/ThreadGroup", "name", "Ljava/lang/String;",
                  ACC_VIRTUAL);
   
+  threadName = 
+     UPCALL_FIELD(loader, "java/lang/Thread", "name", "Ljava/lang/String;",
+                  ACC_VIRTUAL);
+   
+
   priority = 
     UPCALL_FIELD(loader,  "java/lang/Thread", "priority", "I", ACC_VIRTUAL);
 

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

==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JavaUpcalls.h (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JavaUpcalls.h Wed May 20 10:46:54 2009
@@ -131,7 +131,9 @@
   ISOLATE_STATIC JavaMethod* initVMThread;
   ISOLATE_STATIC JavaMethod* runVMThread;
   ISOLATE_STATIC JavaMethod* groupAddThread;
-  ISOLATE_STATIC JavaField* name;
+  ISOLATE_STATIC JavaField* threadName;
+  ISOLATE_STATIC JavaField* groupName;
+  ISOLATE_STATIC JavaMethod* initGroup;
   ISOLATE_STATIC JavaField* priority;
   ISOLATE_STATIC JavaField* daemon;
   ISOLATE_STATIC JavaField* group;
@@ -212,6 +214,7 @@
   ISOLATE_STATIC JavaMethod* IntToString;
 
   ISOLATE_STATIC JavaMethod* InitObject;
+  ISOLATE_STATIC JavaMethod* FinalizeObject;
 
   ISOLATE_STATIC JavaMethod* ErrorWithExcpNoClassDefFoundError;
   ISOLATE_STATIC JavaMethod* ErrorWithExcpExceptionInInitializerError;

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

==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.cpp (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.cpp Wed May 20 10:46:54 2009
@@ -964,6 +964,10 @@
     
     JavaString::internStringVT->destructor = 
       (uintptr_t)JavaString::stringDestructor;
+
+    // Tell the finalizer that this is a native destructor.
+    JavaString::internStringVT->operatorDelete = 
+      (uintptr_t)JavaString::stringDestructor;
   }
   upcalls->newString->initialiseClass(this);
 
@@ -1111,7 +1115,7 @@
 
 void Jnjvm::mainJavaStart(JavaThread* thread) {
   Jnjvm* vm = thread->getJVM();
-  vm->bootstrapThread = thread;
+  vm->mainThread = thread;
 
   vm->loadBootstrap();
 
@@ -1191,9 +1195,12 @@
     mvm::Thread* th = new JavaThread(0, 0, this);
     th->start(serviceCPUMonitor);
 #endif
+  
+    finalizerThread = new JavaThread(0, 0, this);
+    finalizerThread->start((void (*)(mvm::Thread*))finalizerStart);
     
-    bootstrapThread = new JavaThread(0, 0, this);
-    bootstrapThread->start((void (*)(mvm::Thread*))mainJavaStart);
+    mainThread = new JavaThread(0, 0, this);
+    mainThread->start((void (*)(mvm::Thread*))mainJavaStart);
   } else {
     threadSystem.nonDaemonThreads = 0;
   }

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

==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.h (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.h Wed May 20 10:46:54 2009
@@ -113,9 +113,13 @@
 
 private:
   
-  /// bootstrapThread - The initial thread of this JVM.
+  /// mainThread - The initial thread of this JVM.
   ///
-  JavaThread* bootstrapThread;
+  JavaThread* mainThread;
+  
+  /// finalizerThread - The thread that finalizes Java objects.
+  ///
+  JavaThread* finalizerThread;
   
   /// CreateError - Creates a Java object of the specified exception class
   /// and calling its <init> function.
@@ -295,13 +299,21 @@
   ///
   ArrayUInt16* asciizToArray(const char* asciiz);
   
-  /// setBootstrapThread - Set the bootstrap thread of this VM.
+  /// setMainThread - Set the main thread of this VM.
+  ///
+  void setMainThread(JavaThread* th) { mainThread = th; }
+  
+  /// getMainThread - Get the main thread of this VM.
   ///
-  void setBootstrapThread(JavaThread* th) { bootstrapThread = th; }
+  JavaThread* getMainThread() const { return mainThread; }
   
-  /// getBootstrapThread - Get the bootstrap thread of this VM.
+  /// setFinalizerThread - Set the finalizer thread of this VM.
   ///
-  JavaThread* getBootstrapThread() const { return bootstrapThread; }
+  void setFinalizerThread(JavaThread* th) { finalizerThread = th; }
+  
+  /// getFinalizerThread - Get the finalizer thread of this VM.
+  ///
+  JavaThread* getFinalizerThread() const { return finalizerThread; }
 
   /// ~Jnjvm - Destroy the JVM.
   ///
@@ -344,6 +356,10 @@
   virtual void stopService();
 #endif
 
+protected:
+  virtual void invokeFinalizer(gc*);
+
+
 
 };
 

Modified: vmkit/trunk/lib/Mvm/BoehmGC/MvmGC.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/Mvm/BoehmGC/MvmGC.h?rev=72171&r1=72170&r2=72171&view=diff

==============================================================================
--- vmkit/trunk/lib/Mvm/BoehmGC/MvmGC.h (original)
+++ vmkit/trunk/lib/Mvm/BoehmGC/MvmGC.h Wed May 20 10:46:54 2009
@@ -143,6 +143,10 @@
     if(GC_get_heap_size() < size)
     GC_expand_hp(size - GC_get_heap_size());
   }
+
+  static bool isLive() {
+    return true;
+  }
 };
 
 

Modified: vmkit/trunk/lib/Mvm/GCMmap2/MvmGC.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/Mvm/GCMmap2/MvmGC.h?rev=72171&r1=72170&r2=72171&view=diff

==============================================================================
--- vmkit/trunk/lib/Mvm/GCMmap2/MvmGC.h (original)
+++ vmkit/trunk/lib/Mvm/GCMmap2/MvmGC.h Wed May 20 10:46:54 2009
@@ -77,6 +77,7 @@
   static void           inject_my_thread(mvm::Thread* th);
   static void           remove_my_thread(mvm::Thread* th);
 
+  static bool           isLive(void* ptr);
   static gc             *begOf(const void *o);
   static int            byteOffset(void *o);
   inline static bool    isObject(const void *o) { return begOf((void*)o); }

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

==============================================================================
--- vmkit/trunk/lib/Mvm/GCMmap2/gc.cpp (original)
+++ vmkit/trunk/lib/Mvm/GCMmap2/gc.cpp Wed May 20 10:46:54 2009
@@ -139,6 +139,9 @@
   return (off-beg);
 }
 
+bool Collector::isLive(void* ptr) {
+  return GCCollector::isLive(ptr);
+}
 
 void Collector::applyFunc(void (*func)(gcRoot *o, void *data), void *data) {
   return GCCollector::applyFunc(func, data);

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

==============================================================================
--- vmkit/trunk/lib/Mvm/GCMmap2/gccollector.h (original)
+++ vmkit/trunk/lib/Mvm/GCMmap2/gccollector.h Wed May 20 10:46:54 2009
@@ -70,6 +70,13 @@
   static GCThread *threads;        /* le gestionnaire de thread et de synchro */
   static void (*internMemoryError)(unsigned int);
 
+  static bool isLive(void* ptr) {
+    GCChunkNode *node = o2node(ptr);
+    
+    if(node && isMarked(node)) return true;
+    else return false;
+  }
+
 #ifdef HAVE_PTHREAD
   static inline void  unlock_dont_recovery() { threads->unlock_dont_recovery(); }
   static void die_if_sigsegv_occured_during_collection(void *addr);

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

==============================================================================
--- vmkit/trunk/lib/Mvm/Runtime/Object.cpp (original)
+++ vmkit/trunk/lib/Mvm/Runtime/Object.cpp Wed May 20 10:46:54 2009
@@ -14,6 +14,7 @@
 #include "mvm/Allocator.h"
 #include "mvm/Object.h"
 #include "mvm/PrintBuffer.h"
+#include "mvm/VirtualMachine.h"
 #include "mvm/Threads/Thread.h"
 
 using namespace mvm;
@@ -112,3 +113,95 @@
   }
   buf->write("\"");
 }
+
+
+
+
+void VirtualMachine::finalizerStart(mvm::Thread* th) {
+  VirtualMachine* vm = th->MyVM;
+
+  while (true) {
+    vm->FinalizationLock.lock();
+    while (vm->CurrentFinalizedIndex == 0) {
+      vm->FinalizationCond.wait(&vm->FinalizationLock);
+    }
+    vm->FinalizationLock.unlock();
+
+    while (true) {
+      vm->FinalizationQueueLock.acquire();
+      gc* res = 0;
+      if (vm->CurrentFinalizedIndex != 0) {
+        res = vm->ToBeFinalized[--vm->CurrentFinalizedIndex];
+      }
+      vm->FinalizationQueueLock.release();
+      if (!res) break;
+
+      VirtualTable* VT = res->getVirtualTable();
+      try {
+        if (VT->operatorDelete) {
+          // It's a native method!
+          destructor_t dest = (destructor_t)VT->destructor;
+          dest(res);
+        } else {
+          vm->invokeFinalizer(res);
+        }
+      } catch(...) {
+      }
+    }
+  }
+}
+
+void VirtualMachine::growQueue() {
+  if (CurrentIndex >= QueueLength) {
+    uint32 newLength = QueueLength * GROW_FACTOR;
+    gc** newQueue = new gc*[newLength];
+    for (uint32 i = 0; i < QueueLength; ++i) newQueue[i] = FinalizationQueue[i];
+    delete[] FinalizationQueue;
+    FinalizationQueue = newQueue;
+    QueueLength = newLength;
+    
+    newLength = ToBeFinalizedLength * GROW_FACTOR;
+    newQueue = new gc*[newLength];
+    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) {
+    growQueue();
+  }
+  
+  FinalizationQueue[CurrentIndex++] = obj;
+  FinalizationQueueLock.release();
+}
+  
+
+void VirtualMachine::scanFinalizationQueue() {
+  uint32 NewIndex = 0;
+  for (uint32 i = 0; i < CurrentIndex; ++i) {
+    gc* obj = FinalizationQueue[i];
+
+    if (!Collector::isLive(obj)) {
+      obj->markAndTrace();
+      
+      if (CurrentFinalizedIndex >= ToBeFinalizedLength) growQueue();
+      
+      /* Add to object table */
+      ToBeFinalized[CurrentFinalizedIndex++] = obj;
+    } else {
+      FinalizationQueue[NewIndex++] = obj;
+    }
+  }
+  CurrentIndex = NewIndex;
+
+  for (uint32 i = 0; i < CurrentFinalizedIndex; ++i) {
+    gc* obj = ToBeFinalized[i];
+    obj->markAndTrace();
+  }
+}





More information about the vmkit-commits mailing list