[vmkit-commits] [vmkit] r69533 - in /vmkit/trunk: include/jnjvm/ lib/JnJVM/Classpath/ lib/JnJVM/Compiler/ lib/JnJVM/LLVMRuntime/ lib/JnJVM/VMCore/

Nicolas Geoffray nicolas.geoffray at lip6.fr
Sun Apr 19 12:09:19 PDT 2009


Author: geoffray
Date: Sun Apr 19 14:09:19 2009
New Revision: 69533

URL: http://llvm.org/viewvc/llvm-project?rev=69533&view=rev
Log:
Move to the new subtype checking implementation when jitting
Java code (the function call still needs to be lowered) and
finally implement the long-awaiting array-store check!


Modified:
    vmkit/trunk/include/jnjvm/JnjvmModule.h
    vmkit/trunk/lib/JnJVM/Classpath/ClasspathVMThrowable.cpp
    vmkit/trunk/lib/JnJVM/Compiler/JITInfo.cpp
    vmkit/trunk/lib/JnJVM/Compiler/JavaAOTCompiler.cpp
    vmkit/trunk/lib/JnJVM/Compiler/JavaJIT.cpp
    vmkit/trunk/lib/JnJVM/Compiler/JavaJITCompiler.cpp
    vmkit/trunk/lib/JnJVM/Compiler/JavaJITOpcodes.cpp
    vmkit/trunk/lib/JnJVM/Compiler/JnjvmModule.cpp
    vmkit/trunk/lib/JnJVM/Compiler/LowerConstantCalls.cpp
    vmkit/trunk/lib/JnJVM/LLVMRuntime/runtime-default.ll
    vmkit/trunk/lib/JnJVM/LLVMRuntime/runtime-isolate.ll
    vmkit/trunk/lib/JnJVM/LLVMRuntime/runtime-single.ll
    vmkit/trunk/lib/JnJVM/VMCore/JavaClass.cpp
    vmkit/trunk/lib/JnJVM/VMCore/JavaClass.h
    vmkit/trunk/lib/JnJVM/VMCore/JavaRuntimeJIT.cpp
    vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.cpp
    vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.h

Modified: vmkit/trunk/include/jnjvm/JnjvmModule.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/include/jnjvm/JnjvmModule.h?rev=69533&r1=69532&r2=69533&view=diff

==============================================================================
--- vmkit/trunk/include/jnjvm/JnjvmModule.h (original)
+++ vmkit/trunk/include/jnjvm/JnjvmModule.h Sun Apr 19 14:09:19 2009
@@ -66,6 +66,7 @@
 
 
 class LLVMClassInfo : public mvm::JITInfo {
+  friend class JavaJITCompiler;
   friend class JavaLLVMCompiler;
 private:
   Class* classDef;
@@ -253,10 +254,7 @@
 #ifndef WITHOUT_VTABLE
   llvm::Function* VirtualLookupFunction;
 #endif
-  llvm::Function* InstanceOfFunction;
   llvm::Function* IsAssignableFromFunction;
-  llvm::Function* ImplementsFunction;
-  llvm::Function* InstantiationOfArrayFunction;
   llvm::Function* GetDepthFunction;
   llvm::Function* GetClassInDisplayFunction;
   llvm::Function* GetStaticInstanceFunction;
@@ -293,7 +291,9 @@
   llvm::Function* JavaObjectAllocateFunction;
   llvm::Function* GetVTFromClassFunction;
   llvm::Function* GetVTFromClassArrayFunction;
+  llvm::Function* GetVTFromCommonClassFunction;
   llvm::Function* GetObjectSizeFromClassFunction;
+  llvm::Function* GetBaseClassVTFromVTFunction;
 
   llvm::Function* GetLockFunction;
   llvm::Function* OverflowThinLockFunction;
@@ -308,7 +308,6 @@
 
   static llvm::ConstantInt* OffsetObjectSizeInClassConstant;
   static llvm::ConstantInt* OffsetVTInClassConstant;
-  static llvm::ConstantInt* OffsetVTInClassArrayConstant;
   static llvm::ConstantInt* OffsetDepthInClassConstant;
   static llvm::ConstantInt* OffsetDisplayInClassConstant;
   static llvm::ConstantInt* OffsetTaskClassMirrorInClassConstant;
@@ -322,6 +321,7 @@
   static llvm::ConstantInt* OffsetClassInVTConstant;
   static llvm::ConstantInt* OffsetDepthInVTConstant;
   static llvm::ConstantInt* OffsetDisplayInVTConstant;
+  static llvm::ConstantInt* OffsetBaseClassVTInVTConstant;
   
   static llvm::ConstantInt* ClassReadyConstant;
 
@@ -335,6 +335,7 @@
   llvm::Function* ClassCastExceptionFunction;
   llvm::Function* OutOfMemoryErrorFunction;
   llvm::Function* NegativeArraySizeExceptionFunction;
+  llvm::Function* ArrayStoreExceptionFunction;
   
 
   JnjvmModule(llvm::Module*);
@@ -360,8 +361,6 @@
   }
 #endif
   
-  void internalMakeVT(Class* cl);
-
   void addJavaPasses();
 
 private: 

Modified: vmkit/trunk/lib/JnJVM/Classpath/ClasspathVMThrowable.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/Classpath/ClasspathVMThrowable.cpp?rev=69533&r1=69532&r2=69533&view=diff

==============================================================================
--- vmkit/trunk/lib/JnJVM/Classpath/ClasspathVMThrowable.cpp (original)
+++ vmkit/trunk/lib/JnJVM/Classpath/ClasspathVMThrowable.cpp Sun Apr 19 14:09:19 2009
@@ -109,7 +109,7 @@
   while (i != e) {
     JavaMethod* meth = vm->IPToMethod<JavaMethod>(*i);
     assert(meth && "Wrong stack trace");
-    if (meth->classDef->subclassOf(vm->upcalls->newThrowable)) {
+    if (meth->classDef->isAssignableFrom(vm->upcalls->newThrowable)) {
       ++i;
       ++index;
     } else break;

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

==============================================================================
--- vmkit/trunk/lib/JnJVM/Compiler/JITInfo.cpp (original)
+++ vmkit/trunk/lib/JnJVM/Compiler/JITInfo.cpp Sun Apr 19 14:09:19 2009
@@ -73,26 +73,7 @@
     classDef->virtualSize = (uint32)size;
     virtualSizeConstant = ConstantInt::get(Type::Int32Ty, size);
    
-    if (!Mod->isStaticCompiling()) {
-      if (!classDef->virtualVT) {
-        Mod->makeVT(classDef);
-      } else {
-#ifdef WITH_TRACER
-        // So the class is vmjc'ed. Create the virtual tracer.
-        Function* func = Function::Create(JnjvmModule::MarkAndTraceType,
-                                          GlobalValue::ExternalLinkage,
-                                          "markAndTraceObject",
-                                          Mod->getLLVMModule());
-       
-        uintptr_t ptr = classDef->virtualVT->tracer;
-        JnjvmModule::executionEngine->addGlobalMapping(func, (void*)ptr);
-        virtualTracerFunction = func;
-#endif
-      }
-    } else {
-      Mod->makeVT(classDef);
-    }
-  
+    Mod->makeVT(classDef);
   }
 
   return virtualType;

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

==============================================================================
--- vmkit/trunk/lib/JnJVM/Compiler/JavaAOTCompiler.cpp (original)
+++ vmkit/trunk/lib/JnJVM/Compiler/JavaAOTCompiler.cpp Sun Apr 19 14:09:19 2009
@@ -364,11 +364,8 @@
   
   std::vector<Constant*> Elmts;
 
-  if (cl->isClass()) {
-    Elmts.push_back(getVirtualTable(cl->asClass()->virtualVT));
-  } else {
-    Elmts.push_back(getVirtualTable(cl->asArrayClass()->virtualVT));
-  }
+  // VT
+  Elmts.push_back(getVirtualTable(cl->virtualVT));
   
   // lock
   Constant* L = ConstantInt::get(Type::Int64Ty, 0);
@@ -666,7 +663,14 @@
   Constant* loader = ConstantExpr::getBitCast(StaticInitializer,
                                               JnjvmModule::ptrType);
   CommonClassElts.push_back(loader);
- 
+  
+  // virtualTable
+  if (cl->virtualVT) {
+    CommonClassElts.push_back(getVirtualTable(cl->virtualVT));
+  } else {
+    TempTy = JnjvmModule::VTType;
+    CommonClassElts.push_back(Constant::getNullValue(TempTy));
+  }
   return ConstantStruct::get(STy, CommonClassElts);
 }
 
