[vmkit-commits] [vmkit] r69443 - in /vmkit/trunk/lib/JnJVM: Compiler/JITInfo.cpp Compiler/JavaAOTCompiler.cpp Compiler/JnjvmModule.cpp VMCore/JavaClass.cpp VMCore/JavaClass.h VMCore/LockedMap.h

Nicolas Geoffray nicolas.geoffray at lip6.fr
Sat Apr 18 06:08:26 PDT 2009


Author: geoffray
Date: Sat Apr 18 08:07:59 2009
New Revision: 69443

URL: http://llvm.org/viewvc/llvm-project?rev=69443&view=rev
Log:
Implement the algorithm from Click et al.'s paper: 
"Fast Subtype Checking in the HotSpot JVM" (JGI'02).

This improves over the current situation in cases of
array and interface subchecking.


Modified:
    vmkit/trunk/lib/JnJVM/Compiler/JITInfo.cpp
    vmkit/trunk/lib/JnJVM/Compiler/JavaAOTCompiler.cpp
    vmkit/trunk/lib/JnJVM/Compiler/JnjvmModule.cpp
    vmkit/trunk/lib/JnJVM/VMCore/JavaClass.cpp
    vmkit/trunk/lib/JnJVM/VMCore/JavaClass.h
    vmkit/trunk/lib/JnJVM/VMCore/LockedMap.h

Modified: vmkit/trunk/lib/JnJVM/Compiler/JITInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/Compiler/JITInfo.cpp?rev=69443&r1=69442&r2=69443&view=diff

==============================================================================
--- vmkit/trunk/lib/JnJVM/Compiler/JITInfo.cpp (original)
+++ vmkit/trunk/lib/JnJVM/Compiler/JITInfo.cpp Sat Apr 18 08:07:59 2009
@@ -72,10 +72,10 @@
     uint64 size = JnjvmModule::getTypeSize(structType);
     classDef->virtualSize = (uint32)size;
     virtualSizeConstant = ConstantInt::get(Type::Int32Ty, size);
-    
+   
     if (!Mod->isStaticCompiling()) {
       if (!classDef->virtualVT) {
-        Mod->makeVT((Class*)classDef);
+        Mod->makeVT(classDef);
       } else {
 #ifdef WITH_TRACER
         // So the class is vmjc'ed. Create the virtual tracer.
@@ -84,8 +84,8 @@
                                           "markAndTraceObject",
                                           Mod->getLLVMModule());
        
-        void* ptr = ((void**)classDef->virtualVT)[VT_TRACER_OFFSET];
-        JnjvmModule::executionEngine->addGlobalMapping(func, ptr);
+        uintptr_t ptr = classDef->virtualVT->tracer;
+        JnjvmModule::executionEngine->addGlobalMapping(func, (void*)ptr);
         virtualTracerFunction = func;
 #endif
       }

Modified: vmkit/trunk/lib/JnJVM/Compiler/JavaAOTCompiler.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/Compiler/JavaAOTCompiler.cpp?rev=69443&r1=69442&r2=69443&view=diff

==============================================================================
--- vmkit/trunk/lib/JnJVM/Compiler/JavaAOTCompiler.cpp (original)
+++ vmkit/trunk/lib/JnJVM/Compiler/JavaAOTCompiler.cpp Sat Apr 18 08:07:59 2009
@@ -1196,13 +1196,35 @@
   Elemts.push_back(ConstantExpr::getIntToPtr(
         ConstantInt::get(Type::Int64Ty, VT->depth), PTy));
   
+  // offset
+  Elemts.push_back(ConstantExpr::getIntToPtr(
+        ConstantInt::get(Type::Int64Ty, VT->offset), PTy));
+  
+  // cache
+  Elemts.push_back(ConstantExpr::getIntToPtr(
+        ConstantInt::get(Type::Int64Ty, VT->cache), PTy));
+  
   // display
+  for (uint32 i = 0; i < JavaVirtualTable::getDisplayLength(); ++i) {
+    if (VT->display[i]) {
+      Constant* Temp = getVirtualTable(VT->display[i]);
+      Temp = ConstantExpr::getBitCast(Temp, PTy);
+      Elemts.push_back(Temp);
+    } else
+      Elemts.push_back(Constant::getNullValue(PTy));
+  }
+  
+  // nbSecondaryTypes
+  Elemts.push_back(ConstantExpr::getIntToPtr(
+        ConstantInt::get(Type::Int64Ty, VT->nbSecondaryTypes), PTy));
+  
+  // secondaryTypes
   const ArrayType* DTy = ArrayType::get(JnjvmModule::VTType,
-                                        VT->depth + 1);
+                                        VT->nbSecondaryTypes);
   
   std::vector<Constant*> TempElmts;
