[vmkit-commits] [vmkit] r68604 - in /vmkit/trunk: include/mvm/Allocator.h include/mvm/VirtualMachine.h lib/JnJVM/Classpath/ClasspathReflect.h lib/JnJVM/Compiler/JavaAOTCompiler.cpp lib/JnJVM/VMCore/JavaClass.cpp lib/JnJVM/VMCore/JavaInitialise.cpp lib/JnJVM/VMCore/JavaThread.h lib/JnJVM/VMCore/Jnjvm.cpp lib/JnJVM/VMCore/Jnjvm.h lib/JnJVM/VMCore/JnjvmClassLoader.cpp lib/JnJVM/VMCore/JnjvmClassLoader.h lib/JnJVM/VMCore/VirtualTables.cpp lib/Mvm/GCMmap2/gccollector.cpp lib/N3/VMCore/N3.cpp lib/N3/VMCore/VirtualTables.cpp
Nicolas Geoffray
nicolas.geoffray at lip6.fr
Wed Apr 8 04:07:08 PDT 2009
Author: geoffray
Date: Wed Apr 8 06:06:50 2009
New Revision: 68604
URL: http://llvm.org/viewvc/llvm-project?rev=68604&view=rev
Log:
Simplify core code in the presence of GC classes. The Jnjvm
class and the JnjvmClassloader class are now non-GC allocated.
Modified:
vmkit/trunk/include/mvm/Allocator.h
vmkit/trunk/include/mvm/VirtualMachine.h
vmkit/trunk/lib/JnJVM/Classpath/ClasspathReflect.h
vmkit/trunk/lib/JnJVM/Compiler/JavaAOTCompiler.cpp
vmkit/trunk/lib/JnJVM/VMCore/JavaClass.cpp
vmkit/trunk/lib/JnJVM/VMCore/JavaInitialise.cpp
vmkit/trunk/lib/JnJVM/VMCore/JavaThread.h
vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.cpp
vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.h
vmkit/trunk/lib/JnJVM/VMCore/JnjvmClassLoader.cpp
vmkit/trunk/lib/JnJVM/VMCore/JnjvmClassLoader.h
vmkit/trunk/lib/JnJVM/VMCore/VirtualTables.cpp
vmkit/trunk/lib/Mvm/GCMmap2/gccollector.cpp
vmkit/trunk/lib/N3/VMCore/N3.cpp
vmkit/trunk/lib/N3/VMCore/VirtualTables.cpp
Modified: vmkit/trunk/include/mvm/Allocator.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/include/mvm/Allocator.h?rev=68604&r1=68603&r2=68604&view=diff
==============================================================================
--- vmkit/trunk/include/mvm/Allocator.h (original)
+++ vmkit/trunk/include/mvm/Allocator.h Wed Apr 8 06:06:50 2009
@@ -64,13 +64,14 @@
class BumpPtrAllocator {
private:
- LockNormal TheLock;
+ SpinLock TheLock;
llvm::BumpPtrAllocator Allocator;
public:
void* Allocate(size_t sz) {
- TheLock.lock();
+ TheLock.acquire();
void* res = Allocator.Allocate(sz, sizeof(void*));
- TheLock.unlock();
+ TheLock.release();
+ memset(res, 0, sz);
return res;
}
Modified: vmkit/trunk/include/mvm/VirtualMachine.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/include/mvm/VirtualMachine.h?rev=68604&r1=68603&r2=68604&view=diff
==============================================================================
--- vmkit/trunk/include/mvm/VirtualMachine.h (original)
+++ vmkit/trunk/include/mvm/VirtualMachine.h Wed Apr 8 06:06:50 2009
@@ -33,7 +33,7 @@
/// VirtualMachine - This class is the root of virtual machine classes. It
/// defines what a VM should be.
///
-class VirtualMachine : public mvm::Object {
+class VirtualMachine : public mvm::PermanentObject {
protected:
VirtualMachine() {
@@ -48,7 +48,9 @@
#endif
}
public:
-
+
+ virtual void TRACER {}
+
/// runApplication - Run an application. The application name is in
/// the arguments, hence it is the virtual machine's job to parse them.
virtual void runApplication(int argc, char** argv) = 0;
Modified: vmkit/trunk/lib/JnJVM/Classpath/ClasspathReflect.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/Classpath/ClasspathReflect.h?rev=68604&r1=68603&r2=68604&view=diff
==============================================================================
--- vmkit/trunk/lib/JnJVM/Classpath/ClasspathReflect.h (original)
+++ vmkit/trunk/lib/JnJVM/Classpath/ClasspathReflect.h Wed Apr 8 06:06:50 2009
@@ -37,7 +37,10 @@
obj->pd->MARK_AND_TRACE;
obj->signers->MARK_AND_TRACE;
obj->constructor->MARK_AND_TRACE;
- if (obj->vmdata) obj->vmdata->classLoader->MARK_AND_TRACE;
+ if (obj->vmdata) {
+ JavaObject* Obj = obj->vmdata->classLoader->getJavaClassLoader();
+ if (Obj) Obj->MARK_AND_TRACE;
+ }
}
};
Modified: vmkit/trunk/lib/JnJVM/Compiler/JavaAOTCompiler.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/Compiler/JavaAOTCompiler.cpp?rev=68604&r1=68603&r2=68604&view=diff
==============================================================================
--- vmkit/trunk/lib/JnJVM/Compiler/JavaAOTCompiler.cpp (original)
+++ vmkit/trunk/lib/JnJVM/Compiler/JavaAOTCompiler.cpp Wed Apr 8 06:06:50 2009
@@ -1611,7 +1611,8 @@
void JavaAOTCompiler::compileFile(JnjvmClassLoader* JCL, const char* n) {
name = n;
- Jnjvm* vm = gc_new(Jnjvm)((JnjvmBootstrapLoader*)JCL);
+ mvm::BumpPtrAllocator A;
+ Jnjvm* vm = new(A) Jnjvm(A, (JnjvmBootstrapLoader*)JCL);
JavaThread* th = new JavaThread(0, 0, vm);
vm->setBootstrapThread(th);
th->start((void (*)(mvm::Thread*))mainCompilerStart);
Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaClass.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JavaClass.cpp?rev=68604&r1=68603&r2=68604&view=diff
==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JavaClass.cpp (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JavaClass.cpp Wed Apr 8 06:06:50 2009
@@ -739,16 +739,16 @@
void Class::readParents(Reader& reader) {
uint16 superEntry = reader.readU2();
- const UTF8* superUTF8 = superEntry ?
- ctpInfo->resolveClassName(superEntry) : 0;
+ // Use the depth field to store the super entry, to not touch super. The
+ // super field is used during GC scanning and must only be of one type.
+ depth = superEntry;
uint16 nbI = reader.readU2();
- // Use the super field to store the UTF8. since the field is never
- // used before actually loading the super, this is harmless.
- super = (Class*)superUTF8;
// Use the regular interface array to store the UTF8s. Since this array
// is never used before actually loading the interfaces, this is harmless.
+ // During GC scanning, the check is made on super. So the array of
+ // interfaces is not used if super is null.
interfaces = (Class**)
classLoader->allocator.Allocate(nbI * sizeof(Class*));
nbInterfaces = nbI;
@@ -758,7 +758,13 @@
}
void UserClass::loadParents() {
- const UTF8* superUTF8 = (const UTF8*)super;
+ const UTF8* superUTF8 = depth ? ctpInfo->resolveClassName(depth) : 0;
+ // W prevent the GC from scanning the interfaces until they
+ // are loaded. So we temporarly consider that this class does not
+ // have any interfaces. This is harmless because the class is being
+ // resolved and can not be used elsewhere for getting its interfaces.
+ uint32 realNbInterfaces = nbInterfaces;
+ nbInterfaces = 0;
if (superUTF8 == 0) {
depth = 0;
display = (CommonClass**)
@@ -774,10 +780,13 @@
display[depth] = this;
}
- for (unsigned i = 0; i < nbInterfaces; i++)
+ for (unsigned i = 0; i < realNbInterfaces; i++)
interfaces[i] =
((UserClass*)classLoader->loadName((const UTF8*)interfaces[i],
true, true));
+
+ // Interfaces are loaded, put the real number back in place.
+ nbInterfaces = realNbInterfaces;
}
Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaInitialise.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JavaInitialise.cpp?rev=68604&r1=68603&r2=68604&view=diff
==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JavaInitialise.cpp (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JavaInitialise.cpp Wed Apr 8 06:06:50 2009
@@ -11,8 +11,8 @@
#include "JavaArray.h"
#include "JavaObject.h"
-#include "JavaThread.h"
#include "Jnjvm.h"
+#include "JnjvmClassLoader.h"
#ifdef ISOLATE_SHARING
#include "SharedMaps.h"
@@ -32,11 +32,9 @@
X fake; \
X::VT = ((void**)(void*)(&fake))[0]; }
- INIT(JavaThread);
- INIT(Jnjvm);
- INIT(JnjvmBootstrapLoader);
- INIT(JnjvmClassLoader);
INIT(LockObj);
+ INIT(VMClassLoader);
+
#ifdef ISOLATE_SHARING
INIT(JnjvmSharedLoader);
INIT(SharedClassByteMap);
@@ -66,9 +64,11 @@
}
mvm::VirtualMachine* mvm::VirtualMachine::createJVM(JnjvClassLoader* JCL) {
+ mvm::BumpPtrAllocator* A = new mvm::BumpPtrAllocator();
+ mvm::BumpPtrAllocator* C = new mvm::BumpPtrAllocator();
JnjvmBootstraLoader* bootstrapLoader =
- gc_new(JnjvmBootstrapLoader)(JCL->getCompiler());
- Jnjvm* vm = gc_new(Jnjvm)(bootstrapLoader);
+ new(*C) JnjvmBootstrapLoader(*C, JCL->getCompiler());
+ Jnjvm* vm = new(*A) Jnjvm(*A, bootstrapLoader);
return vm;
}
#else
@@ -76,11 +76,13 @@
JnjvmClassLoader*
mvm::VirtualMachine::initialiseJVM(JavaCompiler* Comp, bool dlLoad) {
initialiseVT();
- return gc_new(JnjvmBootstrapLoader)(Comp, dlLoad);
+ mvm::BumpPtrAllocator* A = new mvm::BumpPtrAllocator();
+ return new(*A) JnjvmBootstrapLoader(*A, Comp, dlLoad);
}
mvm::VirtualMachine* mvm::VirtualMachine::createJVM(JnjvmClassLoader* C) {
- Jnjvm* vm = gc_new(Jnjvm)((JnjvmBootstrapLoader*)C);
+ mvm::BumpPtrAllocator* A = new mvm::BumpPtrAllocator();
+ Jnjvm* vm = new(*A) Jnjvm(*A, (JnjvmBootstrapLoader*)C);
return vm;
}
Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaThread.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JavaThread.h?rev=68604&r1=68603&r2=68604&view=diff
==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JavaThread.h (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JavaThread.h Wed Apr 8 06:06:50 2009
@@ -56,11 +56,6 @@
public:
- /// VT - The virtual table of JavaThread objects, so that we know
- /// if a thread is a JavaThread.
- ///
- static VirtualTable *VT;
-
/// jniEnv - The JNI environment of the thread.
///
void* jniEnv;
@@ -268,12 +263,6 @@
uint32_t eipIndex;
#endif
- /// isJavaThread - Is the given thread a Java thread?
- ///
- static bool isJavaThread(mvm::Thread* th) {
- return ((void**)th)[0] == VT;
- }
-
};
} // end namespace jnjvm
Modified: vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.cpp?rev=68604&r1=68603&r2=68604&view=diff
==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.cpp (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.cpp Wed Apr 8 06:06:50 2009
@@ -1002,15 +1002,13 @@
static void serviceCPUMonitor(mvm::Thread* th) {
while (true) {
sleep(1);
- for(mvm::Thread* cur = (mvm::Thread*)th->next(); cur != th;
- cur = (mvm::Thread*)cur->next()) {
- if (JavaThread::isJavaThread(cur)) {
+ for(JavaThread* cur = (Java*)th->next(); cur != th;
+ cur = (JavaThread*)cur->next()) {
JavaThread* th = (JavaThread*)cur;
if (!(th->StateWaiting)) {
mvm::VirtualMachine* executingVM = cur->MyVM;
assert(executingVM && "Thread with no VM!");
++executingVM->executionTime;
- }
}
}
}
@@ -1047,7 +1045,8 @@
}
}
-Jnjvm::Jnjvm(JnjvmBootstrapLoader* loader) : VirtualMachine() {
+Jnjvm::Jnjvm(mvm::BumpPtrAllocator& Alloc, JnjvmBootstrapLoader* loader) :
+ VirtualMachine(), allocator(Alloc) {
classpath = getenv("CLASSPATH");
if (!classpath) classpath = ".";
Modified: vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.h?rev=68604&r1=68603&r2=68604&view=diff
==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.h (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.h Wed Apr 8 06:06:50 2009
@@ -105,7 +105,7 @@
public:
/// allocator - Memory allocator of this JVM.
///
- mvm::BumpPtrAllocator allocator;
+ mvm::BumpPtrAllocator& allocator;
/// throwable - The java/lang/Throwable class. In an isolate
/// environment, generated code references this field.
@@ -170,10 +170,6 @@
public:
- /// VT - The virtual table of this class.
- ///
- static VirtualTable* VT;
-
/// print - Prints the JVM for debugging purposes.
///
virtual void print(mvm::PrintBuffer* buf) const;
@@ -312,14 +308,6 @@
///
~Jnjvm();
- /// Jnjvm - Allocate a default JVM, for VT initialization.
- ///
- Jnjvm() {
-#ifdef ISOLATE
- IsolateID = 0;
-#endif
- }
-
/// addProperty - Adds a new property in the postProperties map.
///
void addProperty(char* key, char* value);
@@ -332,7 +320,7 @@
/// Jnjvm - Allocates a new JVM.
///
- Jnjvm(JnjvmBootstrapLoader* loader);
+ Jnjvm(mvm::BumpPtrAllocator& Alloc, JnjvmBootstrapLoader* loader);
/// runApplication - Runs the application with the given command line.
/// User-visible function, inherited by the VirtualMachine class.
Modified: vmkit/trunk/lib/JnJVM/VMCore/JnjvmClassLoader.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JnjvmClassLoader.cpp?rev=68604&r1=68603&r2=68604&view=diff
==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JnjvmClassLoader.cpp (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JnjvmClassLoader.cpp Wed Apr 8 06:06:50 2009
@@ -63,7 +63,10 @@
typedef void (*static_init_t)(JnjvmClassLoader*);
-JnjvmBootstrapLoader::JnjvmBootstrapLoader(JavaCompiler* Comp, bool dlLoad) {
+JnjvmBootstrapLoader::JnjvmBootstrapLoader(mvm::BumpPtrAllocator& Alloc,
+ JavaCompiler* Comp,
+ bool dlLoad) :
+ JnjvmClassLoader(Alloc) {
hashUTF8 = new(allocator) UTF8Map(allocator, 0);
classes = new(allocator) ClassMap();
@@ -277,8 +280,9 @@
}
-JnjvmClassLoader::JnjvmClassLoader(JnjvmClassLoader& JCL, JavaObject* loader,
- Jnjvm* I) {
+JnjvmClassLoader::JnjvmClassLoader(mvm::BumpPtrAllocator& Alloc,
+ JnjvmClassLoader& JCL, JavaObject* loader,
+ Jnjvm* I) : allocator(Alloc) {
bootstrapLoader = JCL.bootstrapLoader;
TheCompiler = bootstrapLoader->getCompiler()->Create("Applicative loader");
@@ -300,7 +304,7 @@
/// If the appClassLoader is already set in the isolate, then we need
/// a new one each time a class loader is allocated.
if (isolate->appClassLoader) {
- isolate = gc_new(Jnjvm)(bootstrapLoader);
+ isolate = new Jnjvm(allocator, bootstrapLoader);
isolate->memoryLimit = 4000000;
isolate->threadLimit = 10;
isolate->parent = I->parent;
@@ -776,14 +780,25 @@
if (loader == 0)
return vm->bootstrapLoader;
-
+
+ JnjvmClassLoader* JCL = 0;
Classpath* upcalls = vm->bootstrapLoader->upcalls;
- JnjvmClassLoader* JCL =
- (JnjvmClassLoader*)(upcalls->vmdataClassLoader->getObjectField(loader));
+ VMClassLoader* vmdata =
+ (VMClassLoader*)(upcalls->vmdataClassLoader->getObjectField(loader));
- if (!JCL) {
- JCL = gc_new(JnjvmClassLoader)(*vm->bootstrapLoader, loader, vm);
- (upcalls->vmdataClassLoader->setObjectField(loader, (JavaObject*)JCL));
+ if (!vmdata) {
+ loader->acquire();
+ vmdata =
+ (VMClassLoader*)(upcalls->vmdataClassLoader->getObjectField(loader));
+ if (!vmdata) {
+ mvm::BumpPtrAllocator* A = new mvm::BumpPtrAllocator();
+ JCL = new(*A) JnjvmClassLoader(*A, *vm->bootstrapLoader, loader, vm);
+ vmdata = gc_new(VMClassLoader)(JCL);
+ (upcalls->vmdataClassLoader->setObjectField(loader, (JavaObject*)vmdata));
+ }
+ loader->release();
+ } else {
+ JCL = vmdata->getClassLoader();
}
return JCL;
@@ -823,7 +838,13 @@
allocator.Deallocate(javaSignatures);
}
+ for (std::vector<void*>::iterator i = nativeLibs.begin();
+ i < nativeLibs.end(); ++i) {
+ dlclose(*i);
+ }
+
delete TheCompiler;
+ delete &allocator;
}
Modified: vmkit/trunk/lib/JnJVM/VMCore/JnjvmClassLoader.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JnjvmClassLoader.h?rev=68604&r1=68603&r2=68604&view=diff
==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JnjvmClassLoader.h (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JnjvmClassLoader.h Wed Apr 8 06:06:50 2009
@@ -17,9 +17,7 @@
#include "types.h"
#include "mvm/Allocator.h"
-#include "mvm/CompilationUnit.h"
#include "mvm/Object.h"
-#include "mvm/PrintBuffer.h"
#include "JnjvmConfig.h"
@@ -45,11 +43,12 @@
class UTF8Map;
class ZipArchive;
+
/// JnjvmClassLoader - Runtime representation of a class loader. It contains
/// its own tables (signatures, UTF8, types) which are mapped to a single
/// table for non-isolate environments.
///
-class JnjvmClassLoader : public mvm::Object {
+class JnjvmClassLoader : public mvm::PermanentObject {
private:
/// isolate - Which isolate defined me? Null for the bootstrap class loader.
@@ -73,10 +72,13 @@
/// JnjvmClassLoader - Allocate a user-defined class loader. Called on
/// first use of a Java class loader.
///
- JnjvmClassLoader(JnjvmClassLoader& JCL, JavaObject* loader, Jnjvm* isolate);
+ JnjvmClassLoader(mvm::BumpPtrAllocator& Alloc, JnjvmClassLoader& JCL,
+ JavaObject* loader, Jnjvm* isolate);
protected:
+ JnjvmClassLoader(mvm::BumpPtrAllocator& Alloc) : allocator(Alloc) {}
+
/// TheCompiler - The Java compiler for this class loader.
///
JavaCompiler* TheCompiler;
@@ -95,14 +97,10 @@
public:
- /// VT - The virtual table of this class.
- ///
- static VirtualTable* VT;
-
/// allocator - Reference to the memory allocator, which will allocate UTF8s,
/// signatures and types.
///
- mvm::BumpPtrAllocator allocator;
+ mvm::BumpPtrAllocator& allocator;
/// getIsolate - Returns the isolate that created this class loader.
///
@@ -128,12 +126,6 @@
///
virtual void TRACER;
- /// print - String representation of the loader for debugging purposes.
- ///
- virtual void print(mvm::PrintBuffer* buf) const {
- buf->write("Java class loader<>");
- }
-
/// getJnjvmLoaderFromJavaObject - Return the Jnjvm runtime representation
/// of the given class loader.
///
@@ -212,17 +204,6 @@
///
~JnjvmClassLoader();
- /// JnjvmClassLoader - Default constructor, zeroes the field.
- ///
- JnjvmClassLoader() {
- hashUTF8 = 0;
- javaTypes = 0;
- javaSignatures = 0;
- TheCompiler = 0;
- isolate = 0;
- classes = 0;
- }
-
/// loadClass - The user class that defines the loadClass method.
///
UserClass* loadClass;
@@ -313,20 +294,10 @@
public:
- /// VT - The virtual table of this class.
- ///
- static VirtualTable* VT;
-
/// tracer - Traces instances of this class.
///
virtual void TRACER;
- /// print - String representation of the loader, for debugging purposes.
- ///
- virtual void print(mvm::PrintBuffer* buf) const {
- buf->write("Jnjvm bootstrap loader<>");
- }
-
/// libClasspathEnv - The paths for dynamic libraries of Classpath, separated
/// by ':'.
///
@@ -344,8 +315,8 @@
/// to do before any execution of a JVM. Also try to load libvmjc.so
/// if dlLoad is not false.
///
- JnjvmBootstrapLoader(JavaCompiler* Comp, bool dlLoad = true);
- JnjvmBootstrapLoader() {}
+ JnjvmBootstrapLoader(mvm::BumpPtrAllocator& Alloc, JavaCompiler* Comp,
+ bool dlLoad = true);
virtual JavaString* UTF8ToStr(const UTF8* utf8);
@@ -418,6 +389,48 @@
~JnjvmBootstrapLoader();
};
+/// VMClassLoader - The vmdata object that will be placed in and will only
+/// be referenced by the java.lang.Classloader Java object. Having a
+/// separate class between VMClassLoader and JnjvmClassLoader allows to
+/// have a JnjvmClassLoader non-GC object. Also the finalizer of this class
+/// will delete the internal class loader and we do not have to implement
+/// hacks in the java.lang.Classloader finalizer.
+class VMClassLoader : public mvm::Object {
+private:
+
+ /// JCL - The internal class loader.
+ ///
+ JnjvmClassLoader* JCL;
+
+public:
+
+ /// VT - The VirtualTable for this GC-class.
+ static VirtualTable* VT;
+
+ /// TRACER - Trace the internal class loader.
+ virtual void TRACER {
+ JCL->CALL_TRACER;
+ }
+
+ /// ~VMClassLoader - Delete the internal class loader.
+ ///
+ ~VMClassLoader() {
+ if (JCL) JCL->~JnjvmClassLoader();
+ }
+
+ /// VMClassLoader - Default constructors.
+ ///
+ VMClassLoader(JnjvmClassLoader* J) : JCL(J) {}
+ VMClassLoader() : JCL(0) {}
+
+ /// getClassLoader - Get the internal class loader.
+ ///
+ JnjvmClassLoader* getClassLoader() {
+ return JCL;
+ }
+
+};
+
} // end namespace jnjvm
#endif // JNJVM_CLASSLOADER_H
Modified: vmkit/trunk/lib/JnJVM/VMCore/VirtualTables.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/VirtualTables.cpp?rev=68604&r1=68603&r2=68604&view=diff
==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/VirtualTables.cpp (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/VirtualTables.cpp Wed Apr 8 06:06:50 2009
@@ -1,11 +1,24 @@
//===--- VirtualTables.cpp - Virtual methods for JnJVM objects ------------===//
//
-// JnJVM
+// The VMKit project
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
+//
+// This file contains GC specific tracing functions. It is used by the
+// GCMmap2 garbage collector and may be of use for other GCs. Boehm GC does
+// not use these functions.
+//
+// The file is divided into four parts:
+// (1) Declaration of internal GC classes.
+// (2) Tracing roots of objects: regular object, native array, object array.
+// (3) Tracing a class loader, which involves tracing the Java objects
+// referenced by classes.
+// (4) Tracing the roots of a program: the JVM and the threads.
+//
+//===----------------------------------------------------------------------===//
#include "mvm/Object.h"
@@ -21,68 +34,126 @@
using namespace jnjvm;
+//===----------------------------------------------------------------------===//
+// List of classes that will be GC-allocated. One should try to keep this
+// list as minimal as possible, and a GC class must be defined only if
+// absolutely necessary. If there is an easy way to avoid it, do it! Only
+// Java classes should be GC classes.
+// Having many GC classes gives more work to the GC for the scanning phase
+// and for the relocation phase (for copying collectors.
+//
+// In JnJVM, we identified two cases where we really need to declare GC
+// classes: the fat lock object and the class loader.
+//
+// For the fat lock there are many design decisions that we could make to
+// make it a non-GC class. We leave this as a TODO.
+//
+// For the class loader, we decided that this was the best solution because
+// otherwise it would involve hacks on the java.lang.Classloader class.
+// Therefore, we create a new GC class with a finalize method that will
+// delete the internal class loader when the Java object class loader is
+// not reachable anymore. This also relies on the java.lang.Classloader class
+// referencing an object of type VMClassLoader (this is the case in GNU
+// Classpath with the vmdata field).
+//===----------------------------------------------------------------------===//
+
#define INIT(X) VirtualTable* X::VT = 0
- INIT(JavaThread);
- INIT(Jnjvm);
- INIT(JnjvmBootstrapLoader);
- INIT(JnjvmClassLoader);
INIT(LockObj);
+ INIT(VMClassLoader);
#undef INIT
-void ArrayObject::TRACER {
- if (getClass()) getClass()->classLoader->MARK_AND_TRACE;
+//===----------------------------------------------------------------------===//
+// Root trace methods for Java objects. There are three types of roots:
+// (1) Object whose class is not an array: needs to trace the classloader and
+// the lock.
+// (2) Object whose class is an array of objects: needs to trace root (1) and
+// all elements in the array.
+// (3) Object whose class is a native array: only needs to trace the lock. The
+// classloader is the bootstrap loader and is traced by the JVM.
+//===----------------------------------------------------------------------===//
+
+
+/// Method for scanning the root of an object. This method is called by all
+/// JavObjects except native Java arrays.
+void JavaObject::tracer() {
+ if (getClass()) getClass()->classLoader->getJavaClassLoader()->markAndTrace();
+ LockObj* l = lockObj();
+ if (l) l->markAndTrace();
+}
+
+extern "C" void JavaObjectTracer(JavaObject* obj) {
+ obj->JavaObject::tracer();
+}
+
+/// Method for scanning an array whose elements are JavaObjects. This method is
+/// called by all non-native Java arrays.
+void ArrayObject::tracer() {
+ JavaObject::tracer();
for (sint32 i = 0; i < size; i++) {
if (elements[i]) elements[i]->MARK_AND_TRACE;
- }
- LockObj* l = lockObj();
- if (l) l->MARK_AND_TRACE;
+ }
}
-#ifdef MULTIPLE_GC
-extern "C" void ArrayObjectTracer(ArrayObject* obj, Collector* GC) {
-#else
extern "C" void ArrayObjectTracer(ArrayObject* obj) {
-#endif
- obj->CALL_TRACER;
+ obj->ArrayObject::tracer();
+}
+
+/// Method for scanning a native array. Only scan the lock. The classloader of
+/// the class is the bootstrap loader and therefore does not need to be
+/// scanned here.
+void JavaArray::tracer() {
+ LockObj* l = lockObj();
+ if (l) l->markAndTrace();
}
-#ifdef MULTIPLE_GC
-extern "C" void JavaArrayTracer(JavaArray* obj, Collector* GC) {
-#else
extern "C" void JavaArrayTracer(JavaArray* obj) {
-#endif
- LockObj* l = obj->lockObj();
- if (l) l->MARK_AND_TRACE;
+ obj->JavaArray::tracer();
}
-void JavaArray::TRACER {}
-#define TRACE_VECTOR(type,alloc,name) { \
- for (std::vector<type, alloc<type> >::iterator i = name.begin(), \
- e = name.end(); i!= e; ++i) { \
- (*i)->MARK_AND_TRACE; }}
+//===----------------------------------------------------------------------===//
+// Support for scanning Java objects referenced by classes. All classes must
+// trace:
+// (1) The classloader of the parents (super and interfaces) as well as its
+// own class loader.
+// (2) The delegatee object (java.lang.Class) if it exists.
+//
+// Additionaly, non-primitive and non-array classes mus trace:
+// (3) The bytes that represent the class file.
+// (4) The static instance.
+// (5) The class loaders referenced indirectly in the class file (TODO).
+//===----------------------------------------------------------------------===//
+
-void CommonClass::TRACER {
- if (super) super->classLoader->MARK_AND_TRACE;
- for (uint32 i = 0; i < nbInterfaces; ++i) {
- interfaces[i]->classLoader->MARK_AND_TRACE;
+void CommonClass::tracer() {
+
+ if (super && super->classLoader) {
+ JavaObject* Obj = super->classLoader->getJavaClassLoader();
+ if (Obj) Obj->markAndTrace();
+
+ for (uint32 i = 0; i < nbInterfaces; ++i) {
+ if (interfaces[i]->classLoader)
+ interfaces[i]->classLoader->getJavaClassLoader()->markAndTrace();
+ }
}
- classLoader->MARK_AND_TRACE;
+
+ if (classLoader)
+ classLoader->getJavaClassLoader()->markAndTrace();
+
for (uint32 i = 0; i < NR_ISOLATES; ++i) {
// If the delegatee was static allocated, we want to trace its fields.
if (delegatee[i]) {
- delegatee[i]->CALL_TRACER;
- delegatee[i]->MARK_AND_TRACE;
+ delegatee[i]->tracer();
+ delegatee[i]->markAndTrace();
}
}
-
}
-void Class::TRACER {
- CommonClass::CALL_TRACER;
- bytes->MARK_AND_TRACE;
+void Class::tracer() {
+ CommonClass::tracer();
+ bytes->markAndTrace();
for (uint32 i =0; i < NR_ISOLATES; ++i) {
TaskClassMirror &M = IsolateInfo[i];
@@ -92,88 +163,47 @@
}
}
-void JavaObject::TRACER {
- if (getClass()) getClass()->classLoader->MARK_AND_TRACE;
- LockObj* l = lockObj();
- if (l) l->MARK_AND_TRACE;
-}
-
-#ifdef MULTIPLE_GC
-extern "C" void JavaObjectTracer(JavaObject* obj, Collector* GC) {
-#else
-extern "C" void JavaObjectTracer(JavaObject* obj) {
-#endif
- if (obj->getClass()) obj->getClass()->classLoader->MARK_AND_TRACE;
- LockObj* l = obj->lockObj();
- if (l) l->MARK_AND_TRACE;
-}
+//===----------------------------------------------------------------------===//
+// Support for scanning a classloader. A classloader must trace:
+// (1) All the classes it has loaded.
+// (2) All the strings referenced in class files.
+//
+// The class loader does not need to trace its java.lang.Classloader Java object
+// because if we end up here, this means that the Java object is already being
+// scanned. Only the Java object traces the class loader.
+//
+// Additionaly, the bootstrap loader must trace:
+// (3) The delegatees of native array classes. Since these classes are not in
+// the class map and they are not GC-allocated, we must trace the objects
+// referenced by the delegatees.
+//===----------------------------------------------------------------------===//
-static void traceClassMap(ClassMap* classes) {
+void JnjvmClassLoader::tracer() {
+
for (ClassMap::iterator i = classes->map.begin(), e = classes->map.end();
i!= e; ++i) {
CommonClass* cl = i->second;
- if (cl->isClass()) cl->asClass()->CALL_TRACER;
- else cl->CALL_TRACER;
+ if (cl->isClass()) cl->asClass()->tracer();
+ else cl->tracer();
}
-}
-
-void JavaThread::TRACER {
- javaThread->MARK_AND_TRACE;
- if (pendingException) pendingException->MARK_AND_TRACE;
-#ifdef SERVICE
- ServiceException->MARK_AND_TRACE;
-#endif
-}
-
-void Jnjvm::TRACER {
- appClassLoader->MARK_AND_TRACE;
- TRACE_VECTOR(JavaObject*, gc_allocator, globalRefs);
- bootstrapLoader->MARK_AND_TRACE;
-#if defined(ISOLATE_SHARING)
- JnjvmSharedLoader::sharedLoader->MARK_AND_TRACE;
-#endif
- mvm::Thread* th = th->get();
- th->CALL_TRACER;
- for (mvm::Thread* cur = (mvm::Thread*)th->next(); cur != th;
- cur = (mvm::Thread*)cur->next()) {
- cur->CALL_TRACER;
- }
-
-#ifdef SERVICE
- parent->MARK_AND_TRACE;
-#endif
-}
-
-void JnjvmClassLoader::TRACER {
- javaLoader->MARK_AND_TRACE;
- traceClassMap(classes);
- isolate->MARK_AND_TRACE;
for (std::vector<JavaString*,
gc_allocator<JavaString*> >::iterator i = strings.begin(),
e = strings.end(); i!= e; ++i) {
- (*i)->MARK_AND_TRACE;
+ (*i)->markAndTrace();
// If the string was static allocated, we want to trace its lock.
LockObj* l = (*i)->lockObj();
- if (l) l->MARK_AND_TRACE;
+ if (l) l->markAndTrace();
}
+
}
-void JnjvmBootstrapLoader::TRACER {
-
- traceClassMap(classes);
-
- for (std::vector<JavaString*, gc_allocator<JavaString*> >::iterator i =
- bootstrapLoader->strings.begin(),
- e = bootstrapLoader->strings.end(); i!= e; ++i) {
- (*i)->MARK_AND_TRACE;
- // If the string was static allocated, we want to trace its lock.
- LockObj* l = (*i)->lockObj();
- if (l) l->MARK_AND_TRACE;
- }
+void JnjvmBootstrapLoader::tracer() {
+
+ JnjvmClassLoader::tracer();
#define TRACE_DELEGATEE(prim) \
- prim->CALL_TRACER;
+ prim->tracer();
TRACE_DELEGATEE(upcalls->OfVoid);
TRACE_DELEGATEE(upcalls->OfBool);
@@ -186,3 +216,44 @@
TRACE_DELEGATEE(upcalls->OfDouble);
#undef TRACE_DELEGATEE
}
+
+//===----------------------------------------------------------------------===//
+// Support for scanning the roots of a program: JVM and threads. The JVM
+// must trace:
+// (1) The bootstrap class loader: where core classes live.
+// (2) The applicative class loader: the JVM may be the ony one referencing it.
+// (3) Global references from JNI.
+//
+// The threads must trace:
+// (1) Their stack (already done by the GC in the case of GCMmap2 or Boehm)
+// (2) Their pending exception if there is one.
+// (3) The java.lang.Thread delegate.
+//===----------------------------------------------------------------------===//
+
+
+void Jnjvm::tracer() {
+ bootstrapLoader->tracer();
+
+ appClassLoader->getJavaClassLoader()->markAndTrace();
+
+ for (std::vector<JavaObject*, gc_allocator<JavaObject*> >::iterator
+ i = globalRefs.begin(), e = globalRefs.end(); i!= e; ++i) {
+ (*i)->markAndTrace();
+ }
+
+#if defined(ISOLATE_SHARING)
+ JnjvmSharedLoader::sharedLoader->markAndTrace();
+#endif
+
+#ifdef SERVICE
+ parent->tracer();
+#endif
+}
+
+void JavaThread::tracer() {
+ if (pendingException) pendingException->markAndTrace();
+ javaThread->markAndTrace();
+#ifdef SERVICE
+ ServiceException->markAndTrace();
+#endif
+}
Modified: vmkit/trunk/lib/Mvm/GCMmap2/gccollector.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/Mvm/GCMmap2/gccollector.cpp?rev=68604&r1=68603&r2=68604&view=diff
==============================================================================
--- vmkit/trunk/lib/Mvm/GCMmap2/gccollector.cpp (original)
+++ vmkit/trunk/lib/Mvm/GCMmap2/gccollector.cpp Wed Apr 8 06:06:50 2009
@@ -56,13 +56,16 @@
mvm::Thread* th = th->get();
mvm::Thread* tcur = th;
- // First, trace threads.
+ // First, trace the VM.
+ th->MyVM->tracer();
+
+ // Second, trace the threads.
do {
th->tracer();
tcur = (mvm::Thread*)tcur->next();
} while (tcur != th);
- // Then trace stack objects.
+ // Third, trace stack objects.
for(cur=used_nodes->next(); cur!=used_nodes; cur=cur->next())
trace(cur);
Modified: vmkit/trunk/lib/N3/VMCore/N3.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/N3/VMCore/N3.cpp?rev=68604&r1=68603&r2=68604&view=diff
==============================================================================
--- vmkit/trunk/lib/N3/VMCore/N3.cpp (original)
+++ vmkit/trunk/lib/N3/VMCore/N3.cpp Wed Apr 8 06:06:50 2009
@@ -58,7 +58,8 @@
}
N3* N3::allocateBootstrap() {
- N3 *vm= gc_new(N3)();
+ mvm::BumpPtrAllocator * A = new mvm::BumpPtrAllocator();
+ N3 *vm= new(*A) N3();
std::string str =
mvm::MvmModule::executionEngine->getTargetData()->getStringRepresentation();
@@ -82,7 +83,8 @@
N3* N3::allocate(const char* name, N3* parent) {
- N3 *vm= gc_new(N3)();
+ mvm::BumpPtrAllocator * A = new mvm::BumpPtrAllocator();
+ N3 *vm= new(*A) N3();
std::string str =
mvm::MvmModule::executionEngine->getTargetData()->getStringRepresentation();
Modified: vmkit/trunk/lib/N3/VMCore/VirtualTables.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/N3/VMCore/VirtualTables.cpp?rev=68604&r1=68603&r2=68604&view=diff
==============================================================================
--- vmkit/trunk/lib/N3/VMCore/VirtualTables.cpp (original)
+++ vmkit/trunk/lib/N3/VMCore/VirtualTables.cpp Wed Apr 8 06:06:50 2009
@@ -156,7 +156,7 @@
TRACE_VECTOR(VMField*, staticFields, std::allocator);
delegatee->MARK_AND_TRACE;
TRACE_VECTOR(VMCommonClass*, display, std::allocator);
- vm->MARK_AND_TRACE;
+ vm->CALL_TRACER;
assembly->MARK_AND_TRACE;
//funcs->MARK_AND_TRACE;
@@ -227,7 +227,7 @@
void VMThread::TRACER {
vmThread->MARK_AND_TRACE;
- vm->MARK_AND_TRACE;
+ vm->CALL_TRACER;
//lock->MARK_AND_TRACE;
//varcond->MARK_AND_TRACE;
pendingException->MARK_AND_TRACE;
@@ -270,7 +270,7 @@
rsrcSection->MARK_AND_TRACE;
relocSection->MARK_AND_TRACE;
CLIHeader->MARK_AND_TRACE;
- vm->MARK_AND_TRACE;
+ vm->CALL_TRACER;
delegatee->MARK_AND_TRACE;
// TODO trace assembly refs...
}
More information about the vmkit-commits
mailing list