[vmkit-commits] [vmkit] r121130 - in /vmkit/branches/multi-vm: include/mvm/SystemThreads.h include/mvm/VMKit.h include/mvm/VirtualMachine.h lib/J3/Classpath/JavaUpcalls.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/CommonThread/ctthread.cpp lib/Mvm/GCMmap2/gccollector.cpp lib/Mvm/Runtime/SystemThreads.cpp lib/Mvm/Runtime/VMKit.cpp mmtk/mmtk-j3/ReferenceProcessor.cpp
Gael Thomas
gael.thomas at lip6.fr
Tue Dec 7 03:08:03 PST 2010
Author: gthomas
Date: Tue Dec 7 05:08:02 2010
New Revision: 121130
URL: http://llvm.org/viewvc/llvm-project?rev=121130&view=rev
Log:
move the reference thread in vmkit
Modified:
vmkit/branches/multi-vm/include/mvm/SystemThreads.h
vmkit/branches/multi-vm/include/mvm/VMKit.h
vmkit/branches/multi-vm/include/mvm/VirtualMachine.h
vmkit/branches/multi-vm/lib/J3/Classpath/JavaUpcalls.cpp
vmkit/branches/multi-vm/lib/J3/VMCore/Jnjvm.cpp
vmkit/branches/multi-vm/lib/J3/VMCore/Jnjvm.h
vmkit/branches/multi-vm/lib/J3/VMCore/ReferenceQueue.cpp
vmkit/branches/multi-vm/lib/J3/VMCore/ReferenceQueue.h
vmkit/branches/multi-vm/lib/J3/VMCore/VirtualTables.cpp
vmkit/branches/multi-vm/lib/Mvm/CommonThread/ctthread.cpp
vmkit/branches/multi-vm/lib/Mvm/GCMmap2/gccollector.cpp
vmkit/branches/multi-vm/lib/Mvm/Runtime/SystemThreads.cpp
vmkit/branches/multi-vm/lib/Mvm/Runtime/VMKit.cpp
vmkit/branches/multi-vm/mmtk/mmtk-j3/ReferenceProcessor.cpp
Modified: vmkit/branches/multi-vm/include/mvm/SystemThreads.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/multi-vm/include/mvm/SystemThreads.h?rev=121130&r1=121129&r2=121130&view=diff
==============================================================================
--- vmkit/branches/multi-vm/include/mvm/SystemThreads.h (original)
+++ vmkit/branches/multi-vm/include/mvm/SystemThreads.h Tue Dec 7 05:08:02 2010
@@ -11,6 +11,126 @@
namespace mvm {
class VirtualMachine;
+class ReferenceThread;
+class Jnjvm;
+
+class ReferenceQueue {
+private:
+ mvm::gc** References;
+ uint32 QueueLength;
+ uint32 CurrentIndex;
+ mvm::SpinLock QueueLock;
+ uint8_t semantics;
+
+ mvm::gc* processReference(mvm::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 mvm::gc*[INITIAL_QUEUE_SIZE];
+ memset(References, 0, INITIAL_QUEUE_SIZE * sizeof(mvm::gc*));
+ QueueLength = INITIAL_QUEUE_SIZE;
+ CurrentIndex = 0;
+ semantics = s;
+ }
+
+ ~ReferenceQueue() {
+ delete[] References;
+ }
+
+ void addReference(mvm::gc* ref) {
+ llvm_gcroot(ref, 0);
+ QueueLock.acquire();
+ if (CurrentIndex >= QueueLength) {
+ uint32 newLength = QueueLength * GROW_FACTOR;
+ mvm::gc** newQueue = new mvm::gc*[newLength];
+ memset(newQueue, 0, newLength * sizeof(mvm::gc*));
+ 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 mvm::MutatorThread {
+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;
+
+ mvm::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(mvm::gc* obj);
+
+ static void enqueueStart(ReferenceThread*);
+
+ /// addWeakReference - Add a weak reference to the queue.
+ ///
+ void addWeakReference(mvm::gc* ref) {
+ llvm_gcroot(ref, 0);
+ WeakReferencesQueue.addReference(ref);
+ }
+
+ /// addSoftReference - Add a weak reference to the queue.
+ ///
+ void addSoftReference(mvm::gc* ref) {
+ llvm_gcroot(ref, 0);
+ SoftReferencesQueue.addReference(ref);
+ }
+
+ /// addPhantomReference - Add a weak reference to the queue.
+ ///
+ void addPhantomReference(mvm::gc* ref) {
+ llvm_gcroot(ref, 0);
+ PhantomReferencesQueue.addReference(ref);
+ }
+
+ ReferenceThread(mvm::VMKit* vmkit);
+
+ virtual ~ReferenceThread() {
+ delete[] ToEnqueue;
+ }
+
+ virtual void tracer(uintptr_t closure);
+};
+
class FinalizerThread : public mvm::MutatorThread {
public:
/// FinalizationQueueLock - A lock to protect access to the queue.
Modified: vmkit/branches/multi-vm/include/mvm/VMKit.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/multi-vm/include/mvm/VMKit.h?rev=121130&r1=121129&r2=121130&view=diff
==============================================================================
--- vmkit/branches/multi-vm/include/mvm/VMKit.h (original)
+++ vmkit/branches/multi-vm/include/mvm/VMKit.h Tue Dec 7 05:08:02 2010
@@ -10,6 +10,7 @@
class VMKit;
class gc;
class FinalizerThread;
+class ReferenceThread;
class FunctionMap {
public:
@@ -92,7 +93,13 @@
void registerRunningThread(mvm::Thread* th);
void unregisterRunningThread(mvm::Thread* th);
+ /// enqueueThread - The thread that finalizes references.
+ ///
FinalizerThread* finalizerThread;
+
+ /// enqueueThread - The thread that enqueues references.
+ ///
+ ReferenceThread* referenceThread;
/// scanFinalizationQueue - Scan objets with a finalized method and schedule
/// them for finalization if they are not live.
@@ -103,6 +110,21 @@
/// a finalization method.
///
void addFinalizationCandidate(gc* object);
+
+ /// scanWeakReferencesQueue - Scan all weak references. Called by the GC
+ /// before scanning the finalization queue.
+ ///
+ void scanWeakReferencesQueue(uintptr_t closure);
+
+ /// scanSoftReferencesQueue - Scan all soft references. Called by the GC
+ /// before scanning the finalization queue.
+ ///
+ void scanSoftReferencesQueue(uintptr_t closure);
+
+ /// scanPhantomReferencesQueue - Scan all phantom references. Called by the GC
+ /// after the finalization queue.
+ ///
+ void scanPhantomReferencesQueue(uintptr_t closure);
/// ------------------------------------------------- ///
/// --- collection managment --- ///
Modified: vmkit/branches/multi-vm/include/mvm/VirtualMachine.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/multi-vm/include/mvm/VirtualMachine.h?rev=121130&r1=121129&r2=121130&view=diff
==============================================================================
--- vmkit/branches/multi-vm/include/mvm/VirtualMachine.h (original)
+++ vmkit/branches/multi-vm/include/mvm/VirtualMachine.h Tue Dec 7 05:08:02 2010
@@ -79,23 +79,6 @@
///
virtual bool enqueueReference(mvm::gc* _obj) { abort(); }
-
-
- /// scanWeakReferencesQueue - Scan all weak references. Called by the GC
- /// before scanning the finalization queue.
- ///
- virtual void scanWeakReferencesQueue(uintptr_t closure) {}
-
- /// scanSoftReferencesQueue - Scan all soft references. Called by the GC
- /// before scanning the finalization queue.
- ///
- virtual void scanSoftReferencesQueue(uintptr_t closure) {}
-
- /// scanPhantomReferencesQueue - Scan all phantom references. Called by the GC
- /// after the finalization queue.
- ///
- virtual void scanPhantomReferencesQueue(uintptr_t closure) {}
-
/// tracer - Trace this virtual machine's GC-objects.
/// Called once by vm. If you have GC-objects in a thread specific data, redefine the tracer of your VMThreadData.
///
Modified: vmkit/branches/multi-vm/lib/J3/Classpath/JavaUpcalls.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/multi-vm/lib/J3/Classpath/JavaUpcalls.cpp?rev=121130&r1=121129&r2=121130&view=diff
==============================================================================
--- vmkit/branches/multi-vm/lib/J3/Classpath/JavaUpcalls.cpp (original)
+++ vmkit/branches/multi-vm/lib/J3/Classpath/JavaUpcalls.cpp Tue Dec 7 05:08:02 2010
@@ -15,7 +15,8 @@
#include "JavaThread.h"
#include "JavaUpcalls.h"
#include "Jnjvm.h"
-#include "ReferenceQueue.h"
+#include "mvm/SystemThreads.h"
+#include "mvm/VMKit.h"
#define COMPILE_METHODS(cl) \
for (CommonClass::method_iterator i = cl->virtualMethods.begin(), \
@@ -307,7 +308,7 @@
BEGIN_NATIVE_EXCEPTION(0)
JavaObjectReference::init(reference, referent, 0);
- JavaThread::get()->getJVM()->getReferenceThread()->addWeakReference(reference);
+ mvm::Thread::get()->vmkit->referenceThread->addWeakReference(reference);
END_NATIVE_EXCEPTION
@@ -324,7 +325,7 @@
BEGIN_NATIVE_EXCEPTION(0)
JavaObjectReference::init(reference, referent, queue);
- JavaThread::get()->getJVM()->getReferenceThread()->addWeakReference(reference);
+ mvm::Thread::get()->vmkit->referenceThread->addWeakReference(reference);
END_NATIVE_EXCEPTION
@@ -338,7 +339,7 @@
BEGIN_NATIVE_EXCEPTION(0)
JavaObjectReference::init(reference, referent, 0);
- JavaThread::get()->getJVM()->getReferenceThread()->addSoftReference(reference);
+ mvm::Thread::get()->vmkit->referenceThread->addSoftReference(reference);
END_NATIVE_EXCEPTION
@@ -355,7 +356,7 @@
BEGIN_NATIVE_EXCEPTION(0)
JavaObjectReference::init(reference, referent, queue);
- JavaThread::get()->getJVM()->getReferenceThread()->addSoftReference(reference);
+ mvm::Thread::get()->vmkit->referenceThread->addSoftReference(reference);
END_NATIVE_EXCEPTION
@@ -372,7 +373,7 @@
BEGIN_NATIVE_EXCEPTION(0)
JavaObjectReference::init(reference, referent, queue);
- JavaThread::get()->getJVM()->getReferenceThread()->addPhantomReference(reference);
+ mvm::Thread::get()->vmkit->referenceThread->addPhantomReference(reference);
END_NATIVE_EXCEPTION
}
Modified: vmkit/branches/multi-vm/lib/J3/VMCore/Jnjvm.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/multi-vm/lib/J3/VMCore/Jnjvm.cpp?rev=121130&r1=121129&r2=121130&view=diff
==============================================================================
--- vmkit/branches/multi-vm/lib/J3/VMCore/Jnjvm.cpp (original)
+++ vmkit/branches/multi-vm/lib/J3/VMCore/Jnjvm.cpp Tue Dec 7 05:08:02 2010
@@ -35,7 +35,6 @@
#include "LinkJavaRuntime.h"
#include "LockedMap.h"
#include "Reader.h"
-#include "ReferenceQueue.h"
#include "Zip.h"
using namespace j3;
@@ -1076,10 +1075,6 @@
llvm_gcroot(javaLoader, 0);
JnjvmClassLoader* loader = bootstrapLoader;
- referenceThread = new ReferenceThread(vmkit);
- referenceThread->start(
- (void (*)(mvm::Thread*))ReferenceThread::enqueueStart);
-
// Initialise the bootstrap class loader if it's not
// done already.
if (bootstrapLoader->upcalls->newString == NULL) {
@@ -1425,34 +1420,7 @@
UserClass* cl = JavaObject::getClass(obj)->asClass();
return (bool)meth->invokeIntSpecialBuf(this, cl, obj, 0);
}
-
-void Jnjvm::startCollection() {
- referenceThread->ToEnqueueLock.acquire();
- referenceThread->SoftReferencesQueue.acquire();
- referenceThread->WeakReferencesQueue.acquire();
- referenceThread->PhantomReferencesQueue.acquire();
-}
-void Jnjvm::endCollection() {
- referenceThread->ToEnqueueLock.release();
- referenceThread->SoftReferencesQueue.release();
- referenceThread->WeakReferencesQueue.release();
- referenceThread->PhantomReferencesQueue.release();
- 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);
-}
-
size_t Jnjvm::getObjectSize(mvm::gc* object) {
// TODO: because this is called during GC, there is no need to do
// llvm_gcroot. For clarity, it may be useful to have a special type
Modified: vmkit/branches/multi-vm/lib/J3/VMCore/Jnjvm.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/multi-vm/lib/J3/VMCore/Jnjvm.h?rev=121130&r1=121129&r2=121130&view=diff
==============================================================================
--- vmkit/branches/multi-vm/lib/J3/VMCore/Jnjvm.h (original)
+++ vmkit/branches/multi-vm/lib/J3/VMCore/Jnjvm.h Tue Dec 7 05:08:02 2010
@@ -121,16 +121,7 @@
UserClass* throwable;
private:
-
- /// enqueueThread - The thread that enqueue Java references.
- ///
- 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 size_t getObjectSize(mvm::gc* obj);
virtual const char* getObjectTypeName(mvm::gc* obj);
@@ -322,14 +313,6 @@
/// enqueueReference - enqueue the reference
///
virtual bool enqueueReference(mvm::gc* _obj);
-
- /// setReferenceThread - Set the enqueue thread of this VM.
- ///
- void setReferenceThread(ReferenceThread* th) { referenceThread = th; }
-
- /// getReferenceThread - Get the enqueue thread of this VM.
- ///
- ReferenceThread* getReferenceThread() const { return referenceThread; }
/// ~Jnjvm - Destroy the JVM.
///
Modified: vmkit/branches/multi-vm/lib/J3/VMCore/ReferenceQueue.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/multi-vm/lib/J3/VMCore/ReferenceQueue.cpp?rev=121130&r1=121129&r2=121130&view=diff
==============================================================================
--- vmkit/branches/multi-vm/lib/J3/VMCore/ReferenceQueue.cpp (original)
+++ vmkit/branches/multi-vm/lib/J3/VMCore/ReferenceQueue.cpp Tue Dec 7 05:08:02 2010
@@ -12,138 +12,3 @@
#include "JavaUpcalls.h"
#include "Jnjvm.h"
#include "ReferenceQueue.h"
-
-using namespace j3;
-
-ReferenceThread::ReferenceThread(mvm::VMKit* vmkit) :
- MutatorThread(vmkit),
- WeakReferencesQueue(ReferenceQueue::WEAK),
- SoftReferencesQueue(ReferenceQueue::SOFT),
- PhantomReferencesQueue(ReferenceQueue::PHANTOM) {
-
- ToEnqueue = new mvm::gc*[INITIAL_QUEUE_SIZE];
- ToEnqueueLength = INITIAL_QUEUE_SIZE;
- ToEnqueueIndex = 0;
-}
-
-mvm::gc** getReferent(mvm::gc* obj) {
- llvm_gcroot(obj, 0);
- mvm::VirtualMachine* vm = obj->getVirtualTable()->vm;
- mvm::Thread::get()->attach(vm);
- return vm->getReferent(obj);
-}
-
-void setReferent(mvm::gc* obj, mvm::gc* val) {
- printf("set referent: %p %p\n", obj, val);
- llvm_gcroot(obj, 0);
- llvm_gcroot(val, 0);
- mvm::VirtualMachine* vm = obj->getVirtualTable()->vm;
- mvm::Thread::get()->attach(vm);
- vm->setReferent(obj, val);
-}
-
-void invokeEnqueue(mvm::gc* obj) {
- llvm_gcroot(obj, 0);
- TRY {
- mvm::VirtualMachine* vm = obj->getVirtualTable()->vm;
- mvm::Thread::get()->attach(vm);
-
- printf("enqueue reference: %p\n", obj);
- vm->enqueueReference(obj);
- } IGNORE;
- mvm::Thread::get()->clearPendingException();
-}
-
-void ReferenceThread::enqueueStart(ReferenceThread* th) {
- mvm::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(mvm::gc* obj) {
- llvm_gcroot(obj, 0);
- if (ToEnqueueIndex >= ToEnqueueLength) {
- uint32 newLength = ToEnqueueLength * GROW_FACTOR;
- mvm::gc** newQueue = new mvm::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;
-}
-
-mvm::gc* ReferenceQueue::processReference(mvm::gc* reference, ReferenceThread* th, uintptr_t closure) {
- if (!mvm::Collector::isLive(reference, closure)) {
- setReferent(reference, 0);
- return NULL;
- }
-
- mvm::gc* referent = *(getReferent(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.
- }
-
- mvm::gc* newReference =
- mvm::Collector::getForwardedReference(reference, closure);
- if (mvm::Collector::isLive(referent, closure)) {
- mvm::gc* newReferent = mvm::Collector::getForwardedReferent(referent, closure);
- setReferent(newReference, newReferent);
- return newReference;
- } else {
- setReferent(newReference, 0);
- th->addToEnqueue(newReference);
- return NULL;
- }
-}
-
-
-void ReferenceQueue::scan(ReferenceThread* th, uintptr_t closure) {
- uint32 NewIndex = 0;
-
- for (uint32 i = 0; i < CurrentIndex; ++i) {
- mvm::gc* obj = References[i];
- mvm::gc* res = processReference(obj, th, closure);
- if (res) References[NewIndex++] = res;
- }
-
- CurrentIndex = NewIndex;
-}
-
Modified: vmkit/branches/multi-vm/lib/J3/VMCore/ReferenceQueue.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/multi-vm/lib/J3/VMCore/ReferenceQueue.h?rev=121130&r1=121129&r2=121130&view=diff
==============================================================================
--- vmkit/branches/multi-vm/lib/J3/VMCore/ReferenceQueue.h (original)
+++ vmkit/branches/multi-vm/lib/J3/VMCore/ReferenceQueue.h Tue Dec 7 05:08:02 2010
@@ -20,124 +20,6 @@
namespace j3 {
-class ReferenceThread;
-class Jnjvm;
-
-class ReferenceQueue {
-private:
- mvm::gc** References;
- uint32 QueueLength;
- uint32 CurrentIndex;
- mvm::SpinLock QueueLock;
- uint8_t semantics;
-
- mvm::gc* processReference(mvm::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 mvm::gc*[INITIAL_QUEUE_SIZE];
- memset(References, 0, INITIAL_QUEUE_SIZE * sizeof(mvm::gc*));
- QueueLength = INITIAL_QUEUE_SIZE;
- CurrentIndex = 0;
- semantics = s;
- }
-
- ~ReferenceQueue() {
- delete[] References;
- }
-
- void addReference(mvm::gc* ref) {
- llvm_gcroot(ref, 0);
- QueueLock.acquire();
- if (CurrentIndex >= QueueLength) {
- uint32 newLength = QueueLength * GROW_FACTOR;
- mvm::gc** newQueue = new mvm::gc*[newLength];
- memset(newQueue, 0, newLength * sizeof(mvm::gc*));
- 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 mvm::MutatorThread {
-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;
-
- mvm::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(mvm::gc* obj);
-
- static void enqueueStart(ReferenceThread*);
-
- /// addWeakReference - Add a weak reference to the queue.
- ///
- void addWeakReference(mvm::gc* ref) {
- llvm_gcroot(ref, 0);
- WeakReferencesQueue.addReference(ref);
- }
-
- /// addSoftReference - Add a weak reference to the queue.
- ///
- void addSoftReference(mvm::gc* ref) {
- llvm_gcroot(ref, 0);
- SoftReferencesQueue.addReference(ref);
- }
-
- /// addPhantomReference - Add a weak reference to the queue.
- ///
- void addPhantomReference(mvm::gc* ref) {
- llvm_gcroot(ref, 0);
- PhantomReferencesQueue.addReference(ref);
- }
-
- ReferenceThread(mvm::VMKit* vmkit);
-
- virtual ~ReferenceThread() {
- delete[] ToEnqueue;
- }
-};
-
} // namespace j3
#endif //J3_REFERENCE_QUEUE_H
Modified: vmkit/branches/multi-vm/lib/J3/VMCore/VirtualTables.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/multi-vm/lib/J3/VMCore/VirtualTables.cpp?rev=121130&r1=121129&r2=121130&view=diff
==============================================================================
--- vmkit/branches/multi-vm/lib/J3/VMCore/VirtualTables.cpp (original)
+++ vmkit/branches/multi-vm/lib/J3/VMCore/VirtualTables.cpp Tue Dec 7 05:08:02 2010
@@ -291,11 +291,6 @@
mvm::Collector::markAndTraceRoot(key, closure);
}
- // (6) Trace the reference queue
- for (uint32 i = 0; i < referenceThread->ToEnqueueIndex; ++i) {
- mvm::Collector::markAndTraceRoot(referenceThread->ToEnqueue + i, closure);
- }
-
// (7) Trace the locks and their associated object.
uint32 i = 0;
for (; i < mvm::LockSystem::GlobalSize; i++) {
Modified: vmkit/branches/multi-vm/lib/Mvm/CommonThread/ctthread.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/multi-vm/lib/Mvm/CommonThread/ctthread.cpp?rev=121130&r1=121129&r2=121130&view=diff
==============================================================================
--- vmkit/branches/multi-vm/lib/Mvm/CommonThread/ctthread.cpp (original)
+++ vmkit/branches/multi-vm/lib/Mvm/CommonThread/ctthread.cpp Tue Dec 7 05:08:02 2010
@@ -518,14 +518,12 @@
}
void Thread::operator delete(void* th) {
- printf("deleting %p\n", th);
uintptr_t index = ((uintptr_t)th & Thread::IDMask);
index = (index & ~TheStackManager.baseAddr) >> 20;
TheStackManager.used[index] = 0;
}
Thread::~Thread() {
- printf("destroying %p\n", this);
// It seems like the pthread implementation in Linux is clearing with NULL
// the stack of the thread. So we have to get the thread id before
// calling pthread_join.
Modified: vmkit/branches/multi-vm/lib/Mvm/GCMmap2/gccollector.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/multi-vm/lib/Mvm/GCMmap2/gccollector.cpp?rev=121130&r1=121129&r2=121130&view=diff
==============================================================================
--- vmkit/branches/multi-vm/lib/Mvm/GCMmap2/gccollector.cpp (original)
+++ vmkit/branches/multi-vm/lib/Mvm/GCMmap2/gccollector.cpp Tue Dec 7 05:08:02 2010
@@ -9,6 +9,7 @@
#include "mvm/GC.h"
#include "mvm/VMKit.h"
+#include "mvm/SystemThreads.h"
using namespace mvm;
@@ -63,16 +64,16 @@
cur = cur->prev();
// (4) Trace the weak reference queue.
- th->MyVM->scanWeakReferencesQueue(0);
+ th->vmkit->scanWeakReferencesQueue(0);
// (5) Trace the soft reference queue.
- th->MyVM->scanSoftReferencesQueue(0);
+ th->vmkit->scanSoftReferencesQueue(0);
// (6) Trace the finalization queue.
th->vmkit->scanFinalizationQueue(0);
// (7) Trace the phantom reference queue.
- th->MyVM->scanPhantomReferencesQueue(0);
+ th->vmkit->scanPhantomReferencesQueue(0);
// (8) Trace the new objects added by queues.
for(cur = cur->next(); cur != used_nodes; cur = cur->next())
Modified: vmkit/branches/multi-vm/lib/Mvm/Runtime/SystemThreads.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/multi-vm/lib/Mvm/Runtime/SystemThreads.cpp?rev=121130&r1=121129&r2=121130&view=diff
==============================================================================
--- vmkit/branches/multi-vm/lib/Mvm/Runtime/SystemThreads.cpp (original)
+++ vmkit/branches/multi-vm/lib/Mvm/Runtime/SystemThreads.cpp Tue Dec 7 05:08:02 2010
@@ -4,6 +4,144 @@
using namespace mvm;
+ReferenceThread::ReferenceThread(mvm::VMKit* vmkit) :
+ MutatorThread(vmkit),
+ WeakReferencesQueue(ReferenceQueue::WEAK),
+ SoftReferencesQueue(ReferenceQueue::SOFT),
+ PhantomReferencesQueue(ReferenceQueue::PHANTOM) {
+
+ ToEnqueue = new mvm::gc*[INITIAL_QUEUE_SIZE];
+ ToEnqueueLength = INITIAL_QUEUE_SIZE;
+ ToEnqueueIndex = 0;
+}
+
+mvm::gc** getReferent(mvm::gc* obj) {
+ llvm_gcroot(obj, 0);
+ mvm::VirtualMachine* vm = obj->getVirtualTable()->vm;
+ mvm::Thread::get()->attach(vm);
+ return vm->getReferent(obj);
+}
+
+void setReferent(mvm::gc* obj, mvm::gc* val) {
+ llvm_gcroot(obj, 0);
+ llvm_gcroot(val, 0);
+ mvm::VirtualMachine* vm = obj->getVirtualTable()->vm;
+ mvm::Thread::get()->attach(vm);
+ vm->setReferent(obj, val);
+}
+
+void invokeEnqueue(mvm::gc* obj) {
+ llvm_gcroot(obj, 0);
+ TRY {
+ mvm::VirtualMachine* vm = obj->getVirtualTable()->vm;
+ mvm::Thread::get()->attach(vm);
+
+ vm->enqueueReference(obj);
+ } IGNORE;
+ mvm::Thread::get()->clearPendingException();
+}
+
+void ReferenceThread::enqueueStart(ReferenceThread* th) {
+ mvm::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(mvm::gc* obj) {
+ llvm_gcroot(obj, 0);
+ if (ToEnqueueIndex >= ToEnqueueLength) {
+ uint32 newLength = ToEnqueueLength * GROW_FACTOR;
+ mvm::gc** newQueue = new mvm::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;
+}
+
+mvm::gc* ReferenceQueue::processReference(mvm::gc* reference, ReferenceThread* th, uintptr_t closure) {
+ if (!mvm::Collector::isLive(reference, closure)) {
+ setReferent(reference, 0);
+ return NULL;
+ }
+
+ mvm::gc* referent = *(getReferent(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.
+ }
+
+ mvm::gc* newReference =
+ mvm::Collector::getForwardedReference(reference, closure);
+ if (mvm::Collector::isLive(referent, closure)) {
+ mvm::gc* newReferent = mvm::Collector::getForwardedReferent(referent, closure);
+ setReferent(newReference, newReferent);
+ return newReference;
+ } else {
+ setReferent(newReference, 0);
+ th->addToEnqueue(newReference);
+ return NULL;
+ }
+}
+
+
+void ReferenceQueue::scan(ReferenceThread* th, uintptr_t closure) {
+ uint32 NewIndex = 0;
+
+ for (uint32 i = 0; i < CurrentIndex; ++i) {
+ mvm::gc* obj = References[i];
+ mvm::gc* res = processReference(obj, th, closure);
+ if (res) References[NewIndex++] = res;
+ }
+
+ CurrentIndex = NewIndex;
+}
+
+void ReferenceThread::tracer(uintptr_t closure) {
+ for (uint32 i = 0; i < ToEnqueueIndex; ++i) {
+ mvm::Collector::markAndTraceRoot(ToEnqueue + i, closure);
+ }
+ MutatorThread::tracer(closure);
+}
+
+
FinalizerThread::FinalizerThread(VMKit* vmkit) : MutatorThread(vmkit) {
FinalizationQueue = new mvm::gc*[INITIAL_QUEUE_SIZE];
QueueLength = INITIAL_QUEUE_SIZE;
@@ -125,7 +263,6 @@
}
void FinalizerThread::tracer(uintptr_t closure) {
- // (5) Trace the finalization queue.
for (uint32 i = 0; i < CurrentFinalizedIndex; ++i) {
mvm::Collector::markAndTraceRoot(ToBeFinalized + i, closure);
}
Modified: vmkit/branches/multi-vm/lib/Mvm/Runtime/VMKit.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/multi-vm/lib/Mvm/Runtime/VMKit.cpp?rev=121130&r1=121129&r2=121130&view=diff
==============================================================================
--- vmkit/branches/multi-vm/lib/Mvm/Runtime/VMKit.cpp (original)
+++ vmkit/branches/multi-vm/lib/Mvm/Runtime/VMKit.cpp Tue Dec 7 05:08:02 2010
@@ -17,6 +17,21 @@
// First create system threads.
finalizerThread = new FinalizerThread(this);
finalizerThread->start((void (*)(mvm::Thread*))FinalizerThread::finalizerStart);
+
+ referenceThread = new ReferenceThread(this);
+ referenceThread->start((void (*)(mvm::Thread*))ReferenceThread::enqueueStart);
+}
+
+void VMKit::scanWeakReferencesQueue(uintptr_t closure) {
+ referenceThread->WeakReferencesQueue.scan(referenceThread, closure);
+}
+
+void VMKit::scanSoftReferencesQueue(uintptr_t closure) {
+ referenceThread->SoftReferencesQueue.scan(referenceThread, closure);
+}
+
+void VMKit::scanPhantomReferencesQueue(uintptr_t closure) {
+ referenceThread->PhantomReferencesQueue.scan(referenceThread, closure);
}
void VMKit::scanFinalizationQueue(uintptr_t closure) {
@@ -51,6 +66,10 @@
vmkitLock();
finalizerThread->FinalizationQueueLock.acquire();
+ referenceThread->ToEnqueueLock.acquire();
+ referenceThread->SoftReferencesQueue.acquire();
+ referenceThread->WeakReferencesQueue.acquire();
+ referenceThread->PhantomReferencesQueue.acquire();
// call first startCollection on each vm to avoid deadlock.
// indeed, a vm could want to execute applicative code
@@ -74,6 +93,11 @@
vms[i]->endCollection();
finalizerThread->FinalizationQueueLock.release();
+ referenceThread->ToEnqueueLock.release();
+ referenceThread->SoftReferencesQueue.release();
+ referenceThread->WeakReferencesQueue.release();
+ referenceThread->PhantomReferencesQueue.release();
+ referenceThread->EnqueueCond.broadcast();
finalizerThread->FinalizationCond.broadcast();
vmkitUnlock();
Modified: vmkit/branches/multi-vm/mmtk/mmtk-j3/ReferenceProcessor.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/multi-vm/mmtk/mmtk-j3/ReferenceProcessor.cpp?rev=121130&r1=121129&r2=121130&view=diff
==============================================================================
--- vmkit/branches/multi-vm/mmtk/mmtk-j3/ReferenceProcessor.cpp (original)
+++ vmkit/branches/multi-vm/mmtk/mmtk-j3/ReferenceProcessor.cpp Tue Dec 7 05:08:02 2010
@@ -10,6 +10,8 @@
#include "debug.h"
#include "mvm/VirtualMachine.h"
+#include "mvm/VMKit.h"
+#include "mvm/SystemThreads.h"
#include "MMTkObject.h"
namespace mmtk {
@@ -19,12 +21,12 @@
uint32_t val = RP->ordinal;
if (val == 0) {
- th->MyVM->scanSoftReferencesQueue(TL);
+ th->vmkit->scanSoftReferencesQueue(TL);
} else if (val == 1) {
- th->MyVM->scanWeakReferencesQueue(TL);
+ th->vmkit->scanWeakReferencesQueue(TL);
} else {
assert(val == 2);
- th->MyVM->scanPhantomReferencesQueue(TL);
+ th->vmkit->scanPhantomReferencesQueue(TL);
}
}
More information about the vmkit-commits
mailing list