[vmkit-commits] [vmkit] r69999 - 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.cpp lib/Mvm/GCMmap2/gccollector.h lib/Mvm/Runtime/Object.cpp

Nicolas Geoffray nicolas.geoffray at lip6.fr
Fri Apr 24 15:30:56 PDT 2009


Author: geoffray
Date: Fri Apr 24 17:30:56 2009
New Revision: 69999

URL: http://llvm.org/viewvc/llvm-project?rev=69999&view=rev
Log:
Support for finalization in GCMmap2!


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.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=69999&r1=69998&r2=69999&view=diff

==============================================================================
--- vmkit/trunk/include/mvm/VirtualMachine.h (original)
+++ vmkit/trunk/include/mvm/VirtualMachine.h Fri Apr 24 17:30:56 2009
@@ -18,11 +18,23 @@
 #include "mvm/Allocator.h"
 #include "mvm/CompilationUnit.h"
 #include "mvm/Object.h"
+#include "mvm/Threads/Cond.h"
 #include "mvm/Threads/Locks.h"
 
 #include <cassert>
 #include <map>
 
+
+// Same values than JikesRVM
+#define INITIAL_QUEUE_SIZE 256
+#define GROW_FACTOR 2
+
+#if (__WORDSIZE == 64)
+#define LOG_BYTES_IN_ADDRESS 3
+#else
+#define LOG_BYTES_IN_ADDRESS 2
+#endif
+
 namespace jnjvm {
   class JavaCompiler;
   class JnjvmClassLoader;
@@ -46,6 +58,12 @@
     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:
 
@@ -102,6 +120,96 @@
     return (T*)I->second;
   }
 
+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;
+
+  /// countFinalized - The number of entries to be finalized.
+  ///
+  uint32 countFinalized() {
+    return (LastFinalizedIndex - CurrentFinalizedIndex + ToBeFinalizedLength) 
+      % ToBeFinalizedLength;
+  }
+
+  /// freeFinalized - The number of entries available in the ToBeFinalized
+  /// queue.
+  ///
+  uint32 freeFinalized() {
+    return ToBeFinalizedLength - countFinalized();
+  }
+
+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(); }
+
 #ifdef ISOLATE
   size_t IsolateID;
 #endif

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

==============================================================================
--- vmkit/trunk/lib/JnJVM/Compiler/JavaAOTCompiler.cpp (original)
+++ vmkit/trunk/lib/JnJVM/Compiler/JavaAOTCompiler.cpp Fri Apr 24 17:30:56 2009
@@ -1637,7 +1637,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=69999&r1=69998&r2=69999&view=diff

