[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