-  for (uint32 i = 0; i <= VT->depth; ++i) {
-    Constant* Cl = getVirtualTable(VT->display[i]);
+  for (uint32 i = 0; i < VT->nbSecondaryTypes; ++i) {
+    Constant* Cl = getVirtualTable(VT->secondaryTypes[i]);
     TempElmts.push_back(Cl);
   }
   Constant* display = ConstantArray::get(DTy, TempElmts);
@@ -1439,6 +1461,7 @@
     JavaMethod& meth = cl->virtualMethods[i];
     ((void**)VT)[meth.offset] = &meth;
   }
+  if (!cl->super) VT->destructor = 0;
 }
 
 void JavaAOTCompiler::setMethod(JavaMethod* meth, void* ptr, const char* name) {

Modified: vmkit/trunk/lib/JnJVM/Compiler/JnjvmModule.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/Compiler/JnjvmModule.cpp?rev=69443&r1=69442&r2=69443&view=diff

==============================================================================
--- vmkit/trunk/lib/JnJVM/Compiler/JnjvmModule.cpp (original)
+++ vmkit/trunk/lib/JnJVM/Compiler/JnjvmModule.cpp Sat Apr 18 08:07:59 2009
@@ -475,14 +475,16 @@
   if (func->hasNotBeenReadFromBitcode()) {
     // We are jitting. Take the lock.
     JnjvmModule::protectIR();
-    JavaJIT jit(this, meth, func);
-    if (isNative(meth->access)) {
-      jit.nativeCompile();
-      JnjvmModule::runPasses(func, JavaNativeFunctionPasses);
-    } else {
-      jit.javaCompile();
-      JnjvmModule::runPasses(func, JnjvmModule::globalFunctionPasses);
-      JnjvmModule::runPasses(func, JavaFunctionPasses);
+    if (func->hasNotBeenReadFromBitcode()) {
+      JavaJIT jit(this, meth, func);
+      if (isNative(meth->access)) {
+        jit.nativeCompile();
+        JnjvmModule::runPasses(func, JavaNativeFunctionPasses);
+      } else {
+        jit.javaCompile();
+        JnjvmModule::runPasses(func, JnjvmModule::globalFunctionPasses);
+        JnjvmModule::runPasses(func, JavaFunctionPasses);
+      }
     }
     JnjvmModule::unprotectIR();
   }

Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaClass.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JavaClass.cpp?rev=69443&r1=69442&r2=69443&view=diff

==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JavaClass.cpp (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JavaClass.cpp Sat Apr 18 08:07:59 2009
@@ -347,15 +347,12 @@
       th->throwException(th->ServiceException);
     }
 #endif
-    classDef->acquire();
-    if (code == 0) {
-      code = classDef->classLoader->getCompiler()->materializeFunction(this);
-      Jnjvm* vm = JavaThread::get()->getJVM();
-      vm->addMethodInFunctionMap(this, code);
-    }
-    classDef->release();
-    return code;
+    code = classDef->classLoader->getCompiler()->materializeFunction(this);
+    Jnjvm* vm = JavaThread::get()->getJVM();
+    vm->addMethodInFunctionMap(this, code);
   }
+  
+  return code;
 }
 
 void JavaMethod::setCompiledPtr(void* ptr, const char* name) {
@@ -1240,42 +1237,47 @@
   return false;
 }
 
