[vmkit-commits] [vmkit] r180358 - Moved generic ReferenceThread and FinalizerThread in vmkit.

Peter Senna Tschudin peter.senna at gmail.com
Thu Apr 25 10:09:51 PDT 2013


Author: peter.senna
Date: Thu Apr 25 12:01:08 2013
New Revision: 180358

URL: http://llvm.org/viewvc/llvm-project?rev=180358&view=rev
Log:
Moved generic ReferenceThread and FinalizerThread in vmkit.
(cherry picked from commit 8bd3f05b35c4cc907a9d28b95daa8e45079871e5)

Added:
    vmkit/trunk/include/vmkit/FinalizerThread.h
    vmkit/trunk/include/vmkit/ReferenceThread.h
Removed:
    vmkit/trunk/lib/j3/VMCore/ReferenceQueue.cpp
    vmkit/trunk/lib/j3/VMCore/ReferenceQueue.h
Modified:
    vmkit/trunk/lib/j3/ClassLib/GNUClasspath/JavaUpcalls.cpp
    vmkit/trunk/lib/j3/VMCore/Jnjvm.cpp
    vmkit/trunk/lib/j3/VMCore/VirtualTables.cpp

Added: vmkit/trunk/include/vmkit/FinalizerThread.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/include/vmkit/FinalizerThread.h?rev=180358&view=auto
==============================================================================
--- vmkit/trunk/include/vmkit/FinalizerThread.h (added)
+++ vmkit/trunk/include/vmkit/FinalizerThread.h Thu Apr 25 12:01:08 2013
@@ -0,0 +1,177 @@
+//===--- FinalizerThread.h - Implementation of finalizable references--===//
+//
+//                            The VMKit project
+//
+// This file is distributed under the University of Pierre et Marie Curie
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef VMKIT_FINALIZERTHREAD_H_
+#define VMKIT_FINALIZERTHREAD_H_
+
+namespace vmkit {
+
+	template <class T_THREAD> class FinalizerThread : public T_THREAD {
+		public:
+		/// FinalizationQueueLock - A lock to protect access to the queue.
+		///
+		vmkit::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;
+
+		/// growFinalizationQueue - Grow the queue of finalizable objects.
+		///
+		void growFinalizationQueue() {
+			if (CurrentIndex >= QueueLength) {
+				uint32 newLength = QueueLength * GROW_FACTOR;
+				gc** newQueue = new gc*[newLength];
+				if (!newQueue) {
+					fprintf(stderr, "I don't know how to handle finalizer overflows yet!\n");
+					abort();
+				}
+				for (uint32 i = 0; i < QueueLength; ++i) newQueue[i] = FinalizationQueue[i];
+				delete[] FinalizationQueue;
+				FinalizationQueue = newQueue;
+				QueueLength = newLength;
+			}
+		}
+
+
+		/// 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;
+
+		/// growToBeFinalizedQueue - Grow the queue of the to-be finalized objects.
+		///
+		void growToBeFinalizedQueue() {
+			if (CurrentFinalizedIndex >= ToBeFinalizedLength) {
+				uint32 newLength = ToBeFinalizedLength * GROW_FACTOR;
+				gc** newQueue = new gc*[newLength];
+				if (!newQueue) {
+					fprintf(stderr, "I don't know how to handle finalizer overflows yet!\n");
+					abort();
+				}
+				for (uint32 i = 0; i < ToBeFinalizedLength; ++i) newQueue[i] = ToBeFinalized[i];
+				delete[] ToBeFinalized;
+				ToBeFinalized = newQueue;
+				ToBeFinalizedLength = newLength;
+			}
+		}
+
+
+		/// finalizationCond - Condition variable to wake up finalization threads.
+		///
+		vmkit::Cond FinalizationCond;
+
+		/// finalizationLock - Lock for the condition variable.
+		///
+		vmkit::LockNormal FinalizationLock;
+
+		static void finalizerStart(FinalizerThread* th) {
+			gc* res = NULL;
+			llvm_gcroot(res, 0);
+
+			while (true) {
+				th->FinalizationLock.lock();
+				while (th->CurrentFinalizedIndex == 0) {
+					th->FinalizationCond.wait(&th->FinalizationLock);
+				}
+				th->FinalizationLock.unlock();
+
+				while (true) {
+					th->FinalizationQueueLock.acquire();
+					if (th->CurrentFinalizedIndex != 0) {
+						res = th->ToBeFinalized[th->CurrentFinalizedIndex - 1];
+						--th->CurrentFinalizedIndex;
+					}
+					th->FinalizationQueueLock.release();
+					if (!res) break;
+
+					th->MyVM->finalizeObject(res);
+
+					res = NULL;
+				}
+			}
+		}
+
+		/// addFinalizationCandidate - Add an object to the queue of objects with
+		/// a finalization method.
+		///
+		void addFinalizationCandidate(gc* obj) {
+			llvm_gcroot(obj, 0);
+			FinalizationQueueLock.acquire();
+
+			if (CurrentIndex >= QueueLength) {
+				growFinalizationQueue();
+			}
+
+			FinalizationQueue[CurrentIndex++] = obj;
+			FinalizationQueueLock.release();
+		}
+
+
+		/// scanFinalizationQueue - Scan objets with a finalized method and schedule
+		/// them for finalization if they are not live.
+		///
+		void scanFinalizationQueue(word_t closure) {
+			uint32 NewIndex = 0;
+			for (uint32 i = 0; i < CurrentIndex; ++i) {
+				gc* obj = FinalizationQueue[i];
+
+				if (!vmkit::Collector::isLive(obj, closure)) {
+					obj = vmkit::Collector::retainForFinalize(FinalizationQueue[i], closure);
+
+					if (CurrentFinalizedIndex >= ToBeFinalizedLength)
+						growToBeFinalizedQueue();
+
+					/* Add to object table */
+					ToBeFinalized[CurrentFinalizedIndex++] = obj;
+				} else {
+					FinalizationQueue[NewIndex++] =
+							vmkit::Collector::getForwardedFinalizable(obj, closure);
+				}
+			}
+			CurrentIndex = NewIndex;
+		}
+
+
+		FinalizerThread(vmkit::VirtualMachine* vm) : T_THREAD(vm) {
+			FinalizationQueue = new gc*[INITIAL_QUEUE_SIZE];
+			QueueLength = INITIAL_QUEUE_SIZE;
+			CurrentIndex = 0;
+
+			ToBeFinalized = new gc*[INITIAL_QUEUE_SIZE];
+			ToBeFinalizedLength = INITIAL_QUEUE_SIZE;
+			CurrentFinalizedIndex = 0;
+		}
+
+		~FinalizerThread() {
+			delete[] FinalizationQueue;
+			delete[] ToBeFinalized;
+		}
+	};
+}
+
+#endif /* VMKIT_FINALIZERTHREAD_H_ */

