[vmkit-commits] [vmkit] r63512 - in /vmkit/trunk/lib/JnJVM/VMCore: JavaJIT.cpp JavaJIT.h JavaJITOpcodes.cpp

Nicolas Geoffray nicolas.geoffray at lip6.fr
Mon Feb 2 05:39:39 PST 2009


Author: geoffray
Date: Mon Feb  2 07:39:38 2009
New Revision: 63512

URL: http://llvm.org/viewvc/llvm-project?rev=63512&view=rev
Log:
Cleanup and commentify.


Modified:
    vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.cpp
    vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.h
    vmkit/trunk/lib/JnJVM/VMCore/JavaJITOpcodes.cpp

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

==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.cpp (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.cpp Mon Feb  2 07:39:38 2009
@@ -82,9 +82,9 @@
     return invokeSpecial(index);
 
   // If the method is in fact a method defined in an interface,
-  // call invokeInterfaceOrVirtual instead.
+  // call invokeInterface instead.
   if (meth && isInterface(meth->classDef->access)) {
-    return invokeInterfaceOrVirtual(index, true);
+    return invokeInterface(index, true);
   }
 
 #if !defined(WITHOUT_VTABLE)
@@ -183,7 +183,7 @@
   }
     
 #else
-  return invokeInterfaceOrVirtual(index);
+  return invokeInterface(index);
 #endif
 }
 
@@ -229,7 +229,7 @@
   currentBlock = createBasicBlock("start");
   BasicBlock* executeBlock = createBasicBlock("execute");
   endBlock = createBasicBlock("end block");
-  returnType = funcType->getReturnType();
+  const llvm::Type* returnType = funcType->getReturnType();
 
   Value* buf = llvm::CallInst::Create(module->GetSJLJBufferFunction,
                                       "", currentBlock);
@@ -332,19 +332,19 @@
 
   if (returnType != Type::VoidTy)
     endNode->addIncoming(result, currentBlock);
-  llvm::BranchInst::Create(endBlock, currentBlock);
+  BranchInst::Create(endBlock, currentBlock);
 
   currentBlock = endBlock; 
   if (isSynchro(compilingMethod->access))
     endSynchronize();
   
-  llvm::CallInst::Create(module->JniProceedPendingExceptionFunction, "",
-                         currentBlock);
+  CallInst::Create(module->JniProceedPendingExceptionFunction, "",
+                   currentBlock);
   
   if (returnType != Type::VoidTy)
-    llvm::ReturnInst::Create(endNode, currentBlock);
+    ReturnInst::Create(endNode, currentBlock);
   else
-    llvm::ReturnInst::Create(currentBlock);
+    ReturnInst::Create(currentBlock);
   
   PRINT_DEBUG(JNJVM_COMPILE, 1, COLOR_NORMAL, "end native compile %s\n",
               compilingMethod->printString());
@@ -497,9 +497,9 @@
   }
 
   Reader reader(codeAtt, compilingClass->bytes);
-  maxStack = reader.readU2();
-  maxLocals = reader.readU2();
-  codeLen = reader.readU4();
+  /* uint16 maxStack = */ reader.readU2();
+  uint16 maxLocals = reader.readU2();
+  uint32 codeLen = reader.readU4();
   uint32 start = reader.cursor;
   
   reader.seek(codeLen, Reader::SeekCur);
@@ -508,7 +508,7 @@
   assert(LMI);
   Function* func = LMI->getMethod();
 
-  returnType = func->getReturnType();
+  const Type* returnType = func->getReturnType();
   endBlock = createBasicBlock("end");
 
   currentBlock = curBB;
@@ -579,7 +579,7 @@
   nbEnveloppes = 0;
 
   if (returnType != Type::VoidTy) {
-    endNode = llvm::PHINode::Create(returnType, "", endBlock);
+    endNode = PHINode::Create(returnType, "", endBlock);
   }
 
   compileOpcodes(&compilingClass->bytes->elements[start], codeLen);
@@ -607,15 +607,15 @@
   }
 
   Reader reader(codeAtt, compilingClass->bytes);
-  maxStack = reader.readU2();
-  maxLocals = reader.readU2();
-  codeLen = reader.readU4();
+  /* uint16 maxStack = */ reader.readU2();
+  uint16 maxLocals = reader.readU2();
+  uint32 codeLen = reader.readU4();
   uint32 start = reader.cursor;
   
   reader.seek(codeLen, Reader::SeekCur);
 
   const FunctionType *funcType = llvmFunction->getFunctionType();
-  returnType = funcType->getReturnType();
+  const Type* returnType = funcType->getReturnType();
   
   Function* func = llvmFunction;
 
@@ -758,7 +758,7 @@
   }
 #endif
 
-  unsigned nbe = readExceptionTable(reader);
+  unsigned nbe = readExceptionTable(reader, codeLen);
   
   exploreOpcodes(&compilingClass->bytes->elements[start], codeLen);
   compilingMethod->enveloppes = 
@@ -874,21 +874,88 @@
   return llvmFunction;
 }
 
+/// Handler - This class represents an exception handler. It is only needed
+/// when parsing the .class file in the JIT, therefore it is only defined
+/// here. The readExceptionTable function is the only function that makes
+/// use of this class.
+struct Handler {
+  
+  /// startpc - The bytecode number that begins the try clause.
+  uint32 startpc;
+
+  /// endpc - The bytecode number that ends the try clause.
+  uint32 endpc;
+
+  /// handlerpc - The bytecode number where the handler code starts.
+  uint32 handlerpc;
+
+  /// catche - Index in the constant pool of the exception class.
+  uint16 catche;
+
+  /// catchClass - The class of the exception: it must always be loaded before
+  /// reading the exception table so that we do not throw an exception
+  /// when compiling.
+  UserClass* catchClass;
+
+  /// catcher - The basic block that catches the exception. The catcher deals
+  /// with LLVM codegen and declares the llvm.select method. This block is the
+  /// destination of invoke instructions that are in the try clause.
+  llvm::BasicBlock* catcher;
+
+  /// tester - The basic block that tests if the exception is handled by this
+  /// handler. If the handler is not the first of a list of handlers with the
+  /// same range, than this block is the catcher block. Otherwise, it is the
+  /// destination of the catcher block and of the handlers that do not handler
+  /// the exception.
+  llvm::BasicBlock* tester;
+
+  /// javaHandler - The Java code that handles the exception. At this point, we
+  /// know we have caught and are handling the exception. The Java exception
+  /// object is the PHI node that begins this block.
+  llvm::BasicBlock* javaHandler;
+
+  /// nativeHandler - The CXX exception-related code that handles the exception.
+  /// The block clears the exception from the execution environment, calls
+  /// the CXX begin and end catch methods and jumps to the Java handler.
+  llvm::BasicBlock* nativeHandler;
+
+  /// exceptionPHI - The CXX exception object for the tester block. The
+  /// tester has incoming blocks, either from the catcher or from other
+  /// handlers that don't handle the exception. Therefore each incoming block
+  /// specifies the CXX exception object that was caught.
+  llvm::PHINode* exceptionPHI;
+};
 
