[vmkit-commits] [vmkit] r140004 - in /vmkit/trunk/lib/J3/Compiler: JavaAOTCompiler.cpp JavaJIT.cpp JavaJIT.h JavaJITOpcodes.cpp

Nicolas Geoffray nicolas.geoffray at lip6.fr
Sun Sep 18 12:11:13 PDT 2011


Author: geoffray
Date: Sun Sep 18 14:11:13 2011
New Revision: 140004

URL: http://llvm.org/viewvc/llvm-project?rev=140004&view=rev
Log:
Add an inlining framework. Currently inlines simple methods that don't go into runtime and don't call non-inlineable Java methods.


Modified:
    vmkit/trunk/lib/J3/Compiler/JavaAOTCompiler.cpp
    vmkit/trunk/lib/J3/Compiler/JavaJIT.cpp
    vmkit/trunk/lib/J3/Compiler/JavaJIT.h
    vmkit/trunk/lib/J3/Compiler/JavaJITOpcodes.cpp

Modified: vmkit/trunk/lib/J3/Compiler/JavaAOTCompiler.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/J3/Compiler/JavaAOTCompiler.cpp?rev=140004&r1=140003&r2=140004&view=diff
==============================================================================
--- vmkit/trunk/lib/J3/Compiler/JavaAOTCompiler.cpp (original)
+++ vmkit/trunk/lib/J3/Compiler/JavaAOTCompiler.cpp Sun Sep 18 14:11:13 2011
@@ -2178,6 +2178,8 @@
               Function* F = M->getMethod(&cl->virtualMethods[i]);
               M->setMethod(F, ptr, F->getName().data());
               cl->virtualMethods[i].compiledPtr();
+              // Set native so that we don't try to inline it.
+              cl->virtualMethods[i].setNative();
             }
           }
 
@@ -2186,6 +2188,8 @@
               Function* F = M->getMethod(&cl->staticMethods[i]);
               M->setMethod(F, ptr, F->getName().data());
               cl->staticMethods[i].compiledPtr();
+              // Set native so that we don't try to inline it.
+              cl->staticMethods[i].setNative();
             }
           }
         }
@@ -2372,7 +2376,7 @@
     gv->setInitializer(CreateConstantFromVT(VT));
   }
 
-  // Finally add used stubs to the image.
+  // Add used stubs to the image.
   for (SignMap::iterator i = loader->javaSignatures->map.begin(),
        e = loader->javaSignatures->map.end(); i != e; i++) {
     Signdef* signature = i->second;
@@ -2400,7 +2404,7 @@
     }
   }
 
-  // Finally emit the stub for the main signature.
+  // Emit the stub for the main signature.
   Signdef* mainSignature =
     loader->constructSign(loader->asciizConstructUTF8("([Ljava/lang/String;)V"));
   getSignatureInfo(mainSignature)->getStaticBuf();
@@ -2410,6 +2414,13 @@
 
   // Emit the UTF8 map.
   CreateConstantFromUTF8Map(loader->hashUTF8->map);
