[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