Added: vmkit/trunk/include/vmkit/ReferenceThread.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/include/vmkit/ReferenceThread.h?rev=180358&view=auto
==============================================================================
--- vmkit/trunk/include/vmkit/ReferenceThread.h (added)
+++ vmkit/trunk/include/vmkit/ReferenceThread.h Thu Apr 25 12:01:08 2013
@@ -0,0 +1,234 @@
+//===--- ReferenceThread.h - Implementation of soft/weak/phantom references--===//
+//
+//                            The VMKit project
+//
+// This file is distributed under the University of Pierre et Marie Curie
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef VMKIT_REFERENCE_THREAD_H
+#define VMKIT_REFERENCE_THREAD_H
+
+#include "vmkit/Locks.h"
+
+// Same values than JikesRVM
+#define INITIAL_QUEUE_SIZE 256
+#define GROW_FACTOR 2
+
+namespace vmkit {
+
+	template <class T> class ReferenceThread;
+
+	class ReferenceQueue {
+	private:
+	  gc** References;
+	  uint32 QueueLength;
+	  uint32 CurrentIndex;
+	  vmkit::SpinLock QueueLock;
+	  uint8_t semantics;
+
+	  template <class T>
+	  gc* processReference(gc* reference, ReferenceThread<T>* th, word_t closure) {
+	    if (!vmkit::Collector::isLive(reference, closure)) {
+	      vmkit::Thread::get()->MyVM->clearObjectReferent(reference);
+	      return NULL;
+	    }
+
+	    gc* referent = *(vmkit::Thread::get()->MyVM->getObjectReferentPtr(reference));
+
+	    if (!referent) {
+	      return NULL;
+	    }
+
+	    if (semantics == SOFT) {
+	      // TODO: are we are out of memory? Consider that we always are for now.
+	      if (false) {
+	        vmkit::Collector::retainReferent(referent, closure);
+	      }
+	    } else if (semantics == PHANTOM) {
+	      // Nothing to do.
+	    }
+
+	    gc* newReference =
+	        vmkit::Collector::getForwardedReference(reference, closure);
+	    if (vmkit::Collector::isLive(referent, closure)) {
+	      gc* newReferent = vmkit::Collector::getForwardedReferent(referent, closure);
+	      vmkit::Thread::get()->MyVM->setObjectReferent(newReference, newReferent);
+	      return newReference;
+	    } else {
+	    	vmkit::Thread::get()->MyVM->clearObjectReferent(newReference);
+	      th->addToEnqueue(newReference);
+	      return NULL;
+	    }
+	  }
+
+	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];
+	    memset(References, 0, INITIAL_QUEUE_SIZE * sizeof(gc*));
+	    QueueLength = INITIAL_QUEUE_SIZE;
+	    CurrentIndex = 0;
+	    semantics = s;
+	  }
+
+	  ~ReferenceQueue() {
+	    delete[] References;
+	  }
+
+	  void addReference(gc* ref) {
+	    llvm_gcroot(ref, 0);
+	    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();
+	      }
+	      memset(newQueue, 0, newLength * sizeof(gc*));
+	      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();
+	  }
+
+	  template <class T>
+	  void scan(ReferenceThread<T>* thread, word_t closure) {
+	    uint32 NewIndex = 0;
+
+	    for (uint32 i = 0; i < CurrentIndex; ++i) {
+	      gc* obj = References[i];
+	      gc* res = processReference(obj, thread, closure);
+	      if (res) References[NewIndex++] = res;
+	    }
+
+	    CurrentIndex = NewIndex;
+	  }
+
+	};
+
+	template <class T_THREAD> class ReferenceThread : public T_THREAD {
+	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;
+
+	  gc** ToEnqueue;
+	  uint32 ToEnqueueLength;
+	  uint32 ToEnqueueIndex;
+
+	  /// ToEnqueueLock - A lock to protect access to the queue.
+	  ///
+	  vmkit::LockNormal EnqueueLock;
+	  vmkit::Cond EnqueueCond;
+	  vmkit::SpinLock ToEnqueueLock;
+
+	  static void enqueueStart(ReferenceThread* th){
+	    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;
+
+	        vmkit::Thread::get()->MyVM->invokeEnqueueReference(res);
+	        res = NULL;
+	      }
+	    }
+	  }
+
+	  void addToEnqueue(gc* obj) {
+	    llvm_gcroot(obj, 0);
+	    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 < ToEnqueueLength; ++i) {
+	        newQueue[i] = ToEnqueue[i];
+	      }
+	      delete[] ToEnqueue;
+	      ToEnqueue = newQueue;
+	      ToEnqueueLength = newLength;
+	    }
+	    ToEnqueue[ToEnqueueIndex++] = obj;
+	  }
+
+	  /// addWeakReference - Add a weak reference to the queue.
+	  ///
+	  void addWeakReference(gc* ref) {
+	    llvm_gcroot(ref, 0);
+	    WeakReferencesQueue.addReference(ref);
+	  }
+
+	  /// addSoftReference - Add a weak reference to the queue.
+	  ///
+	  void addSoftReference(gc* ref) {
+	    llvm_gcroot(ref, 0);
+	    SoftReferencesQueue.addReference(ref);
+	  }
+
+	  /// addPhantomReference - Add a weak reference to the queue.
+	  ///
+	  void addPhantomReference(gc* ref) {
+	    llvm_gcroot(ref, 0);
+	    PhantomReferencesQueue.addReference(ref);
+	  }
+
+	  ReferenceThread(vmkit::VirtualMachine* vm) : T_THREAD(vm), WeakReferencesQueue(ReferenceQueue::WEAK),
+	      									SoftReferencesQueue(ReferenceQueue::SOFT),
+	      									PhantomReferencesQueue(ReferenceQueue::PHANTOM) {
+	    ToEnqueue = new gc*[INITIAL_QUEUE_SIZE];
+	    ToEnqueueLength = INITIAL_QUEUE_SIZE;
+	    ToEnqueueIndex = 0;
+	  }
+
+	  ~ReferenceThread() {
+	    delete[] ToEnqueue;
+	  }
+	};
+
+
+} /* namespace vmkit */
+
+#endif /* VMKIT_REFERENCETHREAD_H_ */

