[vmkit-commits] [vmkit] r90861 - in /vmkit/trunk: include/jnjvm/JnjvmModule.h include/mvm/UTF8.h lib/JnJVM/Compiler/JITInfo.cpp lib/JnJVM/Compiler/JavaAOTCompiler.cpp lib/JnJVM/Compiler/JavaJIT.cpp lib/JnJVM/Compiler/JavaJITCompiler.cpp lib/JnJVM/Compiler/JnjvmModule.cpp lib/JnJVM/Compiler/LowerConstantCalls.cpp lib/JnJVM/LLVMRuntime/runtime-default.ll lib/JnJVM/VMCore/JavaClass.cpp lib/JnJVM/VMCore/JavaClass.h lib/JnJVM/VMCore/JavaObject.h lib/JnJVM/VMCore/JavaRuntimeJIT.cpp lib/Mvm/Runtime/UTF8.cpp

Nicolas Geoffray nicolas.geoffray at lip6.fr
Tue Dec 8 08:54:05 PST 2009


Author: geoffray
Date: Tue Dec  8 10:54:05 2009
New Revision: 90861

URL: http://llvm.org/viewvc/llvm-project?rev=90861&view=rev
Log:
Implement a variant of IMT-based interface calls: instead of calling
a stub conflict resolution, inline the stub in the caller.


Modified:
    vmkit/trunk/include/jnjvm/JnjvmModule.h
    vmkit/trunk/include/mvm/UTF8.h
    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/JnjvmModule.cpp
    vmkit/trunk/lib/JnJVM/Compiler/LowerConstantCalls.cpp
    vmkit/trunk/lib/JnJVM/LLVMRuntime/runtime-default.ll
    vmkit/trunk/lib/JnJVM/VMCore/JavaClass.cpp
    vmkit/trunk/lib/JnJVM/VMCore/JavaClass.h
    vmkit/trunk/lib/JnJVM/VMCore/JavaObject.h
    vmkit/trunk/lib/JnJVM/VMCore/JavaRuntimeJIT.cpp
    vmkit/trunk/lib/Mvm/Runtime/UTF8.cpp

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

==============================================================================
--- vmkit/trunk/include/jnjvm/JnjvmModule.h (original)
+++ vmkit/trunk/include/jnjvm/JnjvmModule.h Tue Dec  8 10:54:05 2009
@@ -300,6 +300,7 @@
   llvm::Function* RuntimeDelegateeFunction;
   llvm::Function* ArrayLengthFunction;
   llvm::Function* GetVTFunction;
+  llvm::Function* GetIMTFunction;
   llvm::Function* GetClassFunction;
   llvm::Function* GetVTFromClassFunction;
   llvm::Function* GetVTFromClassArrayFunction;
@@ -343,6 +344,7 @@
   llvm::Constant* OffsetDepthInVTConstant;
   llvm::Constant* OffsetDisplayInVTConstant;
   llvm::Constant* OffsetBaseClassVTInVTConstant;
+  llvm::Constant* OffsetIMTInVTConstant;
   
   llvm::Constant* OffsetBaseClassInArrayClassConstant;
   llvm::Constant* OffsetLogSizeInPrimitiveClassConstant;
@@ -391,6 +393,7 @@
   bool cooperativeGC;
   
   virtual void makeVT(Class* cl) = 0;
+  virtual void makeIMT(Class* cl) = 0;
   
   std::map<llvm::Function*, JavaMethod*> functions;  
   typedef std::map<llvm::Function*, JavaMethod*>::iterator function_iterator;
@@ -543,6 +546,7 @@
   }
 
   virtual void makeVT(Class* cl);
+  virtual void makeIMT(Class* cl);
   
   virtual JavaCompiler* Create(const std::string& ModuleID) {
     return new JavaJITCompiler(ModuleID);
@@ -616,6 +620,7 @@
                                    bool stat);
   
   virtual void makeVT(Class* cl);