-
 void ClassArray::initialiseVT(Class* javaLangObject) {
 
   ClassArray::SuperArray = javaLangObject;
   JnjvmClassLoader* JCL = javaLangObject->classLoader;
+  Classpath* upcalls = JCL->bootstrapLoader->upcalls;
+  
+  assert(javaLangObject->virtualVT->init && 
+         "Initializing array VT before JavaObjectVT");
   
-  // Initialize interfaces of array classes.
+  // Load and resolve interfaces of array classes. We resolve them now
+  // so that the secondary type list of array VTs can reference them.
   ClassArray::InterfacesArray[0] = 
     JCL->loadName(JCL->asciizConstructUTF8("java/lang/Cloneable"),
-                  false, false);
+                  true, false);
   
   ClassArray::InterfacesArray[1] = 
     JCL->loadName(JCL->asciizConstructUTF8("java/io/Serializable"),
-                  false, false);
+                  true, false);
+   
+  // Load base array classes that JnJVM internally uses. Now that the interfaces
+  // have been loaded, the secondary type can be safely created.
+  upcalls->ArrayOfString = 
+    JCL->constructArray(JCL->asciizConstructUTF8("[Ljava/lang/String;"));
   
-  Class* cl = ClassArray::SuperArray;
-  assert(cl && "Initializing array VT without a super for arrays");
-  assert(cl->virtualVT->init && "Initializing array VT before JavaObjectVT");
-  
-  // Set the values in the JavaObject VT
-  cl->virtualVT->depth = 0;
-  cl->virtualVT->cl = cl;
-  cl->virtualVT->display = (JavaVirtualTable**)
-    cl->classLoader->allocator.Allocate(sizeof(JavaVirtualTable*));
-  cl->virtualVT->display[0] = cl->virtualVT;
+  upcalls->ArrayOfObject = 
+    JCL->constructArray(JCL->asciizConstructUTF8("[Ljava/lang/Object;"));
 
-  Classpath* upcalls = cl->classLoader->bootstrapLoader->upcalls;
 
+  // Update native array classes. A few things have not been set properly
+  // when loading these classes because java.lang.Object and java.lang.Object[]
+  // were not loaded yet. Correct that now by updating these classes.
   #define COPY(CLASS) \
     memcpy(CLASS->virtualVT->getFirstJavaMethod(), \
-           cl->virtualVT->getFirstJavaMethod(), \
+           javaLangObject->virtualVT->getFirstJavaMethod(), \
            sizeof(uintptr_t) * JavaVirtualTable::getNumJavaMethods()); \
-    CLASS->super = cl; \
-    CLASS->display[0] = cl; \
+    CLASS->super = javaLangObject; \
+    CLASS->display[0] = javaLangObject; \
     CLASS->display[1] = CLASS; \
-    CLASS->virtualVT->display[0] = cl->virtualVT;
+    CLASS->virtualVT->display[0] = javaLangObject->virtualVT; \
+    CLASS->virtualVT->secondaryTypes = \
+      upcalls->ArrayOfObject->virtualVT->secondaryTypes; \
 
     COPY(upcalls->ArrayOfBool)
     COPY(upcalls->ArrayOfByte)
@@ -1288,47 +1290,67 @@
 
 #undef COPY
  