@@ -836,9 +840,6 @@
     
   ClassElts.push_back(Cl);
   
-  // virtualTable
-  ClassElts.push_back(getVirtualTable(cl->virtualVT));
-
   return ConstantStruct::get(STy, ClassElts);
 }
 
@@ -855,11 +856,8 @@
   // virtualSize
   ClassElts.push_back(ConstantInt::get(Type::Int32Ty, cl->virtualSize));
 
-  // virtualTable
-  ClassElts.push_back(getVirtualTable(cl->virtualVT));
-
   // IsolateInfo
-  const ArrayType* ATy = dyn_cast<ArrayType>(STy->getContainedType(3));
+  const ArrayType* ATy = dyn_cast<ArrayType>(STy->getContainedType(2));
   assert(ATy && "Malformed type");
   
   const StructType* TCMTy = dyn_cast<StructType>(ATy->getContainedType(0));
@@ -1201,8 +1199,7 @@
         ConstantInt::get(Type::Int64Ty, VT->offset), PTy));
   
   // cache
-  Elemts.push_back(ConstantExpr::getIntToPtr(
-        ConstantInt::get(Type::Int64Ty, VT->cache), PTy));
+  Elemts.push_back(N);
   
   // display
   for (uint32 i = 0; i < JavaVirtualTable::getDisplayLength(); ++i) {
@@ -1210,8 +1207,9 @@
       Constant* Temp = getVirtualTable(VT->display[i]);
       Temp = ConstantExpr::getBitCast(Temp, PTy);
       Elemts.push_back(Temp);
-    } else
+    } else {
       Elemts.push_back(Constant::getNullValue(PTy));
+    }
   }
   
   // nbSecondaryTypes
@@ -1236,6 +1234,15 @@
   display = ConstantExpr::getCast(Instruction::BitCast, display, PTy);
   
   Elemts.push_back(display);
+    
+  // baseClassVT
+  if (VT->baseClassVT) {
+    Constant* Temp = getVirtualTable(VT->baseClassVT);
+    Temp = ConstantExpr::getBitCast(Temp, PTy);
+    Elemts.push_back(Temp);
+  } else {
+    Elemts.push_back(Constant::getNullValue(PTy));
+  }
 
   
   // methods