+
+  // Check that we have compiled everything.
+  for (Module::iterator I = TheModule->begin(), E = TheModule->end();
+       I != E;
+       I++) {
+    assert(!I->hasExternalWeakLinkage());
+  }
 }
 
 void JavaAOTCompiler::generateClassBytes(JnjvmBootstrapLoader* loader) {

Modified: vmkit/trunk/lib/J3/Compiler/JavaJIT.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/J3/Compiler/JavaJIT.cpp?rev=140004&r1=140003&r2=140004&view=diff
==============================================================================
--- vmkit/trunk/lib/J3/Compiler/JavaJIT.cpp (original)
+++ vmkit/trunk/lib/J3/Compiler/JavaJIT.cpp Sun Sep 18 14:11:13 2011
@@ -44,7 +44,7 @@
 using namespace j3;
 using namespace llvm;
 
-static bool needsInitialisationCheck(Class* cl, Class* compilingClass) {
+bool JavaJIT::needsInitialisationCheck(Class* cl) {
   if (cl->isReadyForCompilation() || 
       (!cl->isInterface() && compilingClass->isAssignableFrom(cl))) {
     return false;
@@ -61,11 +61,29 @@
 }
 
 bool JavaJIT::canBeInlined(JavaMethod* meth) {
-  JnjvmClassLoader* loader = meth->classDef->classLoader;
-  return (meth->canBeInlined &&
-          meth != compilingMethod && inlineMethods[meth] == 0 &&
-          (loader == compilingClass->classLoader ||
-           loader == compilingClass->classLoader->bootstrapLoader));
+  if (inlineMethods[meth]) return false;
+  if (isSynchro(meth->access)) return false;
+  if (isNative(meth->access)) return false;
+
+  Attribut* codeAtt = meth->lookupAttribut(Attribut::codeAttribut);
+  if (codeAtt == NULL) return false;
+
+  Reader reader(codeAtt, meth->classDef->bytes);
+  /* uint16 maxStack = */ reader.readU2();
+  /* uint16 maxLocals = */ reader.readU2();
+  uint32 codeLen = reader.readU4();
+  uint32 start = reader.cursor; 
+  reader.seek(codeLen, Reader::SeekCur);
+  uint16 nbHandlers = reader.readU2();
+  if (nbHandlers != 0) return false;
+  reader.cursor = start;
+
+  JavaJIT jit(TheCompiler, meth, llvmFunction);
+  jit.inlineMethods = inlineMethods;
+  jit.inlineMethods[meth] = true;
+  if (!jit.analyzeForInlining(reader, codeLen)) return false;
+  jit.inlineMethods[meth] = false;
+  return true;
 }
 
 void JavaJIT::invokeVirtual(uint16 index) {
@@ -119,7 +137,11 @@
   llvm::Type* retType = virtualType->getReturnType();
 
   bool needsInit = false;
-  if (canBeDirect && meth && !TheCompiler->needsCallback(meth, &needsInit)) {
+  if (canBeDirect && canBeInlined(meth)) {
+    makeArgs(it, index, args, signature->nbArguments + 1);
+    JITVerifyNull(args[0]);
+    val = invokeInline(meth, args);
+  } else if (canBeDirect && !TheCompiler->needsCallback(meth, &needsInit)) {
     makeArgs(it, index, args, signature->nbArguments + 1);
     JITVerifyNull(args[0]);
     val = invoke(TheCompiler->getMethod(meth), args, "", currentBlock);
@@ -707,35 +729,18 @@
 Instruction* JavaJIT::inlineCompile(BasicBlock*& curBB,
                                     BasicBlock* endExBlock,
                                     std::vector<Value*>& args) {
-  DbgSubprogram = TheCompiler->GetDbgSubprogram(compilingMethod);
-
-  PRINT_DEBUG(JNJVM_COMPILE, 1, COLOR_NORMAL, "inline compile %s.%s\n",
-              UTF8Buffer(compilingClass->name).cString(),
-              UTF8Buffer(compilingMethod->name).cString());
-  
   Attribut* codeAtt = compilingMethod->lookupAttribut(Attribut::codeAttribut);
-  
-  if (!codeAtt) {
-    fprintf(stderr, "I haven't verified your class file and it's malformed:"
-                    " no code attribut found for %s.%s!\n",
-                    UTF8Buffer(compilingClass->name).cString(),
-                    UTF8Buffer(compilingMethod->name).cString());
-    abort();
-  }
-
   Reader reader(codeAtt, compilingClass->bytes);
   uint16 maxStack = reader.readU2();
   uint16 maxLocals = reader.readU2();
   uint32 codeLen = reader.readU4();
-  uint32 start = reader.cursor;
-  
+  uint32 start = reader.cursor; 
   reader.seek(codeLen, Reader::SeekCur);
   
-  LLVMMethodInfo* LMI = TheCompiler->getMethodInfo(compilingMethod);
-  assert(LMI);
-  Function* func = LMI->getMethod();
+  LLVMAssessorInfo& LAI = TheCompiler->getTypedefInfo(
+      compilingMethod->getSignature()->getReturnType());
+  Type* returnType = LAI.llvmType;
 
-  Type* returnType = func->getReturnType();
   endBlock = createBasicBlock("end");
 
   currentBlock = curBB;
@@ -888,7 +893,6 @@
 
   delete[] opcodeInfos;
   return endNode;
-    
 }
 
 llvm::Function* JavaJIT::javaCompile() {
@@ -1157,11 +1161,7 @@
   PRINT_DEBUG(JNJVM_COMPILE, 1, COLOR_NORMAL, "--> end compiling %s.%s\n",
               UTF8Buffer(compilingClass->name).cString(),
               UTF8Buffer(compilingMethod->name).cString());
-  
-  if (codeLen < 5 && !callsStackWalker && !TheCompiler->isStaticCompiling()) {
-    compilingMethod->canBeInlined = false;
-  }
-  
+   
   Attribut* annotationsAtt =
     compilingMethod->lookupAttribut(Attribut::annotationsAttribut);
   
@@ -1486,6 +1486,17 @@
   jit.inlineMethods = inlineMethods;
   jit.inlineMethods[meth] = true;
   jit.inlining = true;
+  jit.DbgSubprogram = DbgSubprogram;
+#if DEBUG
+  static int inlineNb = 0;
+  fprintf(stderr, "inline compile %d %s.%s%s from %s.%s\n", inlineNb++,
+              UTF8Buffer(meth->classDef->name).cString(),
+              UTF8Buffer(meth->name).cString(),
+              UTF8Buffer(meth->getSignature()->keyName).cString(),
+              UTF8Buffer(compilingClass->name).cString(),
+              UTF8Buffer(compilingMethod->name).cString());
+#endif
+  
   Instruction* ret = jit.inlineCompile(currentBlock, 
                                        currentExceptionBlock, args);
   inlineMethods[meth] = false;
@@ -1577,7 +1588,7 @@
   uint32 clIndex = ctpInfo->getClassIndexFromMethod(index);
   UserClass* cl = 0;
   Value* Cl = getResolvedClass(clIndex, true, true, &cl);
-  if (!meth || (cl && needsInitialisationCheck(cl, compilingClass))) {
+  if (!meth || (cl && needsInitialisationCheck(cl))) {
     CallInst::Create(intrinsics->ForceInitialisationCheckFunction, Cl, "",
                      currentBlock);
   }
@@ -1701,7 +1712,7 @@
   if (cl && cl->isResolved()) {
     if (alreadyResolved) (*alreadyResolved) = cl;
     node = TheCompiler->getNativeClass(cl);
-    needsInit = needsInitialisationCheck(cl, compilingClass);
+    needsInit = needsInitialisationCheck(cl);
   } else {
     node = getConstantPoolAt(index, intrinsics->ClassLookupFunction,
                              intrinsics->JavaClassType, 0, doThrow);
@@ -1732,7 +1743,7 @@
     LLVMClassInfo* LCI = TheCompiler->getClassInfo(cl);
     Size = LCI->getVirtualSize();
     
-    bool needsCheck = needsInitialisationCheck(cl, compilingClass);
+    bool needsCheck = needsInitialisationCheck(cl);
     if (needsCheck) {
       Cl = invoke(intrinsics->ForceInitialisationCheckFunction, Cl, "",
                   currentBlock);
@@ -1773,8 +1784,7 @@
     if (stat) {
       type = LCI->getStaticType();
       Value* Cl = TheCompiler->getNativeClass(field->classDef);
-      bool needsCheck = needsInitialisationCheck(field->classDef,
-                                                 compilingClass);
+      bool needsCheck = needsInitialisationCheck(field->classDef);
       if (needsCheck) {
         Cl = invoke(intrinsics->InitialisationCheckFunction, Cl, "",
                     currentBlock);
@@ -2434,6 +2444,7 @@
 Instruction* JavaJIT::invoke(Value *F, std::vector<llvm::Value*>& args,
                        const char* Name,
                        BasicBlock *InsertAtEnd) {
+  assert(!inlining);
   
   Instruction* res = CallInst::Create(F, args, Name, InsertAtEnd);
   DebugLoc DL = CreateLocation();
@@ -2487,6 +2498,7 @@
 
 Instruction* JavaJIT::invoke(Value *F, Value* arg1, const char* Name,
                        BasicBlock *InsertAtEnd) {
+  assert(!inlining);
 
   Instruction* res = CallInst::Create(F, arg1, Name, InsertAtEnd);
   DebugLoc DL = CreateLocation();
@@ -2532,6 +2544,7 @@
 
 Instruction* JavaJIT::invoke(Value *F, Value* arg1, Value* arg2,
                        const char* Name, BasicBlock *InsertAtEnd) {
+  assert(!inlining);
 
   Value* args[2] = { arg1, arg2 };
   
@@ -2579,6 +2592,7 @@
 
 Instruction* JavaJIT::invoke(Value *F, const char* Name,
                        BasicBlock *InsertAtEnd) {
+  assert(!inlining);
   Instruction* res = llvm::CallInst::Create(F, Name, InsertAtEnd);
   DebugLoc DL = CreateLocation();
   res->setDebugLoc(DL);

Modified: vmkit/trunk/lib/J3/Compiler/JavaJIT.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/J3/Compiler/JavaJIT.h?rev=140004&r1=140003&r2=140004&view=diff
==============================================================================
--- vmkit/trunk/lib/J3/Compiler/JavaJIT.h (original)
+++ vmkit/trunk/lib/J3/Compiler/JavaJIT.h Sun Sep 18 14:11:13 2011
@@ -157,7 +157,8 @@
 
   /// getJavaExceptionPtr - Emit code to get a pointer to the Java pending exception
 	llvm::Value* getJavaExceptionPtr(llvm::Value* javaThreadPtr);
-	
+
+  bool needsInitialisationCheck(Class* cl);  
 
 //===------------------------- Debugging support --------------------------===//
   
@@ -193,7 +194,9 @@
   /// then this method can not be inlined.
   bool callsStackWalker;
 
-  
+  bool analyzeForInlining(Reader& reader, uint32_t codeLength);
+  bool canInlineLoadConstant(uint16 index);
+
 //===------------------------- Bytecode parsing ---------------------------===//
 
   /// compileOpcodes - Parse the bytecode and create LLVM instructions.

Modified: vmkit/trunk/lib/J3/Compiler/JavaJITOpcodes.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/J3/Compiler/JavaJITOpcodes.cpp?rev=140004&r1=140003&r2=140004&view=diff
==============================================================================
--- vmkit/trunk/lib/J3/Compiler/JavaJITOpcodes.cpp (original)
+++ vmkit/trunk/lib/J3/Compiler/JavaJITOpcodes.cpp Sun Sep 18 14:11:13 2011
@@ -36,9 +36,7 @@
 
 #include "j3/J3Intrinsics.h"
 
-#if DEBUG > 0 && (JNJVM_COMPILE > 0 || JNJVM_EXECUTE > 0)
 #include "j3/OpcodeNames.def"
-#endif
 
 using namespace j3;
 using namespace llvm;
@@ -2728,3 +2726,679 @@
     }
   }
 }
+
+bool JavaJIT::canInlineLoadConstant(uint16 index) {
+  JavaConstantPool* ctpInfo = compilingClass->ctpInfo;
+  uint8 type = ctpInfo->typeAt(index);
+  if (type == JavaConstantPool::ConstantString
+      || type == JavaConstantPool::ConstantClass) {
+    return false;
+  } else {
+    return true;
+  }
+}
+
+static uint8 getReceiver(const std::vector<uint8>& stack, Signdef* signature) {
+  uint32_t index = stack.size() - 1;
+  Typedef* const* arguments = signature->getArgumentsType();
+  for (uint32 i = 0; i < signature->nbArguments; i++) {
+    index--;
+    if (arguments[i]->isDouble() || arguments[i]->isLong()) {
+      index--;
+    }
+  }
+  return stack[index];
+}
+
+static void updateStack(std::vector<uint8>& stack, Signdef* signature, uint8 bytecode) {
+  Typedef* const* arguments = signature->getArgumentsType();
+  if (bytecode != INVOKESTATIC) {
+    stack.pop_back();
+  }
+  for (uint32 i = 0; i < signature->nbArguments; i++) {
+    stack.pop_back();
+    if (arguments[i]->isDouble() || arguments[i]->isLong()) {
+      stack.pop_back();
+    }
+  }
+  if (!signature->getReturnType()->isVoid()) {
+    stack.push_back(bytecode);
+    if (signature->getReturnType()->isLong()
+        || signature->getReturnType()->isDouble()) {
+      stack.push_back(bytecode);
+    }
+  }
+}
+
+bool JavaJIT::analyzeForInlining(Reader& reader, uint32 codeLength) {
+  JavaConstantPool* ctpInfo = compilingClass->ctpInfo;
+  bool wide = false;
+  uint32 start = reader.cursor;
+  std::vector<uint8_t> stack;
+  for(uint32 i = 0; i < codeLength; ++i) {
+    reader.cursor = start + i;
+    uint8 bytecode = reader.readU1();
+    
+    switch (bytecode) { 
+      case NOP :
+        break;
+
+      case ACONST_NULL :
+      case ICONST_M1 :
+      case ICONST_0 :
+      case ICONST_1 :
+      case ICONST_2 :
+      case ICONST_3 :
+      case ICONST_4 :
+      case ICONST_5 :
+      case FCONST_0 :
+      case FCONST_1 : 
+      case FCONST_2 :
+        stack.push_back(bytecode);
+        break;
+
+      case LCONST_0 :
+      case LCONST_1 :
+      case DCONST_0 :
+      case DCONST_1 :
+        stack.push_back(bytecode);
+        stack.push_back(bytecode);
+        break;
+
+      case BIPUSH :
+        ++i;
+        stack.push_back(bytecode);
+        break;
+      
+      case SIPUSH :
+        i += 2;
+        stack.push_back(bytecode);
+        break;
+      
+      case LDC :
+        i++;
+        stack.push_back(bytecode);
+        if (!canInlineLoadConstant(reader.readU1())) return false;
+        break;
+
+      case LDC_W :
+        i += 2;
+        stack.push_back(bytecode);
+        if (!canInlineLoadConstant(reader.readS2())) return false;
+        break;
+      
+
+      case LDC2_W :
+        i += 2;
+        stack.push_back(bytecode);
+        stack.push_back(bytecode);
+        if (!canInlineLoadConstant(reader.readS2())) return false;
+        break;
+      
+      case ILOAD :
+      case FLOAD :
+      case ALOAD :
+        i += WCALC(1, wide);
+        stack.push_back(bytecode);
+        break;
+
+      case LLOAD :
+      case DLOAD :
+        i += WCALC(1, wide);
+        stack.push_back(bytecode);
+        stack.push_back(bytecode);
+        break;
+      
+      case ILOAD_0 :
+      case ILOAD_1 :
+      case ILOAD_2 :
+      case ILOAD_3 :
+      case FLOAD_0 :
+      case FLOAD_1 :
+      case FLOAD_2 :
+      case FLOAD_3 :
+      case ALOAD_0 :
+      case ALOAD_1 :
+      case ALOAD_2 :
+      case ALOAD_3 :
+        stack.push_back(bytecode);
+        break;
+
+      case LLOAD_0 :
+      case LLOAD_1 :
+      case LLOAD_2 :
+      case LLOAD_3 :
+      case DLOAD_0 :
+      case DLOAD_1 :
+      case DLOAD_2 :
+      case DLOAD_3 :
+        stack.push_back(bytecode);
+        stack.push_back(bytecode);
+        break;
+
+      case IALOAD :
+      case FALOAD :
+      case AALOAD :
+      case BALOAD :
+      case CALOAD :
+      case SALOAD :
+        stack.pop_back();
+        stack.pop_back();
+        stack.push_back(bytecode);
+        return false;
+
+      case LALOAD :
+      case DALOAD :
+        stack.pop_back();
+        stack.pop_back();
+        stack.push_back(bytecode);
+        stack.push_back(bytecode);
+        return false;
+
+      case ISTORE :
+      case FSTORE :
+      case ASTORE :
+        stack.pop_back();
+        i += WCALC(1, wide);
+        break;
+
+      case LSTORE :
+      case DSTORE :
+        stack.pop_back();
+        stack.pop_back();
+        i += WCALC(1, wide);
+        break;
+      
+      case ISTORE_0 :
+      case ISTORE_1 :
+      case ISTORE_2 :
+      case ISTORE_3 :
+      case FSTORE_0 :
+      case FSTORE_1 :
+      case FSTORE_2 :
+      case FSTORE_3 :
+      case ASTORE_0 :
+      case ASTORE_1 :
+      case ASTORE_2 :
+      case ASTORE_3 :
+        stack.pop_back();
+        break;
+
+      case DSTORE_0 :
+      case DSTORE_1 :
+      case DSTORE_2 :
+      case DSTORE_3 :
+      case LSTORE_0 :
+      case LSTORE_1 :
+      case LSTORE_2 :
+      case LSTORE_3 :
+        stack.pop_back();
+        stack.pop_back();
+        break;
+
+      case IASTORE :
+      case FASTORE :
+      case AASTORE :
+      case BASTORE :
+      case CASTORE :
+      case SASTORE :
+        stack.pop_back();
+        stack.pop_back();
+        stack.pop_back();
+        return false;
+
+      case LASTORE :
+      case DASTORE :
+        stack.pop_back();
+        stack.pop_back();
+        stack.pop_back();
+        stack.pop_back();
+        return false;
+
+      case POP :
+        stack.pop_back();
+        break;
+
+      case POP2 :
+        stack.pop_back();
+        stack.pop_back();
+        break;
+
+      case DUP :
+        stack.push_back(stack.back());
+        break;
+
+      case DUP_X1 : {
+        uint8 one = stack.back(); stack.pop_back();
+        uint8 two = stack.back(); stack.pop_back();
+        
+        stack.push_back(one);
+        stack.push_back(two);
+        stack.push_back(one);
+        break;
+      }
+
+      case DUP_X2 : {
+        uint8 one = stack.back(); stack.pop_back();
+        uint8 two = stack.back(); stack.pop_back();
+        uint8 three = stack.back(); stack.pop_back();
+
+        stack.push_back(one);
+        stack.push_back(three);
+        stack.push_back(two);
+        stack.push_back(one);
+        break;
+      }
+
+      case DUP2 : {
+        uint8 one = stack.back(); stack.pop_back();
+        uint8 two = stack.back(); stack.pop_back();
+        
+        stack.push_back(two);
+        stack.push_back(one);
+        stack.push_back(two);
+        stack.push_back(one);
+        break;
+      }
+
+      case DUP2_X1 : {
+        uint8 one = stack.back(); stack.pop_back();
+        uint8 two = stack.back(); stack.pop_back();
+        uint8 three = stack.back(); stack.pop_back();
+
+        stack.push_back(two);
+        stack.push_back(one);
+        stack.push_back(three);
+        stack.push_back(two);
+        stack.push_back(one);
+
+        break;
+      }
+
+      case DUP2_X2 : {
+        uint8 one = stack.back(); stack.pop_back();
+        uint8 two = stack.back(); stack.pop_back();
+        uint8 three = stack.back(); stack.pop_back();
+        uint8 four = stack.back(); stack.pop_back();
+
+        stack.push_back(two);
+        stack.push_back(one);
+        stack.push_back(four);
+        stack.push_back(three);
+        stack.push_back(two);
+        stack.push_back(one);
+
+        break;
+      }
+
+      case SWAP : {
+        uint8 one = stack.back(); stack.pop_back();
+        uint8 two = stack.back(); stack.pop_back();
+        stack.push_back(one);
+        stack.push_back(two);
+        break;
+      }
+
+      case IADD :
+      case FADD :
+      case ISUB :
+      case FSUB :
+      case IMUL :
+      case FMUL :
+      case FDIV :
+      case FREM :
+      case ISHL :
+      case ISHR :
+      case IUSHR :
+      case IAND :
+      case IOR :
+      case IXOR :
+        stack.pop_back();
+        stack.pop_back();
+        stack.push_back(bytecode);
+        break;
+
+      case LADD :
+      case DADD :
+      case DDIV :
+      case LMUL :
+      case DMUL :
+      case DREM :
+      case LSUB :
+      case DSUB :
+        stack.pop_back();
+        stack.pop_back();
+        stack.push_back(bytecode);
+        stack.push_back(bytecode);
+        break;
+
+      case IREM :
+      case IDIV :
+      case LREM :
+      case LDIV :
+        return false;
+
+      case INEG :
+      case FNEG :
+        stack.pop_back();
+        stack.push_back(bytecode);
+        break;
+
+      case LNEG :
+      case DNEG :
+        stack.pop_back();
+        stack.pop_back();
+        stack.push_back(bytecode);
+        stack.push_back(bytecode);
+        break;
+
+      case LSHL :
+      case LSHR :
+      case LUSHR :
+      case LAND :
+      case LOR :
+      case LXOR :
+        stack.pop_back();
+        stack.pop_back();
+        stack.pop_back();
+        stack.push_back(bytecode);
+        stack.push_back(bytecode);
+        break;
+
+      case IINC :
+        i += WCALC(2, wide);
+        break;
+      
+      case I2L :
+      case I2D :
+      case F2L :
+      case F2D :
+        stack.pop_back();
+        stack.push_back(bytecode);
+        stack.push_back(bytecode);
+        break;
+
+      case I2F :
+      case F2I :
+      case I2B :
+      case I2C :
+      case I2S :
+        stack.pop_back();
+        stack.push_back(bytecode);
+        break;
+
+      case L2I :
+      case L2F :
+      case D2I :
+      case D2F :
+        stack.pop_back();
+        stack.pop_back();
+        stack.push_back(bytecode);
+        break;
+
+      case L2D :
+      case D2L :
+        stack.pop_back();
+        stack.pop_back();
+        stack.push_back(bytecode);
+        stack.push_back(bytecode);
+        break;
+
+      case FCMPL :
+      case FCMPG :
+        stack.pop_back();
+        stack.pop_back();
+        stack.push_back(bytecode);
+        break;
+
+      case LCMP :
+      case DCMPL :
+      case DCMPG :
+        stack.pop_back();
+        stack.pop_back();
+        stack.pop_back();
+        stack.pop_back();
+        stack.push_back(bytecode);
+        break;
+
+      case IFEQ :
+      case IFNE :
+      case IFLT :
+      case IFGE :
+      case IFGT :
+      case IFLE : {
+        i += 2;
+        stack.pop_back();
+        if (stack.size() > 0) return false;
+        break;
+      }
+
+      case IF_ICMPEQ :
+      case IF_ICMPNE :
+      case IF_ICMPLT :
+      case IF_ICMPGE :
+      case IF_ICMPGT :
+      case IF_ICMPLE :
+      case IF_ACMPEQ :
+      case IF_ACMPNE : {
+        i += 2;
+        stack.pop_back();
+        stack.pop_back();
+        if (stack.size() > 0) return false;
+        break;
+      }
+      case GOTO : {
+        i += 2;
+        if (stack.size() > 0) return false;
+        break;
+      }
+      
+      case JSR : {
+        i += 2;
+        return false;
+      }
+
+      case RET : {
+        ++i;
+        return false;
+      }
+
+      case TABLESWITCH : {
+        stack.pop_back();
+        if (stack.size() > 0) return false;
+        uint32 tmp = i;
+        uint32 reste = (i + 1) & 3;
+        uint32 filled = reste ?  (4 - reste) : 0;
+        i += filled;
+        reader.cursor += filled;
+        reader.readU4();
+        i += 4;
+
+        sint32 low = reader.readS4();
+        i += 4;
+        sint32 high = reader.readS4() + 1;
+        i += 4;
+        for (sint32 cur = low; cur < high; ++cur) {
+          reader.readU4();
+          i += 4;
+        }
+       
+        i = tmp + 12 + filled + ((high - low) << 2); 
+        break;
+      }
+
+      case LOOKUPSWITCH : {
+        stack.pop_back();
+        if (stack.size() > 0) return false;
+        uint32 tmp = i;
+        uint32 filled = (3 - i) & 3;
+        i += filled;
+        reader.cursor += filled;
+        reader.readU4();
+        i += 4;
+        uint32 nbs = reader.readU4();
+        i += 4;
+        for (uint32 cur = 0; cur < nbs; ++cur) {
+          i += 4;
+          reader.cursor += 4;
+          reader.readU4();
+          i += 4;
+        }
+        
+        i = tmp + 8 + filled + (nbs << 3);
+        break;
+      }
+
+      case IRETURN :
+      case FRETURN :
+      case ARETURN :
+        stack.pop_back();
+        break;
+
+      case RETURN :
+        break;
+      
+      case LRETURN :
+      case DRETURN :
+        stack.pop_back();
+        stack.pop_back();
+        break;
+      
+      case GETSTATIC :
+      case PUTSTATIC : {
+        uint16 index = reader.readU2();
+        Typedef* sign = ctpInfo->infoOfField(index);
+        JavaField* field = ctpInfo->lookupField(index, true);
+        if (field == NULL) return false;
+        if (needsInitialisationCheck(field->classDef)) return false;
+        if (bytecode == GETSTATIC) {
+          stack.push_back(bytecode);
+          if (sign->isDouble() || sign->isLong()) {
+            stack.push_back(bytecode);
+          }
+        } else {
+          stack.pop_back();
+          if (sign->isDouble() || sign->isLong()) {
+            stack.pop_back();
+          }
+        }
+        i += 2;
+        break;
+      }
+
+      case PUTFIELD : {
+        if (isStatic(compilingMethod->access)) return false;
+        i += 2;
+        stack.pop_back(); // value
+        uint16 index = reader.readU2();
+        Typedef* sign = ctpInfo->infoOfField(index);
+        if (sign->isDouble() || sign->isLong()) {
+          stack.pop_back(); // value
+        }
+        if (stack.back() != ALOAD_0) return false;
+        stack.pop_back(); // object
+        break;
+      }
+
+      case GETFIELD : {
+        if (isStatic(compilingMethod->access)) return false;
+        if (stack.back() != ALOAD_0) return false;
+        i += 2;
+        stack.pop_back(); // object
+        uint16 index = reader.readU2();
+        Typedef* sign = ctpInfo->infoOfField(index);
+        stack.push_back(bytecode);
+        if (sign->isDouble() || sign->isLong()) {
+          stack.push_back(bytecode);
+        }
+        break;
+      }
+
+      case INVOKEVIRTUAL :
+        i += 2;
+        return false;
+
+      case INVOKESPECIAL : {
+        if (isStatic(compilingMethod->access)) return false;
+        uint16 index = reader.readU2();
+        CommonClass* cl = NULL;
+        JavaMethod* meth = NULL;
+        ctpInfo->infoOfMethod(index, ACC_VIRTUAL, cl, meth);
+        i += 2;
+        if (meth == NULL) return false;
+        if (getReceiver(stack, meth->getSignature()) != ALOAD_0) return false;
+        if (!canBeInlined(meth)) return false;
+        updateStack(stack, meth->getSignature(), bytecode);
+        break;
+      }
+
+      case INVOKESTATIC : {
+        uint16 index = reader.readU2();
+        CommonClass* cl = NULL;
+        JavaMethod* meth = NULL;
+        ctpInfo->infoOfMethod(index, ACC_STATIC, cl, meth);
+        i += 2;
+        if (meth == NULL) return false;
+        if (!canBeInlined(meth)) return false;
+        if (needsInitialisationCheck(cl->asClass())) return false;
+        updateStack(stack, meth->getSignature(), bytecode);
+        break;
+      }
+      
+      case INVOKEINTERFACE :
+        i += 4;
+        return false;
+
+      case NEW :
+        i += 2;
+        return false;
+
+      case NEWARRAY :
+        ++i;
+        return false;
+      
+      case ANEWARRAY :
+        i += 2;
+        return false;
+
+      case ARRAYLENGTH :
+        stack.pop_back();
+        stack.push_back(bytecode);
+        break;
+
+      case ATHROW :
+        return false;
+
+      case CHECKCAST :
+        i += 2;
+        return false;
+
+      case INSTANCEOF :
+        i += 2;
+        return false;
+      
+      case MONITORENTER :
+      case MONITOREXIT :
+        return false;
+      
+      case MULTIANEWARRAY :
+        i += 3;
+        return false;
+
+      case WIDE :
+        wide = true;
+        break;
+
+      case IFNULL :
+      case IFNONNULL :
+        stack.pop_back();
+        i += 2;
+        if (stack.size() > 0) return false;
+        break;
+
+      default :
+        return false;
+    }
+  }
+  return true;
+}





More information about the vmkit-commits mailing list