[vmkit-commits] [vmkit] r121005 - in /vmkit/branches/multi-vm: include/mvm/Threads/Thread.h include/mvm/VMKit.h include/mvm/VirtualMachine.h lib/J3/VMCore/Jnjvm.cpp lib/J3/VMCore/Jnjvm.h lib/Mvm/CommonThread/CollectionRV.cpp lib/Mvm/CommonThread/ctthread.cpp lib/Mvm/GCMmap2/gccollector.cpp lib/Mvm/Runtime/VMKit.cpp mmtk/mmtk-j3/Collection.cpp mmtk/mmtk-j3/Scanning.cpp
Gael Thomas
gael.thomas at lip6.fr
Mon Dec 6 09:19:12 PST 2010
Author: gthomas
Date: Mon Dec 6 11:19:12 2010
New Revision: 121005
URL: http://llvm.org/viewvc/llvm-project?rev=121005&view=rev
Log:
Use a normal lock to lock vmkit when a thread is added, a vm is added or during a collection.
Define a tracer in vmkit. It calls the tracers of the different vms.
Delete the data of the thread with the new function localDestroy called by releaseThread (notice: a thread is never destroyed!)
Define a generic finalizeObject in VirtualMachine.
Do not lock vmkit inside the collection rv but in the new functions startCollection and stopCollection of vmkit. Notice that the first one returns 1 if another collection is not happening and call directly startRV and synchronize. Fix therefore Collection.cpp/gccollector.cpp.
Modified:
vmkit/branches/multi-vm/include/mvm/Threads/Thread.h
vmkit/branches/multi-vm/include/mvm/VMKit.h
vmkit/branches/multi-vm/include/mvm/VirtualMachine.h
vmkit/branches/multi-vm/lib/J3/VMCore/Jnjvm.cpp
vmkit/branches/multi-vm/lib/J3/VMCore/Jnjvm.h
vmkit/branches/multi-vm/lib/Mvm/CommonThread/CollectionRV.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/VMKit.cpp
vmkit/branches/multi-vm/mmtk/mmtk-j3/Collection.cpp
vmkit/branches/multi-vm/mmtk/mmtk-j3/Scanning.cpp
Modified: vmkit/branches/multi-vm/include/mvm/Threads/Thread.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/multi-vm/include/mvm/Threads/Thread.h?rev=121005&r1=121004&r2=121005&view=diff
==============================================================================
--- vmkit/branches/multi-vm/include/mvm/Threads/Thread.h (original)
+++ vmkit/branches/multi-vm/include/mvm/Threads/Thread.h Mon Dec 6 11:19:12 2010
@@ -312,6 +312,10 @@
///
void* operator new(size_t sz);
void operator delete(void* th) { UNREACHABLE(); }
+
+ /// localDestroy - call by releaseThread. Used for sub classes.
+ ///
+ virtual void localDestroy() {}
/// releaseThread - Free the stack so that another thread can use it.
///
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=121005&r1=121004&r2=121005&view=diff
==============================================================================
--- vmkit/branches/multi-vm/include/mvm/VMKit.h (original)
+++ vmkit/branches/multi-vm/include/mvm/VMKit.h Mon Dec 6 11:19:12 2010
@@ -44,7 +44,7 @@
VMKit(mvm::BumpPtrAllocator &Alloc);
- SpinLock _vmkitLock;
+ LockNormal _vmkitLock;
void vmkitLock() { _vmkitLock.lock(); }
void vmkitUnlock() { _vmkitLock.unlock(); }
@@ -52,8 +52,8 @@
/// ------------------------------------------------- ///
/// --- vm managment --- ///
/// ------------------------------------------------- ///
- // vms - the list of vms. Could be directly an array and we could also directly use the vmID as index in this array.
- // synchronize with vmkitLock
+ // vms - the list of vms.
+ // synchronized with vmkitLock
VirtualMachine** vms;
size_t vmsArraySize;
@@ -64,22 +64,26 @@
/// --- thread managment --- ///
/// ------------------------------------------------- ///
/// preparedThreads - the list of prepared threads, they are not yet running.
+ /// synchronized with vmkitLock
///
CircularBase<Thread> preparedThreads;
/// runningThreads - the list of running threads
+ /// synchronize with vmkitLock
///
CircularBase<Thread> runningThreads;
/// numberOfRunningThreads - The number of threads that currently run under this VM.
+ /// synchronized with vmkitLock
+ ///
size_t numberOfRunningThreads;
/// rendezvous - The rendezvous implementation for garbage collection.
///
#ifdef WITH_LLVM_GCC
- CooperativeCollectionRV rendezvous;
+ CooperativeCollectionRV rendezvous;
#else
- UncooperativeCollectionRV rendezvous;
+ UncooperativeCollectionRV rendezvous;
#endif
void registerPreparedThread(mvm::Thread* th);
@@ -92,9 +96,11 @@
/// --- collection managment --- ///
/// ------------------------------------------------- ///
- void startCollection();
+ bool startCollection(); // 1 ok, begin collection, 0 do not start collection
void endCollection();
+ void tracer(uintptr_t closure);
+
/// ------------------------------------------------- ///
/// --- backtrace related methods --- ///
/// ------------------------------------------------- ///
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=121005&r1=121004&r2=121005&view=diff
==============================================================================
--- vmkit/branches/multi-vm/include/mvm/VirtualMachine.h (original)
+++ vmkit/branches/multi-vm/include/mvm/VirtualMachine.h Mon Dec 6 11:19:12 2010
@@ -55,6 +55,9 @@
//===----------------------------------------------------------------------===//
// (2) GC-related methods.
//===----------------------------------------------------------------------===//
+ /// finalizeObject - invoke the finalizer of a java object
+ ///
+ virtual void finalizeObject(mvm::gc* obj) {}
/// startCollection - Preliminary code before starting a GC.
///
@@ -89,7 +92,8 @@
///
virtual void addFinalizationCandidate(gc* object) {}
- /// tracer - Trace this virtual machine's GC-objects.
+ /// 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.
///
virtual void tracer(uintptr_t closure) {}
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=121005&r1=121004&r2=121005&view=diff
==============================================================================
--- vmkit/branches/multi-vm/lib/J3/VMCore/Jnjvm.cpp (original)
+++ vmkit/branches/multi-vm/lib/J3/VMCore/Jnjvm.cpp Mon Dec 6 11:19:12 2010
@@ -1411,14 +1411,11 @@
}
void Jnjvm::startCollection() {
- printf("start collection of %p\n", this);
- printf("%p - %p\n", finalizerThread, referenceThread);
finalizerThread->FinalizationQueueLock.acquire();
referenceThread->ToEnqueueLock.acquire();
referenceThread->SoftReferencesQueue.acquire();
referenceThread->WeakReferencesQueue.acquire();
referenceThread->PhantomReferencesQueue.acquire();
- printf("yop\n");
}
void Jnjvm::endCollection() {
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=121005&r1=121004&r2=121005&view=diff
==============================================================================
--- vmkit/branches/multi-vm/lib/J3/VMCore/Jnjvm.h (original)
+++ vmkit/branches/multi-vm/lib/J3/VMCore/Jnjvm.h Mon Dec 6 11:19:12 2010
@@ -320,7 +320,7 @@
/// finalizeObject - invoke the finalizer of a java object
///
- void finalizeObject(mvm::gc* obj);
+ virtual void finalizeObject(mvm::gc* obj);
/// setFinalizerThread - Set the finalizer thread of this VM.
///
Modified: vmkit/branches/multi-vm/lib/Mvm/CommonThread/CollectionRV.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/multi-vm/lib/Mvm/CommonThread/CollectionRV.cpp?rev=121005&r1=121004&r2=121005&view=diff
==============================================================================
--- vmkit/branches/multi-vm/lib/Mvm/CommonThread/CollectionRV.cpp (original)
+++ vmkit/branches/multi-vm/lib/Mvm/CommonThread/CollectionRV.cpp Mon Dec 6 11:19:12 2010
@@ -51,10 +51,6 @@
mvm::Thread* self = mvm::Thread::get();
mvm::VMKit* vmkit = self->vmkit;
- // Lock thread lock, so that we can traverse the thread list safely. This will
- // be released on finishRV.
- vmkit->vmkitLock();
-
for(Thread* cur=vmkit->runningThreads.next(); cur!=&vmkit->runningThreads; cur=cur->next()) {
assert(!cur->doYield);
cur->doYield = true;
@@ -94,8 +90,6 @@
// Lock thread lock, so that we can traverse the thread list safely. This will
// be released on finishRV.
- self->vmkit->vmkitLock();
-
for(Thread* cur=vmkit->runningThreads.next(); cur!=&vmkit->runningThreads; cur=cur->next()) {
if(cur!=self) {
int res = cur->kill(SIGGC);
@@ -207,7 +201,6 @@
assert(nbJoined == initiator->MyVM->NumberOfThreads && "Inconsistent state");
nbJoined = 0;
- initiator->vmkit->vmkitUnlock();
condEndRV.broadcast();
unlockRV();
initiator->inRV = false;
@@ -222,7 +215,6 @@
mvm::Thread* initiator = mvm::Thread::get();
assert(nbJoined == initiator->vmkit->NumberOfThreads && "Inconsistent state");
nbJoined = 0;
- initiator->vmkit->vmkitUnlock();
condEndRV.broadcast();
unlockRV();
initiator->inRV = false;
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=121005&r1=121004&r2=121005&view=diff
==============================================================================
--- vmkit/branches/multi-vm/lib/Mvm/CommonThread/ctthread.cpp (original)
+++ vmkit/branches/multi-vm/lib/Mvm/CommonThread/ctthread.cpp Mon Dec 6 11:19:12 2010
@@ -528,6 +528,7 @@
// Wait for the thread to die.
pthread_join((pthread_t)thread_id, NULL);
}
+ th->localDestroy();
th->vmkit->unregisterPreparedThread(th);
uintptr_t index = ((uintptr_t)th & Thread::IDMask);
index = (index & ~TheStackManager.baseAddr) >> 20;
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=121005&r1=121004&r2=121005&view=diff
==============================================================================
--- vmkit/branches/multi-vm/lib/Mvm/GCMmap2/gccollector.cpp (original)
+++ vmkit/branches/multi-vm/lib/Mvm/GCMmap2/gccollector.cpp Mon Dec 6 11:19:12 2010
@@ -41,64 +41,62 @@
unused_nodes->attrape(used_nodes);
mvm::Thread* th = mvm::Thread::get();
- th->vmkit->rendezvous.startRV();
- th->vmkit->startCollection();
+ if(th->startCollection()) {
- th->vmkit->rendezvous.synchronize();
+ mvm::Thread* tcur = th;
- mvm::Thread* tcur = th;
+ // (1) Trace VMKit.
+ th->vmkit->tracer(0);
- // (1) Trace the VM.
- th->MyVM->tracer(0);
+ // (2) Trace the threads.
+ do {
+ tcur->scanStack(0);
+ tcur->tracer(0);
+ tcur = (mvm::Thread*)tcur->next();
+ } while (tcur != th);
- // (2) Trace the threads.
- do {
- tcur->scanStack(0);
- tcur->tracer(0);
- tcur = (mvm::Thread*)tcur->next();
- } while (tcur != th);
+ // (3) Trace stack objects.
+ for(cur = used_nodes->next(); cur != used_nodes; cur = cur->next())
+ trace(cur);
- // (3) Trace stack objects.
- for(cur = used_nodes->next(); cur != used_nodes; cur = cur->next())
- trace(cur);
+ // Go back to the previous node.
+ cur = cur->prev();
- // Go back to the previous node.
- cur = cur->prev();
+ // (4) Trace the weak reference queue.
+ th->MyVM->scanWeakReferencesQueue(0);
- // (4) Trace the weak reference queue.
- th->MyVM->scanWeakReferencesQueue(0);
-
- // (5) Trace the soft reference queue.
- th->MyVM->scanSoftReferencesQueue(0);
+ // (5) Trace the soft reference queue.
+ th->MyVM->scanSoftReferencesQueue(0);
- // (6) Trace the finalization queue.
- th->MyVM->scanFinalizationQueue(0);
+ // (6) Trace the finalization queue.
+ th->MyVM->scanFinalizationQueue(0);
- // (7) Trace the phantom reference queue.
- th->MyVM->scanPhantomReferencesQueue(0);
+ // (7) Trace the phantom reference queue.
+ th->MyVM->scanPhantomReferencesQueue(0);
- // (8) Trace the new objects added by queues.
- for(cur = cur->next(); cur != used_nodes; cur = cur->next())
- trace(cur);
+ // (8) Trace the new objects added by queues.
+ for(cur = cur->next(); cur != used_nodes; cur = cur->next())
+ trace(cur);
- // Finalize.
- GCChunkNode finalizable;
- finalizable.attrape(unused_nodes);
+ // Finalize.
+ GCChunkNode finalizable;
+ finalizable.attrape(unused_nodes);
- // We have stopped collecting, go back to alloc state.
- status = stat_alloc;
+ // We have stopped collecting, go back to alloc state.
+ status = stat_alloc;
- // Wake up all threads.
- th->vmkit->rendezvous.finishRV();
- th->vmkit->endCollection();
+ // Wake up all threads.
+ th->vmkit->rendezvous.finishRV();
+ th->vmkit->endCollection();
- // Kill unreachable objects.
- GCChunkNode *next = 0;
- for(cur=finalizable.next(); cur!=&finalizable; cur=next) {
- next = cur->next();
- allocator->reject_chunk(cur);
- }
+ // Kill unreachable objects.
+ GCChunkNode *next = 0;
+ for(cur=finalizable.next(); cur!=&finalizable; cur=next) {
+ next = cur->next();
+ allocator->reject_chunk(cur);
+ }
+ }
}
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=121005&r1=121004&r2=121005&view=diff
==============================================================================
--- vmkit/branches/multi-vm/lib/Mvm/Runtime/VMKit.cpp (original)
+++ vmkit/branches/multi-vm/lib/Mvm/Runtime/VMKit.cpp Mon Dec 6 11:19:12 2010
@@ -3,28 +3,65 @@
using namespace mvm;
+#if 0
+#define dprintf(...) do { printf("[%p] ", (void*)mvm::Thread::get()); printf(__VA_ARGS__); } while(0)
+#else
+#define dprintf(...)
+#endif
+
VMKit::VMKit(mvm::BumpPtrAllocator &Alloc) : allocator(Alloc) {
vms = 0;
vmsArraySize = 0;
}
-void VMKit::startCollection() {
- vmkitLock();
+void VMKit::tracer(uintptr_t closure) {
+ // don't have to take the vmkitLock, already taken by the rendezvous.
for(size_t i=0; i<vmsArraySize; i++)
if(vms[i])
- vms[i]->startCollection();
- vmkitUnlock();
+ vms[i]->tracer(closure);
+}
+
+bool VMKit::startCollection() {
+ // do not take the lock here because if a gc is currently running, it could call enterUncooperativeCode
+ // which will execute the gc and we will therefore recall the gc just behind. Stupid because the previous one
+ // should have freed some memory
+ rendezvous.startRV();
+
+ if (mvm::Thread::get()->doYield) {
+ rendezvous.cancelRV();
+ rendezvous.join();
+ return 0;
+ } else {
+ dprintf("Start collection\n");
+ // Lock thread lock, so that we can traverse the vm and thread lists safely. This will be released on finishRV.
+ vmkitLock();
+
+ // call first startCollection on each vm to avoid deadlock.
+ // indeed, a vm could want to execute applicative code
+ for(size_t i=0; i<vmsArraySize; i++)
+ if(vms[i])
+ vms[i]->startCollection();
+
+ rendezvous.synchronize();
+
+ return 1;
+ }
}
void VMKit::endCollection() {
- vmkitLock();
+ dprintf("End collection\n");
+
+ rendezvous.finishRV();
+
for(size_t i=0; i<vmsArraySize; i++)
if(vms[i])
vms[i]->endCollection();
+
vmkitUnlock();
}
size_t VMKit::addVM(VirtualMachine* vm) {
+ dprintf("add vm: %p\n", vm);
vmkitLock();
for(size_t i=0; i<vmsArraySize; i++)
@@ -35,7 +72,7 @@
}
int res = vmsArraySize;
- vmsArraySize = vmsArraySize ? (vmsArraySize<<1) : 1;
+ vmsArraySize = vmsArraySize ? (vmsArraySize<<1) : 4;
// reallocate the vms
VirtualMachine **newVms = new VirtualMachine*[vmsArraySize];
@@ -62,11 +99,13 @@
}
void VMKit::removeVM(size_t id) {
- // what can I do with the VMThreadData?
+ dprintf("remove vm: %p\n", vm);
+ // I think that we only should call this function when all the thread data are released
vms[id] = 0;
}
void VMKit::registerPreparedThread(mvm::Thread* th) {
+ dprintf("Create thread: %p\n", th);
vmkitLock();
th->appendTo(&preparedThreads);
th->reallocAllVmsData(0, vmsArraySize);
@@ -74,6 +113,7 @@
}
void VMKit::unregisterPreparedThread(mvm::Thread* th) {
+ dprintf("Delete thread: %p\n", th);
vmkitLock();
th->remove();
for(size_t i=0; i<vmsArraySize; i++)
@@ -84,6 +124,7 @@
}
void VMKit::registerRunningThread(mvm::Thread* th) {
+ dprintf("Register thread: %p\n", th);
vmkitLock();
numberOfRunningThreads++;
th->remove();
@@ -92,6 +133,7 @@
}
void VMKit::unregisterRunningThread(mvm::Thread* th) {
+ dprintf("Unregister thread: %p\n", th);
vmkitLock();
numberOfRunningThreads--;
th->remove();
Modified: vmkit/branches/multi-vm/mmtk/mmtk-j3/Collection.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/multi-vm/mmtk/mmtk-j3/Collection.cpp?rev=121005&r1=121004&r2=121005&view=diff
==============================================================================
--- vmkit/branches/multi-vm/mmtk/mmtk-j3/Collection.cpp (original)
+++ vmkit/branches/multi-vm/mmtk/mmtk-j3/Collection.cpp Mon Dec 6 11:19:12 2010
@@ -35,16 +35,8 @@
extern "C" void Java_org_j3_mmtk_Collection_triggerCollection__I (MMTkObject* C, int why) {
mvm::Thread* th = mvm::Thread::get();
- // Verify that another collection is not happening.
- th->vmkit->rendezvous.startRV();
- if (th->doYield) {
- th->vmkit->rendezvous.cancelRV();
- th->vmkit->rendezvous.join();
- return;
- } else {
- th->vmkit->startCollection();
- th->vmkit->rendezvous.synchronize();
-
+ if (th->vmkit->startCollection()) {
+
JnJVM_org_mmtk_plan_Plan_setCollectionTriggered__();
// Record the starting time
@@ -73,7 +65,6 @@
elapsedTime / 1000000);
}
- th->vmkit->rendezvous.finishRV();
th->vmkit->endCollection();
}
Modified: vmkit/branches/multi-vm/mmtk/mmtk-j3/Scanning.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/multi-vm/mmtk/mmtk-j3/Scanning.cpp?rev=121005&r1=121004&r2=121005&view=diff
==============================================================================
--- vmkit/branches/multi-vm/mmtk/mmtk-j3/Scanning.cpp (original)
+++ vmkit/branches/multi-vm/mmtk/mmtk-j3/Scanning.cpp Mon Dec 6 11:19:12 2010
@@ -27,7 +27,7 @@
}
extern "C" void Java_org_j3_mmtk_Scanning_computeGlobalRoots__Lorg_mmtk_plan_TraceLocal_2 (MMTkObject* Scanning, MMTkObject* TL) {
- mvm::Thread::get()->MyVM->tracer(reinterpret_cast<uintptr_t>(TL));
+ mvm::Thread::get()->vmkit->tracer(reinterpret_cast<uintptr_t>(TL));
mvm::VMKit* vmkit = mvm::Thread::get()->vmkit;
mvm::Thread* tcur;
More information about the vmkit-commits
mailing list