+  virtual void makeIMT(Class* cl);
  
   llvm::Constant* HandleMagic(JavaObject* obj, CommonClass* cl);
   virtual llvm::Constant* getFinalObject(JavaObject* obj, CommonClass* cl);

Modified: vmkit/trunk/include/mvm/UTF8.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/include/mvm/UTF8.h?rev=90861&r1=90860&r2=90861&view=diff

==============================================================================
--- vmkit/trunk/include/mvm/UTF8.h (original)
+++ vmkit/trunk/include/mvm/UTF8.h Tue Dec  8 10:54:05 2009
@@ -57,6 +57,13 @@
   }
 
 	void print(PrintBuffer *pb) const;
+
+	static uint32_t readerHasher(const uint16* buf, sint32 size);
+	
+	uint32_t hash() const {
+		return readerHasher(elements, size);
+	}
+
 };
 
 

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

==============================================================================
--- vmkit/trunk/lib/JnJVM/Compiler/JITInfo.cpp (original)
+++ vmkit/trunk/lib/JnJVM/Compiler/JITInfo.cpp Tue Dec  8 10:54:05 2009
@@ -84,6 +84,7 @@
     virtualSizeConstant = ConstantInt::get(Type::getInt32Ty(context), size);
    
     Mod->makeVT(classDef);
+    Mod->makeIMT(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=90861&r1=90860&r2=90861&view=diff

==============================================================================
--- vmkit/trunk/lib/JnJVM/Compiler/JavaAOTCompiler.cpp (original)
+++ vmkit/trunk/lib/JnJVM/Compiler/JavaAOTCompiler.cpp Tue Dec  8 10:54:05 2009
@@ -1502,8 +1502,10 @@
   } else {
     Elemts.push_back(Constant::getNullValue(PTy));
   }
-
-  
+    
+  // TODO: IMT
+  Elemts.push_back(Constant::getNullValue(PTy));
+ 
   // methods
   for (uint32 i = JavaVirtualTable::getFirstJavaMethodIndex(); i < size; ++i) {
     JavaMethod* meth = ((JavaMethod**)RealVT)[i];
@@ -1761,6 +1763,9 @@
 
 }
 
+void JavaAOTCompiler::makeIMT(Class* cl) {
+}
+
 void JavaAOTCompiler::setMethod(JavaMethod* meth, void* ptr, const char* name) {
   Function* func = getMethodInfo(meth)->getMethod();
   func->setName(name);

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

==============================================================================
--- vmkit/trunk/lib/JnJVM/Compiler/JavaJIT.cpp (original)
+++ vmkit/trunk/lib/JnJVM/Compiler/JavaJIT.cpp Tue Dec  8 10:54:05 2009
@@ -2180,14 +2180,18 @@
   makeArgs(it, index, args, signature->nbArguments + 1);
   
   const llvm::Type* retType = virtualType->getReturnType();
-  BasicBlock* endBlock = createBasicBlock("end virtual invoke");
+  BasicBlock* endBlock = createBasicBlock("end interface invoke");
   PHINode * node = 0;
   if (retType != Type::getVoidTy(getGlobalContext())) {
     node = PHINode::Create(retType, "", endBlock);
   }
   
   JITVerifyNull(args[0]);
-  
+ 
+
+#if 0
+
+
   Value* zero = module->constantZero;
   Value* one = module->constantOne;
 
@@ -2264,6 +2268,114 @@
     node->addIncoming(ret, currentBlock);
   }
 
