[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