-  // Load array classes that JnJVM internally uses.
-  upcalls->ArrayOfString = 
-    JCL->constructArray(JCL->asciizConstructUTF8("[Ljava/lang/String;"));
-  
-  upcalls->ArrayOfObject = 
-    JCL->constructArray(JCL->asciizConstructUTF8("[Ljava/lang/Object;"));
 }
 
 JavaVirtualTable::JavaVirtualTable(Class* C) {
    
   if (C->super) {
-    // (1) Copy the super VT into the current VT.
+    // Copy the super VT into the current VT.
     uint32 size = C->super->virtualTableSize * sizeof(uintptr_t);
     memcpy(this, C->super->virtualVT, size);
   
-    // (2) Set the class of this VT.
+    // Set the class of this VT.
     cl = C;
     
-    // (3) Set depth and display for fast dynamic type checking.
-    depth = C->super->virtualVT->depth + 1;
+    // Set depth and display for fast dynamic type checking.
+    JavaVirtualTable* superVT = C->super->virtualVT;
+    depth = superVT->depth + 1;
+    nbSecondaryTypes = superVT->nbSecondaryTypes + cl->nbInterfaces;
+    
+    uint32 length = getDisplayLength() < depth ? getDisplayLength() : depth;
+    memcpy(display, superVT->display, length * sizeof(JavaVirtualTable*)); 
+    if (depth < getDisplayLength()) {
+      display[depth] = this;
+      offset = getCacheIndex() + depth + 1;
+    } else {
+      offset = getCacheIndex();
+      ++nbSecondaryTypes;
+    }
+
     mvm::BumpPtrAllocator& allocator = C->classLoader->allocator;
-    display = (JavaVirtualTable**)
-      allocator.Allocate(sizeof(JavaVirtualTable*) * (depth + 1));   
-    size = depth * sizeof(JavaVirtualTable*);
-    memcpy(display, C->super->virtualVT->display, size); 
-    display[depth] = this;
+    secondaryTypes = (JavaVirtualTable**)
+      allocator.Allocate(sizeof(JavaVirtualTable*) * nbSecondaryTypes);  
+    
+    if (offset == getCacheIndex()) {
+      secondaryTypes[0] = this;
+    }
+
+    if (superVT->nbSecondaryTypes) {
+      memcpy(secondaryTypes + 1, superVT->secondaryTypes,
+             sizeof(JavaVirtualTable*) * superVT->nbSecondaryTypes);
+    }
+
+    for (uint32 i = 0; i < cl->nbInterfaces; ++i) {
+      JavaVirtualTable* cur = cl->interfaces[i]->virtualVT;
+      secondaryTypes[superVT->nbSecondaryTypes + 1 + i] = cur;
+    }
+
   } else {
-    // (1) Set the tracer, destructor and delete
+    // Set the tracer, destructor and delete
     tracer = (uintptr_t)JavaObjectTracer;
     destructor = 0;
     operatorDelete = 0;
     
-    // (2) Set the class of this VT.
+    // Set the class of this VT.
     cl = C;
     
-    // (3) Set depth and display for fast dynamic type checking.
+    // Set depth and display for fast dynamic type checking.
+    // java.lang.Object does not have any secondary types.
+    offset = getCacheIndex() + 1;
     depth = 0;
-    display = (JavaVirtualTable**)
-      C->classLoader->allocator.Allocate(sizeof(JavaVirtualTable*));
     display[0] = this;
     destructor = 0;
+    nbSecondaryTypes = 0;
   }
     
 
@@ -1337,38 +1359,157 @@
 JavaVirtualTable::JavaVirtualTable(ClassArray* C) {
    
   if (!C->baseClass()->isPrimitive()) {
-    // (1) Copy the super VT into the current VT.
+    // Copy the super VT into the current VT.
     uint32 size = getNumMethods() * sizeof(uintptr_t);
     memcpy(this, C->super->virtualVT, size);
     tracer = (uintptr_t)ArrayObjectTracer;
     
-    // (2) Set the class of this VT.
+    // Set the class of this VT.
     cl = C;
 
-    // (3) Set depth and display for fast dynamic type checking.
-    depth = 1;
-    mvm::BumpPtrAllocator& allocator = cl->classLoader->allocator;
-    display = 
-      (JavaVirtualTable**)allocator.Allocate(sizeof(JavaVirtualTable*) * 2);
-    display[0] = C->super->virtualVT;
-    display[1] = this;
+    // Set depth and display for fast dynamic type checking.
+    JnjvmClassLoader* JCL = cl->classLoader;
+    Classpath* upcalls = JCL->bootstrapLoader->upcalls;
+    
+    if (upcalls->ArrayOfObject) {
+      UserCommonClass* temp = C->baseClass();
+      uint32 dim = 1;
+      while (temp->isArray()) {
+        temp = temp->asArrayClass()->baseClass();
+        ++dim;
+      }
+     
+      bool newSecondaryTypes = false;
+      if (temp->isPrimitive()) {
+        --dim;
+        temp = C->super;
+      } else if (temp == C->super) {
+        --dim;
+        newSecondaryTypes = true;
+      } else {
+        temp = temp->super;
+      }
+      
+      const UTF8* name = JCL->constructArrayName(dim, temp->name);
+      ClassArray* super = JCL->constructArray(name);
+      JavaVirtualTable* superVT = super->virtualVT;
+      depth = superVT->depth + 1;
+
+      uint32 length = getDisplayLength() < depth ? getDisplayLength() : depth;
+      memcpy(display, superVT->display, length * sizeof(JavaVirtualTable*)); 
+      if (depth < getDisplayLength()) display[depth] = this;
+        
+      mvm::BumpPtrAllocator& allocator = JCL->allocator;
+
+      if (!newSecondaryTypes) {
+        if (depth < getDisplayLength()) {
+          nbSecondaryTypes = superVT->nbSecondaryTypes;
+          secondaryTypes = superVT->secondaryTypes;
+        } else {
+          nbSecondaryTypes = superVT->nbSecondaryTypes + 1;
+          secondaryTypes = (JavaVirtualTable**)
+            allocator.Allocate(sizeof(JavaVirtualTable*) * nbSecondaryTypes);
+          secondaryTypes[0] = this;
+          memcpy(secondaryTypes + 1 , superVT->secondaryTypes,
+                 superVT->nbSecondaryTypes * sizeof(JavaVirtualTable*));
+        }
+      } else {
+
+        // This is an Object[....] array class. It will create the list of
+        // secondary types and all array classes of the same dimension will
+        // point to this array.
+
+        // If we're superior than the display limit, we must make room for one
+        // slot that will contain the current VT.
+        uint32 outOfDepth = 0;
+        if (depth >= getDisplayLength()) outOfDepth = 1;
+        
+        assert(cl->nbInterfaces == 2 && "Arrays have more than 2 interface?");
+
+        // The list of secondary types is composed of:
+        // (1) The list of secondary types of super array.
+        // (2) The array of inherited interfaces with the same dimensions.
+        // (3) This VT, if its depth is superior than the display size.
+        nbSecondaryTypes = superVT->nbSecondaryTypes + 2 + outOfDepth;
+
+        secondaryTypes = (JavaVirtualTable**)
+          allocator.Allocate(sizeof(JavaVirtualTable*) * nbSecondaryTypes);
+        
+        // First, copy the list of secondary types from super array.
+        memcpy(secondaryTypes + outOfDepth, superVT->secondaryTypes,
+               superVT->nbSecondaryTypes * sizeof(JavaVirtualTable*));
+
+        // If the depth is superior than the display size, put the current VT
+        // at the beginning of the list.
+        if (outOfDepth) secondaryTypes[0] = this;
+        
+        // Load Cloneable[...] and Serializable[...]
+        const UTF8* name = JCL->constructArrayName(dim, cl->interfaces[0]->name);
+        ClassArray* firstInterface = JCL->constructArray(name);
+        name = JCL->constructArrayName(dim, cl->interfaces[1]->name);
+        ClassArray* secondInterface = JCL->constructArray(name);
+
+        uint32 index = superVT->nbSecondaryTypes + outOfDepth;
+
+        // Put Cloneable[...] and Serializable[...] at the end of the list.
+        secondaryTypes[index] = firstInterface->virtualVT;
+        secondaryTypes[index + 1] = secondInterface->virtualVT;
+
+        // If the depth is greater than the display size, 
+        // Cloneable[...] and Serializable[...] have their own list of
+        // secondary types, and we must therefore tell them that they
+        // implement themselves.
+        // If the depth is less than than the display size, there is nothing
+        // to do: the array of secondary types has been created before loading
+        // the interface arrays, so the interface arrays already reference
+        // the array.
+        if (outOfDepth) {
+          firstInterface->virtualVT->secondaryTypes[index] =
+            firstInterface->virtualVT;
+          firstInterface->virtualVT->secondaryTypes[index + 1] =
+            secondInterface->virtualVT;
+          secondInterface->virtualVT->secondaryTypes[index] =
+            firstInterface->virtualVT;
+          secondInterface->virtualVT->secondaryTypes[index + 1] =
+            secondInterface->virtualVT;
+        }
+      }
+
+    } else {
+      // This is java.lang.Object[].
+      depth = 1;
+      display[0] = C->super->virtualVT;
+      display[1] = this;
+      nbSecondaryTypes = 2;  
+      
+      mvm::BumpPtrAllocator& allocator = JCL->allocator;
+      secondaryTypes = (JavaVirtualTable**)
+        allocator.Allocate(sizeof(JavaVirtualTable*) * nbSecondaryTypes);
+
+      // The interfaces have already been resolved.
+      secondaryTypes[0] = cl->interfaces[0]->virtualVT;
+      secondaryTypes[1] = cl->interfaces[1]->virtualVT;
+    }
+
   } else {
-    // (1) Set the tracer, destructor and delete
+    // Set the tracer, destructor and delete
     tracer = (uintptr_t)JavaArrayTracer;
     destructor = 0;
     operatorDelete = 0;
     
-    // (2) Set the class of this VT.
+    // Set the class of this VT.
     cl = C;
     
-    // (3) Set depth and display for fast dynamic type checking. Since
+    // Set depth and display for fast dynamic type checking. Since
     // JavaObject has not been loaded yet, don't use super.
     depth = 1;
-    mvm::BumpPtrAllocator& allocator = cl->classLoader->allocator;
-    display = 
-      (JavaVirtualTable**)allocator.Allocate(sizeof(JavaVirtualTable*) * 2);
     display[0] = 0;
     display[1] = this;
+    nbSecondaryTypes = 2;
+
+    // The list of secondary types has not been allocated yet by
+    // java.lang.Object[]. The initialiseVT function will update the current
+    // array to point to java.lang.Object[]'s secondary list.
   }
 }
 

Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaClass.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JavaClass.h?rev=69443&r1=69442&r2=69443&view=diff

==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JavaClass.h (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JavaClass.h Sat Apr 18 08:07:59 2009
@@ -1343,7 +1343,11 @@
 public:
   CommonClass* cl;
   size_t depth;
-  JavaVirtualTable** display;
+  size_t offset;
+  size_t cache;
+  JavaVirtualTable* display[8];
+  size_t nbSecondaryTypes;
+  JavaVirtualTable** secondaryTypes;
 
   uintptr_t init;
   uintptr_t equals;
@@ -1356,6 +1360,7 @@
   uintptr_t waitIndefinitely;
   uintptr_t waitMs;
   uintptr_t waitMsNs;
+  uintptr_t virtualMethods[1];
 
   void* operator new(size_t sz, mvm::BumpPtrAllocator& allocator,
                      uint32 nbMethods) {
@@ -1369,19 +1374,28 @@
   uintptr_t* getFirstJavaMethod() {
     return &init;
   }
-
+  
   static uint32_t getFirstJavaMethodIndex() {
-    return 6;
+    return 17;
   }
    
   static uint32_t getNumMethods() {
-    return 17;
+    return 28;
   }
   
   static uint32_t getNumJavaMethods() {
     return 11;
   }
 
+  static uint32_t getDisplayLength() {
+    return 8;
+  }
+  
+private:
+  static uint32_t getCacheIndex() {
+    return 6;
+  }
+
 };
 
 

Modified: vmkit/trunk/lib/JnJVM/VMCore/LockedMap.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/LockedMap.h?rev=69443&r1=69442&r2=69443&view=diff

==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/LockedMap.h (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/LockedMap.h Sat Apr 18 08:07:59 2009
@@ -44,13 +44,13 @@
   }
 };
 
-template<class Key, class Container, class Compare, class Meta>
+template<class Key, class Container, class Compare, class Meta, class TLock>
 class LockedMap : public mvm::PermanentObject {
 public:
   typedef typename std::map<const Key, Container, Compare>::iterator iterator;
   typedef Container (*funcCreate)(Key& V, Meta meta);
 
-  mvm::LockNormal lock;
+  TLock lock;
   std::map<const Key, Container, Compare,
            gc_allocator<std::pair<const Key, Container> > > map;
   
@@ -137,7 +137,8 @@
 };
 
 class ClassMap : 
-  public LockedMap<const UTF8*, UserCommonClass*, ltutf8, JnjvmClassLoader* > {
+  public LockedMap<const UTF8*, UserCommonClass*, ltutf8, JnjvmClassLoader*,
+                   mvm::LockRecursive > {
 
 #ifdef USE_GC_BOEHM
 public:
@@ -148,7 +149,7 @@
 };
 
 class StringMap :
-  public LockedMap<const UTF8*, JavaString*, ltutf8, Jnjvm*> {
+  public LockedMap<const UTF8*, JavaString*, ltutf8, Jnjvm*, mvm::LockNormal> {
 
 public:
   void insert(JavaString* str);





More information about the vmkit-commits mailing list