==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JavaMetaJIT.cpp (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JavaMetaJIT.cpp Fri Apr 24 17:30:56 2009
@@ -15,6 +15,7 @@
 #include "JavaObject.h"
 #include "JavaThread.h"
 #include "JavaTypes.h"
+#include "JavaUpcalls.h"
 #include "Jnjvm.h"
 
 using namespace jnjvm;
@@ -624,3 +625,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=69999&r1=69998&r2=69999&view=diff

==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JavaString.cpp (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JavaString.cpp Fri Apr 24 17:30:56 2009
@@ -28,6 +28,10 @@
   // internStringVT exists (in case of AOT).
   if (internStringVT) res->setVirtualTable(internStringVT);
 
+  // The GC did not have this info. Now we do, so inform the finalizers
+  // that this is a finalization candidate.
+  vm->addFinalizationCandidate(res);
+
   // No need to call the Java function: both the Java function and
   // this function do the same thing.
   res->value = utf8;

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

==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JavaUpcalls.cpp (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JavaUpcalls.cpp Fri Apr 24 17:30:56 2009
@@ -38,7 +38,9 @@
 JavaMethod* Classpath::finaliseCreateInitialThread;
 JavaMethod* Classpath::initVMThread;
 JavaMethod* Classpath::groupAddThread;
-JavaField*  Classpath::name;
+JavaMethod* Classpath::initGroup;
+JavaField*  Classpath::groupName;
+JavaField*  Classpath::threadName;
 JavaField*  Classpath::priority;
 JavaField*  Classpath::daemon;
 JavaField*  Classpath::group;
@@ -175,6 +177,7 @@
 JavaMethod* Classpath::InitClassNotFoundException;
 JavaMethod* Classpath::InitArithmeticException;
 JavaMethod* Classpath::InitObject;
+JavaMethod* Classpath::FinalizeObject;
 
 JavaMethod* Classpath::ErrorWithExcpNoClassDefFoundError;
 JavaMethod* Classpath::ErrorWithExcpExceptionInInitializerError;
@@ -214,7 +217,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);
@@ -239,11 +242,22 @@
   threadGroup->resolveClass();
   threadGroup->initialiseClass(vm);
 
-  // Create the main thread
+  // 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 bootstrap 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) {
@@ -585,6 +599,9 @@
 
   InitObject = UPCALL_METHOD(loader, "java/lang/Object", "<init>", "()V",
                              ACC_VIRTUAL);
+  
+  FinalizeObject = UPCALL_METHOD(loader, "java/lang/Object", "finalize", "()V",
+                                 ACC_VIRTUAL);
 
   newThread = 
     UPCALL_CLASS(loader, "java/lang/Thread");
@@ -619,7 +636,15 @@
     UPCALL_METHOD(loader, "java/lang/ThreadGroup", "addThread",
                   "(Ljava/lang/Thread;)V", ACC_VIRTUAL);
   
-  name = 
+  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);
   

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

==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JavaUpcalls.h (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JavaUpcalls.h Fri Apr 24 17:30:56 2009
@@ -131,7 +131,9 @@
   ISOLATE_STATIC JavaMethod* initVMThread;
   ISOLATE_STATIC JavaMethod* runVMThread;
   ISOLATE_STATIC JavaMethod* groupAddThread;
-  ISOLATE_STATIC JavaField* name;
+  ISOLATE_STATIC JavaMethod* initGroup;
+  ISOLATE_STATIC JavaField* groupName;
+  ISOLATE_STATIC JavaField* threadName;
   ISOLATE_STATIC JavaField* priority;
   ISOLATE_STATIC JavaField* daemon;
   ISOLATE_STATIC JavaField* group;
@@ -208,6 +210,7 @@
   ISOLATE_STATIC JavaMethod* InitArithmeticException;
 
   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=69999&r1=69998&r2=69999&view=diff

==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.cpp (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.cpp Fri Apr 24 17:30:56 2009
@@ -814,6 +814,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);
 
@@ -981,7 +985,7 @@
 
 void Jnjvm::mainJavaStart(JavaThread* thread) {
   Jnjvm* vm = thread->getJVM();
-  vm->bootstrapThread = thread;
+  vm->mainThread = thread;
 
   vm->loadBootstrap();
 
@@ -1062,8 +1066,11 @@
     th->start(serviceCPUMonitor);
 #endif
     
-    bootstrapThread = new JavaThread(0, 0, this);
-    bootstrapThread->start((void (*)(mvm::Thread*))mainJavaStart);
+    finalizerThread = new JavaThread(0, 0, this);
+    finalizerThread->start((void (*)(mvm::Thread*))finalizerStart);
+    
+    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=69999&r1=69998&r2=69999&view=diff

==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.h (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.h Fri Apr 24 17:30:56 2009
@@ -113,10 +113,14 @@
 
 private:
   
-  /// bootstrapThread - The initial thread of this JVM.
+  /// mainThread - The initial thread of this JVM.
   ///
-  JavaThread* bootstrapThread;
+  JavaThread* mainThread;
   
+  /// finalizerThread - The initial thread of this JVM.
+  ///
+  JavaThread* finalizerThread;
+   
   /// CreateError - Creates a Java object of the specified exception class
   /// and calling its <init> function.
   ///
@@ -301,11 +305,19 @@
   
   /// setBootstrapThread - Set the bootstrap thread of this VM.
   ///
-  void setBootstrapThread(JavaThread* th) { bootstrapThread = th; }
+  void setMainThread(JavaThread* th) { mainThread = th; }
   
   /// getBootstrapThread - Get the bootstrap thread of this VM.
   ///
-  JavaThread* getBootstrapThread() const { return bootstrapThread; }
+  JavaThread* getMainThread() const { return mainThread; }
+  
+  /// setFinalizerThread - Set the first finalizer thread of this VM.
+  ///
+  void setFinalizerThread(JavaThread* th) { finalizerThread = th; }
+  
+  /// getFinalizerThread - Get the finalizer thread of this VM.
+  ///
+  JavaThread* getFinalizerThread() const { return finalizerThread; }
 
   /// ~Jnjvm - Destroy the JVM.
   ///
@@ -348,6 +360,9 @@
   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=69999&r1=69998&r2=69999&view=diff

==============================================================================
--- vmkit/trunk/lib/Mvm/BoehmGC/MvmGC.h (original)
+++ vmkit/trunk/lib/Mvm/BoehmGC/MvmGC.h Fri Apr 24 17:30:56 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=69999&r1=69998&r2=69999&view=diff

==============================================================================
--- vmkit/trunk/lib/Mvm/GCMmap2/MvmGC.h (original)
+++ vmkit/trunk/lib/Mvm/GCMmap2/MvmGC.h Fri Apr 24 17:30:56 2009
@@ -87,6 +87,7 @@
         static int      getTotalMemory(void);
         static void     setMaxMemory(size_t);
         static void     setMinMemory(size_t);
+  static bool isLive(void* ptr);
 };
 
 #endif

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

==============================================================================
--- vmkit/trunk/lib/Mvm/GCMmap2/gc.cpp (original)
+++ vmkit/trunk/lib/Mvm/GCMmap2/gc.cpp Fri Apr 24 17:30:56 2009
@@ -173,6 +173,10 @@
 #endif
 }
 
+bool Collector::isLive(void* ptr) {
+  return GCCollector::isLive(ptr);
+}
+
 void GCThread::waitCollection() {
   mvm::Thread* th = mvm::Thread::get();
   unsigned int cm = GCCollector::current_mark;

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

==============================================================================
--- vmkit/trunk/lib/Mvm/GCMmap2/gccollector.cpp (original)
+++ vmkit/trunk/lib/Mvm/GCMmap2/gccollector.cpp Fri Apr 24 17:30:56 2009
@@ -71,63 +71,31 @@
 
   if(_marker)
     _marker(0);
+
+  
   status = stat_finalize;
+#ifdef HAVE_PTHREAD
+  threads->collectionFinished();
+#endif
 
+  Thread::get()->MyVM->scanFinalizationQueue();
+  
   /* finalize */
   GCChunkNode  finalizable;
   finalizable.attrape(unused_nodes);
 
-  status = stat_alloc;
-  
-  unlock();
-
   /* kill everyone */
   GCChunkNode *next = 0;
-
-#ifdef SERVICE
-  Thread* th = Thread::get();
-  VirtualMachine* OldVM = th->MyVM;
-#endif
-
-
-  for(cur=finalizable.next(); cur!=&finalizable; cur=next) {
-#ifdef SERVICE
-    mvm::VirtualMachine* NewVM = cur->meta;
-    if (NewVM) {
-      NewVM->memoryUsed -= real_nbb(cur);
-      th->MyVM = NewVM;
-      th->IsolateID = NewVM->IsolateID;
-    }
-#endif
-    register gc_header *c = cur->chunk();
-    next = cur->next();
-    
-    destructor_t dest = c->getDestructor();
-    if (dest) {
-      try {
-        dest(c);
-      } catch(...) {
-        mvm::Thread::get()->clearException();
-      }
-    }
-  }
-#ifdef SERVICE
-  th->IsolateID = OldVM->IsolateID;
-  th->MyVM = OldVM;
-#endif
-  
-  next = 0;
   for(cur=finalizable.next(); cur!=&finalizable; cur=next) {
     //printf("    !!!! reject %p [%p]\n", cur->chunk()->_2gc(), cur);
     next = cur->next();
     allocator->reject_chunk(cur);
   }
+  status = stat_alloc;
+  
+  Thread::get()->MyVM->wakeUpFinalizers();
 
-  lock();
 
-#ifdef HAVE_PTHREAD
-  threads->collectionFinished();
-#endif
 }
 
 void GCCollector::collect_unprotect() {

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

==============================================================================
--- vmkit/trunk/lib/Mvm/GCMmap2/gccollector.h (original)
+++ vmkit/trunk/lib/Mvm/GCMmap2/gccollector.h Fri Apr 24 17:30:56 2009
@@ -201,6 +201,10 @@
 
 
     unlock();
+
+    if (vt->destructor) 
+      mvm::Thread::get()->MyVM->addFinalizationCandidate((gc*)p->_2gc());
+
     return p->_2gc();
 #endif
   }
@@ -283,6 +287,13 @@
   static inline bool isMarked(GCChunkNode *node) { 
     return node->mark() == (current_mark & 1);
   }
+
+  static bool isLive(void* ptr) {
+    GCChunkNode *node = o2node(ptr);
+
+    if(node && isMarked(node)) return true;
+    else return false;
+  }
   
   static inline void mark(GCChunkNode *node) {
     node->_mark(current_mark & 1);

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

==============================================================================
--- vmkit/trunk/lib/Mvm/Runtime/Object.cpp (original)
+++ vmkit/trunk/lib/Mvm/Runtime/Object.cpp Fri Apr 24 17:30:56 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;
@@ -128,3 +129,90 @@
   }
   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];
+    FinalizationQueue = newQueue;
+    QueueLength = newLength;
+    
+    newLength = ToBeFinalizedLength * GROW_FACTOR;
+    newQueue = new gc*[newLength];
+    for (uint32 i = 0; i < ToBeFinalizedLength; ++i) newQueue[i] = ToBeFinalized[i];
+    ToBeFinalized = newQueue;
+    ToBeFinalizedLength = newLength;
+  }
+}
+
+
+void VirtualMachine::addFinalizationCandidate(gc* obj) {
+  FinalizationQueueLock.acquire();
+ 
+  if (CurrentIndex >= QueueLength) {
+    growQueue();
+  }
+  
+  FinalizationQueue[CurrentIndex++] = obj;
+  FinalizationQueueLock.release();
+}
+
+void VirtualMachine::scanFinalizationQueue() {
+  FinalizationQueueLock.acquire();
+  uint32 NewIndex = 0;
+  for (uint32 i = 0; i < CurrentIndex; ++i) {
+    gc* obj = FinalizationQueue[i];
+
+    if (!Collector::isLive(obj)) {
+      obj->markAndTrace();
+      /* 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();
+  }
+  FinalizationQueueLock.release();
+
+}





More information about the vmkit-commits mailing list