[vmkit-commits] [vmkit] r70119 - in /vmkit/trunk: include/jnjvm/JnjvmModule.h include/mvm/VirtualMachine.h lib/JnJVM/Classpath/ClasspathReflect.h lib/JnJVM/Compiler/JavaJITCompiler.cpp lib/JnJVM/VMCore/JavaMetaJIT.cpp lib/JnJVM/VMCore/JavaUpcalls.cpp lib/JnJVM/VMCore/JavaUpcalls.h lib/JnJVM/VMCore/Jnjvm.cpp lib/JnJVM/VMCore/Jnjvm.h lib/Mvm/GCMmap2/gccollector.cpp lib/Mvm/Runtime/Object.cpp
Nicolas Geoffray
nicolas.geoffray at lip6.fr
Sun Apr 26 02:16:53 PDT 2009
Author: geoffray
Date: Sun Apr 26 04:16:48 2009
New Revision: 70119
URL: http://llvm.org/viewvc/llvm-project?rev=70119&view=rev
Log:
Support for Weak/Soft/Phantom references in GCMmap2.
Modified:
vmkit/trunk/include/jnjvm/JnjvmModule.h
vmkit/trunk/include/mvm/VirtualMachine.h
vmkit/trunk/lib/JnJVM/Classpath/ClasspathReflect.h
vmkit/trunk/lib/JnJVM/Compiler/JavaJITCompiler.cpp
vmkit/trunk/lib/JnJVM/VMCore/JavaMetaJIT.cpp
vmkit/trunk/lib/JnJVM/VMCore/JavaUpcalls.cpp
vmkit/trunk/lib/JnJVM/VMCore/JavaUpcalls.h
vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.cpp
vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.h
vmkit/trunk/lib/Mvm/GCMmap2/gccollector.cpp
vmkit/trunk/lib/Mvm/Runtime/Object.cpp
Modified: vmkit/trunk/include/jnjvm/JnjvmModule.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/include/jnjvm/JnjvmModule.h?rev=70119&r1=70118&r2=70119&view=diff
==============================================================================
--- vmkit/trunk/include/jnjvm/JnjvmModule.h (original)
+++ vmkit/trunk/include/jnjvm/JnjvmModule.h Sun Apr 26 04:16:48 2009
@@ -66,6 +66,7 @@
class LLVMClassInfo : public mvm::JITInfo {
+ friend class JavaAOTCompiler;
friend class JavaJITCompiler;
friend class JavaLLVMCompiler;
private:
Modified: vmkit/trunk/include/mvm/VirtualMachine.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/include/mvm/VirtualMachine.h?rev=70119&r1=70118&r2=70119&view=diff
==============================================================================
--- vmkit/trunk/include/mvm/VirtualMachine.h (original)
+++ vmkit/trunk/include/mvm/VirtualMachine.h Sun Apr 26 04:16:48 2009
@@ -42,13 +42,57 @@
namespace mvm {
+class VirtualMachine;
+
+class ReferenceQueue {
+private:
+ gc** References;
+ uint32 QueueLength;
+ uint32 CurrentIndex;
+ mvm::SpinLock QueueLock;
+ uint8_t semantics;
+
+ gc* processReference(gc*, VirtualMachine*);
+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];
+ QueueLength = INITIAL_QUEUE_SIZE;
+ CurrentIndex = 0;
+ semantics = s;
+ }
+
+ void addReference(gc* ref) {
+ QueueLock.acquire();
+ if (CurrentIndex >= QueueLength) {
+ uint32 newLength = QueueLength * GROW_FACTOR;
+ gc** newQueue = new gc*[newLength];
+ for (uint32 i = 0; i < QueueLength; ++i) newQueue[i] = References[i];
+ delete[] References;
+ References = newQueue;
+ QueueLength = newLength;
+ }
+ References[CurrentIndex++] = ref;
+ QueueLock.release();
+ }
+
+ void scan(VirtualMachine* vm);
+};
+
/// VirtualMachine - This class is the root of virtual machine classes. It
/// defines what a VM should be.
///
class VirtualMachine : public mvm::PermanentObject {
protected:
- VirtualMachine() {
+ VirtualMachine() :
+ WeakReferencesQueue(ReferenceQueue::WEAK),
+ SoftReferencesQueue(ReferenceQueue::SOFT),
+ PhantomReferencesQueue(ReferenceQueue::PHANTOM) {
#ifdef SERVICE
memoryLimit = ~0;
executionLimit = ~0;
@@ -64,6 +108,7 @@
ToBeFinalized = new gc*[INITIAL_QUEUE_SIZE];
ToBeFinalizedLength = INITIAL_QUEUE_SIZE;
+
}
public:
@@ -183,6 +228,18 @@
return ToBeFinalizedLength - countFinalized();
}
+ /// WeakReferencesQueue - The queue of weak references.
+ ///
+ ReferenceQueue WeakReferencesQueue;
+
+ /// SoftReferencesQueue - The queue of soft references.
+ ///
+ ReferenceQueue SoftReferencesQueue;
+
+ /// PhantomReferencesQueue - The queue of phantom references.
+ ///
+ ReferenceQueue PhantomReferencesQueue;
+
protected:
/// invokeFinalizer - Invoke the finalizer of the object. This may involve
/// changing the environment, e.g. going to native to Java.
@@ -210,6 +267,60 @@
///
void wakeUpFinalizers() { FinalizationCond.broadcast(); }
+ /// scanWeakReferencesQueue - Scan all weak references. Called by the GC
+ /// before scanning the finalization queue.
+ ///
+ void scanWeakReferencesQueue() {
+ WeakReferencesQueue.scan(this);
+ }
+
+ /// scanSoftReferencesQueue - Scan all soft references. Called by the GC
+ /// before scanning the finalization queue.
+ ///
+ void scanSoftReferencesQueue() {
+ SoftReferencesQueue.scan(this);
+ }
+
+ /// scanPhantomReferencesQueue - Scan all phantom references. Called by the GC
+ /// after the finalization queue.
+ ///
+ void scanPhantomReferencesQueue() {
+ PhantomReferencesQueue.scan(this);
+ }
+
+ /// addWeakReference - Add a weak reference to the queue.
+ ///
+ void addWeakReference(gc* ref) {
+ WeakReferencesQueue.addReference(ref);
+ }
+
+ /// addSoftReference - Add a weak reference to the queue.
+ ///
+ void addSoftReference(gc* ref) {
+ SoftReferencesQueue.addReference(ref);
+ }
+
+ /// addPhantomReference - Add a weak reference to the queue.
+ ///
+ void addPhantomReference(gc* ref) {
+ PhantomReferencesQueue.addReference(ref);
+ }
+
+ /// clearReferent - Clear the referent in a reference. Should be overriden
+ /// by the VM.
+ ///
+ virtual void clearReferent(gc*) {}
+
+ /// getReferent - Get the referent of the reference. Should be overriden
+ /// by the VM.
+ //
+ virtual gc* getReferent(gc*) { return 0; }
+
+ /// enqueueReference - Calls the enqueue method. Should be overriden
+ /// by the VM.
+ ///
+ virtual bool enqueueReference(gc*) { return false; }
+
#ifdef ISOLATE
size_t IsolateID;
#endif
Modified: vmkit/trunk/lib/JnJVM/Classpath/ClasspathReflect.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/Classpath/ClasspathReflect.h?rev=70119&r1=70118&r2=70119&view=diff
==============================================================================
--- vmkit/trunk/lib/JnJVM/Classpath/ClasspathReflect.h (original)
+++ vmkit/trunk/lib/JnJVM/Classpath/ClasspathReflect.h Sun Apr 26 04:16:48 2009
@@ -148,6 +148,27 @@
}
};
+class JavaObjectReference : public JavaObject {
+private:
+ JavaObject* referent;
+ JavaObject* queue;
+ JavaObject* nextOnQueue;
+
+public:
+ void init(JavaObject* r, JavaObject* q) {
+ referent = r;
+ queue = q;
+ }
+
+ JavaObject* getReferent() const { return referent; }
+ void setReferent(JavaObject* r) { referent = r; }
+
+ static void STATIC_TRACER(JavaObjectReference) {
+ obj->queue->MARK_AND_TRACE;
+ obj->nextOnQueue->MARK_AND_TRACE;
+ }
+};
+
}
#endif
Modified: vmkit/trunk/lib/JnJVM/Compiler/JavaJITCompiler.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/Compiler/JavaJITCompiler.cpp?rev=70119&r1=70118&r2=70119&view=diff
==============================================================================
--- vmkit/trunk/lib/JnJVM/Compiler/JavaJITCompiler.cpp (original)
+++ vmkit/trunk/lib/JnJVM/Compiler/JavaJITCompiler.cpp Sun Apr 26 04:16:48 2009
@@ -138,18 +138,22 @@
assert(VT && "No VT was allocated!");
#ifdef WITH_TRACER
- if (VT->init) {
- // So the class is vmjc'ed. Create the virtual tracer.
+ if (VT->tracer) {
+ // So the class has a tracer because either a) the class was vmjced or
+ // b) the boot sequence has set it. Create the tracer as an external
+ // function.
Function* func = Function::Create(JnjvmModule::MarkAndTraceType,
GlobalValue::ExternalLinkage,
- "markAndTraceObject",
- getLLVMModule());
+ "", getLLVMModule());
uintptr_t ptr = VT->tracer;
JnjvmModule::executionEngine->addGlobalMapping(func, (void*)ptr);
LLVMClassInfo* LCI = getClassInfo(cl);
LCI->virtualTracerFunction = func;
+ }
+
+ if (VT->init) {
// The VT hash already been filled by the AOT compiler so there
// is nothing left to do!
return;
@@ -189,11 +193,13 @@
}
#ifdef WITH_TRACER
- Function* func = makeTracer(cl, false);
+ if (!VT->tracer) {
+ Function* func = makeTracer(cl, false);
- void* codePtr = mvm::MvmModule::executionEngine->getPointerToFunction(func);
- VT->tracer = (uintptr_t)codePtr;
- func->deleteBody();
+ void* codePtr = mvm::MvmModule::executionEngine->getPointerToFunction(func);
+ VT->tracer = (uintptr_t)codePtr;
+ func->deleteBody();
+ }
#endif
}
Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaMetaJIT.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JavaMetaJIT.cpp?rev=70119&r1=70118&r2=70119&view=diff
==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JavaMetaJIT.cpp (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JavaMetaJIT.cpp Sun Apr 26 04:16:48 2009
@@ -633,3 +633,10 @@
UserClass* cl = obj->getClass()->asClass();
meth->invokeIntVirtualBuf(this, cl, obj, 0);
}
+
+bool Jnjvm::enqueueReference(gc* _obj) {
+ JavaObject* obj = (JavaObject*)_obj;
+ JavaMethod* meth = upcalls->EnqueueReference;
+ UserClass* cl = obj->getClass()->asClass();
+ return (bool)meth->invokeIntVirtualBuf(this, cl, obj, 0);
+}
Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaUpcalls.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JavaUpcalls.cpp?rev=70119&r1=70118&r2=70119&view=diff
==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JavaUpcalls.cpp (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JavaUpcalls.cpp Sun Apr 26 04:16:48 2009
@@ -208,6 +208,9 @@
JavaField* Classpath::fieldClass;
JavaField* Classpath::constructorClass;
+JavaMethod* Classpath::EnqueueReference;
+Class* Classpath::newReference;
+
#endif
void Classpath::CreateJavaThread(Jnjvm* vm, JavaThread* myth,
@@ -336,6 +339,44 @@
extern "C" void nativePropertiesPostInit(JavaObject* prop);
+extern "C" void nativeInitWeakReference(JavaObjectReference* reference,
+ JavaObject* referent) {
+ reference->init(referent, 0);
+ JavaThread::get()->getJVM()->addWeakReference(reference);
+
+}
+
+extern "C" void nativeInitWeakReferenceQ(JavaObjectReference* reference,
+ JavaObject* referent,
+ JavaObject* queue) {
+ reference->init(referent, queue);
+ JavaThread::get()->getJVM()->addWeakReference(reference);
+
+}
+
+extern "C" void nativeInitSoftReference(JavaObjectReference* reference,
+ JavaObject* referent) {
+ reference->init(referent, 0);
+ JavaThread::get()->getJVM()->addSoftReference(reference);
+
+}
+
+extern "C" void nativeInitSoftReferenceQ(JavaObjectReference* reference,
+ JavaObject* referent,
+ JavaObject* queue) {
+ reference->init(referent, queue);
+ JavaThread::get()->getJVM()->addSoftReference(reference);
+
+}
+
+extern "C" void nativeInitPhantomReferenceQ(JavaObjectReference* reference,
+ JavaObject* referent,
+ JavaObject* queue) {
+ reference->init(referent, queue);
+ JavaThread::get()->getJVM()->addPhantomReference(reference);
+
+}
+
void Classpath::initialiseClasspath(JnjvmClassLoader* loader) {
newClassLoader =
@@ -745,5 +786,64 @@
ACC_VIRTUAL);
getAnnotations->setCompiledPtr((void*)(intptr_t)nativeGetDeclaredAnnotations,
"nativeGetDeclaredAnnotations");
+
+ newReference =
+ loader->loadName(loader->asciizConstructUTF8("java/lang/ref/Reference"),
+ false, false);
+
+ assert(!newReference->isResolved() && "Reference class already resolved");
+ JavaVirtualTable* ptr = newReference->getVirtualVT();
+ ptr->tracer = (uintptr_t)JavaObjectReference::staticTracer;
+
+ EnqueueReference =
+ UPCALL_METHOD(loader, "java/lang/ref/Reference", "enqueue", "()Z",
+ ACC_VIRTUAL);
+
+ JavaMethod* initWeakReference =
+ UPCALL_METHOD(loader, "java/lang/ref/WeakReference", "<init>",
+ "(Ljava/lang/Object;)V",
+ ACC_VIRTUAL);
+ initWeakReference->setCompiledPtr((void*)(intptr_t)nativeInitWeakReference,
+ "nativeInitWeakReference");
+
+ initWeakReference =
+ UPCALL_METHOD(loader, "java/lang/ref/WeakReference", "<init>",
+ "(Ljava/lang/Object;Ljava/lang/ref/ReferenceQueue;)V",
+ ACC_VIRTUAL);
+ initWeakReference->setCompiledPtr((void*)(intptr_t)nativeInitWeakReferenceQ,
+ "nativeInitWeakReferenceQ");
+
+ JavaMethod* initSoftReference =
+ UPCALL_METHOD(loader, "java/lang/ref/SoftReference", "<init>",
+ "(Ljava/lang/Object;)V",
+ ACC_VIRTUAL);
+ initSoftReference->setCompiledPtr((void*)(intptr_t)nativeInitSoftReference,
+ "nativeInitSoftReference");
+
+ initSoftReference =
+ UPCALL_METHOD(loader, "java/lang/ref/WeakReference", "<init>",
+ "(Ljava/lang/Object;Ljava/lang/ref/ReferenceQueue;)V",
+ ACC_VIRTUAL);
+ initSoftReference->setCompiledPtr((void*)(intptr_t)nativeInitSoftReferenceQ,
+ "nativeInitSoftReferenceQ");
+
+ JavaMethod* initPhantomReference =
+ UPCALL_METHOD(loader, "java/lang/ref/PhantomReference", "<init>",
+ "(Ljava/lang/Object;Ljava/lang/ref/ReferenceQueue;)V",
+ ACC_VIRTUAL);
+ initPhantomReference->setCompiledPtr(
+ (void*)(intptr_t)nativeInitPhantomReferenceQ,
+ "nativeInitPhantomReferenceQ");
+
+
+}
+
+gc* Jnjvm::getReferent(gc* _obj) {
+ JavaObjectReference* obj = (JavaObjectReference*)_obj;
+ return obj->getReferent();
}
+void Jnjvm::clearReferent(gc* _obj) {
+ JavaObjectReference* obj = (JavaObjectReference*)_obj;
+ obj->setReferent(0);
+}
Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaUpcalls.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JavaUpcalls.h?rev=70119&r1=70118&r2=70119&view=diff
==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JavaUpcalls.h (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JavaUpcalls.h Sun Apr 26 04:16:48 2009
@@ -242,6 +242,9 @@
ISOLATE_STATIC JavaField* methodClass;
ISOLATE_STATIC JavaField* fieldClass;
ISOLATE_STATIC JavaField* constructorClass;
+
+ ISOLATE_STATIC JavaMethod* EnqueueReference;
+ ISOLATE_STATIC Class* newReference;
private:
ISOLATE_STATIC void CreateJavaThread(Jnjvm* vm, JavaThread* myth,
Modified: vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.cpp?rev=70119&r1=70118&r2=70119&view=diff
==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.cpp (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.cpp Sun Apr 26 04:16:48 2009
@@ -845,7 +845,7 @@
LOAD_CLASS(upcalls->newVMThread);
ptr = ((uintptr_t*)upcalls->newVMThread->getVirtualVT());
ptr[VT_DESTRUCTOR_OFFSET] = (uintptr_t)JavaObjectVMThread::staticDestructor;
-
+
#ifdef SERVICE
if (!IsolateID)
#endif
Modified: vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.h?rev=70119&r1=70118&r2=70119&view=diff
==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.h (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.h Sun Apr 26 04:16:48 2009
@@ -363,6 +363,10 @@
protected:
virtual void invokeFinalizer(gc*);
+public:
+ virtual void clearReferent(gc*);
+ virtual gc* getReferent(gc*);
+ virtual bool enqueueReference(gc*);
};
Modified: vmkit/trunk/lib/Mvm/GCMmap2/gccollector.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/Mvm/GCMmap2/gccollector.cpp?rev=70119&r1=70118&r2=70119&view=diff
==============================================================================
--- vmkit/trunk/lib/Mvm/GCMmap2/gccollector.cpp (original)
+++ vmkit/trunk/lib/Mvm/GCMmap2/gccollector.cpp Sun Apr 26 04:16:48 2009
@@ -78,7 +78,17 @@
threads->collectionFinished();
#endif
- Thread::get()->MyVM->scanFinalizationQueue();
+ VirtualMachine* vm = Thread::get()->MyVM;
+
+ // Scan soft and weak reference queues.
+ vm->scanWeakReferencesQueue();
+ vm->scanSoftReferencesQueue();
+
+ // Scan finalization queue.
+ vm->scanFinalizationQueue();
+
+ // Now that the finalization queue has been scanned, scan the phantom queue.
+ vm->scanPhantomReferencesQueue();
/* finalize */
GCChunkNode finalizable;
@@ -92,7 +102,8 @@
allocator->reject_chunk(cur);
}
status = stat_alloc;
-
+
+ // Collection finished. Wake up the finalizers if they are waiting.
Thread::get()->MyVM->wakeUpFinalizers();
Modified: vmkit/trunk/lib/Mvm/Runtime/Object.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/Mvm/Runtime/Object.cpp?rev=70119&r1=70118&r2=70119&view=diff
==============================================================================
--- vmkit/trunk/lib/Mvm/Runtime/Object.cpp (original)
+++ vmkit/trunk/lib/Mvm/Runtime/Object.cpp Sun Apr 26 04:16:48 2009
@@ -218,3 +218,44 @@
FinalizationQueueLock.release();
}
+
+gc* ReferenceQueue::processReference(gc* reference, VirtualMachine* vm) {
+ if (!Collector::isLive(reference)) {
+ vm->clearReferent(reference);
+ return 0;
+ }
+
+ gc* referent = vm->getReferent(reference);
+
+ if (!referent) return 0;
+
+ if (semantics == SOFT) {
+ // TODO: are we are out of memory? Consider that we always are for now.
+ if (false) {
+ referent->markAndTrace();
+ }
+ } else if (semantics == PHANTOM) {
+ // Nothing to do.
+ }
+
+ if (Collector::isLive(referent)) {
+ return reference;
+ } else {
+ vm->clearReferent(reference);
+ vm->enqueueReference(reference);
+ return 0;
+ }
+}
+
+
+void ReferenceQueue::scan(VirtualMachine* vm) {
+ uint32 NewIndex = 0;
+
+ for (uint32 i = 0; i < CurrentIndex; ++i) {
+ gc* obj = References[i];
+ processReference(obj, vm);
+ }
+
+ CurrentIndex = NewIndex;
+
+}
More information about the vmkit-commits
mailing list