-unsigned JavaJIT::readExceptionTable(Reader& reader) {
+unsigned JavaJIT::readExceptionTable(Reader& reader, uint32 codeLen) {
+
+  // This function uses currentBlock to simplify things. We save the current
+  // value of currentBlock to restore it at the end of the function
   BasicBlock* temp = currentBlock;
+  
   sint16 nbe = reader.readU2();
   sint16 sync = isSynchro(compilingMethod->access) ? 1 : 0;
   nbe += sync;
-  
+ 
+  // realEndExceptionBlock is the block where handlers will resume if
+  // they don't treat the exception. realEndExceptionBlock does not
+  // have to catch the exception.
   BasicBlock* realEndExceptionBlock = endExceptionBlock;
+
+  // endExceptionBlockCatcher is the block where every instruction will
+  // unwind.
   BasicBlock* endExceptionBlockCatcher = endExceptionBlock;
-  currentExceptionBlock = endExceptionBlock;
+
   if (sync) {
+    // synchronizeExceptionBlock is the the block which will release the lock
+    // on the object. trySynchronizeExceptionBlock is the block which will
+    // catch the exception if one is thrown.
     BasicBlock* synchronizeExceptionBlock = 
           createBasicBlock("synchronizeExceptionBlock");
     BasicBlock* trySynchronizeExceptionBlock = 
           createBasicBlock("trySynchronizeExceptionBlock");
+
+    // So synchronizeExceptionBlock becomes the block where every instructions
+    // will unwind.
     realEndExceptionBlock = synchronizeExceptionBlock;
     endExceptionBlockCatcher = trySynchronizeExceptionBlock;
     Value* argsSync = 0;
@@ -898,11 +965,19 @@
       Value* cl = module->getJavaClass(compilingClass);
       argsSync = cl;
     }
+
+    // In the synchronizeExceptionBlock: release the object and go to
+    // endExceptionBlock, which will unwind the function.
+    
     CallInst::Create(module->ReleaseObjectFunction, argsSync, "",
                      synchronizeExceptionBlock);
 
     BranchInst::Create(endExceptionBlock, synchronizeExceptionBlock);
-    
+   
+
+    // In the trySynchronizeExceptionBlock: catch the exception and move
+    // to synchronizeExceptionBlock.
+
     const PointerType* PointerTy_0 = module->ptrType;
     Instruction* ptr_eh_ptr = CallInst::Create(module->llvmGetException,
                                                "eh_ptr",
@@ -918,6 +993,8 @@
     BranchInst::Create(synchronizeExceptionBlock,
                        trySynchronizeExceptionBlock);
 
+    // Now we can set the unwind destination of all instructions to
+    // the exception catcher.
     for (uint16 i = 0; i < codeLen; ++i) {
       if (opcodeInfos[i].exceptionBlock == endExceptionBlock) {
         opcodeInfos[i].exceptionBlock = trySynchronizeExceptionBlock;
@@ -925,9 +1002,10 @@
     }
   }
   
-  Exception* exceptions = (Exception*)alloca(sizeof(Exception) * (nbe - sync));
+  // Loop over all handlers in the bytecode to initialize their values.
+  Handler* handlers = (Handler*)alloca(sizeof(Handler) * (nbe - sync));
   for (uint16 i = 0; i < nbe - sync; ++i) {
-    Exception* ex = &exceptions[i];
+    Handler* ex   = &handlers[i];
     ex->startpc   = reader.readU2();
     ex->endpc     = reader.readU2();
     ex->handlerpc = reader.readU2();
@@ -938,6 +1016,8 @@
     if (ex->catche) {
       UserClass* cl = 
         (UserClass*)(compilingClass->ctpInfo->isClassLoaded(ex->catche));
+      // When loading the class, we made sure that all exception classes
+      // were loaded, so cl must have a value.
       assert(cl && "exception class has not been loaded");
       ex->catchClass = cl;
     } else {
@@ -945,75 +1025,109 @@
     }
 #endif
     
-    ex->test = createBasicBlock("testException");
+    ex->catcher = createBasicBlock("testException");
     
-    // We can do this because readExceptionTable is the first function to be
-    // called after creation of Opinfos
+    // Set the unwind destination of the instructions in the range of this
+    // handler to the test block of the handler. If an instruction already has
+    // a handler and thus is not the synchronize or regular end handler block,
+    // leave it as-is.
     for (uint16 i = ex->startpc; i < ex->endpc; ++i) {
       if (opcodeInfos[i].exceptionBlock == endExceptionBlockCatcher) {
-        opcodeInfos[i].exceptionBlock = ex->test;
+        opcodeInfos[i].exceptionBlock = ex->catcher;
       }
     }
 
+    // If the handler pc does not already have a block, create a new one.
     if (!(opcodeInfos[ex->handlerpc].newBlock)) {
-      opcodeInfos[ex->handlerpc].newBlock = 
-                    createBasicBlock("javaHandler");
+      opcodeInfos[ex->handlerpc].newBlock = createBasicBlock("javaHandler");
     }
     
+    // Set the Java handler for this exception.
     ex->javaHandler = opcodeInfos[ex->handlerpc].newBlock;
-    ex->nativeHandler = createBasicBlock("nativeHandler");
-    opcodeInfos[ex->handlerpc].reqSuppl = true;
 
+    // Set the native handler of this exception, which will catch the exception
+    // object.
+    ex->nativeHandler = createBasicBlock("nativeHandler");
   }
-  
+
+  // Loop over all handlers to know which ones have the same range. Handlers
+  // with a same range all verify the exception's class, but only one catches
+  // the exception. This is the reason why we have a tester block
+  // and a catcher block: the first one tests the exception's class, and the
+  // second one catches the exception.
   bool first = true;
   for (sint16 i = 0; i < nbe - sync; ++i) {
-    Exception* cur = &exceptions[i];
-
-    Exception* next = 0;
-    if (i + 1 != nbe - sync) {
-      next = &exceptions[i + 1];
-    }
+    Handler* cur = &handlers[i];
 
+    // If we are the first handler, we must have one block for catching
+    // the exception, and one block for comparing the exception. The former
+    // is catcher and the latter is tester. Handlers that live in
+    // the range of this handler will jump to tester because they
+    // have already catched the exception. The other instructions in the range
+    // of this handler will jump to catcher because the
+    // exception still has to be catched.
     if (first) {
-      cur->realTest = createBasicBlock("realTestException");
+      cur->tester = createBasicBlock("realTestException");
     } else {
-      cur->realTest = cur->test;
+      cur->tester = cur->catcher;
     }
-    
-    cur->exceptionPHI = llvm::PHINode::Create(module->ptrType, "",
-                                              cur->realTest);
-
-    if (next && cur->startpc == next->startpc && cur->endpc == next->endpc)
-      first = false;
-    else
-      first = true;
+   
+    // Set the exception as a phi node. This PHI has two types of incoming
+    // nodes:
+    // - Handlers within the range: they have already catched the exception
+    //   and verified its type. They are not the right handler for the
+    //   exception, so they jump to this handler
+    // - The testException block of this handler (which is unique). It has
+    //   catched the exception and is now jumping to perform the test.
+    cur->exceptionPHI = PHINode::Create(module->ptrType, "", cur->tester);
+
+    // Look if the next handler has the same range or has a different range.
+    // If it's in the same range, then no need to catch the exception.
+    // Otherwise, it's a new range and we need to catch the exception.
+    if (i + 1 != nbe - sync) {
+      Handler* next = &handlers[i + 1];
       
+      if (cur->startpc == next->startpc && cur->endpc == next->endpc) {
+        first = false;
+      } else {
+        first = true;
+      }
+    } 
   }
+  
 
+  // Loop over all handlers to implement their catcher and tester.
   for (sint16 i = 0; i < nbe - sync; ++i) {
-    Exception* cur = &exceptions[i];
-    Exception* next = 0;
+    Handler* cur = &handlers[i];
     BasicBlock* bbNext = 0;
     PHINode* nodeNext = 0;
     currentExceptionBlock = opcodeInfos[cur->handlerpc].exceptionBlock;
 
+    // Look out where we go if we're not the handler for the exception.
     if (i + 1 != nbe - sync) {
-      next = &exceptions[i + 1];
+      Handler* next = &handlers[i + 1];
       if (!(cur->startpc >= next->startpc && cur->endpc <= next->endpc)) {
+        // If there is no handler to go to (either one that has the same range
+        // or one that contains the range), then we jump to the end handler.
         bbNext = realEndExceptionBlock;
       } else {
-        bbNext = next->realTest;
+        // If there's a handler to goto, we jump to its tester block and record
+        // the exception PHI node to give our exception to the tester.
+        bbNext = next->tester;
         nodeNext = next->exceptionPHI;
       }
     } else {
+      // If there's no handler after us, we jump to the end handler.
       bbNext = realEndExceptionBlock;
     }
 
-    if (cur->realTest != cur->test) {
+    // If the tester and the catcher is not the same, then we must implement
+    // the catcher. The catcher catches the exception, jumps to the tester
+    // and gives the exception as an incoming node the the exceptionPHI.
+    if (cur->tester != cur->catcher) {
       const PointerType* PointerTy_0 = module->ptrType;
       Instruction* ptr_eh_ptr = 
-        llvm::CallInst::Create(module->llvmGetException, "eh_ptr", cur->test);
+        CallInst::Create(module->llvmGetException, "eh_ptr", cur->catcher);
       Constant* C = ConstantExpr::getCast(Instruction::BitCast,
                                           module->personality, PointerTy_0);
       Value* int32_eh_select_params[3] = 
@@ -1021,13 +1135,14 @@
       llvm::CallInst::Create(module->exceptionSelector,
                              int32_eh_select_params,
                              int32_eh_select_params + 3, "eh_select",
-                             cur->test);
-      llvm::BranchInst::Create(cur->realTest, cur->test);
-      cur->exceptionPHI->addIncoming(ptr_eh_ptr, cur->test);
+                             cur->catcher);
+      llvm::BranchInst::Create(cur->tester, cur->catcher);
+      cur->exceptionPHI->addIncoming(ptr_eh_ptr, cur->catcher);
     } 
     
+    // We now implement the tester of the handler.
     Value* cl = 0;
-    currentBlock = cur->realTest;
+    currentBlock = cur->tester;
 #ifdef ISOLATE_SHARING
     // We're dealing with exceptions, don't catch the exception if the class can
     // not be found.
@@ -1035,120 +1150,141 @@
     else cl = CallInst::Create(module->GetJnjvmExceptionClassFunction,
                                isolateLocal, "", currentBlock);
 #else
-    if (cur->catchClass)
-      cl = module->getNativeClass(cur->catchClass);
-    else
-      cl = getResolvedClass(cur->catche, false, false, 0);
+    // We know catchClass exists because we have loaded all exceptions catched
+    // by the method when we loaded the class that defined this method.
+    cl = module->getNativeClass(cur->catchClass);
 #endif
     
 #ifdef SERVICE
-  JnjvmClassLoader* loader = compilingClass->classLoader;;
-  if (loader != loader->bootstrapLoader) {
-    Value* threadId = CallInst::Create(module->llvm_frameaddress,
-                                       module->constantZero,
-                                       "", currentBlock);
-    threadId = new PtrToIntInst(threadId, module->pointerSizeType, "",
-                                currentBlock);
-    threadId = BinaryOperator::CreateAnd(threadId, module->constantThreadIDMask,
+    // Verifies that the current isolate is not stopped. If it is, we don't
+    // catch the exception but resume unwinding.
+    JnjvmClassLoader* loader = compilingClass->classLoader;;
+    if (loader != loader->bootstrapLoader) {
+      Value* threadId = CallInst::Create(module->llvm_frameaddress,
+                                         module->constantZero,
                                          "", currentBlock);
+      threadId = new PtrToIntInst(threadId, module->pointerSizeType, "",
+                                  currentBlock);
+      threadId = BinaryOperator::CreateAnd(threadId,
+                                           module->constantThreadIDMask,
+                                           "", currentBlock);
   
-    threadId = new IntToPtrInst(threadId, module->ptrPtrType, "",
-                                currentBlock);
+      threadId = new IntToPtrInst(threadId, module->ptrPtrType, "",
+                                  currentBlock);
      
-    Value* Isolate = GetElementPtrInst::Create(threadId,
-                                               module->constantFour, "",
-                                               currentBlock);
+      Value* Isolate = GetElementPtrInst::Create(threadId,
+                                                 module->constantFour, "",
+                                                 currentBlock);
      
-    Isolate = new LoadInst(Isolate, "", currentBlock);
-    Isolate = new BitCastInst(Isolate, module->ptrPtrType, "", currentBlock);
-    Value* Status = GetElementPtrInst::Create(Isolate, module->constantOne, "",
-                                              currentBlock);
-    Status = new LoadInst(Status, "", currentBlock);
-    Status = new PtrToIntInst(Status, Type::Int32Ty, "", currentBlock);
-
-    Value* stopping = new ICmpInst(ICmpInst::ICMP_EQ, Status,
-                                   module->constantOne, "", currentBlock);
-
-    BasicBlock* raiseBlock = createBasicBlock("raiseBlock");
-    BasicBlock* continueBlock = createBasicBlock("continueBlock");
-    BranchInst::Create(raiseBlock, continueBlock, stopping, currentBlock);
-    currentBlock = raiseBlock;
-    BranchInst::Create(endExceptionBlock, currentBlock); 
+      Isolate = new LoadInst(Isolate, "", currentBlock);
+      Isolate = new BitCastInst(Isolate, module->ptrPtrType, "", currentBlock);
+      Value* Status = GetElementPtrInst::Create(Isolate, module->constantOne, "",
+                                                currentBlock);
+      Status = new LoadInst(Status, "", currentBlock);
+      Status = new PtrToIntInst(Status, Type::Int32Ty, "", currentBlock);
+  
+      Value* stopping = new ICmpInst(ICmpInst::ICMP_EQ, Status,
+                                     module->constantOne, "", currentBlock);
+
+      BasicBlock* raiseBlock = createBasicBlock("raiseBlock");
+      BasicBlock* continueBlock = createBasicBlock("continueBlock");
+      BranchInst::Create(raiseBlock, continueBlock, stopping, currentBlock);
+      currentBlock = raiseBlock;
+      BranchInst::Create(endExceptionBlock, currentBlock); 
 
-    currentBlock = continueBlock;
-  }
+      currentBlock = continueBlock;
+    }
 #endif
-    
+   
+    // Compare the exception with the exception class we catch.
     Value* cmp = CallInst::Create(module->CompareExceptionFunction, cl, "",
                                   currentBlock);
+    
+    // If we are catching this exception, then jump to the nativeHandler,
+    // otherwise jump to our next handler.
     BranchInst::Create(cur->nativeHandler, bbNext, cmp, currentBlock);
+    
+    // Add the incoming value to the next handler, which is the exception we
+    // just catched.
     if (nodeNext)
       nodeNext->addIncoming(cur->exceptionPHI, currentBlock);
-    
-    cur->handlerPHI = llvm::PHINode::Create(module->ptrType, "",
-                                            cur->nativeHandler);
-    cur->handlerPHI->addIncoming(cur->exceptionPHI, currentBlock);
+   
+    // Get the Java exception and clear it from the execution context.
     Value* exc = CallInst::Create(module->GetJavaExceptionFunction,
                                   "", cur->nativeHandler);
     CallInst::Create(module->ClearExceptionFunction, "", cur->nativeHandler);
-    CallInst::Create(module->exceptionBeginCatch, cur->handlerPHI,
+
+    // Call the CXX begin and end catcher.
+    CallInst::Create(module->exceptionBeginCatch, cur->exceptionPHI,
                            "tmp8", cur->nativeHandler);
     CallInst::Create(module->exceptionEndCatch, "", cur->nativeHandler);
 
+    // We can now jump to the Java handler!
     BranchInst::Create(cur->javaHandler, cur->nativeHandler);
 
+    // If the Java handler is empty, create a PHI node that will contain the
+    // exception and give our own.
     if (cur->javaHandler->empty()) {
       PHINode* node = PHINode::Create(JnjvmModule::JavaObjectType, "",
                                       cur->javaHandler);
       node->addIncoming(exc, cur->nativeHandler);
       
     } else {
+      // If the Java handler is not empty, then the first instruction is the
+      // PHI node. Give it our own.
       Instruction* insn = cur->javaHandler->begin();
       PHINode* node = dyn_cast<PHINode>(insn);
       assert(node && "malformed exceptions");
       node->addIncoming(exc, cur->nativeHandler);
     }
-#if defined(SERVICE)
-  Value* threadId = 0;
-  Value* OldIsolateID = 0;
-  Value* IsolateIDPtr = 0;
-  Value* OldIsolate = 0;
-  Value* NewIsolate = 0;
-  Value* IsolatePtr = 0;
-  if (loader != loader->bootstrapLoader) {
-    threadId = CallInst::Create(module->llvm_frameaddress, module->constantZero,
-                                "", cur->javaHandler);
-    threadId = new PtrToIntInst(threadId, module->pointerSizeType, "",
-                                cur->javaHandler);
-    threadId = BinaryOperator::CreateAnd(threadId, module->constantThreadIDMask,
-                                       "", cur->javaHandler);
-  
-    threadId = new IntToPtrInst(threadId, module->ptrPtrType, "",
-                                cur->javaHandler);
-     
-    IsolateIDPtr = GetElementPtrInst::Create(threadId, module->constantThree,
-                                             "", cur->javaHandler);
-    const Type* realType = PointerType::getUnqual(module->pointerSizeType);
-    IsolateIDPtr = new BitCastInst(IsolateIDPtr, realType, "",
-                                   cur->javaHandler);
-    OldIsolateID = new LoadInst(IsolateIDPtr, "", cur->javaHandler);
 
-    Value* MyID = ConstantInt::get(module->pointerSizeType,
-                                   loader->getIsolate()->IsolateID);
 
-    new StoreInst(MyID, IsolateIDPtr, cur->javaHandler);
-    IsolatePtr = GetElementPtrInst::Create(threadId, module->constantFour, "",
+#if defined(SERVICE)
+  
+    // Change the isolate we are currently running, now that we have catched
+    // the exception: the exception may have been thrown by another isolate.
+    Value* threadId = 0;
+    Value* OldIsolateID = 0;
+    Value* IsolateIDPtr = 0;
+    Value* OldIsolate = 0;
+    Value* NewIsolate = 0;
+    Value* IsolatePtr = 0;
+    if (loader != loader->bootstrapLoader) {
+      threadId = CallInst::Create(module->llvm_frameaddress, 
+                                  module->constantZero, "", cur->javaHandler);
+      threadId = new PtrToIntInst(threadId, module->pointerSizeType, "",
+                                  cur->javaHandler);
+      threadId = BinaryOperator::CreateAnd(threadId, 
+                                           module->constantThreadIDMask, "",
                                            cur->javaHandler);
+  
+      threadId = new IntToPtrInst(threadId, module->ptrPtrType, "",
+                                  cur->javaHandler);
      
-    OldIsolate = new LoadInst(IsolatePtr, "", cur->javaHandler);
-    NewIsolate = module->getIsolate(loader->getIsolate(), currentBlock);
-    new StoreInst(NewIsolate, IsolatePtr, cur->javaHandler);
+      IsolateIDPtr = GetElementPtrInst::Create(threadId, module->constantThree,
+                                               "", cur->javaHandler);
+      const Type* realType = PointerType::getUnqual(module->pointerSizeType);
+      IsolateIDPtr = new BitCastInst(IsolateIDPtr, realType, "",
+                                     cur->javaHandler);
+      OldIsolateID = new LoadInst(IsolateIDPtr, "", cur->javaHandler);
+
+      Value* MyID = ConstantInt::get(module->pointerSizeType,
+                                     loader->getIsolate()->IsolateID);
+
+      new StoreInst(MyID, IsolateIDPtr, cur->javaHandler);
+      IsolatePtr = GetElementPtrInst::Create(threadId, module->constantFour, "",
+                                             cur->javaHandler);
+     
+      OldIsolate = new LoadInst(IsolatePtr, "", cur->javaHandler);
+      NewIsolate = module->getIsolate(loader->getIsolate(), currentBlock);
+      new StoreInst(NewIsolate, IsolatePtr, cur->javaHandler);
 
-  }
+    }
 #endif
      
   }
-  
+ 
+  // Restore currentBlock.
   currentBlock = temp;
   return nbe;
 
@@ -1170,7 +1306,7 @@
 
 }
 
-void JavaJIT::_ldc(uint16 index) {
+void JavaJIT::loadConstant(uint16 index) {
   JavaConstantPool* ctpInfo = compilingClass->ctpInfo;
   uint8 type = ctpInfo->typeAt(index);
   
@@ -1304,37 +1440,21 @@
   return ptr;
 
 }
-void JavaJIT::setCurrentBlock(BasicBlock* newBlock) {
-
-  stack.clear();
-  uint32 index = 0;
-  for (BasicBlock::iterator i = newBlock->begin(), e = newBlock->end(); i != e;
-       ++i, ++index) {
-    if (!(isa<PHINode>(i))) {
-      break;
-    } else {
-      stack.push_back(std::make_pair(i, false));
-    }
-  }
-  
-  currentBlock = newBlock;
-}
 
-static void testPHINodes(BasicBlock* dest, BasicBlock* insert, JavaJIT* jit) {
+void JavaJIT::testPHINodes(BasicBlock* dest, BasicBlock* insert) {
   if(dest->empty()) {
-    for (std::vector< std::pair<Value*, bool> >::iterator i =
-              jit->stack.begin(),
-            e = jit->stack.end(); i!= e; ++i) {
+    for (std::vector< std::pair<Value*, bool> >::iterator i = stack.begin(),
+         e = stack.end(); i!= e; ++i) {
       Value* cur = i->first;
       bool unsign = i->second;
       PHINode* node = 0;
       const Type* type = cur->getType();
       if (unsign) {
         node = llvm::PHINode::Create(Type::Int32Ty, "", dest);
-        cur = new ZExtInst(cur, Type::Int32Ty, "", jit->currentBlock);
+        cur = new ZExtInst(cur, Type::Int32Ty, "", currentBlock);
       } else if (type == Type::Int8Ty || type == Type::Int16Ty) {
         node = llvm::PHINode::Create(Type::Int32Ty, "", dest);
-        cur = new SExtInst(cur, Type::Int32Ty, "", jit->currentBlock);
+        cur = new SExtInst(cur, Type::Int32Ty, "", currentBlock);
       } else {
         node = llvm::PHINode::Create(cur->getType(), "", dest);
       }
@@ -1342,8 +1462,7 @@
       node->addIncoming(cur, insert);
     }
   } else {
-    std::vector< std::pair<Value*, bool> >::iterator stackit = 
-      jit->stack.begin();
+    std::vector< std::pair<Value*, bool> >::iterator stackit = stack.begin();
     for (BasicBlock::iterator i = dest->begin(), e = dest->end(); i != e;
          ++i) {
       if (!(isa<PHINode>(i))) {
@@ -1355,9 +1474,9 @@
         bool unsign = stackit->second;
         
         if (unsign) {
-          cur = new ZExtInst(cur, Type::Int32Ty, "", jit->currentBlock);
+          cur = new ZExtInst(cur, Type::Int32Ty, "", currentBlock);
         } else if (type == Type::Int8Ty || type == Type::Int16Ty) {
-          cur = new SExtInst(cur, Type::Int32Ty, "", jit->currentBlock);
+          cur = new SExtInst(cur, Type::Int32Ty, "", currentBlock);
         }
         assert(ins->getType() == cur->getType() && "wrong 2");
         ((PHINode*)ins)->addIncoming(cur, insert);
@@ -1368,14 +1487,14 @@
 }
 
 void JavaJIT::branch(llvm::BasicBlock* dest, llvm::BasicBlock* insert) {
-  testPHINodes(dest, insert, this);
+  testPHINodes(dest, insert);
   llvm::BranchInst::Create(dest, insert);
 }
 
 void JavaJIT::branch(llvm::Value* test, llvm::BasicBlock* ifTrue,
                      llvm::BasicBlock* ifFalse, llvm::BasicBlock* insert) {  
-  testPHINodes(ifTrue, insert, this);
-  testPHINodes(ifFalse, insert, this);
+  testPHINodes(ifTrue, insert);
+  testPHINodes(ifFalse, insert);
   llvm::BranchInst::Create(ifTrue, ifFalse, test, insert);
 }
 
@@ -1399,7 +1518,7 @@
     if (it->get() == Type::Int64Ty || it->get() == Type::DoubleTy) {
       pop();
     }
-    bool unsign = topFunc();
+    bool unsign = topSign();
     Value* tmp = pop();
     
     const Type* type = it->get();
@@ -1817,23 +1936,6 @@
   push(val, false);
 }
 
-Value* JavaJIT::arraySize(Value* val) {
-  return CallInst::Create(module->ArrayLengthFunction, val, "", currentBlock);
-}
-
-static Value* fieldGetter(JavaJIT* jit, const Type* type, Value* object,
-                          Value* offset) {
-  Value* objectConvert = new BitCastInst(object, type, "",
-                                         jit->currentBlock);
-
-  Constant* zero = jit->module->constantZero;
-  Value* args[2] = { zero, offset };
-  llvm::Value* ptr = llvm::GetElementPtrInst::Create(objectConvert,
-                                                     args, args + 2, "",
-                                                     jit->currentBlock);
-  return ptr;  
-}
-
 Value* JavaJIT::ldResolved(uint16 index, bool stat, Value* object, 
                            const Type* fieldType, const Type* fieldTypePtr) {
   JavaConstantPool* info = compilingClass->ctpInfo;
@@ -1866,7 +1968,14 @@
     } else {
       type = LCI->getVirtualType();
     }
-    return fieldGetter(this, type, object, LFI->getOffset());
+    
+    Value* objectConvert = new BitCastInst(object, type, "", currentBlock);
+
+    Value* args[2] = { module->constantZero, LFI->getOffset() };
+    Value* ptr = llvm::GetElementPtrInst::Create(objectConvert,
+                                                 args, args + 2, "",
+                                                 currentBlock);
+    return ptr;  
   }
 
   const Type* Pty = module->arrayPtrType;
@@ -1919,7 +2028,7 @@
  
 
 void JavaJIT::setStaticField(uint16 index) {
-  bool unsign = topFunc();
+  bool unsign = topSign();
   Value* val = pop(); 
   
   Typedef* sign = compilingClass->ctpInfo->infoOfField(index);
@@ -1953,7 +2062,7 @@
 }
 
 void JavaJIT::setVirtualField(uint16 index) {
-  bool unsign = topFunc();
+  bool unsign = topSign();
   Value* val = pop();
   Typedef* sign = compilingClass->ctpInfo->infoOfField(index);
   LLVMAssessorInfo& LAI = module->getTypedefInfo(sign);
@@ -2053,7 +2162,7 @@
 }
 
 
-void JavaJIT::invokeInterfaceOrVirtual(uint16 index, bool buggyVirtual) {
+void JavaJIT::invokeInterface(uint16 index, bool buggyVirtual) {
   
   // Do the usual
   JavaConstantPool* ctpInfo = compilingClass->ctpInfo;

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

==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.h (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.h Mon Feb  2 07:39:38 2009
@@ -14,56 +14,45 @@
 #include <map>
 
 #include "llvm/BasicBlock.h"
-#include "llvm/DerivedTypes.h"
 #include "llvm/Function.h"
 #include "llvm/Instructions.h"
+#include "llvm/Type.h"
 #include "llvm/Value.h"
 
 #include "types.h"
 
-#include "mvm/Object.h"
-#include "mvm/PrintBuffer.h"
-
 #include "JnjvmModule.h"
 
 namespace jnjvm {
 
 class Class;
 class JavaMethod;
-class JavaObject;
-class Jnjvm;
 class Reader;
 class UTF8;
 
-struct Exception {
-  uint32 startpc;
-  uint32 endpc;
-  uint32 handlerpc;
-  uint16 catche;
-  UserClass* catchClass;
-  llvm::BasicBlock* test;
-  llvm::BasicBlock* realTest;
-  llvm::BasicBlock* javaHandler;
-  llvm::BasicBlock* nativeHandler;
-  llvm::PHINode* exceptionPHI;
-  llvm::PHINode* handlerPHI;
-};
-
+/// Opinfo - This class gives for each opcode if it starts a new block and
+/// its exception destination.
+///
 struct Opinfo {
+
+  /// newBlock - If it is non-null, the block that the instruction starts.
+  ///
   llvm::BasicBlock* newBlock;
-  bool reqSuppl;
+
+  /// exceptionBlock - Never null, the exception destination of the
+  /// instruction.
+  ///
   llvm::BasicBlock* exceptionBlock; 
 };
 
-class JavaJIT {
-private:
-
-  llvm::Value* getConstantPoolAt(uint32 index, llvm::Function* resolver,
-                                 const llvm::Type* returnType,
-                                 llvm::Value* addArg, bool doThrow = true);
 
+/// JavaJIT - The compilation engine of VMKit. Parses the bycode and returns
+/// its LLVM representation.
+///
+class JavaJIT {
 public:
-  
+ 
+  /// JavaJIT - Default constructor.
   JavaJIT(JavaMethod* meth, llvm::Function* func) {
     nbEnveloppes = 0;
     compilingMethod = meth;
@@ -74,68 +63,163 @@
     callsStackWalker = false;
   }
 
-  JnjvmModule* module;
-
+  /// javaCompile - Compile the Java method.
   llvm::Function* javaCompile();
+  
+  /// nativeCompile - Compile the native method.
   llvm::Function* nativeCompile(intptr_t natPtr = 0);
+
+  /// OpcodeNames - Table for getting the name of a Java instruction
+  /// from its opcode number.
+  static const char* OpcodeNames[256];
+
+private:
+  
+  /// compilingClass - The class that is defining the method being compiled.
+  Class* compilingClass;
+
+  /// compilingMethod - The method being compiled.
+  JavaMethod* compilingMethod;
+
+  /// llvmFunction - The LLVM representation of the method.
+  llvm::Function* llvmFunction;
+  
+  /// module - The LLVM module where lives the compiling LLVM function.
+  JnjvmModule* module;
+  
+  /// locals - The locals of the method.
+  std::vector<llvm::Value*> intLocals;
+  std::vector<llvm::Value*> longLocals;
+  std::vector<llvm::Value*> floatLocals;
+  std::vector<llvm::Value*> doubleLocals;
+  std::vector<llvm::Value*> objectLocals;
+
+  /// endBlock - The block that returns.
+  llvm::BasicBlock* endBlock;
+
+  /// endNode - The result of the method.
+  llvm::PHINode* endNode;
+  
+  /// arraySize - Get the size of the array.
+  llvm::Value* arraySize(llvm::Value* obj) {
+    return llvm::CallInst::Create(module->ArrayLengthFunction, obj, "",
+                                  currentBlock);
+  }
+  
+  /// convertValue - Convert a value to a new type.
+  void convertValue(llvm::Value*& val, const llvm::Type* t1,
+                    llvm::BasicBlock* currentBlock, bool usign);
+ 
+  /// getConstantPoolAt - Return the value at the given index of the constant
+  /// pool. The generated code invokes the resolver if the constant pool
+  /// contains no value at the index.
+  llvm::Value* getConstantPoolAt(uint32 index, llvm::Function* resolver,
+                                 const llvm::Type* returnType,
+                                 llvm::Value* addArg, bool doThrow = true);
+ 
+  /// testPHINodes - Update PHI nodes when branching to a new block.
+  void testPHINodes(llvm::BasicBlock* dest, llvm::BasicBlock* insert);
+  
+
+//===--------------------------- Inline support ---------------------------===//
+
+  /// inlineCompile - Parse the method and start its LLVM representation
+  /// at curBB. endExBlock is the exception destination. args is the
+  /// arguments of the method.
   llvm::Instruction* inlineCompile(llvm::BasicBlock*& curBB,
                                    llvm::BasicBlock* endExBlock,
                                    std::vector<llvm::Value*>& args);
 
+
+  /// inlineMethods - Methods that are currently being inlined. The JIT
+  /// uses this map to not inline a method currently bein inlined.
   std::map<JavaMethod*, bool> inlineMethods;
+
+  /// inlining - Are we JITting a method inline?
   bool inlining;
+  
+  /// canBeInlined - Can this method's body be inlined?
+  bool canBeInlined(JavaMethod* meth);
 
-  Class* compilingClass;
-  JavaMethod* compilingMethod;
-  llvm::Function* llvmFunction;
-  const llvm::Type* returnType;
+  /// callsStackWalker - Is the method calling a stack walker method? If it is,
+  /// then this method can not be inlined.
+  bool callsStackWalker;
 
-  // change into LLVM instructions
+  
+//===------------------------- Bytecode parsing ---------------------------===//
+
+  /// compileOpcodes - Parse the bytecode and create LLVM instructions.
   void compileOpcodes(uint8* bytecodes, uint32 codeLength);
-  // create basic blocks
+
+  /// exploreOpcodes - Parse the bytecode and create the basic blocks.
   void exploreOpcodes(uint8* bytecodes, uint32 codeLength);
+  
+  /// readExceptionTable - Read the exception table in the bytecode. Prepare
+  /// exception destination for all Java instructions and set the exception
+  /// object to handler blocks.
+  unsigned readExceptionTable(Reader& reader, uint32 codeLength);
 
-  // load constant
-  void _ldc(uint16 index);
+  /// loadConstant - Load a constant from the _ldc bytecode.
+  void loadConstant(uint16 index);
 
-  // float comparisons
-  void compareFP(llvm::Value*, llvm::Value*, const llvm::Type*, bool l);
+//===------------------------- Runtime exceptions -------------------------===//
   
-  // null pointer exception
+  /// JITVerifyNull - Insert a null pointer check in the LLVM code.
   void JITVerifyNull(llvm::Value* obj);
+  
+  
+  /// verifyAndComputePtr - Computes the address in the array. If out of bounds
+  /// throw an exception.
+  llvm::Value* verifyAndComputePtr(llvm::Value* obj, llvm::Value* index,
+                                   const llvm::Type* arrayType,
+                                   bool verif = true);
 
+  /// compareFP - Do float comparisons.
+  void compareFP(llvm::Value*, llvm::Value*, const llvm::Type*, bool l);
   
-  // stack manipulation
+
+//===------------------------- Stack manipulation -------------------------===//
+ 
+  /// stack - The compiler stack. We store the value and its sign.
   std::vector< std::pair<llvm::Value*, bool> > stack;
+
+  /// push - Push a new value in the stack.
   void push(llvm::Value* val, bool unsign) {
     stack.push_back(std::make_pair(val, unsign));
   }
 
+  /// push - Push a new value in the stack.
   void push(std::pair<llvm::Value*, bool> pair) {
     stack.push_back(pair);
   }
   
+  /// pop - Pop a value from the stack and return it.
   llvm::Value* pop() {
     llvm::Value * ret = top();
     stack.pop_back();
     return ret; 
   }
 
+  /// top - Return the value on top of the stack.
   llvm::Value* top() {
     return stack.back().first;
   }
   
-  bool topFunc() {
+  /// topSign - Return the sign of the value on top of the stack.
+  bool topSign() {
     return stack.back().second;  
   }
-  
+ 
+  /// stackSize - Return the size of the stack.
   uint32 stackSize() {
     return stack.size();    
   }
   
+  /// popAsInt - Pop a value from the stack and returns it as a Java
+  /// int, ie signed int32.
   llvm::Value* popAsInt() {
     llvm::Value * ret = top();
-    bool unsign = topFunc();
+    bool unsign = topSign();
     stack.pop_back();
 
     if (ret->getType() != llvm::Type::Int32Ty) {
@@ -145,93 +229,143 @@
         ret = new llvm::SExtInst(ret, llvm::Type::Int32Ty, "", currentBlock);
       }
     }
-
     return ret;
-
   }
 
+  /// popPair - Pop the pair on the stack and return it.
   std::pair<llvm::Value*, bool> popPair() {
     std::pair<llvm::Value*, bool> ret = stack.back();
     stack.pop_back();
     return ret;
   }
+
+//===------------------------- Exception support --------------------------===//
   
-  // exceptions
+  /// jsrs - The list of jsrs (jump subroutine) instructions.
   std::vector<llvm::BasicBlock*> jsrs;
-  unsigned readExceptionTable(Reader& reader);
+
+  /// endExceptionBlock - The initial exception block where each handler goes
+  /// if it does not handle the exception.
   llvm::BasicBlock* endExceptionBlock;
+
+  /// currentExceptionBlock - The exception block of the current instruction.
   llvm::BasicBlock* currentExceptionBlock;
+
+  /// unifiedUnreachable - When an exception is thrown, the code after is
+  /// unreachable. All invokes that only throw an exception have the
+  /// unifiedUnreachable block as their normal destination.
   llvm::BasicBlock* unifiedUnreachable;
+
+//===--------------------------- Control flow  ----------------------------===//
+
+  /// opcodeInfos - The informations for each instruction.
   Opinfo* opcodeInfos;
 
-  // block manipulation
+  /// currentBlock - The current block of the JIT.
   llvm::BasicBlock* currentBlock;
+
+  /// createBasicBlock - Create a new basic block.
   llvm::BasicBlock* createBasicBlock(const char* name = "") {
     return llvm::BasicBlock::Create(name, llvmFunction);  
   }
-  void setCurrentBlock(llvm::BasicBlock* block);
-
-  // branches
+  
+  /// branch - Branch based on a boolean value. Update PHI nodes accordingly.
   void branch(llvm::Value* test, llvm::BasicBlock* ifTrue, 
               llvm::BasicBlock* ifFalse, llvm::BasicBlock* insert);
-  void branch(llvm::BasicBlock* where, llvm::BasicBlock* insert);
 
-  // locals
-  std::vector<llvm::Value*> intLocals;
-  std::vector<llvm::Value*> longLocals;
-  std::vector<llvm::Value*> floatLocals;
-  std::vector<llvm::Value*> doubleLocals;
-  std::vector<llvm::Value*> objectLocals;
+  /// branch - Branch to a new block. Update PHI nodes accordingly.
+  void branch(llvm::BasicBlock* where, llvm::BasicBlock* insert);
 
-  // end function
-  llvm::BasicBlock* endBlock;
-  llvm::PHINode* endNode;
-  
-  // array manipulation
-  llvm::Value* verifyAndComputePtr(llvm::Value* obj, llvm::Value* index,
-                                   const llvm::Type* arrayType,
-                                   bool verif = true);
-  llvm::Value* arraySize(llvm::Value* obj);
  
+//===-------------------------- Synchronization  --------------------------===//
   
-  // synchronize
+  /// beginSynchronize - Emit synchronization code to acquire the instance
+  /// or the class.
   void beginSynchronize();
+
+  /// endSynchronize - Emit synchronization code to release the instance or the
+  /// class.
   void endSynchronize();
+
+  /// monitorEnter - Emit synchronization code to acquire the lock of the value.
   void monitorEnter(llvm::Value* obj);
+  
+  /// monitorExit - Emit synchronization code to release the lock of the value.
   void monitorExit(llvm::Value* obj);
 
-  // fields invoke
+//===----------------------- Java field accesses  -------------------------===//
+
+  /// getStaticField - Emit code to get the static field declared at the given
+  /// index in the constant pool.
   void getStaticField(uint16 index);
+
+  /// setStaticField - Emit code to set a value to the static field declared
+  /// at the given index in the constant pool.
   void setStaticField(uint16 index);
+
+  /// getVirtualField - Emit code to get the virtual field declared at the given
+  /// index in the constant pool.
   void getVirtualField(uint16 index);
+
+  /// setVirtualField - Emit code to set a value to the virtual field declared
+  /// at the given index in the constant pool.
   void setVirtualField(uint16 index);
+
+  /// ldResolved - Emit code to get a pointer to a field.
   llvm::Value* ldResolved(uint16 index, bool stat, llvm::Value* object,
                           const llvm::Type* fieldType, 
                           const llvm::Type* fieldTypePtr);
-  llvm::Value* getResolvedClass(uint16 index, bool clinit, bool doThrow,
-                                UserClass** alreadyResolved);
+
+//===--------------------- Constant pool accesses  ------------------------===//
+ 
+  /// getResolvedCommonClass - Emit code to get a resolved common class. If the
+  /// constant pool already links to the class, the class is emitted directly.
+  /// Otherwise the JIT installs a resolver which will be called at runtime.
   llvm::Value* getResolvedCommonClass(uint16 index, bool doThrow,
                                       UserCommonClass** alreadyResolved);
   
-  // methods invoke
+  /// getResolvedCommonClass - Similar to getResolvedCommonClass, but the type
+  /// of the returned value is Class.
+  llvm::Value* getResolvedClass(uint16 index, bool clinit, bool doThrow,
+                                UserClass** alreadyResolved);
+
+
+//===----------------------- Java method calls  ---------------------------===//
+  
+  /// makeArgs - Insert the arguments of a method in the vector. The arguments
+  /// are popped from the compilation stack.
   void makeArgs(llvm::FunctionType::param_iterator it,
                 uint32 index, std::vector<llvm::Value*>& result, uint32 nb);
+
+  /// invokeVirtual - Invoke a Java virtual method.
   void invokeVirtual(uint16 index);
-  void invokeInterfaceOrVirtual(uint16 index, bool buggyVirtual = false);
+
+  /// invokeInterface - Invoke a Java interface method. The buggyVirtual
+  /// argument is for buggy java to bytecode compilers which emit a virtual
+  /// call instead of an interface call in some occasions.
+  void invokeInterface(uint16 index, bool buggyVirtual = false);
+
+  /// invokeSpecial - Invoke an instance Java method directly.
   void invokeSpecial(uint16 index);
+
+  /// invokeStatic - Invoke a static Java method.
   void invokeStatic(uint16 index);
+
+  /// invokeNew - Allocate a new object.
   void invokeNew(uint16 index);
+
+  /// invokeInline - Instead of calling the method, inline it.
   llvm::Instruction* invokeInline(JavaMethod* meth, 
                                   std::vector<llvm::Value*>& args);
+
+  /// lowerMathOps - Map Java Math operations to LLVM intrinsics.
   llvm::Instruction* lowerMathOps(const UTF8* name, 
                                   std::vector<llvm::Value*>& args);
 
-
+  /// invoke - invoke the LLVM method of a Java method.
   llvm::Instruction* invoke(llvm::Value *F, std::vector<llvm::Value*>&args,
                             const char* Name,
                             llvm::BasicBlock *InsertAtEnd);
-  // Alternate CallInst ctors w/ two actuals, w/ one actual and no
-  // actuals, respectively.
   llvm::Instruction* invoke(llvm::Value *F, llvm::Value *Actual1,
                             llvm::Value *Actual2, const char* Name,
                             llvm::BasicBlock *InsertAtEnd);
@@ -239,40 +373,30 @@
                             const char* Name, llvm::BasicBlock *InsertAtEnd);
   llvm::Instruction* invoke(llvm::Value *F, const char* Name,
                             llvm::BasicBlock *InsertAtEnd);
-
   
-  void convertValue(llvm::Value*& val, const llvm::Type* t1,
-                    llvm::BasicBlock* currentBlock, bool usign);
-
+  /// nbEnveloppes - Number of enveloppes (ie invokeinterface) in this
+  /// method.
+  uint32 nbEnveloppes;
 
-  // wide status
-  bool wide;
-  uint32 WREAD_U1(uint8* bytecodes, bool init, uint32 &i);
-  sint32 WREAD_S1(uint8* bytecodes, bool init, uint32 &i);
-  uint32 WCALC(uint32 n);
-
-  uint16 maxStack;
-  uint16 maxLocals;
-  uint32 codeLen;
+ 
 
-#if defined(SERVICE)
+#if defined(ISOLATE_SHARING)
+//===----------------- Sharing bytecode support ---------------------------===//
+  
+  /// isolateLocal - The Jnjvm object that the method is currently executing.
   llvm::Value* isolateLocal;
-#endif
 
-#if defined(ISOLATE_SHARING)
+  /// ctpCache - The constant pool cache.
   llvm::Value* ctpCache;
+
+  /// getStaticInstanceCtp - Get the static instance of the class of the method
+  /// being compiled.
   llvm::Value* getStaticInstanceCtp();
+
+  /// getClassCtp - Get the class of the method being compiled.
   llvm::Value* getClassCtp();
 #endif
-
-  static const char* OpcodeNames[256];
   
-  /// nbEnveloppes - Number of enveloppes (ie invokeinterface) in this
-  /// method.
-  uint32 nbEnveloppes;
-
-  bool canBeInlined(JavaMethod* meth);
-  bool callsStackWalker;
 };
 
 enum Opcode {

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

==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JavaJITOpcodes.cpp (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JavaJITOpcodes.cpp Mon Feb  2 07:39:38 2009
@@ -89,7 +89,7 @@
   return readS4(bytecode, i);
 }
 
-uint32 JavaJIT::WREAD_U1(uint8* array, bool init, uint32 &i) {
+static inline uint32 WREAD_U1(uint8* array, bool init, uint32 &i, bool& wide) {
   if (wide) {
     wide = init; 
     return readU2(array, i);
@@ -98,7 +98,7 @@
   }
 }
 
-sint32 JavaJIT::WREAD_S1(uint8* array, bool init, uint32 &i) {
+static inline sint32 WREAD_S1(uint8* array, bool init, uint32 &i, bool &wide) {
   if (wide) {
     wide = init; 
     return readS2(array, i);
@@ -107,7 +107,7 @@
   }
 }
 
-uint32 JavaJIT::WCALC(uint32 n) {
+static inline uint32 WCALC(uint32 n, bool& wide) {
   if (wide) {
     wide = false;
     return n << 1;
@@ -117,7 +117,7 @@
 }
 
 void JavaJIT::compileOpcodes(uint8* bytecodes, uint32 codeLength) {
-  wide = false;
+  bool wide = false;
   uint32 jsrIndex = 0;
   for(uint32 i = 0; i < codeLength; ++i) {
     
@@ -133,7 +133,17 @@
         branch(opinfo->newBlock, currentBlock);
       }
       
-      setCurrentBlock(opinfo->newBlock);
+      stack.clear();
+      for (BasicBlock::iterator i = opinfo->newBlock->begin(),
+           e = opinfo->newBlock->end(); i != e; ++i) {
+        if (!(isa<PHINode>(i))) {
+          break;
+        } else {
+          stack.push_back(std::make_pair(i, false));
+        }
+      }
+  
+      currentBlock = opinfo->newBlock;
     }
     currentExceptionBlock = opinfo->exceptionBlock;
     
@@ -236,42 +246,42 @@
         break;
 
       case LDC :
-        _ldc(bytecodes[++i]);
+        loadConstant(bytecodes[++i]);
         break;
 
       case LDC_W :
-        _ldc(readS2(bytecodes, i));
+        loadConstant(readS2(bytecodes, i));
         break;
 
       case LDC2_W :
-        _ldc(readS2(bytecodes, i));
+        loadConstant(readS2(bytecodes, i));
         push(module->constantZero, false);
         break;
 
       case ILOAD :
-        push(new LoadInst(intLocals[WREAD_U1(bytecodes, false, i)], "",
+        push(new LoadInst(intLocals[WREAD_U1(bytecodes, false, i, wide)], "",
                           currentBlock), false);
         break;
 
       case LLOAD :
-        push(new LoadInst(longLocals[WREAD_U1(bytecodes, false, i)], "",
+        push(new LoadInst(longLocals[WREAD_U1(bytecodes, false, i, wide)], "",
                           currentBlock), false);
         push(module->constantZero, false);
         break;
 
       case FLOAD :
-        push(new LoadInst(floatLocals[WREAD_U1(bytecodes, false, i)], "",
+        push(new LoadInst(floatLocals[WREAD_U1(bytecodes, false, i, wide)], "",
                           currentBlock), false);
         break;
 
       case DLOAD :
-        push(new LoadInst(doubleLocals[WREAD_U1(bytecodes, false, i)], "",
+        push(new LoadInst(doubleLocals[WREAD_U1(bytecodes, false, i, wide)], "",
                           currentBlock), false);
         push(module->constantZero, false);
         break;
 
       case ALOAD :
-        push(new LoadInst(objectLocals[WREAD_U1(bytecodes, false, i)], "",
+        push(new LoadInst(objectLocals[WREAD_U1(bytecodes, false, i, wide)], "",
                           currentBlock), false);
         break;
       
@@ -461,31 +471,31 @@
 
       case ISTORE : {
         Value* val = popAsInt();
-        new StoreInst(val, intLocals[WREAD_U1(bytecodes, false, i)], false,
-                      currentBlock);
+        new StoreInst(val, intLocals[WREAD_U1(bytecodes, false, i, wide)],
+                      false, currentBlock);
         break;
       }
       
       case LSTORE :
         pop(); // remove the 0 on the stack
-        new StoreInst(pop(), longLocals[WREAD_U1(bytecodes, false, i)], false,
-                      currentBlock);
+        new StoreInst(pop(), longLocals[WREAD_U1(bytecodes, false, i, wide)],
+                      false, currentBlock);
         break;
       
       case FSTORE :
-        new StoreInst(pop(), floatLocals[WREAD_U1(bytecodes, false, i)], false,
-                      currentBlock);
+        new StoreInst(pop(), floatLocals[WREAD_U1(bytecodes, false, i, wide)],
+                      false, currentBlock);
         break;
       
       case DSTORE :
         pop(); // remove the 0 on the stack
-        new StoreInst(pop(), doubleLocals[WREAD_U1(bytecodes, false, i)], false,
-                      currentBlock);
+        new StoreInst(pop(), doubleLocals[WREAD_U1(bytecodes, false, i, wide)],
+                      false, currentBlock);
         break;
 
       case ASTORE :
-        new StoreInst(pop(), objectLocals[WREAD_U1(bytecodes, false, i)], false,
-                      currentBlock);
+        new StoreInst(pop(), objectLocals[WREAD_U1(bytecodes, false, i, wide)],
+                      false, currentBlock);
         break;
       
       case ISTORE_0 : {
@@ -698,7 +708,7 @@
         break;
 
       case DUP :
-        push(top(), topFunc());
+        push(top(), topSign());
         break;
 
       case DUP_X1 : {
@@ -1102,8 +1112,8 @@
       }
 
       case IINC : {
-        uint16 idx = WREAD_U1(bytecodes, true, i);
-        sint16 val = WREAD_S1(bytecodes, false, i);
+        uint16 idx = WREAD_U1(bytecodes, true, i, wide);
+        sint16 val = WREAD_S1(bytecodes, false, i, wide);
         llvm::Value* add = BinaryOperator::CreateAdd(
             new LoadInst(intLocals[idx], "", currentBlock), 
             ConstantInt::get(Type::Int32Ty, val), "",
@@ -1710,7 +1720,7 @@
         BasicBlock* def = opcodeInfos[tmp + readU4(bytecodes, i)].newBlock;
         uint32 nbs = readU4(bytecodes, i);
         
-        bool unsign = topFunc();
+        bool unsign = topSign();
         Value* key = pop();
         const Type* type = key->getType();
         if (unsign) {
@@ -1731,10 +1741,10 @@
         break;
       }
       case IRETURN : {
-        bool unsign = topFunc();
+        bool unsign = topSign();
         Value* val = pop();
         assert(val->getType()->isInteger());
-        convertValue(val, returnType, currentBlock, unsign);
+        convertValue(val, endNode->getType(), currentBlock, unsign);
         endNode->addIncoming(val, currentBlock);
         BranchInst::Create(endBlock, currentBlock);
         break;
@@ -1809,7 +1819,7 @@
 
       case INVOKEINTERFACE : {
         uint16 index = readU2(bytecodes, i);
-        invokeInterfaceOrVirtual(index);
+        invokeInterface(index);
         i += 2;
         break;
       }
@@ -2202,7 +2212,7 @@
 }
 
 void JavaJIT::exploreOpcodes(uint8* bytecodes, uint32 codeLength) {
-  wide = false;
+  bool wide = false;
   for(uint32 i = 0; i < codeLength; ++i) {
     
     PRINT_DEBUG(JNJVM_COMPILE, 1, COLOR_NORMAL, "\t[at %5d] %-5d ", i,
@@ -2244,7 +2254,7 @@
       case FLOAD :
       case DLOAD :
       case ALOAD :
-        i += WCALC(1);
+        i += WCALC(1, wide);
         break;
       
       case ILOAD_0 :
@@ -2281,7 +2291,7 @@
       case FSTORE :
       case DSTORE :
       case ASTORE :
-        i += WCALC(1);
+        i += WCALC(1, wide);
         break;
       
       case ISTORE_0 :
@@ -2359,7 +2369,7 @@
       case LXOR : break;
 
       case IINC :
-        i += WCALC(2);
+        i += WCALC(2, wide);
         break;
       
       case I2L :
@@ -2419,7 +2429,6 @@
         } else {
           jsrs.push_back(opcodeInfos[tmp + 3].newBlock);
         }
-        opcodeInfos[index].reqSuppl = true;
         break;
       }
 





More information about the vmkit-commits mailing list