@@ -1455,8 +1462,16 @@
 }
 
 void JavaAOTCompiler::makeVT(Class* cl) {
-  internalMakeVT(cl);
-  VirtualTable* VT = cl->virtualVT;
+  JavaVirtualTable* VT = cl->virtualVT;
+  
+  if (cl->super) {
+    // Copy the super VT into the current VT.
+    uint32 size = cl->super->virtualTableSize - 
+        JavaVirtualTable::getFirstJavaMethodIndex();
+    memcpy(VT->getFirstJavaMethod(), cl->super->virtualVT->getFirstJavaMethod(),
+           size * sizeof(uintptr_t));
+  }
+  
   for (uint32 i = 0; i < cl->nbVirtualMethods; ++i) {
     JavaMethod& meth = cl->virtualMethods[i];
     ((void**)VT)[meth.offset] = &meth;

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

==============================================================================
--- vmkit/trunk/lib/JnJVM/Compiler/JavaJIT.cpp (original)
+++ vmkit/trunk/lib/JnJVM/Compiler/JavaJIT.cpp Sun Apr 19 14:09:19 2009
@@ -49,7 +49,7 @@
   return true;
 #else
 
-  if (cl->isReadyForCompilation() || compilingClass->subclassOf(cl)) {
+  if (cl->isReadyForCompilation() || compilingClass->isAssignableFrom(cl)) {
     return false;
   }
 

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

==============================================================================
--- vmkit/trunk/lib/JnJVM/Compiler/JavaJITCompiler.cpp (original)
+++ vmkit/trunk/lib/JnJVM/Compiler/JavaJITCompiler.cpp Sun Apr 19 14:09:19 2009
@@ -134,11 +134,37 @@
 #endif
 
 void JavaJITCompiler::makeVT(Class* cl) { 
-  internalMakeVT(cl);
-
   JavaVirtualTable* VT = cl->virtualVT; 
   assert(VT && "No VT was allocated!");
 
+#ifdef WITH_TRACER
+  if (VT->init) {
+    // So the class is vmjc'ed. Create the virtual tracer.
+    Function* func = Function::Create(JnjvmModule::MarkAndTraceType,
+                                      GlobalValue::ExternalLinkage,
+                                      "markAndTraceObject",
+                                      getLLVMModule());
+       
+    uintptr_t ptr = VT->tracer;
+    JnjvmModule::executionEngine->addGlobalMapping(func, (void*)ptr);
+    LLVMClassInfo* LCI = getClassInfo(cl);
+    LCI->virtualTracerFunction = func;
+
+    // The VT hash already been filled by the AOT compiler so there
+    // is nothing left to do!
+    return;
+  }
+#endif
+  
+  if (cl->super) {
+    // Copy the super VT into the current VT.
+    uint32 size = cl->super->virtualTableSize - 
+        JavaVirtualTable::getFirstJavaMethodIndex();
+    memcpy(VT->getFirstJavaMethod(), cl->super->virtualVT->getFirstJavaMethod(),
+           size * sizeof(uintptr_t));
+  }
+
+
   // Fill the virtual table with function pointers.
   ExecutionEngine* EE = mvm::MvmModule::executionEngine;
   for (uint32 i = 0; i < cl->nbVirtualMethods; ++i) {

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

==============================================================================
--- vmkit/trunk/lib/JnJVM/Compiler/JavaJITOpcodes.cpp (original)
+++ vmkit/trunk/lib/JnJVM/Compiler/JavaJITOpcodes.cpp Sun Apr 19 14:09:19 2009
@@ -654,6 +654,41 @@
         Value* obj = pop();
         Value* ptr = verifyAndComputePtr(obj, index,
                                          module->JavaArrayObjectType);
+
+        if (TheCompiler->hasExceptionsEnabled()) {
+
+          Value* cmp = new ICmpInst(ICmpInst::ICMP_EQ, val,
+                                    module->JavaObjectNullConstant,
+                                    "", currentBlock);
+
+          BasicBlock* endBlock = createBasicBlock("end array store check");
+          BasicBlock* checkBlock = createBasicBlock("array store check");
+          BasicBlock* exceptionBlock = 
+            createBasicBlock("array store exception");
+          BranchInst::Create(endBlock, checkBlock, cmp, currentBlock);
+          currentBlock = checkBlock;
+        
+          Value* valVT = CallInst::Create(module->GetVTFunction, val, "",
+                                          currentBlock);
+         
+          Value* objVT = CallInst::Create(module->GetVTFunction, obj, "",
+                                          currentBlock);
+          objVT = CallInst::Create(module->GetBaseClassVTFromVTFunction, objVT,
+                                   "", currentBlock);
+          
+          Value* VTArgs[2] = { valVT, objVT };
+          
+          Value* res = CallInst::Create(module->IsAssignableFromFunction,
+                                        VTArgs, VTArgs + 2, "", currentBlock);
+
+          BranchInst::Create(endBlock, exceptionBlock, res, currentBlock);
+          
+          currentBlock = exceptionBlock;
+          throwException(module->ArrayStoreExceptionFunction, VTArgs, 1);
+
+          currentBlock = endBlock;
+        }
+
         new StoreInst(val, ptr, false, currentBlock);
         break;
       }
@@ -1978,7 +2013,6 @@
         
         BasicBlock* exceptionCheckcast = 0;
         BasicBlock* endCheckcast = 0;
-        Value* result = 0;
 
         uint16 index = readU2(bytecodes, i);
         UserCommonClass* cl = 0;
@@ -1988,6 +2022,8 @@
         Value* cmp = new ICmpInst(ICmpInst::ICMP_EQ, obj,
                                   module->JavaObjectNullConstant,
                                   "", currentBlock);
+        BasicBlock* endBlock = createBasicBlock("end type compare");
+        PHINode* node = PHINode::Create(Type::Int1Ty, "", endBlock);
         
         if (checkcast) {
           exceptionCheckcast = createBasicBlock("false checkcast");
@@ -2000,91 +2036,41 @@
           currentBlock = exceptionCheckcast;
           throwException(module->ClassCastExceptionFunction, args, 2);
           currentBlock = ifFalse;
-        }
-        
-        if (cl) {
-
-          BasicBlock* ifTrue = createBasicBlock("true type compare");
+        } else {
           BasicBlock* ifFalse = createBasicBlock("false type compare");
-          BranchInst::Create(ifTrue, ifFalse, cmp, currentBlock);
-          PHINode* node = PHINode::Create(Type::Int1Ty, "", ifTrue);
+          BranchInst::Create(endBlock, ifFalse, cmp, currentBlock);
           node->addIncoming(ConstantInt::getFalse(), currentBlock);
-          Value* objCl = CallInst::Create(module->GetClassFunction, obj, "",
-                                          ifFalse);
-          Value* classArgs[2] = { objCl, clVar }; 
-            
-          if (isInterface(cl->access)) {
-            Value* res = CallInst::Create(module->ImplementsFunction,
-                                          classArgs, classArgs + 2, "",
-                                          ifFalse);
-            node->addIncoming(res, ifFalse);
-            BranchInst::Create(ifTrue, ifFalse);
-          } else {
-            cmp = new ICmpInst(ICmpInst::ICMP_EQ, objCl, clVar, "", ifFalse);
-            BasicBlock* notEquals = createBasicBlock("false compare");
-            BranchInst::Create(ifTrue, notEquals, cmp, ifFalse);
-            node->addIncoming(ConstantInt::getTrue(), ifFalse);
-              
-            if (cl->isPrimitive()) {
-              fprintf(stderr, "implement me");
-              abort();
-            } else if (cl->isArray()) {
-              Value* res = 
-                CallInst::Create(module->InstantiationOfArrayFunction,
-                                 classArgs, classArgs + 2, "", notEquals);
-              node->addIncoming(res, notEquals);
-              BranchInst::Create(ifTrue, notEquals);
-            } else {
-              Value* depthCl;
-              if (cl->asClass()->isResolved()) {
-                depthCl = ConstantInt::get(Type::Int32Ty, cl->depth);
-              } else {
-                depthCl = CallInst::Create(module->GetDepthFunction,
-                                           clVar, "", notEquals);
-              }
-              
-              Value* depthClObj = CallInst::Create(module->GetDepthFunction,
-                                                   objCl, "", notEquals);
-              Value* cmp = new ICmpInst(ICmpInst::ICMP_ULE, depthCl, depthClObj,
-                                        "", notEquals);
-            
-              BasicBlock* supDepth = createBasicBlock("superior depth");
-            
-              BranchInst::Create(supDepth, ifTrue, cmp, notEquals);
-              node->addIncoming(ConstantInt::getFalse(), notEquals);
-  
-              Value* inDisplay = CallInst::Create(module->GetDisplayFunction,
-                                                  objCl, "", supDepth);
-            
-              Value* displayArgs[2] = { inDisplay, depthCl };
-              Value* clInDisplay = 
-                CallInst::Create(module->GetClassInDisplayFunction, displayArgs,
-                                 displayArgs + 2, "", supDepth);
-             
-              cmp = new ICmpInst(ICmpInst::ICMP_EQ, clInDisplay, clVar, "",
-                                   supDepth);
-              BranchInst::Create(ifTrue, supDepth); 
-            
-              node->addIncoming(cmp, supDepth);
-            }
-          }
-
-          currentBlock = ifTrue;
-          result = node;
+          currentBlock = ifFalse;
+        }
 
+        Value* TheVT = 0;
+        if (!cl) {
+          TheVT = CallInst::Create(module->GetVTFromCommonClassFunction,
+                                   clVar, "", currentBlock);
         } else {
-          result = CallInst::Create(module->InstanceOfFunction, args,
-                                    args + 2, "", currentBlock);
-
+          TheVT = TheCompiler->getVirtualTable(cl->virtualVT);
         }
 
+        
+        Value* objVT = CallInst::Create(module->GetVTFunction, obj, "",
+                                       currentBlock);
+        Value* classArgs[2] = { objVT, TheVT };
+          
+        Value* res = CallInst::Create(module->IsAssignableFromFunction,
+                                      classArgs, classArgs + 2, "",
+                                      currentBlock);
+
+        node->addIncoming(res, currentBlock);
+        BranchInst::Create(endBlock, currentBlock);
+        currentBlock = endBlock;
+
         if (checkcast) {
-          BranchInst::Create(endCheckcast, exceptionCheckcast, result,
+          BranchInst::Create(endCheckcast, exceptionCheckcast, node,
                              currentBlock);
           currentBlock = endCheckcast;
         } else {
           pop();
-          push(new ZExtInst(result, Type::Int32Ty, "", currentBlock),
+          push(new ZExtInst(node, Type::Int32Ty, "", currentBlock),
                false);
         }
 

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

==============================================================================
--- vmkit/trunk/lib/JnJVM/Compiler/JnjvmModule.cpp (original)
+++ vmkit/trunk/lib/JnJVM/Compiler/JnjvmModule.cpp Sun Apr 19 14:09:19 2009
@@ -62,7 +62,6 @@
 llvm::Constant*     JnjvmModule::JavaArraySizeConstant;
 llvm::ConstantInt*  JnjvmModule::OffsetObjectSizeInClassConstant;
 llvm::ConstantInt*  JnjvmModule::OffsetVTInClassConstant;
-llvm::ConstantInt*  JnjvmModule::OffsetVTInClassArrayConstant;
 llvm::ConstantInt*  JnjvmModule::OffsetDepthInClassConstant;
 llvm::ConstantInt*  JnjvmModule::OffsetDisplayInClassConstant;
 llvm::ConstantInt*  JnjvmModule::OffsetTaskClassMirrorInClassConstant;
@@ -84,6 +83,7 @@
 llvm::ConstantInt*  JnjvmModule::OffsetClassInVTConstant;
 llvm::ConstantInt*  JnjvmModule::OffsetDepthInVTConstant;
 llvm::ConstantInt*  JnjvmModule::OffsetDisplayInVTConstant;
+llvm::ConstantInt*  JnjvmModule::OffsetBaseClassVTInVTConstant;
 
 
 JavaLLVMCompiler::JavaLLVMCompiler(const std::string& str) :
@@ -176,43 +176,6 @@
 }
 #endif
 
-
-void JavaLLVMCompiler::internalMakeVT(Class* cl) {
-  
-  for (uint32 i = 0; i < cl->nbVirtualMethods; ++i) {
-    JavaMethod& meth = cl->virtualMethods[i];
-    if (meth.name->equals(cl->classLoader->bootstrapLoader->finalize)) {
-      meth.offset = 0;
-    } else {
-      JavaMethod* parent = cl->super? 
-        cl->super->lookupMethodDontThrow(meth.name, meth.type, false, true,
-                                         0) :
-        0;
-
-      uint64_t offset = 0;
-      if (!parent) {
-        offset = cl->virtualTableSize++;
-        meth.offset = offset;
-      } else {
-        offset = parent->offset;
-        meth.offset = parent->offset;
-      }
-    }
-  }
-
-  uint32 size = cl->virtualTableSize;
-  if (cl->super) {
-    if (!(cl->virtualTableSize >= cl->super->virtualTableSize)) {
-      fprintf(stderr, "cl = %s et super = %s\n", cl->printString(), cl->super->printString());
-    }
-    assert(cl->virtualTableSize >= cl->super->virtualTableSize &&
-           "Size of virtual table less than super!");
-  }
-
-  mvm::BumpPtrAllocator& allocator = cl->classLoader->allocator;
-  cl->virtualVT = new(allocator, size) JavaVirtualTable(cl);
-}
-
 void JavaLLVMCompiler::resolveVirtualClass(Class* cl) {
   // Lock here because we may be called by a class resolver
   mvm::MvmModule::protectIR();
@@ -319,14 +282,14 @@
   OffsetClassInVTConstant = mvm::MvmModule::constantThree;
   OffsetDepthInVTConstant = mvm::MvmModule::constantFour;
   OffsetDisplayInVTConstant = mvm::MvmModule::constantFive;
+  OffsetBaseClassVTInVTConstant = ConstantInt::get(Type::Int32Ty, 17);
   
   OffsetDisplayInClassConstant = mvm::MvmModule::constantZero;
   OffsetDepthInClassConstant = mvm::MvmModule::constantOne;
   
   OffsetObjectSizeInClassConstant = mvm::MvmModule::constantOne;
-  OffsetVTInClassConstant = mvm::MvmModule::constantTwo;
-  OffsetVTInClassArrayConstant = mvm::MvmModule::constantTwo;
-  OffsetTaskClassMirrorInClassConstant = mvm::MvmModule::constantThree;
+  OffsetVTInClassConstant = ConstantInt::get(Type::Int32Ty, 9);
+  OffsetTaskClassMirrorInClassConstant = mvm::MvmModule::constantTwo;
   OffsetStaticInstanceInTaskClassMirrorConstant = mvm::MvmModule::constantTwo;
   OffsetStatusInTaskClassMirrorConstant = mvm::MvmModule::constantZero;
   OffsetInitializedInTaskClassMirrorConstant = mvm::MvmModule::constantOne;
@@ -384,15 +347,14 @@
   ClassLookupFunction = module->getFunction("classLookup");
   GetVTFromClassFunction = module->getFunction("getVTFromClass");
   GetVTFromClassArrayFunction = module->getFunction("getVTFromClassArray");
+  GetVTFromCommonClassFunction = module->getFunction("getVTFromCommonClass");
+  GetBaseClassVTFromVTFunction = module->getFunction("getBaseClassVTFromVT");
   GetObjectSizeFromClassFunction = 
     module->getFunction("getObjectSizeFromClass");
  
   GetClassDelegateeFunction = module->getFunction("getClassDelegatee");
   RuntimeDelegateeFunction = module->getFunction("jnjvmRuntimeDelegatee");
-  InstanceOfFunction = module->getFunction("instanceOf");
-  IsAssignableFromFunction = module->getFunction("isAssignableFrom");
-  ImplementsFunction = module->getFunction("implements");
-  InstantiationOfArrayFunction = module->getFunction("instantiationOfArray");
+  IsAssignableFromFunction = module->getFunction("jnjvmIsAssignableFrom");
   GetDepthFunction = module->getFunction("getDepth");
   GetStaticInstanceFunction = module->getFunction("getStaticInstance");
   GetDisplayFunction = module->getFunction("getDisplay");
@@ -416,6 +378,7 @@
   NegativeArraySizeExceptionFunction = 
     module->getFunction("negativeArraySizeException");
   OutOfMemoryErrorFunction = module->getFunction("outOfMemoryError");
+  ArrayStoreExceptionFunction = module->getFunction("jnjvmArrayStoreException");
 
   JavaObjectAllocateFunction = module->getFunction("gcmalloc");
 

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

==============================================================================
--- vmkit/trunk/lib/JnJVM/Compiler/LowerConstantCalls.cpp (original)
+++ vmkit/trunk/lib/JnJVM/Compiler/LowerConstantCalls.cpp Sun Apr 19 14:09:19 2009
@@ -195,6 +195,18 @@
           Changed = true;
           
           Value* val = Call.getArgument(0);
+          Value* indexes[3] = { module->constantZero, 
+                                module->constantZero, 
+                                module->OffsetVTInClassConstant };
+          Value* VTPtr = GetElementPtrInst::Create(val, indexes, indexes + 3,
+                                                   "", CI);
+          Value* VT = new LoadInst(VTPtr, "", CI);
+          CI->replaceAllUsesWith(VT);
+          CI->eraseFromParent();
+        } else if (V == module->GetVTFromCommonClassFunction) {
+          Changed = true;
+          
+          Value* val = Call.getArgument(0);
           Value* indexes[2] = { module->constantZero, 
                                 module->OffsetVTInClassConstant };
           Value* VTPtr = GetElementPtrInst::Create(val, indexes, indexes + 2,
@@ -206,11 +218,24 @@
           Changed = true;
           
           Value* val = Call.getArgument(0);
-          Value* indexes[2] = { module->constantZero, 
-                                module->OffsetVTInClassArrayConstant };
+          Value* indexes[3] = { module->constantZero,
+                                module->constantZero,
+                                module->OffsetVTInClassConstant };
+          Value* VTPtr = GetElementPtrInst::Create(val, indexes, indexes + 3,
+                                                   "", CI);
+          Value* VT = new LoadInst(VTPtr, "", CI);
+          CI->replaceAllUsesWith(VT);
+          CI->eraseFromParent();
+        } else if (V == module->GetBaseClassVTFromVTFunction) {
+          Changed = true;
+          
+          Value* val = Call.getArgument(0);
+          Value* indexes[2] = { module->constantZero,
+                                module->OffsetBaseClassVTInVTConstant };
           Value* VTPtr = GetElementPtrInst::Create(val, indexes, indexes + 2,
                                                    "", CI);
           Value* VT = new LoadInst(VTPtr, "", CI);
+          VT = new BitCastInst(VT, module->VTType, "", CI);
           CI->replaceAllUsesWith(VT);
           CI->eraseFromParent();
         } else if (V == module->GetObjectSizeFromClassFunction) {

Modified: vmkit/trunk/lib/JnJVM/LLVMRuntime/runtime-default.ll
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/LLVMRuntime/runtime-default.ll?rev=69533&r1=69532&r2=69533&view=diff

==============================================================================
--- vmkit/trunk/lib/JnJVM/LLVMRuntime/runtime-default.ll (original)
+++ vmkit/trunk/lib/JnJVM/LLVMRuntime/runtime-default.ll Sun Apr 19 14:09:19 2009
@@ -61,7 +61,7 @@
                      %UTF8*, %UTF8*, i8, i8*, i32, i8* }
 
 %JavaClassPrimitive = type { %JavaCommonClass, i32 }
-%JavaClassArray = type { %JavaCommonClass, %JavaCommonClass*, %VT* }
+%JavaClassArray = type { %JavaCommonClass, %JavaCommonClass* }
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;;;; Constant calls for Jnjvm runtime internal objects field accesses ;;;;;;;;;
@@ -82,6 +82,10 @@
 ;;; getLock - Get the lock of an object.
 declare i8* @getLock(%JavaObject*)
 
+;;; getVTFromCommonClass - Get the VT of a class from its runtime
+;;; representation.
+declare %VT* @getVTFromCommonClass(%JavaCommonClass*) readnone 
+
 ;;; getVTFromClass - Get the VT of a class from its runtime representation.
 declare %VT* @getVTFromClass(%JavaClass*) readnone 
 
@@ -93,6 +97,10 @@
 ;;; representation.
 declare i32 @getObjectSizeFromClass(%JavaClass*) readnone 
 
+;;; getBaseClassVTFromVT - Get the VT of the base class of an array, or the
+;;; VT of the array class of a regular class.
+declare %VT* @getBaseClassVTFromVT(%VT*) readnone
+
 ;;; getDisplay - Get the display array of this class.
 declare %JavaCommonClass** @getDisplay(%JavaCommonClass*) readnone 
 
@@ -169,17 +177,8 @@
 ;;; overflows
 declare void @overflowThinLock(%JavaObject*)
 
-;;; isAssignableFrom - Returns if the objet's class implements the given class.
-declare i1 @instanceOf(%JavaObject*, %JavaCommonClass*) readnone 
-
-;;; isAssignableFrom - Returns if the class implements the given class.
-declare i1 @isAssignableFrom(%JavaCommonClass*, %JavaCommonClass*) readnone 
-
-;;; implements - Returns if the class implements the given interface.
-declare i1 @implements(%JavaCommonClass*, %JavaCommonClass*) readnone 
-
-;;; instantiationOfArray - Returns if the class implements the given array.
-declare i1 @instantiationOfArray(%JavaCommonClass*, %JavaCommonClass*) readnone
+;;; isAssignableFrom - Returns if a type is a subtype of another type.
+declare i1 @jnjvmIsAssignableFrom(%VT*, %VT*) readnone
 
 ;;; getClassDelegatee - Returns the java/lang/Class representation of the
 ;;; class. This method is lowered to the GEP to the class delegatee in
@@ -212,6 +211,7 @@
 declare %JavaObject* @indexOutOfBoundsException(%JavaObject*, i32)
 declare %JavaObject* @negativeArraySizeException(i32)
 declare %JavaObject* @outOfMemoryError(i32)
+declare %JavaObject* @jnjvmArrayStoreException(%VT*)
 declare void @JavaThreadThrowException(%JavaObject*)
 
 declare void @jniProceedPendingException()

Modified: vmkit/trunk/lib/JnJVM/LLVMRuntime/runtime-isolate.ll
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/LLVMRuntime/runtime-isolate.ll?rev=69533&r1=69532&r2=69533&view=diff

==============================================================================
--- vmkit/trunk/lib/JnJVM/LLVMRuntime/runtime-isolate.ll (original)
+++ vmkit/trunk/lib/JnJVM/LLVMRuntime/runtime-isolate.ll Sun Apr 19 14:09:19 2009
@@ -5,10 +5,11 @@
 %Jnjvm = type { %VT*, %JavaClass*, [9 x %JavaClass*] }
 
 %JavaCommonClass = type { %JavaCommonClass**, i32, [32 x %JavaObject*],
-                          i16, %JavaClass**, i16, %UTF8*, %JavaClass*, i8* }
+                          i16, %JavaClass**, i16, %UTF8*, %JavaClass*, i8*,
+                          %VT* }
 
 
-%JavaClass = type { %JavaCommonClass, i32, %VT*, [32 x %TaskClassMirror], i8*, 
+%JavaClass = type { %JavaCommonClass, i32, [32 x %TaskClassMirror], i8*, 
                     %JavaField*, i16, %JavaField*, i16, %JavaMethod*, i16, 
                     %JavaMethod*, i16, i8*, %ArrayUInt8*, i8*, %Attribut*, 
                     i16, %JavaClass**, i16, %JavaClass*, i16, i8, i32, i32, i8*,

Modified: vmkit/trunk/lib/JnJVM/LLVMRuntime/runtime-single.ll
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/LLVMRuntime/runtime-single.ll?rev=69533&r1=69532&r2=69533&view=diff

==============================================================================
--- vmkit/trunk/lib/JnJVM/LLVMRuntime/runtime-single.ll (original)
+++ vmkit/trunk/lib/JnJVM/LLVMRuntime/runtime-single.ll Sun Apr 19 14:09:19 2009
@@ -3,11 +3,11 @@
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
 %JavaCommonClass = type { %JavaCommonClass**, i32, [1 x %JavaObject*], i16,
-                          %JavaClass**, i16, %UTF8*, %JavaClass*, i8* } 
+                          %JavaClass**, i16, %UTF8*, %JavaClass*, i8*, %VT* }
 
 
-%JavaClass = type { %JavaCommonClass, i32, %VT*, [1 x %TaskClassMirror], i8*, 
-                    %JavaField*, i16, %JavaField*, i16, %JavaMethod*, i16, 
-                    %JavaMethod*, i16, i8*, %ArrayUInt8*, i8*, %Attribut*, 
+%JavaClass = type { %JavaCommonClass, i32, [1 x %TaskClassMirror], i8*,
+                    %JavaField*, i16, %JavaField*, i16, %JavaMethod*, i16,
+                    %JavaMethod*, i16, i8*, %ArrayUInt8*, i8*, %Attribut*,
                     i16, %JavaClass**, i16, %JavaClass*, i16, i8, i32, i32, i8*,
                     void (i8*)* }

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

==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JavaClass.cpp (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JavaClass.cpp Sun Apr 19 14:09:19 2009
@@ -253,6 +253,8 @@
   display = (CommonClass**)loader->allocator.Allocate(sizeof(CommonClass*));
   display[0] = this;
   depth = 0;
+  uint32 size = JavaVirtualTable::getBaseSize();
+  virtualVT = new(loader->allocator, size) JavaVirtualTable(this);
   access = ACC_ABSTRACT | ACC_FINAL | ACC_PUBLIC | JNJVM_PRIMITIVE;
   primSize = nb;
 }
@@ -290,7 +292,7 @@
   interfaces = ClassArray::InterfacesArray;
   nbInterfaces = 2;
   
-  uint32 size = JavaVirtualTable::getNumMethods();
+  uint32 size = JavaVirtualTable::getBaseSize();
   virtualVT = new(loader->allocator, size) JavaVirtualTable(this);
   
   depth = 1;
@@ -604,15 +606,43 @@
 }
 
 bool UserCommonClass::isAssignableFrom(UserCommonClass* cl) {
+  bool res = false;
   if (this == cl) {
-    return true;
+    res = true;
   } else if (cl->isInterface()) {
-    return this->implements(cl);
+    res = this->implements(cl);
   } else if (cl->isArray()) {
-    return this->instantiationOfArray((UserClassArray*)cl);
+    res = this->instantiationOfArray((UserClassArray*)cl);
   } else {
-    return this->subclassOf(cl);
+    res = this->subclassOf(cl);
   }
+  if(virtualVT && cl->virtualVT && res != virtualVT->isSubtypeOf(cl->virtualVT)) {
+    fprintf(stderr, "wrong result for %s and %s\n", printString(), cl->printString());
+    fprintf(stderr, "I have offset = %d\n", cl->virtualVT->offset);
+    fprintf(stderr, "I have secondary types = %d\n", virtualVT->nbSecondaryTypes);
+    fprintf(stderr, "I have secondary types = %s\n", virtualVT->secondaryTypes[0]->cl->printString());
+    fprintf(stderr, "I have secondary types = %d\n", virtualVT->secondaryTypes[0]->cl->super->virtualVT->nbSecondaryTypes);
+    fprintf(stderr, "I have secondary types = %s\n", virtualVT->secondaryTypes[0]->cl->super->printString());
+    fprintf(stderr, "I have secondary types = %d\n", virtualVT->secondaryTypes[0]->cl->nbInterfaces);
+    abort();
+  }
+  return res;
+}
+
+bool JavaVirtualTable::isSubtypeOf(JavaVirtualTable* otherVT) {
+  
+  if (otherVT == ((JavaVirtualTable**)this)[otherVT->offset]) return true;
+  else if (otherVT->offset != getCacheIndex()) return false;
+  else if (this == otherVT) return true;
+  else {
+    for (uint32 i = 0; i < nbSecondaryTypes; ++i) {
+      if (secondaryTypes[i] == otherVT) {
+        cache = otherVT;
+        return true;
+      }
+    }
+  }
+  return false;
 }
 
 void JavaField::InitField(void* obj, uint64 val) {
@@ -730,11 +760,13 @@
       allocator.Allocate(sizeof(CommonClass*) * (depth + 1));
     memcpy(display, super->display, depth * sizeof(UserCommonClass*));
     display[depth] = this;
+    virtualTableSize = super->virtualTableSize;
   } else {
     depth = 0;
     display = (CommonClass**)
       classLoader->allocator.Allocate(sizeof(CommonClass*));
     display[0] = this;
+    virtualTableSize = JavaVirtualTable::getFirstJavaMethodIndex();
   }
 
   uint16 nbI = reader.readU2();
@@ -753,12 +785,8 @@
 }
 
 void UserClass::loadParents() {
-  if (super) {
+  if (super)
     super->resolveClass();
-    virtualTableSize = super->virtualTableSize;
-  } else {
-    virtualTableSize = JavaVirtualTable::getFirstJavaMethodIndex();
-  }
 
   for (unsigned i = 0; i < nbInterfaces; i++)
     interfaces[i]->resolveClass();
@@ -846,6 +874,38 @@
   }
 }
 
+void Class::makeVT() {
+  
+  for (uint32 i = 0; i < nbVirtualMethods; ++i) {
+    JavaMethod& meth = virtualMethods[i];
+    if (meth.name->equals(classLoader->bootstrapLoader->finalize)) {
+      meth.offset = 0;
+    } else {
+      JavaMethod* parent = super? 
+        super->lookupMethodDontThrow(meth.name, meth.type, false, true, 0) :
+        0;
+
+      uint64_t offset = 0;
+      if (!parent) {
+        offset = virtualTableSize++;
+        meth.offset = offset;
+      } else {
+        offset = parent->offset;
+        meth.offset = parent->offset;
+      }
+    }
+  }
+
+  if (super) {
+    assert(virtualTableSize >= super->virtualTableSize &&
+           "Size of virtual table less than super!");
+  }
+
+  mvm::BumpPtrAllocator& allocator = classLoader->allocator;
+  virtualVT = new(allocator, virtualTableSize) JavaVirtualTable(this);
+}
+
+
 void Class::readMethods(Reader& reader) {
   uint16 nbMethods = reader.readU2();
   virtualMethods = new(classLoader->allocator) JavaMethod[nbMethods];
@@ -901,6 +961,7 @@
   readParents(reader);
   readFields(reader);
   readMethods(reader);
+  makeVT();
   attributs = readAttributs(reader, nbAttributs);
   setIsRead();
 }
@@ -1258,13 +1319,12 @@
    
   // Load base array classes that JnJVM internally uses. Now that the interfaces
   // have been loaded, the secondary type can be safely created.
+  upcalls->ArrayOfObject = 
+    JCL->constructArray(JCL->asciizConstructUTF8("[Ljava/lang/Object;"));
+  
   upcalls->ArrayOfString = 
     JCL->constructArray(JCL->asciizConstructUTF8("[Ljava/lang/String;"));
   
-  upcalls->ArrayOfObject = 
-    JCL->constructArray(JCL->asciizConstructUTF8("[Ljava/lang/Object;"));
-
-
   // 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.
@@ -1295,10 +1355,6 @@
 JavaVirtualTable::JavaVirtualTable(Class* C) {
    
   if (C->super) {
-    // Copy the super VT into the current VT.
-    uint32 size = C->super->virtualTableSize * sizeof(uintptr_t);
-    memcpy(this, C->super->virtualVT, size);
-  
     // Set the class of this VT.
     cl = C;
     
@@ -1306,11 +1362,17 @@
     JavaVirtualTable* superVT = C->super->virtualVT;
     depth = superVT->depth + 1;
     nbSecondaryTypes = superVT->nbSecondaryTypes + cl->nbInterfaces;
+
+    for (uint32 i = 0; i < cl->nbInterfaces; ++i) {
+      nbSecondaryTypes += cl->interfaces[i]->virtualVT->nbSecondaryTypes;
+    }
     
     uint32 length = getDisplayLength() < depth ? getDisplayLength() : depth;
     memcpy(display, superVT->display, length * sizeof(JavaVirtualTable*)); 
     uint32 outOfDepth = 0;
-    if (depth < getDisplayLength()) {
+    if (C->isInterface()) {
+      offset = getCacheIndex();
+    } else if (depth < getDisplayLength()) {
       display[depth] = this;
       offset = getCacheIndex() + depth + 1;
     } else {
@@ -1338,6 +1400,15 @@
       uint32 index = superVT->nbSecondaryTypes + outOfDepth + i;
       secondaryTypes[index] = cur;
     }
+   
+    uint32 lastIndex = superVT->nbSecondaryTypes + cl->nbInterfaces +
+                        outOfDepth;
+
+    for (uint32 i = 0; i < cl->nbInterfaces; ++i) {
+      JavaVirtualTable* cur = cl->interfaces[i]->virtualVT;
+      memcpy(secondaryTypes + lastIndex, cur->secondaryTypes,
+             sizeof(JavaVirtualTable*) * cur->nbSecondaryTypes);
+    }
 
   } else {
     // Set the tracer, destructor and delete
@@ -1361,11 +1432,16 @@
 }
   
 JavaVirtualTable::JavaVirtualTable(ClassArray* C) {
-   
+  
+  baseClassVT = C->baseClass()->virtualVT;
+  assert(baseClassVT && "Not base VT when creating an array");
+
   if (!C->baseClass()->isPrimitive()) {
     // Copy the super VT into the current VT.
-    uint32 size = getNumMethods() * sizeof(uintptr_t);
-    memcpy(this, C->super->virtualVT, size);
+    uint32 size = (getBaseSize() - getFirstJavaMethodIndex());
+    memcpy(this->getFirstJavaMethod(),
+           C->super->virtualVT->getFirstJavaMethod(),
+           size * sizeof(uintptr_t));
     tracer = (uintptr_t)ArrayObjectTracer;
     
     // Set the class of this VT.
@@ -1401,7 +1477,12 @@
 
       uint32 length = getDisplayLength() < depth ? getDisplayLength() : depth;
       memcpy(display, superVT->display, length * sizeof(JavaVirtualTable*)); 
-      if (depth < getDisplayLength()) display[depth] = this;
+      if (depth < getDisplayLength()) {
+        display[depth] = this;
+        offset = getCacheIndex() + depth + 1;
+      } else {
+        offset = getCacheIndex();
+      }
         
       mvm::BumpPtrAllocator& allocator = JCL->allocator;
 
@@ -1484,7 +1565,8 @@
       depth = 1;
       display[0] = C->super->virtualVT;
       display[1] = this;
-      nbSecondaryTypes = 2;  
+      offset = getCacheIndex() + 2;
+      nbSecondaryTypes = 2;
       
       mvm::BumpPtrAllocator& allocator = JCL->allocator;
       secondaryTypes = (JavaVirtualTable**)
@@ -1510,6 +1592,7 @@
     display[0] = 0;
     display[1] = this;
     nbSecondaryTypes = 2;
+    offset = getCacheIndex() + 2;
 
     // The list of secondary types has not been allocated yet by
     // java.lang.Object[]. The initialiseVT function will update the current
@@ -1517,3 +1600,11 @@
   }
 }
 
+
+JavaVirtualTable::JavaVirtualTable(ClassPrimitive* C) {
+  // Only used for subtype checking
+  depth = 0;
+  display[0] = this;
+  nbSecondaryTypes = 0;
+  offset = getCacheIndex() + 1;
+}

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

==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JavaClass.h (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JavaClass.h Sun Apr 19 14:09:19 2009
@@ -187,6 +187,11 @@
   /// classLoader - The Jnjvm class loader that loaded the class.
   ///
   JnjvmClassLoader* classLoader;
+  
+  /// virtualVT - The virtual table of instances of this class.
+  ///
+  JavaVirtualTable* virtualVT;
+  
 
 //===----------------------------------------------------------------------===//
 //
@@ -454,10 +459,6 @@
   /// 
   uint32 virtualSize;
 
-  /// virtualVT - The virtual table of instances of this class.
-  ///
-  JavaVirtualTable* virtualVT;
-  
   /// IsolateInfo - Per isolate informations for static instances and
   /// initialization state.
   ///
@@ -900,7 +901,13 @@
   /// needsInitialisationCheck - Does the method need an initialisation check?
   ///
   bool needsInitialisationCheck();
-   
+
+private:
+
+  /// makeVT - Create the virtual table of this class.
+  ///
+  void makeVT();
+
 };
 
 /// ClassArray - This class represents Java array classes.
@@ -918,10 +925,6 @@
   ///
   CommonClass*  _baseClass;
 
-  /// virtualVT - The virtual table of this array class.
-  ///
-  JavaVirtualTable* virtualVT;
-
   /// baseClass - Get the base class of this array class.
   ///
   CommonClass* baseClass() const {
@@ -1339,16 +1342,52 @@
 
 };
 
+/// JavaVirtualTable - This class is the virtual table of instances of
+/// Java classes. Besides holding function pointers for virtual calls,
+/// it contains a bunch of information useful for fast dynamic type checking.
+/// These are placed here for fast access of information from a Java object
+/// (that only points to the VT, not the class).
+///
 class JavaVirtualTable : public VirtualTable {
 public:
+
+  /// cl - The class which defined this virtual table.
+  ///
   CommonClass* cl;
+
+  /// depth - The super hierarchy depth of the class.
+  ///
   size_t depth;
+
+  /// offset - Offset in the virtual table where this virtual
+  /// table may be pointed. The offset is the cache if the class
+  /// is an interface or depth is too big, or an offset in the display.
+  ///
   size_t offset;
-  size_t cache;
+
+  /// cache - The cached result for better type checks on secondary types.
+  ///
+  JavaVirtualTable* cache;
+
+  /// display - Array of super classes.
+  ///
   JavaVirtualTable* display[8];
+
+  /// nbSecondaryTypes - The length of the secondary type list.
+  ///
   size_t nbSecondaryTypes;
+
+  /// secondaryTypes - The list of secondary types of this type. These
+  /// are the interface and all the supers whose depth is too big.
+  ///
   JavaVirtualTable** secondaryTypes;
 
+  /// baseClass - Holds the base class VT of an array, or the array class VT
+  /// of a regular class.
+  ///
+  JavaVirtualTable* baseClassVT;
+
+  /// Java methods for the virtual table functions.
   uintptr_t init;
   uintptr_t equals;
   uintptr_t hashCode;
@@ -1362,40 +1401,67 @@
   uintptr_t waitMsNs;
   uintptr_t virtualMethods[1];
 
+  /// operator new - Allocates a JavaVirtualTable with the given size. The
+  /// size must contain the additional information for type checking, as well
+  /// as the function pointers.
+  ///
   void* operator new(size_t sz, mvm::BumpPtrAllocator& allocator,
                      uint32 nbMethods) {
     return allocator.Allocate(sizeof(uintptr_t) * (nbMethods));
   }
 
+  /// JavaVirtualTable - Create JavaVirtualTable objects for classes, array
+  /// classes and primitive classes.
+  ///
   JavaVirtualTable(Class* C);
-  
   JavaVirtualTable(ClassArray* C);
+  JavaVirtualTable(ClassPrimitive* C);
 
+
+  /// getFirstJavaMethod - Get the byte offset of the first Java method
+  /// (<init>).
+  ///
   uintptr_t* getFirstJavaMethod() {
     return &init;
   }
   
+  /// getFirstJavaMethodIndex - Get the word offset of the first Java method.
+  ///
   static uint32_t getFirstJavaMethodIndex() {
-    return 17;
+    return 18;
   }
    
-  static uint32_t getNumMethods() {
-    return 28;
+  /// getBaseSize - Get the size of the java.lang.Object virtual table.
+  ///
+  static uint32_t getBaseSize() {
+    return 29;
   }
   
+  /// getNumJavaMethods - Get the number of methods of the java.lang.Object
+  /// class.
+  ///
   static uint32_t getNumJavaMethods() {
     return 11;
   }
 
+  /// getDisplayLength - Get the length of the display (primary type) array.
+  ///
   static uint32_t getDisplayLength() {
     return 8;
   }
   
-private:
+  /// getCacheIndex - Get the word offset of the type cache.
+  ///
   static uint32_t getCacheIndex() {
     return 6;
   }
 
+  /// isSubtypeOf - Returns true if the given VT is a subtype of the this
+  /// VT.
+  ///
+  bool isSubtypeOf(JavaVirtualTable* VT);
+
+
 };
 
 

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

==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JavaRuntimeJIT.cpp (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JavaRuntimeJIT.cpp Sun Apr 19 14:09:19 2009
@@ -409,24 +409,9 @@
 }
 
 // Never throws.
-extern "C" bool instanceOf(JavaObject* obj, UserCommonClass* cl) {
-  return obj->instanceOf(cl);
-}
-
-// Never throws.
-extern "C" bool instantiationOfArray(UserCommonClass* cl1,
-                                     UserClassArray* cl2) {
-  return cl1->instantiationOfArray(cl2);
-}
-
-// Never throws.
-extern "C" bool implements(UserCommonClass* cl1, UserCommonClass* cl2) {
-  return cl1->implements(cl2);
-}
-
-// Never throws.
-extern "C" bool isAssignableFrom(UserCommonClass* cl1, UserCommonClass* cl2) {
-  return cl1->isAssignableFrom(cl2);
+extern "C" bool jnjvmIsAssignableFrom(JavaVirtualTable* VT1,
+                                      JavaVirtualTable* VT2) {
+  return VT1->isSubtypeOf(VT2);
 }
 
 // Does not call any Java code.
@@ -542,22 +527,39 @@
   return exc;
 }
 
+// Creates a Java object and then throws it.
+extern "C" JavaObject* jnjvmArrayStoreException(JavaVirtualTable* VT) {
+  JavaObject *exc = 0;
+  JavaThread *th = JavaThread::get();
+
+  BEGIN_NATIVE_EXCEPTION(1)
+  
+  exc = th->getJVM()->CreateArrayStoreException(VT);
+
+  END_NATIVE_EXCEPTION
+
+#ifdef DWARF_EXCEPTIONS
+  th->throwException(exc);
+#else
+  th->pendingException = exc;
+#endif
+  
+  return exc;
+}
+
 extern "C" void printMethodStart(JavaMethod* meth) {
-  printf("[%p] executing %s\n", (void*)mvm::Thread::get(),
+  fprintf(stderr, "[%p] executing %s\n", (void*)mvm::Thread::get(),
          meth->printString());
-  fflush(stdout);
 }
 
 extern "C" void printMethodEnd(JavaMethod* meth) {
-  printf("[%p] return from %s\n", (void*)mvm::Thread::get(),
+  fprintf(stderr, "[%p] return from %s\n", (void*)mvm::Thread::get(),
          meth->printString());
-  fflush(stdout);
 }
 
 extern "C" void printExecution(uint32 opcode, uint32 index, JavaMethod* meth) {
-  printf("[%p] executing %s %s at %d\n", (void*)mvm::Thread::get(),
+  fprintf(stderr, "[%p] executing %s %s at %d\n", (void*)mvm::Thread::get(),
          meth->printString(), OpcodeNames[opcode], index);
-  fflush(stdout);
 }
 
 #ifdef SERVICE

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

==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.cpp (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.cpp Sun Apr 19 14:09:19 2009
@@ -325,6 +325,12 @@
                      "Java heap space");
 }
 
+JavaObject* Jnjvm::CreateArrayStoreException(JavaVirtualTable* VT) {
+  return CreateError(upcalls->ArrayStoreException,
+                     upcalls->InitArrayStoreException,
+                     VT->cl->printString());
+}
+
 JavaObject* Jnjvm::CreateClassCastException(JavaObject* obj,
                                             UserCommonClass* cl) {
   return CreateError(upcalls->ClassCastException,

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

==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.h (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.h Sun Apr 19 14:09:19 2009
@@ -252,6 +252,7 @@
   JavaObject* CreateNegativeArraySizeException();
   JavaObject* CreateClassCastException(JavaObject* obj, UserCommonClass* cl);
   JavaObject* CreateLinkageError(const char* msg = "");
+  JavaObject* CreateArrayStoreException(JavaVirtualTable* VT);
   
   /// Exceptions - These are the only exceptions VMKit will make.
   ///





More information about the vmkit-commits mailing list