[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