Modified: vmkit/trunk/lib/j3/ClassLib/GNUClasspath/JavaUpcalls.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/j3/ClassLib/GNUClasspath/JavaUpcalls.cpp?rev=180358&r1=180357&r2=180358&view=diff
==============================================================================
--- vmkit/trunk/lib/j3/ClassLib/GNUClasspath/JavaUpcalls.cpp (original)
+++ vmkit/trunk/lib/j3/ClassLib/GNUClasspath/JavaUpcalls.cpp Thu Apr 25 12:01:08 2013
@@ -15,7 +15,7 @@
 #include "JavaThread.h"
 #include "JavaUpcalls.h"
 #include "Jnjvm.h"
-#include "ReferenceQueue.h"
+#include "JavaReferenceQueue.h"
 
 #define COMPILE_METHODS(cl) \
   for (CommonClass::method_iterator i = cl->virtualMethods.begin(), \

Modified: vmkit/trunk/lib/j3/VMCore/Jnjvm.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/j3/VMCore/Jnjvm.cpp?rev=180358&r1=180357&r2=180358&view=diff
==============================================================================
--- vmkit/trunk/lib/j3/VMCore/Jnjvm.cpp (original)
+++ vmkit/trunk/lib/j3/VMCore/Jnjvm.cpp Thu Apr 25 12:01:08 2013
@@ -34,7 +34,7 @@
 #include "LinkJavaRuntime.h"
 #include "LockedMap.h"
 #include "Reader.h"
-#include "ReferenceQueue.h"
+#include "JavaReferenceQueue.h"
 #include "VMStaticInstance.h"
 #include "Zip.h"
 

Removed: vmkit/trunk/lib/j3/VMCore/ReferenceQueue.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/j3/VMCore/ReferenceQueue.cpp?rev=180357&view=auto
==============================================================================
--- vmkit/trunk/lib/j3/VMCore/ReferenceQueue.cpp (original)
+++ vmkit/trunk/lib/j3/VMCore/ReferenceQueue.cpp (removed)
@@ -1,89 +0,0 @@
-//===--ReferenceQueue.cpp - Implementation of soft/weak/phantom references-===//
-//
-//                            The VMKit project
-//
-// This file is distributed under the University of Pierre et Marie Curie 
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "ClasspathReflect.h"
-#include "JavaClass.h"
-#include "JavaUpcalls.h"
-#include "Jnjvm.h"
-#include "ReferenceQueue.h"
-
-using namespace j3;
-
-bool enqueueReference(gc* _obj) {
-  Jnjvm* vm = JavaThread::get()->getJVM();
-  JavaObject* obj = (JavaObject*)_obj;
-  llvm_gcroot(obj, 0);
-  JavaMethod* meth = vm->upcalls->EnqueueReference;
-  UserClass* cl = JavaObject::getClass(obj)->asClass();
-  return (bool)meth->invokeIntSpecialBuf(vm, cl, obj, 0);
-}
-
-void Jnjvm::invokeEnqueueReference(gc* res) {
-  llvm_gcroot(res, 0);
-  TRY {
-    enqueueReference(res);
-  } IGNORE;
-  vmkit::Thread::get()->clearException();
-}
-
-gc** Jnjvm::getObjectReferentPtr(gc* _obj) {
-  JavaObjectReference* obj = (JavaObjectReference*)_obj;
-  llvm_gcroot(obj, 0);
-  return (gc**)JavaObjectReference::getReferentPtr(obj);
-}
-
-void Jnjvm::setObjectReferent(gc* _obj, gc* val) {
-  JavaObjectReference* obj = (JavaObjectReference*)_obj;
-  llvm_gcroot(obj, 0);
-  llvm_gcroot(val, 0);
-  JavaObjectReference::setReferent(obj, (JavaObject*)val);
-}
- 
-void Jnjvm::clearObjectReferent(gc* _obj) {
-  JavaObjectReference* obj = (JavaObjectReference*)_obj;
-  llvm_gcroot(obj, 0);
-  JavaObjectReference::setReferent(obj, NULL);
-}
-
-typedef void (*destructor_t)(void*);
-
-void invokeFinalizer(gc* _obj) {
-  Jnjvm* vm = JavaThread::get()->getJVM();
-  JavaObject* obj = (JavaObject*)_obj;
-  llvm_gcroot(obj, 0);
-  JavaMethod* meth = vm->upcalls->FinalizeObject;
-  UserClass* cl = JavaObject::getClass(obj)->asClass();
-  meth->invokeIntVirtualBuf(vm, cl, obj, 0);
-}
-
-void invokeFinalize(gc* res) {
-  llvm_gcroot(res, 0);
-  TRY {
-    invokeFinalizer(res);
-  } IGNORE;
-  vmkit::Thread::get()->clearException();
-}
-
-/*
- *
- */
-
-void Jnjvm::finalizeObject(gc* object) {
-	JavaObject* res = 0;
-	llvm_gcroot(object, 0);
-	llvm_gcroot(res, 0);
-	res = (JavaObject*) object;
-  JavaVirtualTable* VT = res->getVirtualTable();
-  if (VT->operatorDelete) {
-    destructor_t dest = (destructor_t)VT->destructor;
-    dest(res);
-  } else {
-    invokeFinalize(res);
-  }
-}

Removed: vmkit/trunk/lib/j3/VMCore/ReferenceQueue.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/j3/VMCore/ReferenceQueue.h?rev=180357&view=auto
==============================================================================
--- vmkit/trunk/lib/j3/VMCore/ReferenceQueue.h (original)
+++ vmkit/trunk/lib/j3/VMCore/ReferenceQueue.h (removed)
@@ -1,409 +0,0 @@
-//===---ReferenceQueue.h - Implementation of soft/weak/phantom references--===//
-//
-//                            The VMKit project
-//
-// This file is distributed under the University of Pierre et Marie Curie 
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef J3_REFERENCE_QUEUE_H
-#define J3_REFERENCE_QUEUE_H
-
-#include "vmkit/Locks.h"
-
-#include "JavaThread.h"
-
-// Same values than JikesRVM
-#define INITIAL_QUEUE_SIZE 256
-#define GROW_FACTOR 2
-
-namespace j3 {
-
-template <class T> class ReferenceThread;
-class Jnjvm;
-
-
-class ReferenceQueue {
-private:
-  gc** References;
-  uint32 QueueLength;
-  uint32 CurrentIndex;
-  vmkit::SpinLock QueueLock;
-  uint8_t semantics;
-
-  template <class T>
-  gc* processReference(gc* reference, ReferenceThread<T>* th, word_t closure) {
-    if (!vmkit::Collector::isLive(reference, closure)) {
-      vmkit::Thread::get()->MyVM->clearObjectReferent(reference);
-      return NULL;
-    }
-
-    gc* referent = *(vmkit::Thread::get()->MyVM->getObjectReferentPtr(reference));
-
-    if (!referent) {
-      return NULL;
-    }
-
-    if (semantics == SOFT) {
-      // TODO: are we are out of memory? Consider that we always are for now.
-      if (false) {
-        vmkit::Collector::retainReferent(referent, closure);
-      }
-    } else if (semantics == PHANTOM) {
-      // Nothing to do.
-    }
-
-    gc* newReference =
-        vmkit::Collector::getForwardedReference(reference, closure);
-    if (vmkit::Collector::isLive(referent, closure)) {
-      gc* newReferent = vmkit::Collector::getForwardedReferent(referent, closure);
-      vmkit::Thread::get()->MyVM->setObjectReferent(newReference, newReferent);
-      return newReference;
-    } else {
-    	vmkit::Thread::get()->MyVM->clearObjectReferent(newReference);
-      th->addToEnqueue(newReference);
-      return NULL;
-    }
-  }
-
-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];
-    memset(References, 0, INITIAL_QUEUE_SIZE * sizeof(gc*));
-    QueueLength = INITIAL_QUEUE_SIZE;
-    CurrentIndex = 0;
-    semantics = s;
-  }
-
-  ~ReferenceQueue() {
-    delete[] References;
-  }
- 
-  void addReference(gc* ref) {
-    llvm_gcroot(ref, 0);
-    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();
-      }
-      memset(newQueue, 0, newLength * sizeof(gc*));
-      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();
-  }
-
-  template <class T>
-  void scan(ReferenceThread<T>* thread, word_t closure) {
-    uint32 NewIndex = 0;
-
-    for (uint32 i = 0; i < CurrentIndex; ++i) {
-      gc* obj = References[i];
-      gc* res = processReference(obj, thread, closure);
-      if (res) References[NewIndex++] = res;
-    }
-
-    CurrentIndex = NewIndex;
-  }
-
-};
-
-template <class T_THREAD> class ReferenceThread : public T_THREAD {
-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;
-
-  gc** ToEnqueue;
-  uint32 ToEnqueueLength;
-  uint32 ToEnqueueIndex;
-
-  /// ToEnqueueLock - A lock to protect access to the queue.
-  ///
-  vmkit::LockNormal EnqueueLock;
-  vmkit::Cond EnqueueCond;
-  vmkit::SpinLock ToEnqueueLock;
-
-  static void enqueueStart(ReferenceThread* th){
-    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;
-
-        vmkit::Thread::get()->MyVM->invokeEnqueueReference(res);
-        res = NULL;
-      }
-    }
-  }
-
-  void addToEnqueue(gc* obj) {
-    llvm_gcroot(obj, 0);
-    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 < ToEnqueueLength; ++i) {
-        newQueue[i] = ToEnqueue[i];
-      }
-      delete[] ToEnqueue;
-      ToEnqueue = newQueue;
-      ToEnqueueLength = newLength;
-    }
-    ToEnqueue[ToEnqueueIndex++] = obj;
-  }
-
-  /// addWeakReference - Add a weak reference to the queue.
-  ///
-  void addWeakReference(gc* ref) {
-    llvm_gcroot(ref, 0);
-    WeakReferencesQueue.addReference(ref);
-  }
-
-  /// addSoftReference - Add a weak reference to the queue.
-  ///
-  void addSoftReference(gc* ref) {
-    llvm_gcroot(ref, 0);
-    SoftReferencesQueue.addReference(ref);
-  }
-
-  /// addPhantomReference - Add a weak reference to the queue.
-  ///
-  void addPhantomReference(gc* ref) {
-    llvm_gcroot(ref, 0);
-    PhantomReferencesQueue.addReference(ref);
-  }
-
-  ReferenceThread(vmkit::VirtualMachine* vm) : T_THREAD(vm), WeakReferencesQueue(ReferenceQueue::WEAK),
-      									SoftReferencesQueue(ReferenceQueue::SOFT),
-      									PhantomReferencesQueue(ReferenceQueue::PHANTOM) {
-    ToEnqueue = new gc*[INITIAL_QUEUE_SIZE];
-    ToEnqueueLength = INITIAL_QUEUE_SIZE;
-    ToEnqueueIndex = 0;
-  }
-
-  ~ReferenceThread() {
-    delete[] ToEnqueue;
-  }
-};
-
-template <class T_THREAD> class FinalizerThread : public T_THREAD {
-public:
-  /// FinalizationQueueLock - A lock to protect access to the queue.
-  ///
-  vmkit::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;
-
-  /// growFinalizationQueue - Grow the queue of finalizable objects.
-  ///
-  void growFinalizationQueue() {
-    if (CurrentIndex >= QueueLength) {
-      uint32 newLength = QueueLength * GROW_FACTOR;
-      gc** newQueue = new gc*[newLength];
-      if (!newQueue) {
-        fprintf(stderr, "I don't know how to handle finalizer overflows yet!\n");
-        abort();
-      }
-      for (uint32 i = 0; i < QueueLength; ++i) newQueue[i] = FinalizationQueue[i];
-      delete[] FinalizationQueue;
-      FinalizationQueue = newQueue;
-      QueueLength = newLength;
-    }
-  }
-
-  
-  /// 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;
-  
-  /// growToBeFinalizedQueue - Grow the queue of the to-be finalized objects.
-  ///
-  void growToBeFinalizedQueue() {
-    if (CurrentFinalizedIndex >= ToBeFinalizedLength) {
-      uint32 newLength = ToBeFinalizedLength * GROW_FACTOR;
-      gc** newQueue = new gc*[newLength];
-      if (!newQueue) {
-        fprintf(stderr, "I don't know how to handle finalizer overflows yet!\n");
-        abort();
-      }
-      for (uint32 i = 0; i < ToBeFinalizedLength; ++i) newQueue[i] = ToBeFinalized[i];
-      delete[] ToBeFinalized;
-      ToBeFinalized = newQueue;
-      ToBeFinalizedLength = newLength;
-    }
-  }
-
-  
-  /// finalizationCond - Condition variable to wake up finalization threads.
-  ///
-  vmkit::Cond FinalizationCond;
-
-  /// finalizationLock - Lock for the condition variable.
-  ///
-  vmkit::LockNormal FinalizationLock;
-
-  static void finalizerStart(FinalizerThread* th) {
-    gc* res = NULL;
-    llvm_gcroot(res, 0);
-
-    while (true) {
-      th->FinalizationLock.lock();
-      while (th->CurrentFinalizedIndex == 0) {
-        th->FinalizationCond.wait(&th->FinalizationLock);
-      }
-      th->FinalizationLock.unlock();
-
-      while (true) {
-        th->FinalizationQueueLock.acquire();
-        if (th->CurrentFinalizedIndex != 0) {
-          res = th->ToBeFinalized[th->CurrentFinalizedIndex - 1];
-          --th->CurrentFinalizedIndex;
-        }
-        th->FinalizationQueueLock.release();
-        if (!res) break;
-
-       th->MyVM->finalizeObject(res);
-
-        res = NULL;
-      }
-    }
-  }
-
-  /// addFinalizationCandidate - Add an object to the queue of objects with
-  /// a finalization method.
-  ///
-  void addFinalizationCandidate(gc* obj) {
-    llvm_gcroot(obj, 0);
-    FinalizationQueueLock.acquire();
-
-    if (CurrentIndex >= QueueLength) {
-      growFinalizationQueue();
-    }
-
-    FinalizationQueue[CurrentIndex++] = obj;
-    FinalizationQueueLock.release();
-  }
-
-
-  /// scanFinalizationQueue - Scan objets with a finalized method and schedule
-  /// them for finalization if they are not live.
-  ///
-  void scanFinalizationQueue(word_t closure) {
-    uint32 NewIndex = 0;
-    for (uint32 i = 0; i < CurrentIndex; ++i) {
-      gc* obj = FinalizationQueue[i];
-
-      if (!vmkit::Collector::isLive(obj, closure)) {
-        obj = vmkit::Collector::retainForFinalize(FinalizationQueue[i], closure);
-
-        if (CurrentFinalizedIndex >= ToBeFinalizedLength)
-          growToBeFinalizedQueue();
-
-        /* Add to object table */
-        ToBeFinalized[CurrentFinalizedIndex++] = obj;
-      } else {
-        FinalizationQueue[NewIndex++] =
-          vmkit::Collector::getForwardedFinalizable(obj, closure);
-      }
-    }
-    CurrentIndex = NewIndex;
-  }
-
-
-  FinalizerThread(vmkit::VirtualMachine* vm) : T_THREAD(vm) {
-    FinalizationQueue = new gc*[INITIAL_QUEUE_SIZE];
-    QueueLength = INITIAL_QUEUE_SIZE;
-    CurrentIndex = 0;
-
-    ToBeFinalized = new gc*[INITIAL_QUEUE_SIZE];
-    ToBeFinalizedLength = INITIAL_QUEUE_SIZE;
-    CurrentFinalizedIndex = 0;
-  }
-
-  ~FinalizerThread() {
-    delete[] FinalizationQueue;
-    delete[] ToBeFinalized;
-  }
-};
-
-class JavaFinalizerThread : public FinalizerThread<JavaThread>{
-	public:
-		JavaFinalizerThread(Jnjvm* vm) : FinalizerThread<JavaThread>(vm) {}
-};
-
-class JavaReferenceThread : public ReferenceThread<JavaThread> {
-public:
-	JavaReferenceThread(Jnjvm* vm) : ReferenceThread<JavaThread>(vm) {}
-};
-
-
-} // namespace j3
-
-#endif  //J3_REFERENCE_QUEUE_H

Modified: vmkit/trunk/lib/j3/VMCore/VirtualTables.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/j3/VMCore/VirtualTables.cpp?rev=180358&r1=180357&r2=180358&view=diff
==============================================================================
--- vmkit/trunk/lib/j3/VMCore/VirtualTables.cpp (original)
+++ vmkit/trunk/lib/j3/VMCore/VirtualTables.cpp Thu Apr 25 12:01:08 2013
@@ -31,7 +31,7 @@
 #include "Jnjvm.h"
 #include "JnjvmClassLoader.h"
 #include "LockedMap.h"
-#include "ReferenceQueue.h"
+#include "JavaReferenceQueue.h"
 #include "VMStaticInstance.h"
 #include "Zip.h"
 





More information about the vmkit-commits mailing list