+#else
+
+  CommonClass* cl = 0;
+  JavaMethod* meth = 0;
+  ctpInfo->infoOfMethod(index, ACC_VIRTUAL, cl, meth);
+  Value* Meth = 0;
+
+  if (meth) {
+    Meth = TheCompiler->getMethodInClass(meth);
+  } else {
+    Meth = getConstantPoolAt(index, module->InterfaceLookupFunction,
+                             module->JavaMethodType, 0, false);
+  }
+
+  BasicBlock* label_bb = createBasicBlock("bb");
+  BasicBlock* label_bb4 = createBasicBlock("bb4");
+  BasicBlock* label_bb6 = createBasicBlock("bb6");
+  BasicBlock* label_bb7 = createBasicBlock("bb7");
+    
+  // Block entry (label_entry)
+  Value* VT = CallInst::Create(module->GetVTFunction, args[0], "",
+                               currentBlock);
+  Value* IMT = CallInst::Create(module->GetIMTFunction, VT, "",
+                                currentBlock);
+
+  uint32_t tableIndex = InterfaceMethodTable::getIndex(name, signature->keyName);
+  Constant* Index = ConstantInt::get(Type::getInt32Ty(getGlobalContext()),
+                                     tableIndex);
+
+  Value* indices[2] = { module->constantZero, Index };
+  Instruction* ptr_18 = GetElementPtrInst::Create(IMT, indices, indices + 2, "",
+                                                  currentBlock);
+  Instruction* int32_19 = new LoadInst(ptr_18, "", false, currentBlock);
+  int32_19 = new PtrToIntInst(int32_19, module->pointerSizeType, "",
+                              currentBlock);
+  Value* one = ConstantInt::get(module->pointerSizeType, 1);
+  Value* zero = ConstantInt::get(module->pointerSizeType, 0);
+  BinaryOperator* int32_20 = BinaryOperator::Create(Instruction::And, int32_19,
+                                                    one, "", currentBlock);
+  ICmpInst* int1_toBool = new ICmpInst(*currentBlock, ICmpInst::ICMP_EQ,
+                                       int32_20, zero, "toBool");
+  BranchInst::Create(label_bb, label_bb4, int1_toBool, currentBlock);
+    
+  // Block bb (label_bb)
+  currentBlock = label_bb;
+  CastInst* ptr_22 = new IntToPtrInst(int32_19, virtualPtrType, "", currentBlock);
+  Value* ret = invoke(ptr_22, args, "", currentBlock);
+  if (node) node->addIncoming(ret, currentBlock);
+  BranchInst::Create(endBlock, currentBlock);
+    
+  // Block bb4 (label_bb4)
+  currentBlock = label_bb4;
+  Constant* MinusTwo = ConstantInt::get(module->pointerSizeType, -2);
+  BinaryOperator* int32_25 = BinaryOperator::Create(Instruction::And, int32_19,
+                                                    MinusTwo, "", currentBlock);
+  const PointerType* Ty = PointerType::getUnqual(module->JavaMethodType);
+  CastInst* ptr_26 = new IntToPtrInst(int32_25, Ty, "", currentBlock);
+  LoadInst* int32_27 = new LoadInst(ptr_26, "", false, currentBlock);
+  ICmpInst* int1_28 = new ICmpInst(*currentBlock, ICmpInst::ICMP_EQ, int32_27,
+                                   Meth, "");
+  BranchInst::Create(label_bb6, label_bb7, int1_28, currentBlock);
+    
+  // Block bb6 (label_bb6)
+  currentBlock = label_bb6;
+  PHINode* ptr_table_0_lcssa = PHINode::Create(Ty, "table.0.lcssa",
+                                               currentBlock);
+  ptr_table_0_lcssa->reserveOperandSpace(2);
+  ptr_table_0_lcssa->addIncoming(ptr_26, label_bb4);
+   
+  GetElementPtrInst* ptr_31 = GetElementPtrInst::Create(ptr_table_0_lcssa,
+                                                        module->constantOne, "",
+                                                        currentBlock);
+
+  LoadInst* int32_32 = new LoadInst(ptr_31, "", false, currentBlock);
+  CastInst* ptr_33 = new BitCastInst(int32_32, virtualPtrType, "",
+                                     currentBlock);
+  ret = invoke(ptr_33, args, "", currentBlock);
+  if (node) node->addIncoming(ret, currentBlock);
+  BranchInst::Create(endBlock, currentBlock);
+    
+  // Block bb7 (label_bb7)
+  currentBlock = label_bb7;
+  PHINode* int32_indvar = PHINode::Create(Type::getInt32Ty(*llvmContext),
+                                          "indvar", currentBlock);
+  int32_indvar->reserveOperandSpace(2);
+  int32_indvar->addIncoming(module->constantZero, label_bb4);
+    
+  BinaryOperator* int32_table_010_rec =
+    BinaryOperator::Create(Instruction::Shl, int32_indvar, module->constantOne,
+                           "table.010.rec", currentBlock);
+
+  BinaryOperator* int32__rec =
+    BinaryOperator::Create(Instruction::Add, int32_table_010_rec,
+                           module->constantTwo, ".rec", currentBlock);
+  GetElementPtrInst* ptr_37 = GetElementPtrInst::Create(ptr_26, int32__rec, "",
+                                                        currentBlock);
+  LoadInst* int32_38 = new LoadInst(ptr_37, "", false, currentBlock);
+  ICmpInst* int1_39 = new ICmpInst(*currentBlock, ICmpInst::ICMP_EQ, int32_38,
+                                   Meth, "");
+  BinaryOperator* int32_indvar_next =
+    BinaryOperator::Create(Instruction::Add, int32_indvar, module->constantOne,
+                           "indvar.next", currentBlock);
+  BranchInst::Create(label_bb6, label_bb7, int1_39, currentBlock);
+  
+  int32_indvar->addIncoming(int32_indvar_next, currentBlock);
+  ptr_table_0_lcssa->addIncoming(ptr_37, currentBlock);
+      
+#endif
   currentBlock = endBlock;
   if (node) {
     if (node->getType() == module->JavaObjectType) {

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

==============================================================================
--- vmkit/trunk/lib/JnJVM/Compiler/JavaJITCompiler.cpp (original)
+++ vmkit/trunk/lib/JnJVM/Compiler/JavaJITCompiler.cpp Tue Dec  8 10:54:05 2009
@@ -262,6 +262,48 @@
 
 }
 
+void JavaJITCompiler::makeIMT(Class* cl) {
+  InterfaceMethodTable* IMT = cl->virtualVT->IMT;
+  if (!IMT) return;
+ 
+  std::vector<JavaMethod*> contents[InterfaceMethodTable::NumIndexes];
+  cl->fillIMT(contents);
+  
+  ExecutionEngine* EE = mvm::MvmModule::executionEngine;
+  
+  for (uint32_t i = 0; i < InterfaceMethodTable::NumIndexes; ++i) {
+    std::vector<JavaMethod*>& atIndex = contents[i];
+    uint32_t size = atIndex.size();
+    if (size == 1) {
+      JavaMethod* meth = cl->lookupMethodDontThrow(atIndex[0]->name,
+                                                   atIndex[0]->type,
+                                                   false, true, 0);
+      LLVMMethodInfo* LMI = getMethodInfo(meth);
+      Function* func = LMI->getMethod();
+      uintptr_t res = (uintptr_t)EE->getPointerToFunctionOrStub(func);
+      IMT->contents[i] = res;
+    } else if (size > 1) {
+      uint32_t length = 2 * size * sizeof(uintptr_t);
+      
+      uintptr_t* table = (uintptr_t*)
+        cl->classLoader->allocator.Allocate(length, "IMT");
+      
+      IMT->contents[i] = (uintptr_t)table | 1;
+
+      for (uint32_t j = 0; j < size; ++j) {
+        JavaMethod* Imeth = atIndex[j];
+        JavaMethod* Cmeth = cl->lookupMethodDontThrow(Imeth->name, Imeth->type,
+                                                      false, true, 0);
+        LLVMMethodInfo* LMI = getMethodInfo(Cmeth);
+        Function* func = LMI->getMethod();
+        uintptr_t res = (uintptr_t)EE->getPointerToFunctionOrStub(func);
+        table[j << 1] = (uintptr_t)Imeth;
+        table[(j << 1) + 1] = res;
+      }
+    }
+  }
+}
+
 void JavaJITCompiler::setMethod(JavaMethod* meth, void* ptr, const char* name) {
   Function* func = getMethodInfo(meth)->getMethod();
   func->setName(name);

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

==============================================================================
--- vmkit/trunk/lib/JnJVM/Compiler/JnjvmModule.cpp (original)
+++ vmkit/trunk/lib/JnJVM/Compiler/JnjvmModule.cpp Tue Dec  8 10:54:05 2009
@@ -199,6 +199,8 @@
   OffsetDisplayInVTConstant = constantSeven;
   OffsetBaseClassVTInVTConstant =
     ConstantInt::get(Type::getInt32Ty(getGlobalContext()), 17);
+  OffsetIMTInVTConstant =
+    ConstantInt::get(Type::getInt32Ty(getGlobalContext()), 18);
   
   OffsetAccessInCommonClassConstant = constantOne;
   IsArrayConstant = ConstantInt::get(Type::getInt16Ty(getGlobalContext()),
@@ -264,6 +266,7 @@
   GetConstantPoolAtFunction = module->getFunction("getConstantPoolAt");
   ArrayLengthFunction = module->getFunction("arrayLength");
   GetVTFunction = module->getFunction("getVT");
+  GetIMTFunction = module->getFunction("getIMT");
   GetClassFunction = module->getFunction("getClass");
   ClassLookupFunction = module->getFunction("jnjvmClassLookup");
   GetVTFromClassFunction = module->getFunction("getVTFromClass");

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

==============================================================================
--- vmkit/trunk/lib/JnJVM/Compiler/LowerConstantCalls.cpp (original)
+++ vmkit/trunk/lib/JnJVM/Compiler/LowerConstantCalls.cpp Tue Dec  8 10:54:05 2009
@@ -224,6 +224,17 @@
           Value* VT = new LoadInst(VTPtr, "", CI);
           CI->replaceAllUsesWith(VT);
           CI->eraseFromParent();
+        } else if (V == module->GetIMTFunction) {
+          Changed = true;
+          Value* val = Call.getArgument(0); // get the VT
+          Value* indexes[2] = { module->constantZero,
+                                module->OffsetIMTInVTConstant };
+          Value* IMTPtr = GetElementPtrInst::Create(val, indexes, indexes + 2,
+                                                    "", CI);
+          Value* IMT = new LoadInst(IMTPtr, "", CI);
+          IMT = new BitCastInst(IMT, CI->getType(), "", CI);
+          CI->replaceAllUsesWith(IMT);
+          CI->eraseFromParent();
         } else if (V == module->GetClassFunction) {
           Changed = true;
           Value* val = Call.getArgument(0); // get the object

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=90861&r1=90860&r2=90861&view=diff

==============================================================================
--- vmkit/trunk/lib/JnJVM/LLVMRuntime/runtime-default.ll (original)
+++ vmkit/trunk/lib/JnJVM/LLVMRuntime/runtime-default.ll Tue Dec  8 10:54:05 2009
@@ -64,6 +64,9 @@
 ;;; getVT - Get the VT of the object.
 declare %VT* @getVT(%JavaObject*) readnone 
 
+;;; getIMT - Get the IMT of the VT.
+declare %VT* @getIMT(%VT*) readnone 
+
 ;;; getClass - Get the class of an object.
 declare %JavaCommonClass* @getClass(%JavaObject*) readnone 
 
@@ -107,7 +110,7 @@
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
 ;;; jnjvmInterfaceLookup - Used for interface calls.
-declare i8* @jnjvmInterfaceLookup(%CacheNode*, %JavaObject*)
+declare i8* @jnjvmInterfaceLookup(%JavaClass*, i32, ...)
 
 ;;; jnjvmMultiCallNew - Allocate multi-dimensional arrays. This will go to
 ;;; allocation specific methods.

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

==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JavaClass.cpp (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JavaClass.cpp Tue Dec  8 10:54:05 2009
@@ -772,6 +772,22 @@
   }
 }
 
+void Class::fillIMT(std::vector<JavaMethod*>* meths) {
+  for (uint32 i = 0; i < nbInterfaces; ++i) {
+    interfaces[i]->fillIMT(meths);
+  }
+
+  if (super) super->fillIMT(meths);
+
+  if (isInterface()) {
+    for (uint32 i = 0; i < nbVirtualMethods; ++i) {
+      JavaMethod& meth = virtualMethods[i];
+      uint32_t index = InterfaceMethodTable::getIndex(meth.name, meth.type);
+      meths[index].push_back(&meth);
+    }
+  }
+}
+
 void Class::makeVT() {
   
   for (uint32 i = 0; i < nbVirtualMethods; ++i) {
@@ -1377,6 +1393,10 @@
     destructor = 0;
     operatorDelete = 0;
     
+    // Set IMT.
+    if (!isAbstract(C->access))
+      IMT = new (C->classLoader->allocator, "IMT") InterfaceMethodTable();
+    
     // Set the class of this VT.
     cl = C;
     
@@ -1439,7 +1459,7 @@
     }
 
   } else {
-    // Set the tracer, destructor and delete
+    // Set the tracer, destructor and delete.
     tracer = (uintptr_t)JavaObjectTracer;
     destructor = 0;
     operatorDelete = 0;

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

==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JavaClass.h (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JavaClass.h Tue Dec  8 10:54:05 2009
@@ -915,6 +915,11 @@
   ///
   bool needsInitialisationCheck();
 
+  /// fillIMT - Fill the vector with vectors of methods with the same IMT
+  /// index.
+  ///
+  void fillIMT(std::vector<JavaMethod*>* meths);
+
 private:
 
   /// makeVT - Create the virtual table of this class.

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

==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JavaObject.h (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JavaObject.h Tue Dec  8 10:54:05 2009
@@ -10,7 +10,9 @@
 #ifndef JNJVM_JAVA_OBJECT_H
 #define JNJVM_JAVA_OBJECT_H
 
+#include "mvm/Allocator.h"
 #include "mvm/Object.h"
+#include "mvm/UTF8.h"
 #include "mvm/Threads/Locks.h"
 #include "mvm/Threads/Thread.h"
 
@@ -27,6 +29,16 @@
 class Typedef;
 class UserCommonClass;
 
+class InterfaceMethodTable : public mvm::PermanentObject {
+public:
+	static const uint32_t NumIndexes = 29;
+	uintptr_t contents[NumIndexes];
+
+  static uint32_t getIndex(const mvm::UTF8* name, const mvm::UTF8* type) {
+    return (name->hash() + type->hash()) % NumIndexes;
+  }
+};
+
 /// 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.
@@ -72,6 +84,10 @@
   ///
   JavaVirtualTable* baseClassVT;
 
+  /// IMT - The interface method table.
+  ///
+  InterfaceMethodTable* IMT;
+
   /// Java methods for the virtual table functions.
   uintptr_t init;
   uintptr_t equals;
@@ -113,13 +129,13 @@
   /// getFirstJavaMethodIndex - Get the word offset of the first Java method.
   ///
   static uint32_t getFirstJavaMethodIndex() {
-    return 18;
+    return 19;
   }
    
   /// getBaseSize - Get the size of the java.lang.Object virtual table.
   ///
   static uint32_t getBaseSize() {
-    return 29;
+    return 30;
   }
   
   /// getNumJavaMethods - Get the number of methods of the java.lang.Object

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

==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JavaRuntimeJIT.cpp (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JavaRuntimeJIT.cpp Tue Dec  8 10:54:05 2009
@@ -25,6 +25,7 @@
 
 using namespace jnjvm;
 
+#if 0
 // Throws if the method is not found.
 extern "C" void* jnjvmInterfaceLookup(CacheNode* cache, JavaObject *obj) {
 
@@ -107,6 +108,40 @@
 
   return res; 
 }
+#endif
+
+extern "C" void* jnjvmInterfaceLookup(UserClass* caller, uint32 index) {
+
+  void* res = 0;
+
+  BEGIN_NATIVE_EXCEPTION(1)
+  
+  UserConstantPool* ctpInfo = caller->getConstantPool();
+  if (ctpInfo->ctpRes[index]) {
+    res = ctpInfo->ctpRes[index];
+  } else {
+    UserCommonClass* cl = 0;
+    const UTF8* utf8 = 0;
+    Signdef* sign = 0;
+  
+    ctpInfo->resolveMethod(index, cl, utf8, sign);
+    assert(cl->isClass() && isInterface(cl->access) && "Wrong type of method");
+    res = cl->asClass()->lookupInterfaceMethodDontThrow(utf8, sign->keyName);
+    
+    assert(res && "Can not found method");
+    ctpInfo->ctpRes[index] = (void*)res;
+  }
+  
+    
+  END_NATIVE_EXCEPTION
+
+  // Since the function is marked readnone, LLVM may move it after the
+  // exception check. Therefore, we trick LLVM to check the return value of the
+  // function.
+  JavaObject* obj = JavaThread::get()->pendingException;
+  if (obj) return (JavaMethod*)obj;
+  return res;
+}
 
 // Throws if the field is not found.
 extern "C" void* jnjvmVirtualFieldLookup(UserClass* caller, uint32 index) {

Modified: vmkit/trunk/lib/Mvm/Runtime/UTF8.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/Mvm/Runtime/UTF8.cpp?rev=90861&r1=90860&r2=90861&view=diff

==============================================================================
--- vmkit/trunk/lib/Mvm/Runtime/UTF8.cpp (original)
+++ vmkit/trunk/lib/Mvm/Runtime/UTF8.cpp Tue Dec  8 10:54:05 2009
@@ -29,7 +29,7 @@
   return (r1 & 255) + ((r0 & 255) << 8);
 }
 
-static uint32 readerHasher(const uint16* buf, sint32 size) {
+uint32 UTF8::readerHasher(const uint16* buf, sint32 size) {
   uint32 r0 = 0, r1 = 0;
   for (sint32 i = 0; i < size; i++) {
     uint16 c = buf[i];
@@ -58,7 +58,7 @@
 
 void UTF8Map::replace(const UTF8* oldUTF8, const UTF8* newUTF8) {
   lock.lock();
-  uint32 key = readerHasher(oldUTF8->elements, oldUTF8->size);
+  uint32 key = oldUTF8->hash();
   std::pair<UTF8Map::iterator, UTF8Map::iterator> p = map.equal_range(key);
   
   for (UTF8Map::iterator i = p.first; i != p.second; i++) {
@@ -102,7 +102,7 @@
 
 const UTF8* UTF8Map::lookupOrCreateReader(const uint16* buf, uint32 len) {
   sint32 size = (sint32)len;
-  uint32 key = readerHasher(buf, size);
+  uint32 key = UTF8::readerHasher(buf, size);
   const UTF8* res = 0;
   lock.lock();
   
@@ -147,7 +147,7 @@
 
 const UTF8* UTF8Map::lookupReader(const uint16* buf, uint32 len) {
   sint32 size = (sint32)len;
-  uint32 key = readerHasher(buf, size);
+  uint32 key = UTF8::readerHasher(buf, size);
   const UTF8* res = 0;
   lock.lock();
   
@@ -165,5 +165,5 @@
 }
 
 void UTF8Map::insert(const UTF8* val) {
-  map.insert(std::make_pair(readerHasher(val->elements, val->size), val));
+  map.insert(std::make_pair(val->hash(), val));
 }





More information about the vmkit-commits mailing list