[vmkit-commits] [vmkit] r72413 - in /vmkit/trunk: include/mvm/VirtualMachine.h lib/JnJVM/Classpath/ClasspathReflect.h lib/JnJVM/Classpath/ClasspathVMRuntime.cpp lib/JnJVM/VMCore/JavaMetaJIT.cpp lib/JnJVM/VMCore/JavaUpcalls.cpp lib/JnJVM/VMCore/JavaUpcalls.h lib/JnJVM/VMCore/Jnjvm.cpp lib/JnJVM/VMCore/Jnjvm.h lib/Mvm/GCMmap2/gccollector.cpp lib/Mvm/Runtime/Object.cpp
Nicolas Geoffray
nicolas.geoffray at lip6.fr
Tue May 26 01:48:29 PDT 2009
Author: geoffray
Date: Tue May 26 03:48:28 2009
New Revision: 72413
URL: http://llvm.org/viewvc/llvm-project?rev=72413&view=rev
Log:
Support for weak/soft/phantom references.
Modified:
vmkit/trunk/include/mvm/VirtualMachine.h
vmkit/trunk/lib/JnJVM/Classpath/ClasspathReflect.h
vmkit/trunk/lib/JnJVM/Classpath/ClasspathVMRuntime.cpp
vmkit/trunk/lib/JnJVM/VMCore/JavaMetaJIT.cpp
vmkit/trunk/lib/JnJVM/VMCore/JavaUpcalls.cpp
vmkit/trunk/lib/JnJVM/VMCore/JavaUpcalls.h
vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.cpp
vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.h
vmkit/trunk/lib/Mvm/GCMmap2/gccollector.cpp
vmkit/trunk/lib/Mvm/Runtime/Object.cpp
Modified: vmkit/trunk/include/mvm/VirtualMachine.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/include/mvm/VirtualMachine.h?rev=72413&r1=72412&r2=72413&view=diff
==============================================================================
--- vmkit/trunk/include/mvm/VirtualMachine.h (original)
+++ vmkit/trunk/include/mvm/VirtualMachine.h Tue May 26 03:48:28 2009
@@ -36,15 +36,72 @@
#define INITIAL_QUEUE_SIZE 256
#define GROW_FACTOR 2
+class VirtualMachine;
+
+class ReferenceQueue {
+private:
+ gc** References;
+ uint32 QueueLength;
+ uint32 CurrentIndex;
+ mvm::SpinLock QueueLock;
+ uint8_t semantics;
+
+ gc* processReference(gc*, VirtualMachine*);
+public:
+
+ static const uint8_t WEAK = 1;
+ static const uint8_t SOFT = 2;
+ static const uint8_t PHANTOM = 3;
+
+ ReferenceQueue(uint8_t s) {
+ References = new gc*[INITIAL_QUEUE_SIZE];
+ QueueLength = INITIAL_QUEUE_SIZE;
+ CurrentIndex = 0;
+ semantics = s;
+ }
+
+ void addReference(gc* ref) {
+ QueueLock.acquire();
+ if (CurrentIndex >= QueueLength) {
+ uint32 newLength = QueueLength * GROW_FACTOR;
+ gc** newQueue = new gc*[newLength];
+ if (!newQueue) {
+ fprintf(stderr, "I don't know how to handle reference overflow yet!\n");
+ abort();
+ }
+ for (uint32 i = 0; i < QueueLength; ++i) newQueue[i] = References[i];
+ delete[] References;
+ References = newQueue;
+ QueueLength = newLength;
+ }
+ References[CurrentIndex++] = ref;
+ QueueLock.release();
+ }
+
+ void acquire() {
+ QueueLock.acquire();
+ }
+
+ void release() {
+ QueueLock.release();
+ }
+
+ void scan(VirtualMachine* vm);
+};
/// VirtualMachine - This class is the root of virtual machine classes. It
/// defines what a VM should be.
///
class VirtualMachine : public mvm::PermanentObject {
+ friend class ReferenceQueue;
+
protected:
- VirtualMachine() {
+ VirtualMachine() :
+ WeakReferencesQueue(ReferenceQueue::WEAK),
+ SoftReferencesQueue(ReferenceQueue::SOFT),
+ PhantomReferencesQueue(ReferenceQueue::PHANTOM) {
#ifdef SERVICE
memoryLimit = ~0;
executionLimit = ~0;
@@ -56,9 +113,15 @@
#endif
FinalizationQueue = new gc*[INITIAL_QUEUE_SIZE];
QueueLength = INITIAL_QUEUE_SIZE;
+ CurrentIndex = 0;
ToBeFinalized = new gc*[INITIAL_QUEUE_SIZE];
ToBeFinalizedLength = INITIAL_QUEUE_SIZE;
+ CurrentFinalizedIndex = 0;
+
+ ToEnqueue = new gc*[INITIAL_QUEUE_SIZE];
+ ToEnqueueLength = INITIAL_QUEUE_SIZE;
+ ToEnqueueIndex = 0;
}
public:
@@ -82,6 +145,19 @@
private:
+ /// WeakReferencesQueue - The queue of weak references.
+ ///
+ ReferenceQueue WeakReferencesQueue;
+
+ /// SoftReferencesQueue - The queue of soft references.
+ ///
+ ReferenceQueue SoftReferencesQueue;
+
+ /// PhantomReferencesQueue - The queue of phantom references.
+ ///
+ ReferenceQueue PhantomReferencesQueue;
+
+
/// FinalizationQueueLock - A lock to protect access to the queue.
///
mvm::SpinLock FinalizationQueueLock;
@@ -128,6 +204,32 @@
/// finalizationLock - Lock for the condition variable.
///
mvm::LockNormal FinalizationLock;
+
+ gc** ToEnqueue;
+ uint32 ToEnqueueLength;
+ uint32 ToEnqueueIndex;
+
+ /// ToEnqueueLock - A lock to protect access to the queue.
+ ///
+ mvm::LockNormal EnqueueLock;
+ mvm::Cond EnqueueCond;
+ mvm::SpinLock ToEnqueueLock;
+
+ void addToEnqueue(gc* obj) {
+ if (ToEnqueueIndex >= ToEnqueueLength) {
+ uint32 newLength = ToEnqueueLength * GROW_FACTOR;
+ gc** newQueue = new gc*[newLength];
+ if (!newQueue) {
+ fprintf(stderr, "I don't know how to handle reference overflow yet!\n");
+ abort();
+ }
+ for (uint32 i = 0; i < QueueLength; ++i) newQueue[i] = ToEnqueue[i];
+ delete[] ToEnqueue;
+ ToEnqueue = newQueue;
+ ToEnqueueLength = newLength;
+ }
+ ToEnqueue[ToEnqueueIndex++] = obj;
+ }
protected:
/// invokeFinalizer - Invoke the finalizer of the object. This may involve
@@ -141,6 +243,11 @@
/// finalizationQueue.
///
static void finalizerStart(mvm::Thread*);
+
+ /// enqueueStart - The start function of a thread for references. Will poll
+ /// ToEnqueue.
+ ///
+ static void enqueueStart(mvm::Thread*);
/// addFinalizationCandidate - Add an object to the queue of objects with
/// a finalization method.
@@ -155,14 +262,81 @@
/// wakeUpFinalizers - Wake the finalizers.
///
void wakeUpFinalizers() { FinalizationCond.broadcast(); }
+
+ /// wakeUpEnqueue - Wake the threads for enqueueing.
+ ///
+ void wakeUpEnqueue() { EnqueueCond.broadcast(); }
virtual void startCollection() {
FinalizationQueueLock.acquire();
+ ToEnqueueLock.acquire();
+ SoftReferencesQueue.acquire();
+ WeakReferencesQueue.acquire();
+ PhantomReferencesQueue.acquire();
}
virtual void endCollection() {
FinalizationQueueLock.release();
+ ToEnqueueLock.release();
+ SoftReferencesQueue.release();
+ WeakReferencesQueue.release();
+ PhantomReferencesQueue.release();
+ }
+
+ /// scanWeakReferencesQueue - Scan all weak references. Called by the GC
+ /// before scanning the finalization queue.
+ ///
+ void scanWeakReferencesQueue() {
+ WeakReferencesQueue.scan(this);
}
+
+ /// scanSoftReferencesQueue - Scan all soft references. Called by the GC
+ /// before scanning the finalization queue.
+ ///
+ void scanSoftReferencesQueue() {
+ SoftReferencesQueue.scan(this);
+ }
+
+ /// scanPhantomReferencesQueue - Scan all phantom references. Called by the GC
+ /// after the finalization queue.
+ ///
+ void scanPhantomReferencesQueue() {
+ PhantomReferencesQueue.scan(this);
+ }
+
+ /// addWeakReference - Add a weak reference to the queue.
+ ///
+ void addWeakReference(gc* ref) {
+ WeakReferencesQueue.addReference(ref);
+ }
+
+ /// addSoftReference - Add a weak reference to the queue.
+ ///
+ void addSoftReference(gc* ref) {
+ SoftReferencesQueue.addReference(ref);
+ }
+
+ /// addPhantomReference - Add a weak reference to the queue.
+ ///
+ void addPhantomReference(gc* ref) {
+ PhantomReferencesQueue.addReference(ref);
+ }
+
+ /// clearReferent - Clear the referent in a reference. Should be overriden
+ /// by the VM.
+ ///
+ virtual void clearReferent(gc*) {}
+
+ /// getReferent - Get the referent of the reference. Should be overriden
+ /// by the VM.
+ //
+ virtual gc* getReferent(gc*) { return 0; }
+
+ /// enqueueReference - Calls the enqueue method. Should be overriden
+ /// by the VM.
+ ///
+ virtual bool enqueueReference(gc*) { return false; }
+
protected:
Modified: vmkit/trunk/lib/JnJVM/Classpath/ClasspathReflect.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/Classpath/ClasspathReflect.h?rev=72413&r1=72412&r2=72413&view=diff
==============================================================================
--- vmkit/trunk/lib/JnJVM/Classpath/ClasspathReflect.h (original)
+++ vmkit/trunk/lib/JnJVM/Classpath/ClasspathReflect.h Tue May 26 03:48:28 2009
@@ -153,6 +153,27 @@
}
};
+class JavaObjectReference : public JavaObject {
+private:
+ JavaObject* referent;
+ JavaObject* queue;
+ JavaObject* nextOnQueue;
+
+public:
+ void init(JavaObject* r, JavaObject* q) {
+ referent = r;
+ queue = q;
+ }
+
+ JavaObject* getReferent() const { return referent; }
+ void setReferent(JavaObject* r) { referent = r; }
+
+ static void STATIC_TRACER(JavaObjectReference) {
+ obj->queue->MARK_AND_TRACE;
+ obj->nextOnQueue->MARK_AND_TRACE;
+ }
+};
+
}
#endif
Modified: vmkit/trunk/lib/JnJVM/Classpath/ClasspathVMRuntime.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/Classpath/ClasspathVMRuntime.cpp?rev=72413&r1=72412&r2=72413&view=diff
==============================================================================
--- vmkit/trunk/lib/JnJVM/Classpath/ClasspathVMRuntime.cpp (original)
+++ vmkit/trunk/lib/JnJVM/Classpath/ClasspathVMRuntime.cpp Tue May 26 03:48:28 2009
@@ -143,6 +143,10 @@
jclass clazz,
#endif
) {
+ Jnjvm* vm = JavaThread::get()->getJVM();
+ vm->wakeUpFinalizers();
+ // Sleep a bit.
+ sleep(1);
return;
}
Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaMetaJIT.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JavaMetaJIT.cpp?rev=72413&r1=72412&r2=72413&view=diff
==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JavaMetaJIT.cpp (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JavaMetaJIT.cpp Tue May 26 03:48:28 2009
@@ -634,3 +634,9 @@
meth->invokeIntVirtualBuf(this, cl, obj, 0);
}
+bool Jnjvm::enqueueReference(gc* _obj) {
+ JavaObject* obj = (JavaObject*)_obj;
+ JavaMethod* meth = upcalls->EnqueueReference;
+ UserClass* cl = obj->getClass()->asClass();
+ return (bool)meth->invokeIntSpecialBuf(this, cl, obj, 0);
+}
Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaUpcalls.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JavaUpcalls.cpp?rev=72413&r1=72412&r2=72413&view=diff
==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JavaUpcalls.cpp (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JavaUpcalls.cpp Tue May 26 03:48:28 2009
@@ -18,12 +18,12 @@
#define COMPILE_METHODS(cl) \
for (CommonClass::method_iterator i = cl->virtualMethods.begin(), \
- e = cl->virtualMethods.end(); i!= e; +i) { \
+ e = cl->virtualMethods.end(); i!= e; ++i) { \
i->second->compiledPtr(); \
} \
\
for (CommonClass::method_iterator i = cl->staticMethods.begin(), \
- e = cl->staticMethods.end(); i!= e; +i) { \
+ e = cl->staticMethods.end(); i!= e; ++i) { \
i->second->compiledPtr(); \
}
@@ -216,6 +216,9 @@
JavaField* Classpath::fieldClass;
JavaField* Classpath::constructorClass;
+JavaMethod* Classpath::EnqueueReference;
+Class* Classpath::newReference;
+
#endif
void Classpath::CreateJavaThread(Jnjvm* vm, JavaThread* myth,
@@ -262,9 +265,51 @@
JavaObject* systemName = (JavaObject*)vm->asciizToStr("system");
groupName->setObjectField(SystemGroup, systemName);
- // And create the finalizer thread.
+ // Create the finalizer thread.
assert(vm->getFinalizerThread() && "VM did not set its finalizer thread");
CreateJavaThread(vm, vm->getFinalizerThread(), "Finalizer", SystemGroup);
+
+ // Create the enqueue thread.
+ assert(vm->getEnqueueThread() && "VM did not set its enqueue thread");
+ CreateJavaThread(vm, vm->getEnqueueThread(), "Reference", SystemGroup);
+}
+
+extern "C" void nativeInitWeakReference(JavaObjectReference* reference,
+ JavaObject* referent) {
+ reference->init(referent, 0);
+ JavaThread::get()->getJVM()->addWeakReference(reference);
+
+}
+
+extern "C" void nativeInitWeakReferenceQ(JavaObjectReference* reference,
+ JavaObject* referent,
+ JavaObject* queue) {
+ reference->init(referent, queue);
+ JavaThread::get()->getJVM()->addWeakReference(reference);
+
+}
+
+extern "C" void nativeInitSoftReference(JavaObjectReference* reference,
+ JavaObject* referent) {
+ reference->init(referent, 0);
+ JavaThread::get()->getJVM()->addSoftReference(reference);
+
+}
+
+extern "C" void nativeInitSoftReferenceQ(JavaObjectReference* reference,
+ JavaObject* referent,
+ JavaObject* queue) {
+ reference->init(referent, queue);
+ JavaThread::get()->getJVM()->addSoftReference(reference);
+
+}
+
+extern "C" void nativeInitPhantomReferenceQ(JavaObjectReference* reference,
+ JavaObject* referent,
+ JavaObject* queue) {
+ reference->init(referent, queue);
+ JavaThread::get()->getJVM()->addPhantomReference(reference);
+
}
extern "C" JavaString* nativeInternString(JavaString* obj) {
@@ -359,6 +404,10 @@
JavaObjectConstructor::staticTracer(obj);
}
+extern "C" void nativeJavaObjectReferenceTracer(JavaObjectReference* obj) {
+ JavaObjectReference::staticTracer(obj);
+}
+
extern "C" void nativeJavaObjectVMThreadDestructor(JavaObjectVMThread* obj) {
JavaObjectVMThread::staticDestructor(obj);
}
@@ -833,4 +882,63 @@
newVMThread->getVirtualVT()->setNativeDestructor(
(uintptr_t)nativeJavaObjectVMThreadDestructor,
"nativeJavaObjectVMThreadDestructor");
+
+
+ newReference = UPCALL_CLASS(loader, "java/lang/ref/Reference");
+
+ newReference->getVirtualVT()->setNativeTracer(
+ (uintptr_t)nativeJavaObjectReferenceTracer,
+ "nativeJavaObjectReferenceTracer");
+
+ EnqueueReference =
+ UPCALL_METHOD(loader, "java/lang/ref/Reference", "enqueue", "()Z",
+ ACC_VIRTUAL);
+
+ JavaMethod* initWeakReference =
+ UPCALL_METHOD(loader, "java/lang/ref/WeakReference", "<init>",
+ "(Ljava/lang/Object;)V",
+ ACC_VIRTUAL);
+ initWeakReference->setCompiledPtr((void*)(intptr_t)nativeInitWeakReference,
+ "nativeInitWeakReference");
+
+ initWeakReference =
+ UPCALL_METHOD(loader, "java/lang/ref/WeakReference", "<init>",
+ "(Ljava/lang/Object;Ljava/lang/ref/ReferenceQueue;)V",
+ ACC_VIRTUAL);
+ initWeakReference->setCompiledPtr((void*)(intptr_t)nativeInitWeakReferenceQ,
+ "nativeInitWeakReferenceQ");
+
+ JavaMethod* initSoftReference =
+ UPCALL_METHOD(loader, "java/lang/ref/SoftReference", "<init>",
+ "(Ljava/lang/Object;)V",
+ ACC_VIRTUAL);
+ initSoftReference->setCompiledPtr((void*)(intptr_t)nativeInitSoftReference,
+ "nativeInitSoftReference");
+
+ initSoftReference =
+ UPCALL_METHOD(loader, "java/lang/ref/WeakReference", "<init>",
+ "(Ljava/lang/Object;Ljava/lang/ref/ReferenceQueue;)V",
+ ACC_VIRTUAL);
+ initSoftReference->setCompiledPtr((void*)(intptr_t)nativeInitSoftReferenceQ,
+ "nativeInitSoftReferenceQ");
+
+ JavaMethod* initPhantomReference =
+ UPCALL_METHOD(loader, "java/lang/ref/PhantomReference", "<init>",
+ "(Ljava/lang/Object;Ljava/lang/ref/ReferenceQueue;)V",
+ ACC_VIRTUAL);
+ initPhantomReference->setCompiledPtr(
+ (void*)(intptr_t)nativeInitPhantomReferenceQ,
+ "nativeInitPhantomReferenceQ");
+
+
+}
+
+gc* Jnjvm::getReferent(gc* _obj) {
+ JavaObjectReference* obj = (JavaObjectReference*)_obj;
+ return obj->getReferent();
+ }
+
+void Jnjvm::clearReferent(gc* _obj) {
+ JavaObjectReference* obj = (JavaObjectReference*)_obj;
+ obj->setReferent(0);
}
Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaUpcalls.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JavaUpcalls.h?rev=72413&r1=72412&r2=72413&view=diff
==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JavaUpcalls.h (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JavaUpcalls.h Tue May 26 03:48:28 2009
@@ -252,6 +252,9 @@
ISOLATE_STATIC JavaField* fieldClass;
ISOLATE_STATIC JavaField* constructorClass;
+ ISOLATE_STATIC JavaMethod* EnqueueReference;
+ ISOLATE_STATIC Class* newReference;
+
private:
ISOLATE_STATIC void CreateJavaThread(Jnjvm* vm, JavaThread* myth,
const char* name, JavaObject* Group);
Modified: vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.cpp?rev=72413&r1=72412&r2=72413&view=diff
==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.cpp (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.cpp Tue May 26 03:48:28 2009
@@ -1205,6 +1205,9 @@
finalizerThread = new JavaThread(0, 0, this);
finalizerThread->start((void (*)(mvm::Thread*))finalizerStart);
+ enqueueThread = new JavaThread(0, 0, this);
+ enqueueThread->start((void (*)(mvm::Thread*))enqueueStart);
+
mainThread = new JavaThread(0, 0, this);
mainThread->start((void (*)(mvm::Thread*))mainJavaStart);
} else {
Modified: vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.h?rev=72413&r1=72412&r2=72413&view=diff
==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.h (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.h Tue May 26 03:48:28 2009
@@ -120,7 +120,11 @@
/// finalizerThread - The thread that finalizes Java objects.
///
JavaThread* finalizerThread;
-
+
+ /// enqueueThread - The thread that enqueue Java references.
+ ///
+ JavaThread* enqueueThread;
+
/// CreateError - Creates a Java object of the specified exception class
/// and calling its <init> function.
///
@@ -315,6 +319,14 @@
/// getFinalizerThread - Get the finalizer thread of this VM.
///
JavaThread* getFinalizerThread() const { return finalizerThread; }
+
+ /// setEnqueueThread - Set the enqueue thread of this VM.
+ ///
+ void setEnqueueThread(JavaThread* th) { enqueueThread = th; }
+
+ /// getEnqueueThread - Get the enqueue thread of this VM.
+ ///
+ JavaThread* getEnqueueThread() const { return enqueueThread; }
/// ~Jnjvm - Destroy the JVM.
///
@@ -367,6 +379,10 @@
hashStr.lock.unlock();
}
+ virtual void clearReferent(gc*);
+ virtual gc* getReferent(gc*);
+ virtual bool enqueueReference(gc*);
+
protected:
virtual void invokeFinalizer(gc*);
Modified: vmkit/trunk/lib/Mvm/GCMmap2/gccollector.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/Mvm/GCMmap2/gccollector.cpp?rev=72413&r1=72412&r2=72413&view=diff
==============================================================================
--- vmkit/trunk/lib/Mvm/GCMmap2/gccollector.cpp (original)
+++ vmkit/trunk/lib/Mvm/GCMmap2/gccollector.cpp Tue May 26 03:48:28 2009
@@ -58,22 +58,31 @@
mvm::Thread* tcur = th;
- // First, trace the VM.
+ // (1) Trace the VM.
th->MyVM->tracer();
- // Second, trace the threads.
+ // (2) Trace the threads.
do {
th->tracer();
tcur = (mvm::Thread*)tcur->next();
} while (tcur != th);
- // Third, trace stack objects.
+ // (3) Trace stack objects.
for(cur=used_nodes->next(); cur!=used_nodes; cur=cur->next())
trace(cur);
- // Fourth, trace the finalization queue.
+ // (4) Trace the weak reference queue.
+ th->MyVM->scanWeakReferencesQueue();
+
+ // (5) Trace the soft reference queue.
+ th->MyVM->scanSoftReferencesQueue();
+
+ // (6) Trace the finalization queue.
th->MyVM->scanFinalizationQueue();
+ // (7) Trace the phantom reference queue.
+ th->MyVM->scanPhantomReferencesQueue();
+
if(_marker)
_marker(0);
status = stat_finalize;
@@ -104,6 +113,7 @@
threads->collectionFinished();
#endif
th->MyVM->wakeUpFinalizers();
+ th->MyVM->wakeUpEnqueue();
}
void GCCollector::collect_unprotect() {
Modified: vmkit/trunk/lib/Mvm/Runtime/Object.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/Mvm/Runtime/Object.cpp?rev=72413&r1=72412&r2=72413&view=diff
==============================================================================
--- vmkit/trunk/lib/Mvm/Runtime/Object.cpp (original)
+++ vmkit/trunk/lib/Mvm/Runtime/Object.cpp Tue May 26 03:48:28 2009
@@ -145,6 +145,34 @@
}
}
+void VirtualMachine::enqueueStart(mvm::Thread* th) {
+ VirtualMachine* vm = th->MyVM;
+
+ while (true) {
+ vm->EnqueueLock.lock();
+ while (vm->ToEnqueueIndex == 0) {
+ vm->EnqueueCond.wait(&vm->EnqueueLock);
+ }
+ vm->EnqueueLock.unlock();
+
+ while (true) {
+ vm->ToEnqueueLock.acquire();
+ gc* res = 0;
+ if (vm->ToEnqueueIndex != 0) {
+ res = vm->ToEnqueue[--vm->ToEnqueueIndex];
+ }
+ vm->ToEnqueueLock.release();
+ if (!res) break;
+
+ try {
+ vm->enqueueReference(res);
+ } catch(...) {
+ }
+ th->clearException();
+ }
+ }
+}
+
void VirtualMachine::growFinalizationQueue() {
if (CurrentIndex >= QueueLength) {
uint32 newLength = QueueLength * GROW_FACTOR;
@@ -212,3 +240,44 @@
obj->markAndTrace();
}
}
+
+gc* ReferenceQueue::processReference(gc* reference, VirtualMachine* vm) {
+ if (!Collector::isLive(reference)) {
+ vm->clearReferent(reference);
+ return 0;
+ }
+
+ gc* referent = vm->getReferent(reference);
+
+ if (!referent) return 0;
+
+ if (semantics == SOFT) {
+ // TODO: are we are out of memory? Consider that we always are for now.
+ if (false) {
+ referent->markAndTrace();
+ }
+ } else if (semantics == PHANTOM) {
+ // Nothing to do.
+ }
+
+ if (Collector::isLive(referent)) {
+ return reference;
+ } else {
+ vm->clearReferent(reference);
+ vm->addToEnqueue(reference);
+ return 0;
+ }
+}
+
+
+void ReferenceQueue::scan(VirtualMachine* vm) {
+ uint32 NewIndex = 0;
+
+ for (uint32 i = 0; i < CurrentIndex; ++i) {
+ gc* obj = References[i];
+ gc* res = processReference(obj, vm);
+ if (res) References[NewIndex++] = res;
+ }
+
+ CurrentIndex = NewIndex;
+}
More information about the vmkit-commits
mailing list