[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