[vmkit-commits] [vmkit] r69885 - in /vmkit/trunk/lib/JnJVM: Compiler/JnjvmModule.cpp Compiler/LowerConstantCalls.cpp LLVMRuntime/runtime-default.ll VMCore/JavaClass.h VMCore/JavaRuntimeJIT.cpp

Nicolas Geoffray nicolas.geoffray at lip6.fr
Thu Apr 23 04:23:13 PDT 2009


Author: geoffray
Date: Thu Apr 23 06:22:53 2009
New Revision: 69885

URL: http://llvm.org/viewvc/llvm-project?rev=69885&view=rev
Log:
Inline dynamic runtime checks.


Modified:
    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.h
    vmkit/trunk/lib/JnJVM/VMCore/JavaRuntimeJIT.cpp

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

==============================================================================
--- vmkit/trunk/lib/JnJVM/Compiler/JnjvmModule.cpp (original)
+++ vmkit/trunk/lib/JnJVM/Compiler/JnjvmModule.cpp Thu Apr 23 06:22:53 2009
@@ -349,7 +349,7 @@
  
   GetClassDelegateeFunction = module->getFunction("getClassDelegatee");
   RuntimeDelegateeFunction = module->getFunction("jnjvmRuntimeDelegatee");
-  IsAssignableFromFunction = module->getFunction("jnjvmIsAssignableFrom");
+  IsAssignableFromFunction = module->getFunction("isAssignableFrom");
   IsSecondaryClassFunction = module->getFunction("isSecondaryClass");
   GetDepthFunction = module->getFunction("getDepth");
   GetStaticInstanceFunction = module->getFunction("getStaticInstance");

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

==============================================================================
--- vmkit/trunk/lib/JnJVM/Compiler/LowerConstantCalls.cpp (original)
+++ vmkit/trunk/lib/JnJVM/Compiler/LowerConstantCalls.cpp Thu Apr 23 06:22:53 2009
@@ -523,16 +523,165 @@
           Value* res = new LoadInst(val, "", CI);
           CI->replaceAllUsesWith(res);
           CI->eraseFromParent();
