[vmkit-commits] [vmkit] r180349 - Moved VirtualTable getter/setter to JavaObject so now Type is accessed threw the VirtualMachine.
Peter Senna Tschudin
peter.senna at gmail.com
Thu Apr 25 10:02:15 PDT 2013
Author: peter.senna
Date: Thu Apr 25 12:00:19 2013
New Revision: 180349
URL: http://llvm.org/viewvc/llvm-project?rev=180349&view=rev
Log:
Moved VirtualTable getter/setter to JavaObject so now Type is accessed threw the VirtualMachine.
Made ReferenceQueue generic with template class, have to put implementation in a separated file in vmkit folder.
(cherry picked from commit 06f4e14e863db720daf75f18bc47a752af7b8ab1)
Modified:
vmkit/trunk/include/vmkit/GC.h
vmkit/trunk/include/vmkit/VirtualMachine.h
vmkit/trunk/lib/j3/VMCore/JavaObject.h
vmkit/trunk/lib/j3/VMCore/JavaThread.cpp
vmkit/trunk/lib/j3/VMCore/JavaThread.h
vmkit/trunk/lib/j3/VMCore/Jnjvm.cpp
vmkit/trunk/lib/j3/VMCore/Jnjvm.h
vmkit/trunk/lib/j3/VMCore/ReferenceQueue.cpp
vmkit/trunk/lib/j3/VMCore/ReferenceQueue.h
vmkit/trunk/lib/vmkit/MMTk/VmkitGC.cpp
vmkit/trunk/lib/vmkit/MMTk/VmkitGC.h
vmkit/trunk/mmtk/mmtk-alloc/Selected.cpp
vmkit/trunk/mmtk/mmtk-j3/ObjectModel.cpp
Modified: vmkit/trunk/include/vmkit/GC.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/include/vmkit/GC.h?rev=180349&r1=180348&r2=180349&view=diff
==============================================================================
--- vmkit/trunk/include/vmkit/GC.h (original)
+++ vmkit/trunk/include/vmkit/GC.h Thu Apr 25 12:00:19 2013
@@ -28,25 +28,25 @@ public:
class gcRoot {
private:
+ /// getVirtualTable - Returns the virtual table of this object.
+ ///
+// VirtualTable* getVirtualTable() const {
+// return ((VirtualTable**)(this))[0];
+// }
+
+ /// setVirtualTable - Sets the virtual table of this object.
+ ///
+// void setVirtualTable(VirtualTable* VT) {
+// ((VirtualTable**)(this))[0] = VT;
+// }
public:
virtual ~gcRoot() {}
virtual void tracer(word_t closure) {}
word_t& header(){return toHeader()->_header; }
-
+
inline gcHeader* toHeader() { return (gcHeader*)((uintptr_t)this - gcHeader::hiddenHeaderSize()); }
- /// getVirtualTable - Returns the virtual table of this object.
- ///
- VirtualTable* getVirtualTable() const {
- return ((VirtualTable**)(this))[0];
- }
-
- /// setVirtualTable - Sets the virtual table of this object.
- ///
- void setVirtualTable(VirtualTable* VT) {
- ((VirtualTable**)(this))[0] = VT;
- }
};
namespace vmkit {
Modified: vmkit/trunk/include/vmkit/VirtualMachine.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/include/vmkit/VirtualMachine.h?rev=180349&r1=180348&r2=180349&view=diff
==============================================================================
--- vmkit/trunk/include/vmkit/VirtualMachine.h (original)
+++ vmkit/trunk/include/vmkit/VirtualMachine.h Thu Apr 25 12:00:19 2013
@@ -188,6 +188,10 @@ public:
///
virtual void addFinalizationCandidate(gc* object) {}
+ /// finalizeObject - Called by the finalizer thread for objects finalization.
+ ///
+ virtual void finalizeObject(gc* res) {}
+
/// tracer - Trace this virtual machine's GC-objects.
///
virtual void tracer(word_t closure) {}
@@ -199,7 +203,11 @@ public:
/// setType - Method called when allocating an object. The VirtualMachine has to
/// set the identity of the object (identity is determined by user).
///
- virtual void setType(gcHeader* header, void* type) = 0;
+ virtual void setType(gc* header, void* type) = 0;
+
+ /// getType - Gets the type of given object.
+ ///
+ virtual void* getType(gc* header) = 0;
/// getObjectSize - Get the size of this object. Used by copying collectors.
///
@@ -219,6 +227,15 @@ public:
#endif
//===----------------------------------------------------------------------===//
+// (2.5) GC-DEBUG-related methods.
+//===----------------------------------------------------------------------===//
+
+ /// isCorruptedType - Return true if object is corrupted.
+ ///
+ virtual bool isCorruptedType(gc* header) { return false; }
+
+
+//===----------------------------------------------------------------------===//
// (3) Backtrace-related methods.
//===----------------------------------------------------------------------===//
@@ -246,7 +263,34 @@ public:
virtual void nullPointerException() = 0;
virtual void stackOverflowError() = 0;
+
+//===----------------------------------------------------------------------===//
+// (6) ReferenceQueue-related methods (if used).
+// You have to create a class which inherits from specialized ReferenceThread class.
+// e.g: class MyReferenceThread : public ReferenceThread<YourThread> (see ReferenceQueue.h)
+//
+// Then once thread has been started you can enqueue references and the reference thread
+// delegates enqueuing process to the virtual machine threw the following methods.
+//===----------------------------------------------------------------------===//
+
+ /// invokeEnqueueReference - This method is called whenever an object is enqueued in
+ /// Soft, Weak or Phantom reference queues.
+ ///
+ virtual void invokeEnqueueReference(gc* ref) {}
+
+ /// clearObjectReferent - Clears object's referent
+ ///
+ virtual void clearObjectReferent(gc* ref) {}
+
+ /// getObjectReferentPtr - returns object referent's pointer
+ ///
+ virtual gc** getObjectReferentPtr(gc* _obj) { abort(); return NULL; }
+
+ /// setObjectReferent - set the referent of an object
+ ///
+ virtual void setObjectReferent(gc* _obj, gc* val) {}
};
+
} // end namespace vmkit
#endif // VMKIT_VIRTUALMACHINE_H
Modified: vmkit/trunk/lib/j3/VMCore/JavaObject.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/j3/VMCore/JavaObject.h?rev=180349&r1=180348&r2=180349&view=diff
==============================================================================
--- vmkit/trunk/lib/j3/VMCore/JavaObject.h (original)
+++ vmkit/trunk/lib/j3/VMCore/JavaObject.h Thu Apr 25 12:00:19 2013
@@ -237,6 +237,18 @@ private:
public:
+ /// getVirtualTable - Returns the java virtual table of this object.
+ ///
+ JavaVirtualTable* getVirtualTable() const {
+ return ((JavaVirtualTable**)(this))[0];
+ }
+
+ /// setVirtualTable - Sets the java virtual table of this object.
+ ///
+ void setVirtualTable(JavaVirtualTable* VT) {
+ ((JavaVirtualTable**)(this))[0] = VT;
+ }
+
/// getClass - Returns the class of this object.
///
static UserCommonClass* getClass(const JavaObject* self) {
Modified: vmkit/trunk/lib/j3/VMCore/JavaThread.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/j3/VMCore/JavaThread.cpp?rev=180349&r1=180348&r2=180349&view=diff
==============================================================================
--- vmkit/trunk/lib/j3/VMCore/JavaThread.cpp (original)
+++ vmkit/trunk/lib/j3/VMCore/JavaThread.cpp Thu Apr 25 12:00:19 2013
@@ -23,10 +23,10 @@
using namespace j3;
using namespace std;
-JavaThread::JavaThread(Jnjvm* isolate) : MutatorThread() {
+JavaThread::JavaThread(vmkit::VirtualMachine* isolate) : MutatorThread() {
MyVM = isolate;
pendingException = NULL;
- jniEnv = isolate->jniEnv;
+ jniEnv = ((Jnjvm*)isolate)->jniEnv;
localJNIRefs = new JNILocalReferences();
currentAddedReferences = NULL;
javaThread = NULL;
Modified: vmkit/trunk/lib/j3/VMCore/JavaThread.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/j3/VMCore/JavaThread.h?rev=180349&r1=180348&r2=180349&view=diff
==============================================================================
--- vmkit/trunk/lib/j3/VMCore/JavaThread.h (original)
+++ vmkit/trunk/lib/j3/VMCore/JavaThread.h Thu Apr 25 12:00:19 2013
@@ -119,7 +119,7 @@ public:
/// JavaThread - Creates a Java thread.
///
- JavaThread(Jnjvm* isolate);
+ JavaThread(vmkit::VirtualMachine* isolate);
void initialise(JavaObject* thread, JavaObject* vmth);
Modified: vmkit/trunk/lib/j3/VMCore/Jnjvm.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/j3/VMCore/Jnjvm.cpp?rev=180349&r1=180348&r2=180349&view=diff
==============================================================================
--- vmkit/trunk/lib/j3/VMCore/Jnjvm.cpp (original)
+++ vmkit/trunk/lib/j3/VMCore/Jnjvm.cpp Thu Apr 25 12:00:19 2013
@@ -1075,9 +1075,9 @@ void Jnjvm::loadBootstrap() {
finalizerThread->start(
(void (*)(vmkit::Thread*))FinalizerThread::finalizerStart);
- referenceThread = new ReferenceThread(this);
+ referenceThread = new JavaReferenceThread(this);
referenceThread->start(
- (void (*)(vmkit::Thread*))ReferenceThread::enqueueStart);
+ (void (*)(vmkit::Thread*))JavaReferenceThread::enqueueStart);
// Initialise the bootstrap class loader if it's not
// done already.
@@ -1378,23 +1378,86 @@ void Jnjvm::scanFinalizationQueue(word_t
}
void Jnjvm::addFinalizationCandidate(gc* object) {
- llvm_gcroot(object, 0);
- if (object->getVirtualTable()->hasDestructor())
- finalizerThread->addFinalizationCandidate(object);
+ JavaObject* src = 0;
+ llvm_gcroot(object, 0);
+ llvm_gcroot(src, 0);
+ src = (JavaObject*)object;
+ if (src->getVirtualTable()->hasDestructor())
+ finalizerThread->addFinalizationCandidate(src);
+}
+
+/*
+ * PUT THIS INTO A SEPARATED FILE
+ */
+
+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);
+ }
+}
+
+void Jnjvm::setType(gc* header, void* type) {
+ JavaObject* src = 0;
+ llvm_gcroot(src, 0);
+ llvm_gcroot(header, 0);
+ src = (JavaObject*) header;
+ src->setVirtualTable((JavaVirtualTable*)type);
}
-void Jnjvm::setType(gcHeader* header, void* type) {
- header->toReference()->setVirtualTable((VirtualTable*)type);
+void* Jnjvm::getType(gc* header) {
+ JavaObject* src = 0;
+ llvm_gcroot(src, 0);
+ llvm_gcroot(header, 0);
+ src = (JavaObject*) header;
+ return src->getVirtualTable();
}
// This method is called during GC so no llvm_gcroot needed.
-void Jnjvm::traceObject(gc* obj, word_t closure) {
+void Jnjvm::traceObject(gc* _obj, word_t closure) {
+ JavaObject* obj = 0;
+ obj = (JavaObject*)_obj;
assert(obj && "No object to trace");
assert(obj->getVirtualTable() && "No virtual table");
assert(obj->getVirtualTable()->tracer && "No tracer in VT");
obj->tracer(closure);
}
+// This method is called during GC so no llvm_gcroot needed.
+bool Jnjvm::isCorruptedType(gc* obj) {
+ return ((JavaObject*)obj)->getVirtualTable();
+}
+
size_t Jnjvm::getObjectSize(gc* object) {
// TODO: because this is called during GC, there is no need to do
// llvm_gcroot. For clarity, it may be useful to have a special type
Modified: vmkit/trunk/lib/j3/VMCore/Jnjvm.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/j3/VMCore/Jnjvm.h?rev=180349&r1=180348&r2=180349&view=diff
==============================================================================
--- vmkit/trunk/lib/j3/VMCore/Jnjvm.h (original)
+++ vmkit/trunk/lib/j3/VMCore/Jnjvm.h Thu Apr 25 12:00:19 2013
@@ -41,7 +41,7 @@ class JavaThread;
class JavaVirtualTable;
class JnjvmBootstrapLoader;
class JnjvmClassLoader;
-class ReferenceThread;
+class JavaReferenceThread;
class UserClass;
class UserClassArray;
class UserClassPrimitive;
@@ -121,7 +121,7 @@ private:
/// enqueueThread - The thread that enqueue Java references.
///
- ReferenceThread* referenceThread;
+ JavaReferenceThread* referenceThread;
virtual void startCollection();
virtual void endCollection();
@@ -130,12 +130,18 @@ private:
virtual void scanPhantomReferencesQueue(word_t closure);
virtual void scanFinalizationQueue(word_t closure);
virtual void addFinalizationCandidate(gc* obj);
+ virtual void finalizeObject(gc* res);
virtual void traceObject(gc* obj, word_t closure);
- virtual void setType(gcHeader* header, void* type);
+ virtual void setType(gc* header, void* type);
+ virtual void* getType(gc* obj);
virtual size_t getObjectSize(gc* obj);
virtual const char* getObjectTypeName(gc* obj);
+ virtual bool isCorruptedType(gc* header);
virtual void printMethod(vmkit::FrameInfo* FI, word_t ip, word_t addr);
-
+ virtual void invokeEnqueueReference(gc* res);
+ virtual void clearObjectReferent(gc* ref);
+ virtual gc** getObjectReferentPtr(gc* _obj);
+ virtual void setObjectReferent(gc* _obj, gc* val);
/// CreateError - Creates a Java object of the specified exception class
/// and calling its <init> function.
@@ -317,11 +323,11 @@ public:
/// setReferenceThread - Set the enqueue thread of this VM.
///
- void setReferenceThread(ReferenceThread* th) { referenceThread = th; }
+ void setReferenceThread(JavaReferenceThread* th) { referenceThread = th; }
/// getReferenceThread - Get the enqueue thread of this VM.
///
- ReferenceThread* getReferenceThread() const { return referenceThread; }
+ JavaReferenceThread* getReferenceThread() const { return referenceThread; }
/// ~Jnjvm - Destroy the JVM.
///
Modified: vmkit/trunk/lib/j3/VMCore/ReferenceQueue.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/j3/VMCore/ReferenceQueue.cpp?rev=180349&r1=180348&r2=180349&view=diff
==============================================================================
--- vmkit/trunk/lib/j3/VMCore/ReferenceQueue.cpp (original)
+++ vmkit/trunk/lib/j3/VMCore/ReferenceQueue.cpp Thu Apr 25 12:00:19 2013
@@ -15,17 +15,6 @@
using namespace j3;
-ReferenceThread::ReferenceThread(Jnjvm* vm) : JavaThread(vm),
- WeakReferencesQueue(ReferenceQueue::WEAK),
- SoftReferencesQueue(ReferenceQueue::SOFT),
- PhantomReferencesQueue(ReferenceQueue::PHANTOM) {
-
- ToEnqueue = new gc*[INITIAL_QUEUE_SIZE];
- ToEnqueueLength = INITIAL_QUEUE_SIZE;
- ToEnqueueIndex = 0;
-}
-
-
bool enqueueReference(gc* _obj) {
Jnjvm* vm = JavaThread::get()->getJVM();
JavaObject* obj = (JavaObject*)_obj;
@@ -35,7 +24,7 @@ bool enqueueReference(gc* _obj) {
return (bool)meth->invokeIntSpecialBuf(vm, cl, obj, 0);
}
-void invokeEnqueue(gc* res) {
+void Jnjvm::invokeEnqueueReference(gc* res) {
llvm_gcroot(res, 0);
TRY {
enqueueReference(res);
@@ -43,119 +32,25 @@ void invokeEnqueue(gc* res) {
vmkit::Thread::get()->clearException();
}
-void ReferenceThread::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;
-
- invokeEnqueue(res);
- res = NULL;
- }
- }
-}
-
-
-void ReferenceThread::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;
-}
-
-gc** getReferentPtr(gc* _obj) {
+gc** Jnjvm::getObjectReferentPtr(gc* _obj) {
JavaObjectReference* obj = (JavaObjectReference*)_obj;
llvm_gcroot(obj, 0);
return (gc**)JavaObjectReference::getReferentPtr(obj);
}
-void setReferent(gc* _obj, gc* val) {
+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 clearReferent(gc* _obj) {
+void Jnjvm::clearObjectReferent(gc* _obj) {
JavaObjectReference* obj = (JavaObjectReference*)_obj;
llvm_gcroot(obj, 0);
JavaObjectReference::setReferent(obj, NULL);
}
-gc* ReferenceQueue::processReference(gc* reference, ReferenceThread* th, word_t closure) {
- if (!vmkit::Collector::isLive(reference, closure)) {
- clearReferent(reference);
- return NULL;
- }
-
- gc* referent = *(getReferentPtr(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);
- setReferent(newReference, newReferent);
- return newReference;
- } else {
- clearReferent(newReference);
- th->addToEnqueue(newReference);
- return NULL;
- }
-}
-
-
-void ReferenceQueue::scan(ReferenceThread* th, word_t closure) {
- uint32 NewIndex = 0;
-
- for (uint32 i = 0; i < CurrentIndex; ++i) {
- gc* obj = References[i];
- gc* res = processReference(obj, th, closure);
- if (res) References[NewIndex++] = res;
- }
-
- CurrentIndex = NewIndex;
-}
-
-
FinalizerThread::FinalizerThread(Jnjvm* vm) : JavaThread(vm) {
FinalizationQueue = new gc*[INITIAL_QUEUE_SIZE];
QueueLength = INITIAL_QUEUE_SIZE;
@@ -231,24 +126,6 @@ void FinalizerThread::scanFinalizationQu
CurrentIndex = NewIndex;
}
-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 FinalizerThread::finalizerStart(FinalizerThread* th) {
gc* res = NULL;
@@ -270,13 +147,8 @@ void FinalizerThread::finalizerStart(Fin
th->FinalizationQueueLock.release();
if (!res) break;
- VirtualTable* VT = res->getVirtualTable();
- if (VT->operatorDelete) {
- destructor_t dest = (destructor_t)VT->destructor;
- dest(res);
- } else {
- invokeFinalize(res);
- }
+ th->MyVM->finalizeObject(res);
+
res = NULL;
}
}
Modified: vmkit/trunk/lib/j3/VMCore/ReferenceQueue.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/j3/VMCore/ReferenceQueue.h?rev=180349&r1=180348&r2=180349&view=diff
==============================================================================
--- vmkit/trunk/lib/j3/VMCore/ReferenceQueue.h (original)
+++ vmkit/trunk/lib/j3/VMCore/ReferenceQueue.h Thu Apr 25 12:00:19 2013
@@ -20,9 +20,10 @@
namespace j3 {
-class ReferenceThread;
+template <class T> class ReferenceThread;
class Jnjvm;
+
class ReferenceQueue {
private:
gc** References;
@@ -31,7 +32,41 @@ private:
vmkit::SpinLock QueueLock;
uint8_t semantics;
- gc* processReference(gc*, ReferenceThread*, word_t closure);
+ 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;
@@ -79,10 +114,22 @@ public:
QueueLock.release();
}
- void scan(ReferenceThread* thread, word_t closure);
+ 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;
+ }
+
};
-class ReferenceThread : public JavaThread {
+template <class T_THREAD> class ReferenceThread : public T_THREAD {
public:
/// WeakReferencesQueue - The queue of weak references.
///
@@ -99,16 +146,57 @@ public:
gc** ToEnqueue;
uint32 ToEnqueueLength;
uint32 ToEnqueueIndex;
-
+
/// ToEnqueueLock - A lock to protect access to the queue.
///
vmkit::LockNormal EnqueueLock;
vmkit::Cond EnqueueCond;
vmkit::SpinLock ToEnqueueLock;
- void addToEnqueue(gc* obj);
+ 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;
- static void enqueueStart(ReferenceThread*);
+ 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.
///
@@ -116,14 +204,14 @@ public:
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) {
@@ -131,16 +219,27 @@ public:
PhantomReferencesQueue.addReference(ref);
}
- ReferenceThread(Jnjvm* vm);
+ 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;
}
};
+class JavaReferenceThread : public ReferenceThread<JavaThread> {
+public:
+ JavaReferenceThread(Jnjvm* vm) : ReferenceThread<JavaThread>(vm) {}
+};
+
class FinalizerThread : public JavaThread {
public:
- /// FinalizationQueueLock - A lock to protect access to the queue.
+ /// FinalizationQueueLock - A lock to protect access to the queue.
///
vmkit::SpinLock FinalizationQueueLock;
Modified: vmkit/trunk/lib/vmkit/MMTk/VmkitGC.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/vmkit/MMTk/VmkitGC.cpp?rev=180349&r1=180348&r2=180349&view=diff
==============================================================================
--- vmkit/trunk/lib/vmkit/MMTk/VmkitGC.cpp (original)
+++ vmkit/trunk/lib/vmkit/MMTk/VmkitGC.cpp Thu Apr 25 12:00:19 2013
@@ -36,7 +36,7 @@ extern "C" void* prealloc(uint32_t sz) {
}
extern "C" void postalloc(gc* obj, void* type, uint32_t size) {
- vmkit::Thread::get()->MyVM->setType(obj->toHeader(), type);
+ vmkit::Thread::get()->MyVM->setType(obj, type);
}
extern "C" void* gcmalloc(uint32_t sz, void* type) {
@@ -53,21 +53,22 @@ extern "C" void* gcmallocUnresolved(uint
return res;
}
-extern "C" void addFinalizationCandidate(gc* obj) {
- vmkit::Thread::get()->MyVM->addFinalizationCandidate(obj);
-}
-
+// Do not insert MagicArray ref to InternalSet of references.
extern "C" void* AllocateMagicArray(int32_t sz, void* length) {
- sz += gcHeader::hiddenHeaderSize();
gcHeader* head = 0;
gc* res = 0;
- head = (gcHeader*)malloc(sz);
- memset((void*)head, 0, sz);
- res = head->toReference();
- res->setVirtualTable((VirtualTable*)length);
+ sz += gcHeader::hiddenHeaderSize();
+ head = (gcHeader*)malloc(sz);
+ memset((void*)head, 0, sz);
+ res = head->toReference();
+ vmkit::Thread::get()->MyVM->setType(res, length);
return res;
}
+extern "C" void addFinalizationCandidate(gc* obj) {
+ vmkit::Thread::get()->MyVM->addFinalizationCandidate(obj);
+}
+
void* Collector::begOf(gc* obj) {
lock.acquire();
std::set<gc*>::iterator I = __InternalSet__.find(obj);
Modified: vmkit/trunk/lib/vmkit/MMTk/VmkitGC.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/vmkit/MMTk/VmkitGC.h?rev=180349&r1=180348&r2=180349&view=diff
==============================================================================
--- vmkit/trunk/lib/vmkit/MMTk/VmkitGC.h (original)
+++ vmkit/trunk/lib/vmkit/MMTk/VmkitGC.h Thu Apr 25 12:00:19 2013
@@ -65,8 +65,8 @@ public:
return 0;
}
- void* operator new(size_t sz, VirtualTable *VT) {
- return gcmallocUnresolved(sz, VT);
+ void* operator new(size_t sz, void *type) {
+ return gcmallocUnresolved(sz, type);
}
};
Modified: vmkit/trunk/mmtk/mmtk-alloc/Selected.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/mmtk/mmtk-alloc/Selected.cpp?rev=180349&r1=180348&r2=180349&view=diff
==============================================================================
--- vmkit/trunk/mmtk/mmtk-alloc/Selected.cpp (original)
+++ vmkit/trunk/mmtk/mmtk-alloc/Selected.cpp Thu Apr 25 12:00:19 2013
@@ -63,6 +63,7 @@ extern "C" void* JnJVM_org_j3_bindings_B
extern "C" void* prealloc(uint32_t size) {
gc* res = 0;
gcHeader* head = 0;
+ llvm_gcroot(res, 0);
size = llvm::RoundUpToAlignment(size, sizeof(void*));
head = (gcHeader*) JnJVM_org_j3_bindings_Bindings_prealloc__I(size);
res = head->toReference();
@@ -70,7 +71,7 @@ extern "C" void* prealloc(uint32_t size)
}
extern "C" void postalloc(gc* obj, void* type, uint32_t size) {
- vmkit::Thread::get()->MyVM->setType(obj->toHeader(), type);
+ vmkit::Thread::get()->MyVM->setType(obj, type);
JnJVM_org_j3_bindings_Bindings_postalloc__Lorg_vmmagic_unboxed_ObjectReference_2Lorg_vmmagic_unboxed_ObjectReference_2I(obj, type, size);
}
@@ -132,37 +133,25 @@ bool Collector::isLive(gc* ptr, word_t c
void Collector::scanObject(void** ptr, word_t closure) {
if ((*ptr) != NULL) {
- assert(((gc*)(*ptr))->getVirtualTable());
+ assert(vmkit::Thread::get()->MyVM->isCorruptedType((gc*)(*ptr)));
}
-#if RESET_STALE_REFERENCES
- // Allow the VM to reset references if needed
- vmkit::Thread::get()->MyVM->resetReferenceIfStale(NULL, ptr);
-#endif
JnJVM_org_j3_bindings_Bindings_reportDelayedRootEdge__Lorg_mmtk_plan_TraceLocal_2Lorg_vmmagic_unboxed_Address_2(closure, ptr);
}
void Collector::markAndTrace(void* source, void* ptr, word_t closure) {
void** ptr_ = (void**)ptr;
if ((*ptr_) != NULL) {
- assert(((gc*)(*ptr_))->getVirtualTable());
+ assert(vmkit::Thread::get()->MyVM->isCorruptedType((gc*)(*ptr_)));
}
- if ((*(void**)ptr) != NULL) assert(((gc*)(*(void**)ptr))->getVirtualTable());
-#if RESET_STALE_REFERENCES
- // Allow the VM to reset references if needed
- vmkit::Thread::get()->MyVM->resetReferenceIfStale(source, ptr_);
-#endif
+ if ((*(void**)ptr) != NULL) assert(vmkit::Thread::get()->MyVM->isCorruptedType((gc*)(*(void**)ptr)));
JnJVM_org_j3_bindings_Bindings_processEdge__Lorg_mmtk_plan_TransitiveClosure_2Lorg_vmmagic_unboxed_ObjectReference_2Lorg_vmmagic_unboxed_Address_2(closure, source, ptr);
}
-void Collector::markAndTraceRoot(void* source, void* ptr, word_t closure) {
+void Collector::markAndTraceRoot(void* ptr, word_t closure) {
void** ptr_ = (void**)ptr;
if ((*ptr_) != NULL) {
- assert(((gc*)(*ptr_))->getVirtualTable());
+ assert(vmkit::Thread::get()->MyVM->isCorruptedType((gc*)(*ptr_)));
}
-#if RESET_STALE_REFERENCES
- // Allow the VM to reset references if needed
- vmkit::Thread::get()->MyVM->resetReferenceIfStale(source, ptr_);
-#endif
JnJVM_org_j3_bindings_Bindings_processRootEdge__Lorg_mmtk_plan_TraceLocal_2Lorg_vmmagic_unboxed_Address_2Z(closure, ptr, true);
}
@@ -235,9 +224,9 @@ void Collector::initialise(int argc, cha
JnJVM_org_j3_bindings_Bindings_boot__Lorg_vmmagic_unboxed_Extent_2Lorg_vmmagic_unboxed_Extent_2_3Ljava_lang_String_2(20 * 1024 * 1024, 100 * 1024 * 1024, arguments);
}
-extern "C" void* MMTkMutatorAllocate(uint32_t size, VirtualTable* VT) {
+extern "C" void* MMTkMutatorAllocate(uint32_t size, void* type) {
gc* val = (gc*)MutatorThread::get()->Allocator.Allocate(size);
- val->setVirtualTable(VT);
+ vmkit::Thread::get()->MyVM->setType(val, type);
return val;
}
Modified: vmkit/trunk/mmtk/mmtk-j3/ObjectModel.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/mmtk/mmtk-j3/ObjectModel.cpp?rev=180349&r1=180348&r2=180349&view=diff
==============================================================================
--- vmkit/trunk/mmtk/mmtk-j3/ObjectModel.cpp (original)
+++ vmkit/trunk/mmtk/mmtk-j3/ObjectModel.cpp Thu Apr 25 12:00:19 2013
@@ -86,7 +86,7 @@ extern "C" void Java_org_j3_bindings_Bin
extern "C" word_t JnJVM_org_j3_bindings_Bindings_copy__Lorg_vmmagic_unboxed_ObjectReference_2Lorg_vmmagic_unboxed_ObjectReference_2II(
- gc* obj, VirtualTable* VT, int size, int allocator);
+ gc* obj, void* type, int size, int allocator);
extern "C" word_t Java_org_j3_mmtk_ObjectModel_copy__Lorg_vmmagic_unboxed_ObjectReference_2I (
MMTkObject* OM, gc* src, int allocator) ALWAYS_INLINE;
@@ -96,7 +96,7 @@ extern "C" word_t Java_org_j3_mmtk_Objec
size_t size = vmkit::Thread::get()->MyVM->getObjectSize(src);
size = llvm::RoundUpToAlignment(size, sizeof(void*));
gc* res = (gc*)JnJVM_org_j3_bindings_Bindings_copy__Lorg_vmmagic_unboxed_ObjectReference_2Lorg_vmmagic_unboxed_ObjectReference_2II(
- src, src->getVirtualTable(), size, allocator);
+ src, vmkit::Thread::get()->MyVM->getType(src), size, allocator);
assert((res->header() & ~vmkit::GCBitMask) == (src->header() & ~vmkit::GCBitMask));
return (word_t)res;
}
More information about the vmkit-commits
mailing list