+        } else if (V == module->IsAssignableFromFunction) {
+          Changed = true;
+          Value* VT1 = Call.getArgument(0);
+          Value* VT2 = Call.getArgument(1);
+          
+          BasicBlock* EndBlock = II->getParent()->splitBasicBlock(II);
+          I->getParent()->getTerminator()->eraseFromParent();
+          
+          BasicBlock* CurEndBlock = BasicBlock::Create("", &F);
+          BasicBlock* FailedBlock = BasicBlock::Create("", &F);
+          PHINode* node = PHINode::Create(Type::Int1Ty, "", CurEndBlock);
+
+          ConstantInt* CC = ConstantInt::get(Type::Int32Ty,
+              JavaVirtualTable::getOffsetIndex());
+          Value* indices[2] = { module->constantZero, CC };
+          Value* Offset = GetElementPtrInst::Create(VT2, indices, indices + 2,
+                                                    "", CI);
+          Offset = new LoadInst(Offset, "", false, CI);
+          Offset = new PtrToIntInst(Offset, Type::Int32Ty, "", CI);
+          indices[1] = Offset;
+          Value* CurVT = GetElementPtrInst::Create(VT1, indices, indices + 2,
+                                                   "", CI);
+          CurVT = new LoadInst(CurVT, "", false, CI);
+          CurVT = new BitCastInst(CurVT, module->VTType, "", CI);
+             
+          Value* res = new ICmpInst(ICmpInst::ICMP_EQ, CurVT, VT2, "", CI);
+
+          node->addIncoming(ConstantInt::getTrue(), CI->getParent());
+          BranchInst::Create(CurEndBlock, FailedBlock, res, CI);
+
+          Value* Args[2] = { VT1, VT2 };
+          res = CallInst::Create(module->IsSecondaryClassFunction, Args,
+                                 Args + 2, "", FailedBlock);
+         
+          node->addIncoming(res, FailedBlock);
+          BranchInst::Create(CurEndBlock, FailedBlock);
+
+          // Branch to the next block.
+          BranchInst::Create(EndBlock, CurEndBlock);
+          
+          // We can now replace the previous instruction.
+          CI->replaceAllUsesWith(node);
+          CI->eraseFromParent();
+          
+          // Reanalyse the current block.
+          break;
+
         } else if (V == module->IsSecondaryClassFunction) {
           Changed = true;
           Value* VT1 = Call.getArgument(0);
           Value* VT2 = Call.getArgument(1);
+            
+          BasicBlock* EndBlock = II->getParent()->splitBasicBlock(II);
+          I->getParent()->getTerminator()->eraseFromParent();
 
-          Value* args[2] = { VT1, VT2 };
-          CallInst* res = CallInst::Create(module->IsAssignableFromFunction,
-                                           args, args + 2, "", CI);
-          CI->replaceAllUsesWith(res);
+
+          BasicBlock* Preheader = BasicBlock::Create("preheader", &F);
+          BasicBlock* BB4 = BasicBlock::Create("BB4", &F);
+          BasicBlock* BB5 = BasicBlock::Create("BB5", &F);
+          BasicBlock* BB6 = BasicBlock::Create("BB6", &F);
+          BasicBlock* BB7 = BasicBlock::Create("BB7", &F);
+          BasicBlock* BB9 = BasicBlock::Create("BB9", &F);
+          const Type* Ty = PointerType::getUnqual(module->VTType);
+          
+          PHINode* resFwd = PHINode::Create(Type::Int32Ty, "", BB7);
+   
+          // This corresponds to:
+          //    if (VT1.cache == VT2 || VT1 == VT2) goto end with true;
+          //    else goto headerLoop;
+          ConstantInt* cacheIndex = 
+            ConstantInt::get(Type::Int32Ty, JavaVirtualTable::getCacheIndex());
+          Value* indices[2] = { module->constantZero, cacheIndex };
+          Instruction* CachePtr = 
+            GetElementPtrInst::Create(VT1, indices, indices + 2, "", CI);
+          CachePtr = new BitCastInst(CachePtr, Ty, "", CI);
+          Value* Cache = new LoadInst(CachePtr, "", false, CI);
+          ICmpInst* cmp1 = new ICmpInst(ICmpInst::ICMP_EQ, Cache, VT2, "", CI);
+          ICmpInst* cmp2 = new ICmpInst(ICmpInst::ICMP_EQ, VT1, VT2, "", CI);
+          BinaryOperator* Or = BinaryOperator::Create(Instruction::Or, cmp1,
+                                                      cmp2, "", CI);
+          BranchInst::Create(BB9, Preheader, Or, CI);
+    
+          // First test failed. Go into the loop. The Preheader looks like this:
+          // headerLoop:
+          //    types = VT1->secondaryTypes;
+          //    size = VT1->nbSecondaryTypes;
+          //    i = 0;
+          //    goto test;
+          ConstantInt* sizeIndex = ConstantInt::get(Type::Int32Ty, 
+              JavaVirtualTable::getNumSecondaryTypesIndex());
+          indices[1] = sizeIndex;
+          Instruction* Size = GetElementPtrInst::Create(VT1, indices,
+                                                        indices + 2, "",
+                                                        Preheader);
+          Size = new LoadInst(Size, "", false, Preheader);
+          Size = new PtrToIntInst(Size, Type::Int32Ty, "", Preheader);
+    
+          ConstantInt* secondaryTypesIndex = ConstantInt::get(Type::Int32Ty, 
+              JavaVirtualTable::getSecondaryTypesIndex());
+          indices[1] = secondaryTypesIndex;
+          Instruction* secondaryTypes = 
+            GetElementPtrInst::Create(VT1, indices, indices + 2, "", Preheader);
+          secondaryTypes = new LoadInst(secondaryTypes, "", false, Preheader);
+          secondaryTypes = new BitCastInst(secondaryTypes, Ty, "", Preheader);
+          BranchInst::Create(BB7, Preheader);
+    
+          // Here is the test if the current secondary type is VT2.
+          // test:
+          //   CurVT = types[i];
+          //   if (CurVT == VT2) goto update cache;
+          //   est goto inc;
+          Instruction* CurVT = GetElementPtrInst::Create(secondaryTypes, resFwd,
+                                                         "", BB4);
+          CurVT = new LoadInst(CurVT, "", false, BB4);
+          cmp1 = new ICmpInst(ICmpInst::ICMP_EQ, CurVT, VT2, "", BB4);
+          BranchInst::Create(BB5, BB6, cmp1, BB4);
+    
+          // Increment i if the previous test failed
+          // inc:
+          //    ++i;
+          //    goto endLoopTest;
+          BinaryOperator* IndVar = 
+            BinaryOperator::CreateAdd(resFwd, module->constantOne, "", BB6);
+          BranchInst::Create(BB7, BB6);
+    
+          // Verify that we haven't reached the end of the loop:
+          // endLoopTest:
+          //    if (i < size) goto test
+          //    else goto end with false
+          resFwd->reserveOperandSpace(2);
+          resFwd->addIncoming(module->constantZero, Preheader);
+          resFwd->addIncoming(IndVar, BB6);
+    
+          cmp1 = new ICmpInst(ICmpInst::ICMP_SGT, Size, resFwd, "", BB7);
+          BranchInst::Create(BB4, BB9, cmp1, BB7);
+   
+          // Update the cache if the result is found.
+          // updateCache:
+          //    VT1->cache = result
+          //    goto end with true
+          new StoreInst(VT2, CachePtr, false, BB5);
+          BranchInst::Create(BB9, BB5);
+
+          // Final block, that gets the result.
+          PHINode* node = PHINode::Create(Type::Int1Ty, "", BB9);
+          node->reserveOperandSpace(3);
+          node->addIncoming(ConstantInt::getTrue(), CI->getParent());
+          node->addIncoming(ConstantInt::getFalse(), BB7);
+          node->addIncoming(ConstantInt::getTrue(), BB5);
+    
+          // Don't forget to jump to the next block.
+          BranchInst::Create(EndBlock, BB9);
+   
+          // We can now replace the previous instruction
+          CI->replaceAllUsesWith(node);
           CI->eraseFromParent();
+
+          // And reanalyse the current block.
+          break;
         }
 #ifdef ISOLATE_SHARING
         else if (V == module->GetCtpClassFunction) {

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=69885&r1=69884&r2=69885&view=diff

==============================================================================
--- vmkit/trunk/lib/JnJVM/LLVMRuntime/runtime-default.ll (original)
+++ vmkit/trunk/lib/JnJVM/LLVMRuntime/runtime-default.ll Thu Apr 23 06:22:53 2009
@@ -178,9 +178,9 @@
 declare void @overflowThinLock(%JavaObject*)
 
 ;;; isAssignableFrom - Returns if a type is a subtype of another type.
-declare i1 @jnjvmIsAssignableFrom(%VT*, %VT*) readnone
+declare i1 @isAssignableFrom(%VT*, %VT*) readnone
 
-;;; isAssignableFrom - Returns if a type is a secondary super type of
+;;; isSecondaryClass - Returns if a type is a secondary super type of
 ;;; another type.
 declare i1 @isSecondaryClass(%VT*, %VT*) readnone
 

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

==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JavaClass.h (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JavaClass.h Thu Apr 23 06:22:53 2009
@@ -98,7 +98,7 @@
   JavaVirtualTable** secondaryTypes;
 
   /// baseClass - Holds the base class VT of an array, or the array class VT
-  /// of a regular class.
+  /// of a regular class. Used for AASTORE checks.
   ///
   JavaVirtualTable* baseClassVT;
 
@@ -181,7 +181,14 @@
   /// list.
   ///
   static uint32_t getSecondaryTypesIndex() {
-    return 5;
+    return 16;
+  }
+  
+  /// getNumSecondaryTypesIndex - Get the word offset of the number of
+  /// secondary types.
+  ///
+  static uint32_t getNumSecondaryTypesIndex() {
+    return 15;
   }
 
   /// isSubtypeOf - Returns true if the given VT is a subtype of the this

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

==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JavaRuntimeJIT.cpp (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JavaRuntimeJIT.cpp Thu Apr 23 06:22:53 2009
@@ -408,12 +408,6 @@
   obj->release();
 }
 
-// Never throws.
-extern "C" bool jnjvmIsAssignableFrom(JavaVirtualTable* VT1,
-                                      JavaVirtualTable* VT2) {
-  return VT1->isSubtypeOf(VT2);
-}
-
 // Does not call any Java code.
 extern "C" void JavaThreadThrowException(JavaObject* obj) {
   return JavaThread::get()->throwException(obj);





More information about the vmkit-commits mailing list