From nicolas.geoffray at lip6.fr Mon Feb 2 05:39:39 2009 From: nicolas.geoffray at lip6.fr (Nicolas Geoffray) Date: Mon, 02 Feb 2009 13:39:39 -0000 Subject: [vmkit-commits] [vmkit] r63512 - in /vmkit/trunk/lib/JnJVM/VMCore: JavaJIT.cpp JavaJIT.h JavaJITOpcodes.cpp Message-ID: <200902021339.n12Ddddj002927@zion.cs.uiuc.edu> 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(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(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 >::iterator i = - jit->stack.begin(), - e = jit->stack.end(); i!= e; ++i) { + for (std::vector< std::pair >::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 >::iterator stackit = - jit->stack.begin(); + std::vector< std::pair >::iterator stackit = stack.begin(); for (BasicBlock::iterator i = dest->begin(), e = dest->end(); i != e; ++i) { if (!(isa(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 #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 intLocals; + std::vector longLocals; + std::vector floatLocals; + std::vector doubleLocals; + std::vector 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& args); + + /// inlineMethods - Methods that are currently being inlined. The JIT + /// uses this map to not inline a method currently bein inlined. std::map 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 > 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 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 popPair() { std::pair ret = stack.back(); stack.pop_back(); return ret; } + +//===------------------------- Exception support --------------------------===// - // exceptions + /// jsrs - The list of jsrs (jump subroutine) instructions. std::vector 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 intLocals; - std::vector longLocals; - std::vector floatLocals; - std::vector doubleLocals; - std::vector 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& 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& args); + + /// lowerMathOps - Map Java Math operations to LLVM intrinsics. llvm::Instruction* lowerMathOps(const UTF8* name, std::vector& args); - + /// invoke - invoke the LLVM method of a Java method. llvm::Instruction* invoke(llvm::Value *F, std::vector&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(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; } From nicolas.geoffray at lip6.fr Mon Feb 2 06:16:12 2009 From: nicolas.geoffray at lip6.fr (Nicolas Geoffray) Date: Mon, 02 Feb 2009 14:16:12 -0000 Subject: [vmkit-commits] [vmkit] r63513 - in /vmkit/trunk/lib/JnJVM/VMCore: JavaJIT.cpp JavaJIT.h JavaJITOpcodes.cpp Message-ID: <200902021416.n12EGCmL004140@zion.cs.uiuc.edu> Author: geoffray Date: Mon Feb 2 08:16:11 2009 New Revision: 63513 URL: http://llvm.org/viewvc/llvm-project?rev=63513&view=rev Log: Factorize code, no functionality changes. 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=63513&r1=63512&r2=63513&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.cpp (original) +++ vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.cpp Mon Feb 2 08:16:11 2009 @@ -20,7 +20,6 @@ #include #include #include -#include #include #include "mvm/JIT.h" @@ -37,9 +36,7 @@ #include "JavaTypes.h" #include "JavaUpcalls.h" #include "Jnjvm.h" -#include "JnjvmModuleProvider.h" #include "Reader.h" -#include "Zip.h" using namespace jnjvm; using namespace llvm; @@ -778,7 +775,7 @@ compileOpcodes(&compilingClass->bytes->elements[start], codeLen); assert(stack.size() == 0 && "Stack not empty after compiling bytecode"); - // Fix a javac(?) bug where a method only throws an exception and des + // Fix a javac(?) bug where a method only throws an exception and does // not return. pred_iterator PI = pred_begin(endBlock); pred_iterator PE = pred_end(endBlock); @@ -1378,20 +1375,9 @@ BasicBlock* exit = createBasicBlock("verifyNullExit"); BasicBlock* cont = createBasicBlock("verifyNullCont"); - llvm::BranchInst::Create(exit, cont, test, currentBlock); - if (currentExceptionBlock != endExceptionBlock) { - Value** val = 0; - InvokeInst::Create(module->NullPointerExceptionFunction, - unifiedUnreachable, - currentExceptionBlock, val, val, - "", exit); - } else { - llvm::CallInst::Create(module->NullPointerExceptionFunction, - "", exit); - new UnreachableInst(exit); - } - - + BranchInst::Create(exit, cont, test, currentBlock); + currentBlock = exit; + throwException(module->NullPointerExceptionFunction, 0, 0); currentBlock = cont; } @@ -1415,18 +1401,9 @@ branch(cmp, ifTrue, ifFalse, currentBlock); + currentBlock = ifFalse; Value* args[2] = { obj, index }; - if (currentExceptionBlock != endExceptionBlock) { - InvokeInst::Create(module->IndexOutOfBoundsExceptionFunction, - unifiedUnreachable, - currentExceptionBlock, args, args + 2, - "", ifFalse); - } else { - CallInst::Create(module->IndexOutOfBoundsExceptionFunction, - args, args + 2, "", ifFalse); - new UnreachableInst(ifFalse); - } - + throwException(module->IndexOutOfBoundsExceptionFunction, args, 2); currentBlock = ifTrue; } @@ -1486,18 +1463,6 @@ } } -void JavaJIT::branch(llvm::BasicBlock* dest, llvm::BasicBlock* insert) { - 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); - testPHINodes(ifFalse, insert); - llvm::BranchInst::Create(ifTrue, ifFalse, test, insert); -} - void JavaJIT::makeArgs(FunctionType::param_iterator it, uint32 index, std::vector& Args, uint32 nb) { #if defined(ISOLATE_SHARING) @@ -2270,3 +2235,27 @@ } } } + +void JavaJIT::throwException(llvm::Function* F, Value* arg1) { + if (currentExceptionBlock != endExceptionBlock) { + Value* exArgs[1] = { arg1 }; + InvokeInst::Create(F, unifiedUnreachable, + currentExceptionBlock, exArgs, exArgs + 1, + "", currentBlock); + } else { + CallInst::Create(F, arg1, "", currentBlock); + new UnreachableInst(currentBlock); + } +} + +void JavaJIT::throwException(llvm::Function* F, Value** args, + uint32 nbArgs) { + if (currentExceptionBlock != endExceptionBlock) { + InvokeInst::Create(F, unifiedUnreachable, + currentExceptionBlock, args, args + nbArgs, + "", currentBlock); + } else { + CallInst::Create(F, args, args + nbArgs, "", currentBlock); + new UnreachableInst(currentBlock); + } +} Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.h URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.h?rev=63513&r1=63512&r2=63513&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.h (original) +++ vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.h Mon Feb 2 08:16:11 2009 @@ -117,8 +117,6 @@ 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 ---------------------------===// @@ -256,6 +254,11 @@ /// unifiedUnreachable block as their normal destination. llvm::BasicBlock* unifiedUnreachable; + /// throwException - Emit code to throw a function. + void throwException(llvm::Function* F, llvm::Value** args, + uint32 nbArgs); + void throwException(llvm::Function* F, llvm::Value* arg1); + //===--------------------------- Control flow ----------------------------===// /// opcodeInfos - The informations for each instruction. @@ -271,10 +274,20 @@ /// 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); + llvm::BasicBlock* ifFalse, llvm::BasicBlock* insert) { + testPHINodes(ifTrue, insert); + testPHINodes(ifFalse, insert); + llvm::BranchInst::Create(ifTrue, ifFalse, test, insert); + } /// branch - Branch to a new block. Update PHI nodes accordingly. - void branch(llvm::BasicBlock* where, llvm::BasicBlock* insert); + void branch(llvm::BasicBlock* dest, llvm::BasicBlock* insert) { + testPHINodes(dest, insert); + llvm::BranchInst::Create(dest, insert); + } + + /// testPHINodes - Update PHI nodes when branching to a new block. + void testPHINodes(llvm::BasicBlock* dest, llvm::BasicBlock* insert); //===-------------------------- Synchronization --------------------------===// Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaJITOpcodes.cpp URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JavaJITOpcodes.cpp?rev=63513&r1=63512&r2=63513&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/JavaJITOpcodes.cpp (original) +++ vmkit/trunk/lib/JnJVM/VMCore/JavaJITOpcodes.cpp Mon Feb 2 08:16:11 2009 @@ -1904,17 +1904,7 @@ BranchInst::Create(BB1, BB2, cmp, currentBlock); currentBlock = BB1; - if (currentExceptionBlock != endExceptionBlock) { - Value* exArgs[1] = { arg1 }; - InvokeInst::Create(module->NegativeArraySizeExceptionFunction, - unifiedUnreachable, - currentExceptionBlock, exArgs, exArgs + 1, - "", currentBlock); - } else { - CallInst::Create(module->NegativeArraySizeExceptionFunction, - arg1, "", currentBlock); - new UnreachableInst(currentBlock); - } + throwException(module->NegativeArraySizeExceptionFunction, arg1); currentBlock = BB2; cmp = new ICmpInst(ICmpInst::ICMP_SGT, arg1, @@ -1926,17 +1916,7 @@ BranchInst::Create(BB1, BB2, cmp, currentBlock); currentBlock = BB1; - if (currentExceptionBlock != endExceptionBlock) { - Value* exArgs[1] = { arg1 }; - InvokeInst::Create(module->OutOfMemoryErrorFunction, - unifiedUnreachable, - currentExceptionBlock, exArgs, exArgs + 1, - "", currentBlock); - } else { - CallInst::Create(module->OutOfMemoryErrorFunction, arg1, "", - currentBlock); - new UnreachableInst(currentBlock); - } + throwException(module->OutOfMemoryErrorFunction, arg1); currentBlock = BB2; Value* mult = BinaryOperator::CreateMul(arg1, sizeElement, "", @@ -1995,17 +1975,7 @@ case ATHROW : { llvm::Value* arg = pop(); - if (currentExceptionBlock != endExceptionBlock) { - Value* args[1] = { arg }; - InvokeInst::Create(module->ThrowExceptionFunction, - unifiedUnreachable, - currentExceptionBlock, args, args + 1, - "", currentBlock); - } else { - CallInst::Create(module->ThrowExceptionFunction, arg, "", - currentBlock); - new UnreachableInst(currentBlock); - } + throwException(module->ThrowExceptionFunction, arg); break; } @@ -2035,17 +2005,8 @@ BasicBlock* ifFalse = createBasicBlock("non null checkcast"); BranchInst::Create(endCheckcast, ifFalse, cmp, currentBlock); - - if (currentExceptionBlock != endExceptionBlock) { - InvokeInst::Create(module->ClassCastExceptionFunction, - unifiedUnreachable, - currentExceptionBlock, args, args + 2, "", - exceptionCheckcast); - } else { - CallInst::Create(module->ClassCastExceptionFunction, - args, args + 2, "", exceptionCheckcast); - new UnreachableInst(exceptionCheckcast); - } + currentBlock = exceptionCheckcast; + throwException(module->ClassCastExceptionFunction, args, 2); currentBlock = ifFalse; } From nicolas.geoffray at lip6.fr Mon Feb 2 06:23:00 2009 From: nicolas.geoffray at lip6.fr (Nicolas Geoffray) Date: Mon, 02 Feb 2009 14:23:00 -0000 Subject: [vmkit-commits] [vmkit] r63514 - /vmkit/trunk/lib/JnJVM/VMCore/JavaRuntimeJIT.cpp Message-ID: <200902021423.n12EN07D004362@zion.cs.uiuc.edu> Author: geoffray Date: Mon Feb 2 08:23:00 2009 New Revision: 63514 URL: http://llvm.org/viewvc/llvm-project?rev=63514&view=rev Log: Include cleanups. Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaRuntimeJIT.cpp Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaRuntimeJIT.cpp URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JavaRuntimeJIT.cpp?rev=63514&r1=63513&r2=63514&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/JavaRuntimeJIT.cpp (original) +++ vmkit/trunk/lib/JnJVM/VMCore/JavaRuntimeJIT.cpp Mon Feb 2 08:23:00 2009 @@ -8,9 +8,6 @@ // //===----------------------------------------------------------------------===// -#include - -#include "mvm/Threads/Thread.h" #include "JavaArray.h" #include "JavaCache.h" @@ -21,7 +18,8 @@ #include "JavaThread.h" #include "JavaTypes.h" #include "Jnjvm.h" -#include "LockedMap.h" + +#include using namespace jnjvm; From nicolas.geoffray at lip6.fr Mon Feb 2 06:48:14 2009 From: nicolas.geoffray at lip6.fr (Nicolas Geoffray) Date: Mon, 02 Feb 2009 14:48:14 -0000 Subject: [vmkit-commits] [vmkit] r63515 - in /vmkit/trunk/lib/JnJVM: LLVMRuntime/runtime-default.ll VMCore/JavaThread.h Message-ID: <200902021448.n12EmE61005204@zion.cs.uiuc.edu> Author: geoffray Date: Mon Feb 2 08:48:12 2009 New Revision: 63515 URL: http://llvm.org/viewvc/llvm-project?rev=63515&view=rev Log: Add the exception objects into the LLVM representation of a thread. Modified: vmkit/trunk/lib/JnJVM/LLVMRuntime/runtime-default.ll vmkit/trunk/lib/JnJVM/VMCore/JavaThread.h Modified: vmkit/trunk/lib/JnJVM/LLVMRuntime/runtime-default.ll URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/LLVMRuntime/runtime-default.ll?rev=63515&r1=63514&r2=63515&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/LLVMRuntime/runtime-default.ll (original) +++ vmkit/trunk/lib/JnJVM/LLVMRuntime/runtime-default.ll Mon Feb 2 08:48:12 2009 @@ -42,8 +42,10 @@ ;;; Field 6: internalThreadID ;;; field 7: routine ;;; field 8: jnienv +;;; field 9: Java pendingException +;;; field 10: CXX pendingException %JavaThread = type { %VT*, %JavaThread*, %JavaThread*, i8*, i8*, i8*, i8*, i8*, - i8* } + i8*, %JavaObject*, i8* } %Attribut = type { %UTF8*, i32, i32 } Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaThread.h URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JavaThread.h?rev=63515&r1=63514&r2=63515&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/JavaThread.h (original) +++ vmkit/trunk/lib/JnJVM/VMCore/JavaThread.h Mon Feb 2 08:48:12 2009 @@ -64,6 +64,14 @@ /// jniEnv - The JNI environment of the thread. /// void* jniEnv; + + /// pendingException - The Java exception currently pending. + /// + JavaObject* pendingException; + + /// internalPendingException - The C++ exception currencty pending. + /// + void* internalPendingException; /// javaThread - The Java representation of this thread. /// @@ -82,14 +90,6 @@ /// mvm::Cond varcond; - /// pendingException - The Java exception currently pending. - /// - JavaObject* pendingException; - - /// internalPendingException - The C++ exception currencty pending. - /// - void* internalPendingException; - /// interruptFlag - Has this thread been interrupted? /// uint32 interruptFlag; From nicolas.geoffray at lip6.fr Mon Feb 2 06:49:22 2009 From: nicolas.geoffray at lip6.fr (Nicolas Geoffray) Date: Mon, 02 Feb 2009 14:49:22 -0000 Subject: [vmkit-commits] [vmkit] r63516 - in /vmkit/trunk/lib/JnJVM/VMCore: JavaJIT.cpp JavaJIT.h JavaJITOpcodes.cpp Message-ID: <200902021449.n12EnN4r005251@zion.cs.uiuc.edu> Author: geoffray Date: Mon Feb 2 08:49:22 2009 New Revision: 63516 URL: http://llvm.org/viewvc/llvm-project?rev=63516&view=rev Log: Factorize code, no functionality changes. 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=63516&r1=63515&r2=63516&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.cpp (original) +++ vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.cpp Mon Feb 2 08:49:22 2009 @@ -184,6 +184,20 @@ #endif } +llvm::Value* JavaJIT::getCurrentThread() { + Value* FrameAddr = CallInst::Create(module->llvm_frameaddress, + module->constantZero, "", currentBlock); + Value* threadId = new PtrToIntInst(FrameAddr, module->pointerSizeType, "", + currentBlock); + threadId = BinaryOperator::CreateAnd(threadId, module->constantThreadIDMask, + "", currentBlock); + threadId = new IntToPtrInst(threadId, module->JavaThreadType, "", + currentBlock); + + return threadId; +} + + llvm::Function* JavaJIT::nativeCompile(intptr_t natPtr) { PRINT_DEBUG(JNJVM_COMPILE, 1, COLOR_NORMAL, "native compile %s\n", @@ -250,15 +264,8 @@ uint32 nargs = func->arg_size() + 1 + (stat ? 1 : 0); std::vector nativeArgs; - Value* FrameAddr = CallInst::Create(module->llvm_frameaddress, - module->constantZero, "", currentBlock); - Value* threadId = new PtrToIntInst(FrameAddr, module->pointerSizeType, "", - currentBlock); - threadId = BinaryOperator::CreateAnd(threadId, module->constantThreadIDMask, - "", currentBlock); - threadId = new IntToPtrInst(threadId, module->JavaThreadType, "", - currentBlock); - + + Value* threadId = getCurrentThread(); Value* geps[2] = { module->constantZero, module->constantEight }; @@ -316,6 +323,9 @@ currentBlock = endBlock; nativeFunc = node; } + + Value* FrameAddr = CallInst::Create(module->llvm_frameaddress, + module->constantZero, "", currentBlock); // When calling a native method, it may do whatever it wants with the // frame pointer. Therefore make sure it's on the stack. x86_64 has @@ -362,12 +372,9 @@ Value* lockMask = BinaryOperator::CreateAnd(lock, module->constantThreadFreeMask, "", currentBlock); - Value* threadId = CallInst::Create(module->llvm_frameaddress, - module->constantZero, "", currentBlock); + Value* threadId = getCurrentThread(); threadId = new PtrToIntInst(threadId, module->pointerSizeType, "", currentBlock); - threadId = BinaryOperator::CreateAnd(threadId, module->constantThreadIDMask, - "", currentBlock); Value* cmp = new ICmpInst(ICmpInst::ICMP_EQ, lockMask, threadId, "", currentBlock); @@ -404,13 +411,9 @@ lock = new PtrToIntInst(lock, module->pointerSizeType, "", currentBlock); Value* lockMask = BinaryOperator::CreateAnd(lock, module->constantLockedMask, "", currentBlock); - Value* threadId = CallInst::Create(module->llvm_frameaddress, - module->constantZero, "", currentBlock); + Value* threadId = getCurrentThread(); threadId = new PtrToIntInst(threadId, module->pointerSizeType, "", currentBlock); - threadId = BinaryOperator::CreateAnd(threadId, module->constantThreadIDMask, - "", currentBlock); - Value* cmp = new ICmpInst(ICmpInst::ICMP_EQ, lockMask, threadId, "", currentBlock); @@ -710,14 +713,7 @@ Value* NewIsolate = 0; Value* IsolatePtr = 0; if (loader != loader->bootstrapLoader && isPublic(compilingMethod->access)) { - 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 = getCurrentThread(); IsolateIDPtr = GetElementPtrInst::Create(threadId, module->constantThree, "", currentBlock); @@ -1157,18 +1153,7 @@ // 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); - + Value* threadId = getCurrentThread(); Value* Isolate = GetElementPtrInst::Create(threadId, module->constantFour, "", currentBlock); @@ -1246,17 +1231,9 @@ Value* OldIsolate = 0; Value* NewIsolate = 0; Value* IsolatePtr = 0; + currentBlock = cur->javaHandler; 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); + threadId = getCurrentThread(); IsolateIDPtr = GetElementPtrInst::Create(threadId, module->constantThree, "", cur->javaHandler); @@ -1886,16 +1863,12 @@ Cl = new BitCastInst(Cl, module->JavaCommonClassType, "", currentBlock); new StoreInst(Cl, GEP, currentBlock); - Value* gep2[2] = { module->constantZero, module->JavaObjectLockOffsetConstant }; + Value* gep2[2] = { module->constantZero, + module->JavaObjectLockOffsetConstant }; Value* lockPtr = GetElementPtrInst::Create(val, gep2, gep2 + 2, "", currentBlock); - 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->ptrType, "", currentBlock); + Value* threadId = getCurrentThread(); + threadId = new BitCastInst(threadId, module->ptrType, "", currentBlock); new StoreInst(threadId, lockPtr, currentBlock); push(val, false); Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.h URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.h?rev=63516&r1=63515&r2=63516&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.h (original) +++ vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.h Mon Feb 2 08:49:22 2009 @@ -116,8 +116,9 @@ llvm::Value* getConstantPoolAt(uint32 index, llvm::Function* resolver, const llvm::Type* returnType, llvm::Value* addArg, bool doThrow = true); - - + + /// getCurrentThread - Emit code to get the current thread. + llvm::Value* getCurrentThread(); //===--------------------------- Inline support ---------------------------===// Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaJITOpcodes.cpp URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JavaJITOpcodes.cpp?rev=63516&r1=63515&r2=63516&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/JavaJITOpcodes.cpp (original) +++ vmkit/trunk/lib/JnJVM/VMCore/JavaJITOpcodes.cpp Mon Feb 2 08:49:22 2009 @@ -1948,16 +1948,9 @@ module->JavaObjectLockOffsetConstant }; Value* lockPtr = GetElementPtrInst::Create(res, gep1, gep1 + 2, "", currentBlock); - 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->ptrType, "", - currentBlock); + Value* threadId = getCurrentThread(); + + threadId = new BitCastInst(threadId, module->ptrType, "", currentBlock); new StoreInst(threadId, lockPtr, currentBlock); From nicolas.geoffray at lip6.fr Mon Feb 2 08:09:41 2009 From: nicolas.geoffray at lip6.fr (Nicolas Geoffray) Date: Mon, 02 Feb 2009 16:09:41 -0000 Subject: [vmkit-commits] [vmkit] r63520 - in /vmkit/trunk/lib/JnJVM: LLVMRuntime/runtime-default.ll VMCore/JavaJIT.cpp VMCore/JavaRuntimeJIT.cpp VMCore/JavaThread.cpp VMCore/JavaThread.h VMCore/JnjvmModule.cpp VMCore/JnjvmModule.h Message-ID: <200902021609.n12G9gVk008184@zion.cs.uiuc.edu> Author: geoffray Date: Mon Feb 2 10:09:41 2009 New Revision: 63520 URL: http://llvm.org/viewvc/llvm-project?rev=63520&view=rev Log: Code cleanup: inline some exception functions in the LLVM code. Modified: vmkit/trunk/lib/JnJVM/LLVMRuntime/runtime-default.ll vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.cpp vmkit/trunk/lib/JnJVM/VMCore/JavaRuntimeJIT.cpp vmkit/trunk/lib/JnJVM/VMCore/JavaThread.cpp vmkit/trunk/lib/JnJVM/VMCore/JavaThread.h vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.cpp vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.h Modified: vmkit/trunk/lib/JnJVM/LLVMRuntime/runtime-default.ll URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/LLVMRuntime/runtime-default.ll?rev=63520&r1=63519&r2=63520&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/LLVMRuntime/runtime-default.ll (original) +++ vmkit/trunk/lib/JnJVM/LLVMRuntime/runtime-default.ll Mon Feb 2 10:09:41 2009 @@ -199,12 +199,7 @@ declare void @indexOutOfBoundsException(%JavaObject*, i32) declare void @negativeArraySizeException(i32) declare void @outOfMemoryError(i32) - -declare void @JavaThreadThrowException(%JavaObject*) -declare void @JavaThreadClearException() -declare i8* @JavaThreadGetException() -declare %JavaObject* @JavaThreadGetJavaException() -declare i1 @JavaThreadCompareException(%JavaClass*) +declare void @JavaThreadThrowException(%JavaObject*) declare void @jniProceedPendingException() declare i8* @getSJLJBuffer() Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.cpp URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.cpp?rev=63520&r1=63519&r2=63520&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.cpp (original) +++ vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.cpp Mon Feb 2 10:09:41 2009 @@ -836,16 +836,23 @@ ReturnInst::Create(currentBlock); } + currentBlock = endExceptionBlock; PI = pred_begin(endExceptionBlock); PE = pred_end(endExceptionBlock); if (PI == PE) { endExceptionBlock->eraseFromParent(); } else { - CallInst* ptr_eh_ptr = CallInst::Create(module->GetExceptionFunction, - "eh_ptr", endExceptionBlock); - llvm::CallInst::Create(module->unwindResume, ptr_eh_ptr, "", - endExceptionBlock); - new UnreachableInst(endExceptionBlock); + Value* threadId = getCurrentThread(); + Value* geps2[2] = { module->constantZero, + module->OffsetCXXExceptionInThreadConstant }; + + Value* cxxExceptionPtr = GetElementPtrInst::Create(threadId, geps2, + geps2 + 2, "", + currentBlock); + cxxExceptionPtr = new LoadInst(cxxExceptionPtr, "", currentBlock); + llvm::CallInst::Create(module->unwindResume, cxxExceptionPtr, "", + currentBlock); + new UnreachableInst(currentBlock); } PI = pred_begin(unifiedUnreachable); @@ -1133,20 +1140,7 @@ cur->exceptionPHI->addIncoming(ptr_eh_ptr, cur->catcher); } - // We now implement the tester of the handler. - Value* cl = 0; currentBlock = cur->tester; -#ifdef ISOLATE_SHARING - // We're dealing with exceptions, don't catch the exception if the class can - // not be found. - if (cur->catche) cl = getResolvedClass(cur->catche, false, false, 0); - else cl = CallInst::Create(module->GetJnjvmExceptionClassFunction, - isolateLocal, "", currentBlock); -#else - // 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 // Verifies that the current isolate is not stopped. If it is, we don't @@ -1178,10 +1172,28 @@ } #endif - // Compare the exception with the exception class we catch. - Value* cmp = CallInst::Create(module->CompareExceptionFunction, cl, "", - currentBlock); + Value* threadId = getCurrentThread(); + Value* geps[2] = { module->constantZero, + module->OffsetJavaExceptionInThreadConstant }; + + Value* javaExceptionPtr = GetElementPtrInst::Create(threadId, geps, + geps + 2, "", + currentBlock); + + // Get the Java exception. + Value* obj = new LoadInst(javaExceptionPtr, "", currentBlock); + + Value* objCl = CallInst::Create(module->GetClassFunction, obj, "", + currentBlock); + + Value* depthCl = ConstantInt::get(Type::Int32Ty, cur->catchClass->depth); + Value* depthClObj = CallInst::Create(module->GetDepthFunction, objCl, "", + currentBlock); + // Compare the exception with the exception class we catch. + Value* cmp = new ICmpInst(ICmpInst::ICMP_ULE, depthCl, depthClObj, "", + 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); @@ -1190,11 +1202,27 @@ // just catched. if (nodeNext) nodeNext->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); + + currentBlock = cur->nativeHandler; + + threadId = getCurrentThread(); + javaExceptionPtr = GetElementPtrInst::Create(threadId, geps, geps + 2, "", + currentBlock); + + // Get the Java exception. + Value* exc = new LoadInst(javaExceptionPtr, "", currentBlock); + + Value* geps2[2] = { module->constantZero, + module->OffsetCXXExceptionInThreadConstant }; + + Value* cxxExceptionPtr = GetElementPtrInst::Create(threadId, geps2, + geps2 + 2, "", + currentBlock); + + // Clear exceptions. + new StoreInst(module->constantPtrNull, cxxExceptionPtr, currentBlock); + new StoreInst(module->JavaObjectNullConstant, javaExceptionPtr, + currentBlock); // Call the CXX begin and end catcher. CallInst::Create(module->exceptionBeginCatch, cur->exceptionPHI, Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaRuntimeJIT.cpp URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JavaRuntimeJIT.cpp?rev=63520&r1=63519&r2=63520&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/JavaRuntimeJIT.cpp (original) +++ vmkit/trunk/lib/JnJVM/VMCore/JavaRuntimeJIT.cpp Mon Feb 2 10:09:41 2009 @@ -390,32 +390,12 @@ return cl1->isAssignableFrom(cl2); } -// Never throws. -extern "C" void* JavaThreadGetException() { - return JavaThread::get()->getException(); -} - -// Never throws. -extern "C" JavaObject* JavaThreadGetJavaException() { - return JavaThread::get()->getJavaException(); -} - // Does not call any Java code. extern "C" void JavaThreadThrowException(JavaObject* obj) { return JavaThread::get()->throwException(obj); } // Never throws. -extern "C" bool JavaThreadCompareException(UserClass* cl) { - return JavaThread::get()->compareException(cl); -} - -// Never throws. -extern "C" void JavaThreadClearException() { - return JavaThread::get()->clearException(); -} - -// Never throws. extern "C" void overflowThinLock(JavaObject* obj) { obj->overflowThinLock(); } Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaThread.cpp URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JavaThread.cpp?rev=63520&r1=63519&r2=63520&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/JavaThread.cpp (original) +++ vmkit/trunk/lib/JnJVM/VMCore/JavaThread.cpp Mon Feb 2 10:09:41 2009 @@ -59,7 +59,8 @@ assert(th->pendingException == 0 && "pending exception already there?"); th->pendingException = obj; void* exc = __cxa_allocate_exception(0); - th->internalPendingException = exc; + // 32 = sizeof(_Unwind_Exception) in libgcc... + th->internalPendingException = (void*)((uintptr_t)exc - 32); __cxa_throw(exc, 0, 0); } @@ -67,7 +68,7 @@ JavaThread* th = JavaThread::get(); assert(th->pendingException); void* exc = __cxa_allocate_exception(0); - th->internalPendingException = exc; + th->internalPendingException = (void*)((uintptr_t)exc - 32); __cxa_throw(exc, 0, 0); } Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaThread.h URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JavaThread.h?rev=63520&r1=63519&r2=63520&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/JavaThread.h (original) +++ vmkit/trunk/lib/JnJVM/VMCore/JavaThread.h Mon Feb 2 10:09:41 2009 @@ -154,14 +154,6 @@ return 0; } - /// getException - Return the C++ specific exception object. - /// - void* getException() { - // 32 = sizeof(_Unwind_Exception) in libgcc... - return (void*) - ((uintptr_t)JavaThread::get()->internalPendingException - 32); - } - /// throwException - Throw the given exception in the current thread. /// void throwException(JavaObject* obj); Modified: vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.cpp URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.cpp?rev=63520&r1=63519&r2=63520&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.cpp (original) +++ vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.cpp Mon Feb 2 10:09:41 2009 @@ -92,6 +92,8 @@ llvm::ConstantInt* JnjvmModule::OffsetTaskClassMirrorInClassConstant; llvm::ConstantInt* JnjvmModule::OffsetStaticInstanceInTaskClassMirrorConstant; llvm::ConstantInt* JnjvmModule::OffsetStatusInTaskClassMirrorConstant; +llvm::ConstantInt* JnjvmModule::OffsetJavaExceptionInThreadConstant; +llvm::ConstantInt* JnjvmModule::OffsetCXXExceptionInThreadConstant; llvm::ConstantInt* JnjvmModule::ClassReadyConstant; const llvm::Type* JnjvmModule::JavaClassType; const llvm::Type* JnjvmModule::JavaClassPrimitiveType; @@ -2020,6 +2022,9 @@ OffsetStaticInstanceInTaskClassMirrorConstant = mvm::MvmModule::constantOne; OffsetStatusInTaskClassMirrorConstant = mvm::MvmModule::constantZero; + OffsetJavaExceptionInThreadConstant = ConstantInt::get(Type::Int32Ty, 9); + OffsetCXXExceptionInThreadConstant = ConstantInt::get(Type::Int32Ty, 10); + ClassReadyConstant = ConstantInt::get(Type::Int32Ty, ready); @@ -2179,9 +2184,6 @@ VirtualFieldLookupFunction = module->getFunction("virtualFieldLookup"); StaticFieldLookupFunction = module->getFunction("staticFieldLookup"); - GetExceptionFunction = module->getFunction("JavaThreadGetException"); - GetJavaExceptionFunction = module->getFunction("JavaThreadGetJavaException"); - CompareExceptionFunction = module->getFunction("JavaThreadCompareException"); JniProceedPendingExceptionFunction = module->getFunction("jniProceedPendingException"); GetSJLJBufferFunction = module->getFunction("getSJLJBuffer"); @@ -2203,8 +2205,6 @@ ThrowExceptionFunction = module->getFunction("JavaThreadThrowException"); - ClearExceptionFunction = module->getFunction("JavaThreadClearException"); - GetArrayClassFunction = module->getFunction("getArrayClass"); Modified: vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.h URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.h?rev=63520&r1=63519&r2=63520&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.h (original) +++ vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.h Mon Feb 2 10:09:41 2009 @@ -367,17 +367,16 @@ static llvm::ConstantInt* OffsetStaticInstanceInTaskClassMirrorConstant; static llvm::ConstantInt* OffsetStatusInTaskClassMirrorConstant; + static llvm::ConstantInt* OffsetJavaExceptionInThreadConstant; + static llvm::ConstantInt* OffsetCXXExceptionInThreadConstant; + static llvm::ConstantInt* ClassReadyConstant; static llvm::Constant* JavaObjectNullConstant; static llvm::Constant* MaxArraySizeConstant; static llvm::Constant* JavaArraySizeConstant; - llvm::Function* GetExceptionFunction; - llvm::Function* GetJavaExceptionFunction; llvm::Function* ThrowExceptionFunction; - llvm::Function* ClearExceptionFunction; - llvm::Function* CompareExceptionFunction; llvm::Function* NullPointerExceptionFunction; llvm::Function* IndexOutOfBoundsExceptionFunction; llvm::Function* ClassCastExceptionFunction; From nicolas.geoffray at lip6.fr Mon Feb 2 09:27:33 2009 From: nicolas.geoffray at lip6.fr (Nicolas Geoffray) Date: Mon, 02 Feb 2009 17:27:33 -0000 Subject: [vmkit-commits] [vmkit] r63524 - /vmkit/trunk/lib/JnJVM/VMCore/JavaThread.h Message-ID: <200902021727.n12HRXqp011125@zion.cs.uiuc.edu> Author: geoffray Date: Mon Feb 2 11:27:33 2009 New Revision: 63524 URL: http://llvm.org/viewvc/llvm-project?rev=63524&view=rev Log: Code cleanup. Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaThread.h Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaThread.h URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JavaThread.h?rev=63524&r1=63523&r2=63524&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/JavaThread.h (original) +++ vmkit/trunk/lib/JnJVM/VMCore/JavaThread.h Mon Feb 2 11:27:33 2009 @@ -147,11 +147,7 @@ /// currentThread - Return the current thread as a Java object. /// JavaObject* currentThread() { - JavaThread* result = get(); - if (result != 0) - return result->javaThread; - else - return 0; + return javaThread; } /// throwException - Throw the given exception in the current thread. @@ -162,16 +158,6 @@ /// void throwPendingException(); - /// compareException - Compare the pending exception's class with the - /// given class. - /// - bool compareException(UserClass* cl) { - JavaObject* pe = pendingException; - assert(pe && "no pending exception?"); - bool val = pe->getClass()->subclassOf(cl); - return val; - } - /// getJavaException - Return the pending exception. /// JavaObject* getJavaException() { From nicolas.geoffray at lip6.fr Mon Feb 2 14:25:11 2009 From: nicolas.geoffray at lip6.fr (Nicolas Geoffray) Date: Mon, 02 Feb 2009 22:25:11 -0000 Subject: [vmkit-commits] [vmkit] r63556 - /vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.cpp Message-ID: <200902022225.n12MPB9t022871@zion.cs.uiuc.edu> Author: geoffray Date: Mon Feb 2 16:25:10 2009 New Revision: 63556 URL: http://llvm.org/viewvc/llvm-project?rev=63556&view=rev Log: Fix exception testing. Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.cpp Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.cpp URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.cpp?rev=63556&r1=63555&r2=63556&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.cpp (original) +++ vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.cpp Mon Feb 2 16:25:10 2009 @@ -1142,6 +1142,23 @@ currentBlock = cur->tester; + Value* clVar = 0; +#ifdef ISOLATE_SHARING + // We're dealing with exceptions, don't catch the exception if the class can + // not be found. + if (cur->catche) clVar = getResolvedClass(cur->catche, false, false, 0); + else clVar = CallInst::Create(module->GetJnjvmExceptionClassFunction, + isolateLocal, "", currentBlock); +#else + // We know catchClass exists because we have loaded all exceptions catched + // by the method when we loaded the class that defined this method. + clVar = module->getNativeClass(cur->catchClass); +#endif + if (clVar->getType() != module->JavaCommonClassType) + clVar = new BitCastInst(clVar, module->JavaCommonClassType, "", + currentBlock); + + #ifdef SERVICE // Verifies that the current isolate is not stopped. If it is, we don't // catch the exception but resume unwinding. @@ -1194,10 +1211,29 @@ Value* cmp = new ICmpInst(ICmpInst::ICMP_ULE, depthCl, depthClObj, "", currentBlock); + BasicBlock* supDepth = createBasicBlock("superior depth"); + + BranchInst::Create(supDepth, bbNext, cmp, currentBlock); + + if (nodeNext) + nodeNext->addIncoming(cur->exceptionPHI, currentBlock); + + currentBlock = supDepth; + Value* inDisplay = CallInst::Create(module->GetDisplayFunction, + objCl, "", currentBlock); + + Value* displayArgs[2] = { inDisplay, depthCl }; + Value* clInDisplay = CallInst::Create(module->GetClassInDisplayFunction, + displayArgs, displayArgs + 2, "", + currentBlock); + + cmp = new ICmpInst(ICmpInst::ICMP_EQ, clInDisplay, clVar, "", + 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); - + BranchInst::Create(cur->nativeHandler, bbNext, cmp, currentBlock); + // Add the incoming value to the next handler, which is the exception we // just catched. if (nodeNext) From nicolas.geoffray at lip6.fr Thu Feb 5 02:52:36 2009 From: nicolas.geoffray at lip6.fr (Nicolas Geoffray) Date: Thu, 05 Feb 2009 10:52:36 -0000 Subject: [vmkit-commits] [vmkit] r63862 - /vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.h Message-ID: <200902051052.n15Aqbfu017017@zion.cs.uiuc.edu> Author: geoffray Date: Thu Feb 5 04:52:32 2009 New Revision: 63862 URL: http://llvm.org/viewvc/llvm-project?rev=63862&view=rev Log: Fix a comment. Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.h Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.h URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.h?rev=63862&r1=63861&r2=63862&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.h (original) +++ vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.h Thu Feb 5 04:52:32 2009 @@ -255,7 +255,7 @@ /// unifiedUnreachable block as their normal destination. llvm::BasicBlock* unifiedUnreachable; - /// throwException - Emit code to throw a function. + /// throwException - Emit code to throw an exception. void throwException(llvm::Function* F, llvm::Value** args, uint32 nbArgs); void throwException(llvm::Function* F, llvm::Value* arg1); From nicolas.geoffray at lip6.fr Mon Feb 9 05:05:18 2009 From: nicolas.geoffray at lip6.fr (Nicolas Geoffray) Date: Mon, 09 Feb 2009 13:05:18 -0000 Subject: [vmkit-commits] [vmkit] r64138 - in /vmkit/trunk: Makefile.common.in autoconf/configure.ac Message-ID: <200902091305.n19D5JEL026713@zion.cs.uiuc.edu> Author: geoffray Date: Mon Feb 9 07:05:16 2009 New Revision: 64138 URL: http://llvm.org/viewvc/llvm-project?rev=64138&view=rev Log: New configure parameter to specify the type of exception: dwarf or runtime checks. Modified: vmkit/trunk/Makefile.common.in vmkit/trunk/autoconf/configure.ac Modified: vmkit/trunk/Makefile.common.in URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/Makefile.common.in?rev=64138&r1=64137&r2=64138&view=diff ============================================================================== --- vmkit/trunk/Makefile.common.in (original) +++ vmkit/trunk/Makefile.common.in Mon Feb 9 07:05:16 2009 @@ -23,7 +23,7 @@ # Include LLVM's Master Makefile. include $(LLVM_OBJ_ROOT)/Makefile.common -CXX.Flags += @GC_FLAGS@ @VM_FLAGS@ -Wno-variadic-macros -fno-omit-frame-pointer -fno-strict-aliasing -Wno-deprecated -ansi -DENABLE_THREADS +CXX.Flags += @GC_FLAGS@ @VM_FLAGS@ @EXCEPTION_FLAGS@ -Wno-variadic-macros -fno-omit-frame-pointer -fno-strict-aliasing -Wno-deprecated -ansi -DENABLE_THREADS # GNU Classpath flags CLASSPATH_FLAGS = @classpathinclude@ Modified: vmkit/trunk/autoconf/configure.ac URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/autoconf/configure.ac?rev=64138&r1=64137&r2=64138&view=diff ============================================================================== --- vmkit/trunk/autoconf/configure.ac (original) +++ vmkit/trunk/autoconf/configure.ac Mon Feb 9 07:05:16 2009 @@ -245,6 +245,24 @@ AC_SUBST([VM_FLAGS]) dnl ************************************************************************** +dnl Exception type +dnl ************************************************************************** +AC_ARG_WITH(exception-type, + [AS_HELP_STRING(--with-exception-type=something, + [VM type ('check' or 'dwarf')])], + [[exceptiontype=$withval]], + [[ echo Using check as exception type. + exceptiontype=check + ]] +) + +if test "x$exceptiontype" = "xdwarf"; then + EXCEPTION_FLAGS="-DDWARF_EXCEPTIONS" +fi + +AC_SUBST([EXCEPTION_FLAGS]) + +dnl ************************************************************************** dnl GNU CLASSPATH installation prefix dnl ************************************************************************** From nicolas.geoffray at lip6.fr Mon Feb 9 05:28:11 2009 From: nicolas.geoffray at lip6.fr (Nicolas Geoffray) Date: Mon, 09 Feb 2009 13:28:11 -0000 Subject: [vmkit-commits] [vmkit] r64139 - /vmkit/trunk/configure Message-ID: <200902091328.n19DSBbt027440@zion.cs.uiuc.edu> Author: geoffray Date: Mon Feb 9 07:28:11 2009 New Revision: 64139 URL: http://llvm.org/viewvc/llvm-project?rev=64139&view=rev Log: Regenerate. Modified: vmkit/trunk/configure Modified: vmkit/trunk/configure URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/configure?rev=64139&r1=64138&r2=64139&view=diff ============================================================================== --- vmkit/trunk/configure (original) +++ vmkit/trunk/configure Mon Feb 9 07:28:11 2009 @@ -691,6 +691,7 @@ SERVICE_BUILD ISOLATE_BUILD VM_FLAGS +EXCEPTION_FLAGS classpathglibj classpathlibs classpathinclude @@ -1324,6 +1325,8 @@ --with-vm-type=something VM type ('single' 'isolate' 'isolate-sharing' or 'service') + --with-exception-type=something + VM type ('check' or 'dwarf') --with-gnu-classpath-libs=something GNU CLASSPATH libraries (default is /usr/lib/classpath) @@ -3968,6 +3971,24 @@ +# Check whether --with-exception-type was given. +if test "${with_exception_type+set}" = set; then + withval=$with_exception_type; exceptiontype=$withval +else + echo Using check as exception type. + exceptiontype=check + + +fi + + +if test "x$exceptiontype" = "xdwarf"; then + EXCEPTION_FLAGS="-DDWARF_EXCEPTIONS" +fi + + + + classpathversion=0.97.2; @@ -7866,6 +7887,7 @@ SERVICE_BUILD!$SERVICE_BUILD$ac_delim ISOLATE_BUILD!$ISOLATE_BUILD$ac_delim VM_FLAGS!$VM_FLAGS$ac_delim +EXCEPTION_FLAGS!$EXCEPTION_FLAGS$ac_delim classpathglibj!$classpathglibj$ac_delim classpathlibs!$classpathlibs$ac_delim classpathinclude!$classpathinclude$ac_delim @@ -7889,7 +7911,6 @@ FIND!$FIND$ac_delim MKDIR!$MKDIR$ac_delim MV!$MV$ac_delim -RANLIB!$RANLIB$ac_delim _ACEOF if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 97; then @@ -7931,6 +7952,7 @@ ac_delim='%!_!# ' for ac_last_try in false false false false false :; do cat >conf$$subs.sed <<_ACEOF +RANLIB!$RANLIB$ac_delim RM!$RM$ac_delim SED!$SED$ac_delim TAR!$TAR$ac_delim @@ -7947,7 +7969,7 @@ LTLIBOBJS!$LTLIBOBJS$ac_delim _ACEOF - if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 14; then + if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 15; then break elif $ac_last_try; then { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 From nicolas.geoffray at lip6.fr Mon Feb 9 05:33:31 2009 From: nicolas.geoffray at lip6.fr (Nicolas Geoffray) Date: Mon, 09 Feb 2009 13:33:31 -0000 Subject: [vmkit-commits] [vmkit] r64140 - in /vmkit/trunk/lib: JnJVM/LLVMRuntime/runtime-default.ll JnJVM/VMCore/ExceptionsCheck.inc JnJVM/VMCore/ExceptionsDwarf.inc JnJVM/VMCore/JavaJIT.cpp JnJVM/VMCore/JavaJIT.h JnJVM/VMCore/JavaJITOpcodes.cpp JnJVM/VMCore/JavaMetaJIT.cpp JnJVM/VMCore/JavaObject.cpp JnJVM/VMCore/JavaRuntimeJIT.cpp JnJVM/VMCore/JavaThread.h Mvm/Runtime/JIT.cpp Message-ID: <200902091333.n19DXWoc027663@zion.cs.uiuc.edu> Author: geoffray Date: Mon Feb 9 07:33:30 2009 New Revision: 64140 URL: http://llvm.org/viewvc/llvm-project?rev=64140&view=rev Log: New exception model, where exceptions are checked after each function call. This has a little cost for applications without exceptions, but is a big win for application with a lot of exceptions. Since exceptions are usual in Java, we chose not to continue with dwarf. Added: vmkit/trunk/lib/JnJVM/VMCore/ExceptionsCheck.inc vmkit/trunk/lib/JnJVM/VMCore/ExceptionsDwarf.inc Modified: vmkit/trunk/lib/JnJVM/LLVMRuntime/runtime-default.ll vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.cpp vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.h vmkit/trunk/lib/JnJVM/VMCore/JavaJITOpcodes.cpp vmkit/trunk/lib/JnJVM/VMCore/JavaMetaJIT.cpp vmkit/trunk/lib/JnJVM/VMCore/JavaObject.cpp vmkit/trunk/lib/JnJVM/VMCore/JavaRuntimeJIT.cpp vmkit/trunk/lib/JnJVM/VMCore/JavaThread.h vmkit/trunk/lib/Mvm/Runtime/JIT.cpp Modified: vmkit/trunk/lib/JnJVM/LLVMRuntime/runtime-default.ll URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/LLVMRuntime/runtime-default.ll?rev=64140&r1=64139&r2=64140&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/LLVMRuntime/runtime-default.ll (original) +++ vmkit/trunk/lib/JnJVM/LLVMRuntime/runtime-default.ll Mon Feb 9 07:33:30 2009 @@ -194,11 +194,11 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Exception methods ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -declare void @jnjvmNullPointerException() -declare void @jnjvmClassCastException(%JavaObject*, %JavaCommonClass*) -declare void @indexOutOfBoundsException(%JavaObject*, i32) -declare void @negativeArraySizeException(i32) -declare void @outOfMemoryError(i32) +declare %JavaObject* @jnjvmNullPointerException() +declare %JavaObject* @jnjvmClassCastException(%JavaObject*, %JavaCommonClass*) +declare %JavaObject* @indexOutOfBoundsException(%JavaObject*, i32) +declare %JavaObject* @negativeArraySizeException(i32) +declare %JavaObject* @outOfMemoryError(i32) declare void @JavaThreadThrowException(%JavaObject*) declare void @jniProceedPendingException() Added: vmkit/trunk/lib/JnJVM/VMCore/ExceptionsCheck.inc URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/ExceptionsCheck.inc?rev=64140&view=auto ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/ExceptionsCheck.inc (added) +++ vmkit/trunk/lib/JnJVM/VMCore/ExceptionsCheck.inc Mon Feb 9 07:33:30 2009 @@ -0,0 +1,518 @@ +Instruction* JavaJIT::invoke(Value *F, std::vector& args, + const char* Name, + BasicBlock *InsertAtEnd) { + + Instruction* res = CallInst::Create(F, args.begin(), args.end(), Name, + InsertAtEnd); + Value* threadId = getCurrentThread(); + Value* geps[2] = { module->constantZero, + module->OffsetJavaExceptionInThreadConstant }; + + Value* javaExceptionPtr = GetElementPtrInst::Create(threadId, geps, + geps + 2, "", + currentBlock); + + // Get the Java exception. + Value* obj = new LoadInst(javaExceptionPtr, "", currentBlock); + + BasicBlock* ifNormal = createBasicBlock("no exception block"); + + Constant* zero = module->JavaObjectNullConstant; + Value* test = new ICmpInst(ICmpInst::ICMP_NE, obj, zero, "", + currentBlock); + + BranchInst::Create(currentExceptionBlock, ifNormal, test, currentBlock); + + + if (!currentExceptionBlock->empty()) { + Instruction* insn = currentExceptionBlock->begin(); + PHINode* node = dyn_cast(insn); + if (node) node->addIncoming(obj, currentBlock); + } + + currentBlock = ifNormal; + + return res; +} + +Instruction* JavaJIT::invoke(Value *F, Value* arg1, const char* Name, + BasicBlock *InsertAtEnd) { + + Instruction* res = CallInst::Create(F, arg1, Name, InsertAtEnd); + Value* threadId = getCurrentThread(); + Value* geps[2] = { module->constantZero, + module->OffsetJavaExceptionInThreadConstant }; + + Value* javaExceptionPtr = GetElementPtrInst::Create(threadId, geps, + geps + 2, "", + currentBlock); + + // Get the Java exception. + Value* obj = new LoadInst(javaExceptionPtr, "", currentBlock); + + BasicBlock* ifNormal = createBasicBlock("no exception block"); + + Constant* zero = module->JavaObjectNullConstant; + Value* test = new ICmpInst(ICmpInst::ICMP_NE, obj, zero, "", + currentBlock); + + BranchInst::Create(currentExceptionBlock, ifNormal, test, currentBlock); + + if (!currentExceptionBlock->empty()) { + Instruction* insn = currentExceptionBlock->begin(); + PHINode* node = dyn_cast(insn); + if (node) node->addIncoming(obj, currentBlock); + } + + currentBlock = ifNormal; + + return res; +} + +Instruction* JavaJIT::invoke(Value *F, Value* arg1, Value* arg2, + const char* Name, BasicBlock *InsertAtEnd) { + + Value* args[2] = { arg1, arg2 }; + + Instruction* res = CallInst::Create(F, args, args + 2, Name, InsertAtEnd); + + Value* threadId = getCurrentThread(); + Value* geps[2] = { module->constantZero, + module->OffsetJavaExceptionInThreadConstant }; + + Value* javaExceptionPtr = GetElementPtrInst::Create(threadId, geps, + geps + 2, "", + currentBlock); + + // Get the Java exception. + Value* obj = new LoadInst(javaExceptionPtr, "", currentBlock); + + BasicBlock* ifNormal = createBasicBlock("no exception block"); + + Constant* zero = module->JavaObjectNullConstant; + Value* test = new ICmpInst(ICmpInst::ICMP_NE, obj, zero, "", + currentBlock); + + BranchInst::Create(currentExceptionBlock, ifNormal, test, currentBlock); + + if (!currentExceptionBlock->empty()) { + Instruction* insn = currentExceptionBlock->begin(); + PHINode* node = dyn_cast(insn); + if (node) node->addIncoming(obj, currentBlock); + } + + currentBlock = ifNormal; + + return res; +} + +Instruction* JavaJIT::invoke(Value *F, const char* Name, + BasicBlock *InsertAtEnd) { + Instruction* res = llvm::CallInst::Create(F, Name, InsertAtEnd); + Value* threadId = getCurrentThread(); + Value* geps[2] = { module->constantZero, + module->OffsetJavaExceptionInThreadConstant }; + + Value* javaExceptionPtr = GetElementPtrInst::Create(threadId, geps, + geps + 2, "", + currentBlock); + + // Get the Java exception. + Value* obj = new LoadInst(javaExceptionPtr, "", currentBlock); + + BasicBlock* ifNormal = createBasicBlock("no exception block"); + + Constant* zero = module->JavaObjectNullConstant; + Value* test = new ICmpInst(ICmpInst::ICMP_NE, obj, zero, "", + currentBlock); + + BranchInst::Create(currentExceptionBlock, ifNormal, test, currentBlock); + + if (!currentExceptionBlock->empty()) { + Instruction* insn = currentExceptionBlock->begin(); + PHINode* node = dyn_cast(insn); + if (node) node->addIncoming(obj, currentBlock); + } + + currentBlock = ifNormal; + + return res; +} + +void JavaJIT::throwException(llvm::Function* F, Value* arg1) { + Value* obj = CallInst::Create(F, arg1, "", currentBlock); + if (currentExceptionBlock != endExceptionBlock) { + Instruction* insn = currentExceptionBlock->begin(); + PHINode* node = dyn_cast(insn); + if (node) node->addIncoming(obj, currentBlock); + BranchInst::Create(currentExceptionBlock, currentBlock); + } else { + if (endNode) { + const FunctionType *funcType = llvmFunction->getFunctionType(); + const Type* returnType = funcType->getReturnType(); + endNode->addIncoming(Constant::getNullValue(returnType), currentBlock); + } + BranchInst::Create(endBlock, currentBlock); + } +} + +void JavaJIT::throwException(Value* obj) { + Value* threadId = getCurrentThread(); + Value* geps[2] = { module->constantZero, + module->OffsetJavaExceptionInThreadConstant }; + + Value* javaExceptionPtr = GetElementPtrInst::Create(threadId, geps, + geps + 2, "", + currentBlock); + new StoreInst(obj, javaExceptionPtr, currentBlock); + if (currentExceptionBlock != endExceptionBlock) { + Instruction* insn = currentExceptionBlock->begin(); + PHINode* node = dyn_cast(insn); + if (node) node->addIncoming(obj, currentBlock); + BranchInst::Create(currentExceptionBlock, currentBlock); + } else { + if (endNode) { + const FunctionType *funcType = llvmFunction->getFunctionType(); + const Type* returnType = funcType->getReturnType(); + endNode->addIncoming(Constant::getNullValue(returnType), currentBlock); + } + BranchInst::Create(endBlock, currentBlock); + } +} + +void JavaJIT::throwException(llvm::Function* F, Value** args, + uint32 nbArgs) { + Value* obj = CallInst::Create(F, args, args + nbArgs, "", currentBlock); + if (currentExceptionBlock != endExceptionBlock) { + Instruction* insn = currentExceptionBlock->begin(); + PHINode* node = dyn_cast(insn); + if (node) node->addIncoming(obj, currentBlock); + BranchInst::Create(currentExceptionBlock, currentBlock); + } else { + if (endNode) { + const FunctionType *funcType = llvmFunction->getFunctionType(); + const Type* returnType = funcType->getReturnType(); + endNode->addIncoming(Constant::getNullValue(returnType), currentBlock); + } + BranchInst::Create(endBlock, currentBlock); + } +} + +/// 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; + + /// 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; + +}; + +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; + + // 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) { + Handler* ex = &handlers[i]; + ex->startpc = reader.readU2(); + ex->endpc = reader.readU2(); + ex->handlerpc = reader.readU2(); + + ex->catche = reader.readU2(); + +#ifndef ISOLATE_SHARING + 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 { + ex->catchClass = Classpath::newThrowable; + } +#endif + + ex->tester = createBasicBlock("testException"); + + // PHI Node for the exception object + PHINode::Create(JnjvmModule::JavaObjectType, "", ex->tester); + + // 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 == endExceptionBlock) { + opcodeInfos[i].exceptionBlock = ex->tester; + } + } + + // 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"); + } + + // Set the Java handler for this exception. + ex->javaHandler = opcodeInfos[ex->handlerpc].newBlock; + + if (ex->javaHandler->empty()) { + PHINode::Create(JnjvmModule::JavaObjectType, "", ex->javaHandler); + } + + } + + // Loop over all handlers to implement their tester. + for (sint16 i = 0; i < nbe - sync; ++i) { + Handler* cur = &handlers[i]; + BasicBlock* bbNext = 0; + PHINode* javaNode = 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) { + 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 = endExceptionBlock; + } else { + // 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; + javaNode = dyn_cast(bbNext->begin()); + assert(javaNode); + } + } else { + // If there's no handler after us, we jump to the end handler. + bbNext = endExceptionBlock; + } + + currentBlock = cur->tester; + + Value* clVar = 0; +#ifdef ISOLATE_SHARING + // We're dealing with exceptions, don't catch the exception if the class can + // not be found. + if (cur->catche) clVar = getResolvedClass(cur->catche, false, false, 0); + else clVar = CallInst::Create(module->GetJnjvmExceptionClassFunction, + isolateLocal, "", currentBlock); +#else + // We know catchClass exists because we have loaded all exceptions catched + // by the method when we loaded the class that defined this method. + clVar = module->getNativeClass(cur->catchClass); +#endif + if (clVar->getType() != module->JavaCommonClassType) + clVar = new BitCastInst(clVar, module->JavaCommonClassType, "", + currentBlock); + + +#ifdef SERVICE + // 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 = getCurrentThread(); + 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); + + currentBlock = continueBlock; + } +#endif + + // Get the Java exception. + Value* obj = currentBlock->begin(); + + Value* objCl = CallInst::Create(module->GetClassFunction, obj, "", + currentBlock); + + Value* depthCl = ConstantInt::get(Type::Int32Ty, cur->catchClass->depth); + Value* depthClObj = CallInst::Create(module->GetDepthFunction, objCl, "", + currentBlock); + + // Compare the exception with the exception class we catch. + Value* cmp = new ICmpInst(ICmpInst::ICMP_ULE, depthCl, depthClObj, "", + currentBlock); + + BasicBlock* supDepth = createBasicBlock("superior depth"); + + // Add the Java exception in the phi node of the next block. + if (javaNode) + javaNode->addIncoming(obj, currentBlock); + + BranchInst::Create(supDepth, bbNext, cmp, currentBlock); + + currentBlock = supDepth; + Value* inDisplay = CallInst::Create(module->GetDisplayFunction, + objCl, "", currentBlock); + + Value* displayArgs[2] = { inDisplay, depthCl }; + Value* clInDisplay = CallInst::Create(module->GetClassInDisplayFunction, + displayArgs, displayArgs + 2, "", + currentBlock); + + cmp = new ICmpInst(ICmpInst::ICMP_EQ, clInDisplay, clVar, "", + currentBlock); + + // Add the Java exception in the phi node of the handler. + Instruction* insn = cur->javaHandler->begin(); + PHINode* node = dyn_cast(insn); + assert(node && "malformed exceptions"); + node->addIncoming(obj, currentBlock); + + // Add the Java exception in the phi node of the next block. + if (javaNode) + javaNode->addIncoming(obj, currentBlock); + + // If we are catching this exception, then jump to the Java Handler, + // otherwise jump to our next handler. + BranchInst::Create(cur->javaHandler, bbNext, cmp, currentBlock); + + currentBlock = cur->javaHandler; + + // First thing in the handler: clear the exception. + Value* geps[2] = { module->constantZero, + module->OffsetJavaExceptionInThreadConstant }; + Value* threadId = getCurrentThread(); + Value* javaExceptionPtr = GetElementPtrInst::Create(threadId, geps, + geps + 2, "", + currentBlock); + + // Clear exceptions. + new StoreInst(module->JavaObjectNullConstant, javaExceptionPtr, + currentBlock); + +#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; + currentBlock = cur->javaHandler; + if (loader != loader->bootstrapLoader) { + threadId = getCurrentThread(); + + 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; + +} + +void JavaJIT::finishExceptions() { + pred_iterator PI = pred_begin(endExceptionBlock); + pred_iterator PE = pred_end(endExceptionBlock); + if (PI == PE) { + endExceptionBlock->eraseFromParent(); + } else { + if (endNode) { + const FunctionType *funcType = llvmFunction->getFunctionType(); + const Type* returnType = funcType->getReturnType(); + endNode->addIncoming(Constant::getNullValue(returnType), + endExceptionBlock); + } + BranchInst::Create(endBlock, endExceptionBlock); + } + + + PI = pred_begin(unifiedUnreachable); + PE = pred_end(unifiedUnreachable); + if (PI == PE) { + unifiedUnreachable->eraseFromParent(); + } else { + new UnreachableInst(unifiedUnreachable); + } + + for (Function::iterator BI = llvmFunction->begin(), BE = llvmFunction->end(); + BI != BE; BI++) { + PI = pred_begin(BI); + PE = pred_end(BI); + if (PI == PE) { + Instruction* insn = BI->begin(); + PHINode* node = dyn_cast(insn); + if (node) { + node->replaceAllUsesWith(Constant::getNullValue(node->getType())); + node->eraseFromParent(); + } + } + } + +} Added: vmkit/trunk/lib/JnJVM/VMCore/ExceptionsDwarf.inc URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/ExceptionsDwarf.inc?rev=64140&view=auto ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/ExceptionsDwarf.inc (added) +++ vmkit/trunk/lib/JnJVM/VMCore/ExceptionsDwarf.inc Mon Feb 9 07:33:30 2009 @@ -0,0 +1,581 @@ +Instruction* JavaJIT::invoke(Value *F, std::vector& args, + const char* Name, + BasicBlock *InsertAtEnd) { + + // means: is there a handler for me? + if (currentExceptionBlock != endExceptionBlock) { + BasicBlock* ifNormal = createBasicBlock("no exception block"); + currentBlock = ifNormal; + return llvm::InvokeInst::Create(F, ifNormal, currentExceptionBlock, + args.begin(), + args.end(), Name, InsertAtEnd); + } else { + return llvm::CallInst::Create(F, args.begin(), args.end(), Name, InsertAtEnd); + } +} + +Instruction* JavaJIT::invoke(Value *F, Value* arg1, const char* Name, + BasicBlock *InsertAtEnd) { + + // means: is there a handler for me? + if (currentExceptionBlock != endExceptionBlock) { + BasicBlock* ifNormal = createBasicBlock("no exception block"); + currentBlock = ifNormal; + Value* arg[1] = { arg1 }; + return InvokeInst::Create(F, ifNormal, currentExceptionBlock, + arg, arg + 1, Name, InsertAtEnd); + } else { + return CallInst::Create(F, arg1, Name, InsertAtEnd); + } +} + +Instruction* JavaJIT::invoke(Value *F, Value* arg1, Value* arg2, + const char* Name, BasicBlock *InsertAtEnd) { + + Value* args[2] = { arg1, arg2 }; + + // means: is there a handler for me? + if (currentExceptionBlock != endExceptionBlock) { + BasicBlock* ifNormal = createBasicBlock("no exception block"); + currentBlock = ifNormal; + return InvokeInst::Create(F, ifNormal, currentExceptionBlock, + args, args + 2, Name, InsertAtEnd); + } else { + return CallInst::Create(F, args, args + 2, Name, InsertAtEnd); + } +} + +Instruction* JavaJIT::invoke(Value *F, const char* Name, + BasicBlock *InsertAtEnd) { + // means: is there a handler for me? + if (currentExceptionBlock != endExceptionBlock) { + BasicBlock* ifNormal = createBasicBlock("no exception block"); + currentBlock = ifNormal; + Value* args[1]; + return llvm::InvokeInst::Create(F, ifNormal, currentExceptionBlock, + args, args, Name, + InsertAtEnd); + } else { + return llvm::CallInst::Create(F, Name, InsertAtEnd); + } +} + +void JavaJIT::throwException(llvm::Function* F, Value* arg1) { + if (currentExceptionBlock != endExceptionBlock) { + Value* exArgs[1] = { arg1 }; + InvokeInst::Create(F, unifiedUnreachable, + currentExceptionBlock, exArgs, exArgs + 1, + "", currentBlock); + } else { + CallInst::Create(F, arg1, "", currentBlock); + new UnreachableInst(currentBlock); + } +} + +void JavaJIT::throwException(Value* obj) { + Function* F = module->ThrowExceptionFunction; + if (currentExceptionBlock != endExceptionBlock) { + Value* exArgs[1] = { obj }; + InvokeInst::Create(F, unifiedUnreachable, + currentExceptionBlock, exArgs, exArgs + 1, + "", currentBlock); + } else { + CallInst::Create(F, obj, "", currentBlock); + new UnreachableInst(currentBlock); + } +} + +void JavaJIT::throwException(llvm::Function* F, Value** args, + uint32 nbArgs) { + if (currentExceptionBlock != endExceptionBlock) { + InvokeInst::Create(F, unifiedUnreachable, + currentExceptionBlock, args, args + nbArgs, + "", currentBlock); + } else { + CallInst::Create(F, args, args + nbArgs, "", currentBlock); + new UnreachableInst(currentBlock); + } +} + +/// 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, 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; + + 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; + if (isVirtual(compilingMethod->access)) { + argsSync = llvmFunction->arg_begin(); + } else { + 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", + trySynchronizeExceptionBlock); + Constant* C = ConstantExpr::getCast(Instruction::BitCast, + module->personality, PointerTy_0); + Value* int32_eh_select_params[3] = + { ptr_eh_ptr, C, module->constantPtrNull }; + CallInst::Create(module->exceptionSelector, int32_eh_select_params, + int32_eh_select_params + 3, "eh_select", + trySynchronizeExceptionBlock); + + 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; + } + } + } + + // 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) { + Handler* ex = &handlers[i]; + ex->startpc = reader.readU2(); + ex->endpc = reader.readU2(); + ex->handlerpc = reader.readU2(); + + ex->catche = reader.readU2(); + +#ifndef ISOLATE_SHARING + 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 { + ex->catchClass = Classpath::newThrowable; + } +#endif + + ex->catcher = createBasicBlock("testException"); + + // 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->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"); + } + + // Set the Java handler for this exception. + ex->javaHandler = opcodeInfos[ex->handlerpc].newBlock; + + // 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) { + 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->tester = createBasicBlock("realTestException"); + } else { + cur->tester = cur->catcher; + } + + // 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) { + 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) { + 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 { + // 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 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 = + CallInst::Create(module->llvmGetException, "eh_ptr", cur->catcher); + Constant* C = ConstantExpr::getCast(Instruction::BitCast, + module->personality, PointerTy_0); + Value* int32_eh_select_params[3] = + { ptr_eh_ptr, C, module->constantPtrNull }; + llvm::CallInst::Create(module->exceptionSelector, + int32_eh_select_params, + int32_eh_select_params + 3, "eh_select", + cur->catcher); + llvm::BranchInst::Create(cur->tester, cur->catcher); + cur->exceptionPHI->addIncoming(ptr_eh_ptr, cur->catcher); + } + + currentBlock = cur->tester; + + Value* clVar = 0; +#ifdef ISOLATE_SHARING + // We're dealing with exceptions, don't catch the exception if the class can + // not be found. + if (cur->catche) clVar = getResolvedClass(cur->catche, false, false, 0); + else clVar = CallInst::Create(module->GetJnjvmExceptionClassFunction, + isolateLocal, "", currentBlock); +#else + // We know catchClass exists because we have loaded all exceptions catched + // by the method when we loaded the class that defined this method. + clVar = module->getNativeClass(cur->catchClass); +#endif + if (clVar->getType() != module->JavaCommonClassType) + clVar = new BitCastInst(clVar, module->JavaCommonClassType, "", + currentBlock); + + +#ifdef SERVICE + // 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 = getCurrentThread(); + 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); + + currentBlock = continueBlock; + } +#endif + + Value* threadId = getCurrentThread(); + Value* geps[2] = { module->constantZero, + module->OffsetJavaExceptionInThreadConstant }; + + Value* javaExceptionPtr = GetElementPtrInst::Create(threadId, geps, + geps + 2, "", + currentBlock); + + // Get the Java exception. + Value* obj = new LoadInst(javaExceptionPtr, "", currentBlock); + + Value* objCl = CallInst::Create(module->GetClassFunction, obj, "", + currentBlock); + + Value* depthCl = ConstantInt::get(Type::Int32Ty, cur->catchClass->depth); + Value* depthClObj = CallInst::Create(module->GetDepthFunction, objCl, "", + currentBlock); + + // Compare the exception with the exception class we catch. + Value* cmp = new ICmpInst(ICmpInst::ICMP_ULE, depthCl, depthClObj, "", + currentBlock); + + BasicBlock* supDepth = createBasicBlock("superior depth"); + + BranchInst::Create(supDepth, bbNext, cmp, currentBlock); + + if (nodeNext) + nodeNext->addIncoming(cur->exceptionPHI, currentBlock); + + currentBlock = supDepth; + Value* inDisplay = CallInst::Create(module->GetDisplayFunction, + objCl, "", currentBlock); + + Value* displayArgs[2] = { inDisplay, depthCl }; + Value* clInDisplay = CallInst::Create(module->GetClassInDisplayFunction, + displayArgs, displayArgs + 2, "", + currentBlock); + + cmp = new ICmpInst(ICmpInst::ICMP_EQ, clInDisplay, clVar, "", + 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); + + currentBlock = cur->nativeHandler; + + threadId = getCurrentThread(); + javaExceptionPtr = GetElementPtrInst::Create(threadId, geps, geps + 2, "", + currentBlock); + + // Get the Java exception. + Value* exc = new LoadInst(javaExceptionPtr, "", currentBlock); + + Value* geps2[2] = { module->constantZero, + module->OffsetCXXExceptionInThreadConstant }; + + Value* cxxExceptionPtr = GetElementPtrInst::Create(threadId, geps2, + geps2 + 2, "", + currentBlock); + + // Clear exceptions. + new StoreInst(module->constantPtrNull, cxxExceptionPtr, currentBlock); + new StoreInst(module->JavaObjectNullConstant, javaExceptionPtr, + currentBlock); + + // 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(insn); + assert(node && "malformed exceptions"); + node->addIncoming(exc, cur->nativeHandler); + } + + +#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; + currentBlock = cur->javaHandler; + if (loader != loader->bootstrapLoader) { + threadId = getCurrentThread(); + + 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; + +} + +void JavaJIT::finishExceptions() { + pred_iterator PI = pred_begin(endExceptionBlock); + pred_iterator PE = pred_end(endExceptionBlock); + if (PI == PE) { + endExceptionBlock->eraseFromParent(); + } else { + Value* threadId = getCurrentThread(); + Value* geps2[2] = { module->constantZero, + module->OffsetCXXExceptionInThreadConstant }; + + Value* cxxExceptionPtr = GetElementPtrInst::Create(threadId, geps2, + geps2 + 2, "", + currentBlock); + cxxExceptionPtr = new LoadInst(cxxExceptionPtr, "", currentBlock); + llvm::CallInst::Create(module->unwindResume, cxxExceptionPtr, "", + currentBlock); + new UnreachableInst(currentBlock); + } + + PI = pred_begin(unifiedUnreachable); + PE = pred_end(unifiedUnreachable); + if (PI == PE) { + unifiedUnreachable->eraseFromParent(); + } else { + new UnreachableInst(unifiedUnreachable); + } + +} Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.cpp URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.cpp?rev=64140&r1=64139&r2=64140&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.cpp (original) +++ vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.cpp Mon Feb 9 07:33:30 2009 @@ -778,18 +778,17 @@ if (PI == PE && returnType != Type::VoidTy) { Instruction* I = currentBlock->getTerminator(); - assert((isa(I) || isa(I)) && - "Malformed end Java block"); - if (isa(I)) { I->eraseFromParent(); BranchInst::Create(endBlock, currentBlock); + endNode->addIncoming(Constant::getNullValue(returnType), + currentBlock); } else if (InvokeInst* II = dyn_cast(I)) { II->setNormalDest(endBlock); + endNode->addIncoming(Constant::getNullValue(returnType), + currentBlock); } - endNode->addIncoming(Constant::getNullValue(returnType), - currentBlock); } currentBlock = endBlock; @@ -837,31 +836,8 @@ } currentBlock = endExceptionBlock; - PI = pred_begin(endExceptionBlock); - PE = pred_end(endExceptionBlock); - if (PI == PE) { - endExceptionBlock->eraseFromParent(); - } else { - Value* threadId = getCurrentThread(); - Value* geps2[2] = { module->constantZero, - module->OffsetCXXExceptionInThreadConstant }; - - Value* cxxExceptionPtr = GetElementPtrInst::Create(threadId, geps2, - geps2 + 2, "", - currentBlock); - cxxExceptionPtr = new LoadInst(cxxExceptionPtr, "", currentBlock); - llvm::CallInst::Create(module->unwindResume, cxxExceptionPtr, "", - currentBlock); - new UnreachableInst(currentBlock); - } - - PI = pred_begin(unifiedUnreachable); - PE = pred_end(unifiedUnreachable); - if (PI == PE) { - unifiedUnreachable->eraseFromParent(); - } else { - new UnreachableInst(unifiedUnreachable); - } + + finishExceptions(); func->setLinkage(GlobalValue::ExternalLinkage); @@ -874,460 +850,6 @@ 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, 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; - - 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; - if (isVirtual(compilingMethod->access)) { - argsSync = llvmFunction->arg_begin(); - } else { - 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", - trySynchronizeExceptionBlock); - Constant* C = ConstantExpr::getCast(Instruction::BitCast, - module->personality, PointerTy_0); - Value* int32_eh_select_params[3] = - { ptr_eh_ptr, C, module->constantPtrNull }; - CallInst::Create(module->exceptionSelector, int32_eh_select_params, - int32_eh_select_params + 3, "eh_select", - trySynchronizeExceptionBlock); - - 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; - } - } - } - - // 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) { - Handler* ex = &handlers[i]; - ex->startpc = reader.readU2(); - ex->endpc = reader.readU2(); - ex->handlerpc = reader.readU2(); - - ex->catche = reader.readU2(); - -#ifndef ISOLATE_SHARING - 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 { - ex->catchClass = Classpath::newThrowable; - } -#endif - - ex->catcher = createBasicBlock("testException"); - - // 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->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"); - } - - // Set the Java handler for this exception. - ex->javaHandler = opcodeInfos[ex->handlerpc].newBlock; - - // 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) { - 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->tester = createBasicBlock("realTestException"); - } else { - cur->tester = cur->catcher; - } - - // 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) { - 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) { - 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 { - // 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 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 = - CallInst::Create(module->llvmGetException, "eh_ptr", cur->catcher); - Constant* C = ConstantExpr::getCast(Instruction::BitCast, - module->personality, PointerTy_0); - Value* int32_eh_select_params[3] = - { ptr_eh_ptr, C, module->constantPtrNull }; - llvm::CallInst::Create(module->exceptionSelector, - int32_eh_select_params, - int32_eh_select_params + 3, "eh_select", - cur->catcher); - llvm::BranchInst::Create(cur->tester, cur->catcher); - cur->exceptionPHI->addIncoming(ptr_eh_ptr, cur->catcher); - } - - currentBlock = cur->tester; - - Value* clVar = 0; -#ifdef ISOLATE_SHARING - // We're dealing with exceptions, don't catch the exception if the class can - // not be found. - if (cur->catche) clVar = getResolvedClass(cur->catche, false, false, 0); - else clVar = CallInst::Create(module->GetJnjvmExceptionClassFunction, - isolateLocal, "", currentBlock); -#else - // We know catchClass exists because we have loaded all exceptions catched - // by the method when we loaded the class that defined this method. - clVar = module->getNativeClass(cur->catchClass); -#endif - if (clVar->getType() != module->JavaCommonClassType) - clVar = new BitCastInst(clVar, module->JavaCommonClassType, "", - currentBlock); - - -#ifdef SERVICE - // 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 = getCurrentThread(); - 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); - - currentBlock = continueBlock; - } -#endif - - Value* threadId = getCurrentThread(); - Value* geps[2] = { module->constantZero, - module->OffsetJavaExceptionInThreadConstant }; - - Value* javaExceptionPtr = GetElementPtrInst::Create(threadId, geps, - geps + 2, "", - currentBlock); - - // Get the Java exception. - Value* obj = new LoadInst(javaExceptionPtr, "", currentBlock); - - Value* objCl = CallInst::Create(module->GetClassFunction, obj, "", - currentBlock); - - Value* depthCl = ConstantInt::get(Type::Int32Ty, cur->catchClass->depth); - Value* depthClObj = CallInst::Create(module->GetDepthFunction, objCl, "", - currentBlock); - - // Compare the exception with the exception class we catch. - Value* cmp = new ICmpInst(ICmpInst::ICMP_ULE, depthCl, depthClObj, "", - currentBlock); - - BasicBlock* supDepth = createBasicBlock("superior depth"); - - BranchInst::Create(supDepth, bbNext, cmp, currentBlock); - - if (nodeNext) - nodeNext->addIncoming(cur->exceptionPHI, currentBlock); - - currentBlock = supDepth; - Value* inDisplay = CallInst::Create(module->GetDisplayFunction, - objCl, "", currentBlock); - - Value* displayArgs[2] = { inDisplay, depthCl }; - Value* clInDisplay = CallInst::Create(module->GetClassInDisplayFunction, - displayArgs, displayArgs + 2, "", - currentBlock); - - cmp = new ICmpInst(ICmpInst::ICMP_EQ, clInDisplay, clVar, "", - 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); - - currentBlock = cur->nativeHandler; - - threadId = getCurrentThread(); - javaExceptionPtr = GetElementPtrInst::Create(threadId, geps, geps + 2, "", - currentBlock); - - // Get the Java exception. - Value* exc = new LoadInst(javaExceptionPtr, "", currentBlock); - - Value* geps2[2] = { module->constantZero, - module->OffsetCXXExceptionInThreadConstant }; - - Value* cxxExceptionPtr = GetElementPtrInst::Create(threadId, geps2, - geps2 + 2, "", - currentBlock); - - // Clear exceptions. - new StoreInst(module->constantPtrNull, cxxExceptionPtr, currentBlock); - new StoreInst(module->JavaObjectNullConstant, javaExceptionPtr, - currentBlock); - - // 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(insn); - assert(node && "malformed exceptions"); - node->addIncoming(exc, cur->nativeHandler); - } - - -#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; - currentBlock = cur->javaHandler; - if (loader != loader->bootstrapLoader) { - threadId = getCurrentThread(); - - 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; - -} - void JavaJIT::compareFP(Value* val1, Value* val2, const Type* ty, bool l) { Value* one = module->constantOne; Value* zero = module->constantZero; @@ -2101,69 +1623,6 @@ } -Instruction* JavaJIT::invoke(Value *F, std::vector& args, - const char* Name, - BasicBlock *InsertAtEnd) { - - // means: is there a handler for me? - if (currentExceptionBlock != endExceptionBlock) { - BasicBlock* ifNormal = createBasicBlock("no exception block"); - currentBlock = ifNormal; - return llvm::InvokeInst::Create(F, ifNormal, currentExceptionBlock, - args.begin(), - args.end(), Name, InsertAtEnd); - } else { - return llvm::CallInst::Create(F, args.begin(), args.end(), Name, InsertAtEnd); - } -} - -Instruction* JavaJIT::invoke(Value *F, Value* arg1, const char* Name, - BasicBlock *InsertAtEnd) { - - // means: is there a handler for me? - if (currentExceptionBlock != endExceptionBlock) { - BasicBlock* ifNormal = createBasicBlock("no exception block"); - currentBlock = ifNormal; - Value* arg[1] = { arg1 }; - return InvokeInst::Create(F, ifNormal, currentExceptionBlock, - arg, arg + 1, Name, InsertAtEnd); - } else { - return CallInst::Create(F, arg1, Name, InsertAtEnd); - } -} - -Instruction* JavaJIT::invoke(Value *F, Value* arg1, Value* arg2, - const char* Name, BasicBlock *InsertAtEnd) { - - Value* args[2] = { arg1, arg2 }; - - // means: is there a handler for me? - if (currentExceptionBlock != endExceptionBlock) { - BasicBlock* ifNormal = createBasicBlock("no exception block"); - currentBlock = ifNormal; - return InvokeInst::Create(F, ifNormal, currentExceptionBlock, - args, args + 2, Name, InsertAtEnd); - } else { - return CallInst::Create(F, args, args + 2, Name, InsertAtEnd); - } -} - -Instruction* JavaJIT::invoke(Value *F, const char* Name, - BasicBlock *InsertAtEnd) { - // means: is there a handler for me? - if (currentExceptionBlock != endExceptionBlock) { - BasicBlock* ifNormal = createBasicBlock("no exception block"); - currentBlock = ifNormal; - Value* args[1]; - return llvm::InvokeInst::Create(F, ifNormal, currentExceptionBlock, - args, args, Name, - InsertAtEnd); - } else { - return llvm::CallInst::Create(F, Name, InsertAtEnd); - } -} - - void JavaJIT::invokeInterface(uint16 index, bool buggyVirtual) { // Do the usual @@ -2273,26 +1732,9 @@ } } -void JavaJIT::throwException(llvm::Function* F, Value* arg1) { - if (currentExceptionBlock != endExceptionBlock) { - Value* exArgs[1] = { arg1 }; - InvokeInst::Create(F, unifiedUnreachable, - currentExceptionBlock, exArgs, exArgs + 1, - "", currentBlock); - } else { - CallInst::Create(F, arg1, "", currentBlock); - new UnreachableInst(currentBlock); - } -} -void JavaJIT::throwException(llvm::Function* F, Value** args, - uint32 nbArgs) { - if (currentExceptionBlock != endExceptionBlock) { - InvokeInst::Create(F, unifiedUnreachable, - currentExceptionBlock, args, args + nbArgs, - "", currentBlock); - } else { - CallInst::Create(F, args, args + nbArgs, "", currentBlock); - new UnreachableInst(currentBlock); - } -} +#ifdef DWARF_EXCEPTIONS +#include "ExceptionsDwarf.inc" +#else +#include "ExceptionsCheck.inc" +#endif Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.h URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.h?rev=64140&r1=64139&r2=64140&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.h (original) +++ vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.h Mon Feb 9 07:33:30 2009 @@ -61,6 +61,7 @@ llvmFunction = func; inlining = false; callsStackWalker = false; + endNode = 0; } /// javaCompile - Compile the Java method. @@ -259,7 +260,11 @@ void throwException(llvm::Function* F, llvm::Value** args, uint32 nbArgs); void throwException(llvm::Function* F, llvm::Value* arg1); + void throwException(llvm::Value* obj); + /// finishExceptions - Emit code to unwind the current function if an + /// exception is thrown. + void finishExceptions(); //===--------------------------- Control flow ----------------------------===// /// opcodeInfos - The informations for each instruction. Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaJITOpcodes.cpp URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JavaJITOpcodes.cpp?rev=64140&r1=64139&r2=64140&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/JavaJITOpcodes.cpp (original) +++ vmkit/trunk/lib/JnJVM/VMCore/JavaJITOpcodes.cpp Mon Feb 9 07:33:30 2009 @@ -1968,7 +1968,7 @@ case ATHROW : { llvm::Value* arg = pop(); - throwException(module->ThrowExceptionFunction, arg); + throwException(arg); break; } Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaMetaJIT.cpp URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JavaMetaJIT.cpp?rev=64140&r1=64139&r2=64140&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/JavaMetaJIT.cpp (original) +++ vmkit/trunk/lib/JnJVM/VMCore/JavaMetaJIT.cpp Mon Feb 9 07:33:30 2009 @@ -52,6 +52,8 @@ }\ +#if defined(DWARF_EXCEPTIONS) + #if 1//defined(__PPC__) && !defined(__MACH__) #define INVOKE(TYPE, TYPE_NAME, FUNC_TYPE_VIRTUAL_AP, FUNC_TYPE_STATIC_AP, FUNC_TYPE_VIRTUAL_BUF, FUNC_TYPE_STATIC_BUF) \ \ @@ -366,6 +368,311 @@ #endif +#else // DWARF_EXCEPTIONS + +#if 1//defined(__PPC__) && !defined(__MACH__) +#define INVOKE(TYPE, TYPE_NAME, FUNC_TYPE_VIRTUAL_AP, FUNC_TYPE_STATIC_AP, FUNC_TYPE_VIRTUAL_BUF, FUNC_TYPE_STATIC_BUF) \ +\ +TYPE JavaMethod::invoke##TYPE_NAME##VirtualAP(Jnjvm* vm, UserClass* cl, JavaObject* obj, va_list ap) { \ + if (!cl->isReady()) { \ + cl->classLoader->loadName(cl->getName(), true, true); \ + cl->initialiseClass(vm); \ + } \ + verifyNull(obj); \ + Signdef* sign = getSignature(); \ + uintptr_t buf = (uintptr_t)alloca(sign->nbArguments * sizeof(uint64)); \ + void* _buf = (void*)buf; \ + readArgs(buf, sign, ap); \ + void* func = (((void***)obj)[0])[offset];\ + JavaThread* th = JavaThread::get(); \ + th->startJava(); \ + TYPE res = 0; \ + res = ((FUNC_TYPE_VIRTUAL_BUF)sign->getVirtualCallBuf())(cl->getConstantPool(), func, obj, _buf);\ + if (th->pendingException) { \ + th->throwFromJava(); \ + } \ + th->endJava(); \ + return res; \ +}\ +\ +TYPE JavaMethod::invoke##TYPE_NAME##SpecialAP(Jnjvm* vm, UserClass* cl, JavaObject* obj, va_list ap) {\ + if (!cl->isReady()) { \ + cl->classLoader->loadName(cl->getName(), true, true); \ + cl->initialiseClass(vm); \ + } \ + \ + verifyNull(obj);\ + Signdef* sign = getSignature(); \ + uintptr_t buf = (uintptr_t)alloca(sign->nbArguments * sizeof(uint64)); \ + void* _buf = (void*)buf; \ + readArgs(buf, sign, ap); \ + void* func = this->compiledPtr();\ + JavaThread* th = JavaThread::get(); \ + th->startJava(); \ + TYPE res = 0; \ + res = ((FUNC_TYPE_VIRTUAL_BUF)sign->getVirtualCallBuf())(cl->getConstantPool(), func, obj, _buf);\ + if (th->pendingException) { \ + th->throwFromJava(); \ + } \ + th->endJava(); \ + return res; \ +}\ +\ +TYPE JavaMethod::invoke##TYPE_NAME##StaticAP(Jnjvm* vm, UserClass* cl, va_list ap) {\ + if (!cl->isReady()) { \ + cl->classLoader->loadName(cl->getName(), true, true); \ + cl->initialiseClass(vm); \ + } \ + \ + Signdef* sign = getSignature(); \ + uintptr_t buf = (uintptr_t)alloca(sign->nbArguments * sizeof(uint64)); \ + void* _buf = (void*)buf; \ + readArgs(buf, sign, ap); \ + void* func = this->compiledPtr();\ + JavaThread* th = JavaThread::get(); \ + th->startJava(); \ + TYPE res = 0; \ + res = ((FUNC_TYPE_STATIC_BUF)sign->getStaticCallBuf())(cl->getConstantPool(), func, _buf);\ + if (th->pendingException) { \ + th->throwFromJava(); \ + } \ + th->endJava(); \ + return res; \ +}\ +\ +TYPE JavaMethod::invoke##TYPE_NAME##VirtualBuf(Jnjvm* vm, UserClass* cl, JavaObject* obj, void* buf) {\ + if (!cl->isReady()) { \ + cl->classLoader->loadName(cl->getName(), true, true); \ + cl->initialiseClass(vm); \ + } \ + \ + verifyNull(obj);\ + \ + Signdef* sign = getSignature(); \ + void* func = (((void***)obj)[0])[offset];\ + JavaThread* th = JavaThread::get(); \ + th->startJava(); \ + TYPE res = 0; \ + res = ((FUNC_TYPE_VIRTUAL_BUF)sign->getVirtualCallBuf())(cl->getConstantPool(), func, obj, buf);\ + if (th->pendingException) { \ + th->throwFromJava(); \ + } \ + th->endJava(); \ + return res; \ +}\ +\ +TYPE JavaMethod::invoke##TYPE_NAME##SpecialBuf(Jnjvm* vm, UserClass* cl, JavaObject* obj, void* buf) {\ + if (!cl->isReady()) { \ + cl->classLoader->loadName(cl->getName(), true, true); \ + cl->initialiseClass(vm); \ + } \ + \ + verifyNull(obj);\ + void* func = this->compiledPtr();\ + Signdef* sign = getSignature(); \ + JavaThread* th = JavaThread::get(); \ + th->startJava(); \ + TYPE res = 0; \ + res = ((FUNC_TYPE_VIRTUAL_BUF)sign->getVirtualCallBuf())(cl->getConstantPool(), func, obj, buf);\ + if (th->pendingException) { \ + th->throwFromJava(); \ + } \ + th->endJava(); \ + return res; \ +}\ +\ +TYPE JavaMethod::invoke##TYPE_NAME##StaticBuf(Jnjvm* vm, UserClass* cl, void* buf) {\ + if (!cl->isReady()) { \ + cl->classLoader->loadName(cl->getName(), true, true); \ + cl->initialiseClass(vm); \ + } \ + \ + void* func = this->compiledPtr();\ + Signdef* sign = getSignature(); \ + JavaThread* th = JavaThread::get(); \ + th->startJava(); \ + TYPE res = 0; \ + res = ((FUNC_TYPE_STATIC_BUF)sign->getStaticCallBuf())(cl->getConstantPool(), func, buf);\ + if (th->pendingException) { \ + th->throwFromJava(); \ + } \ + th->endJava(); \ + return res; \ +}\ +\ +TYPE JavaMethod::invoke##TYPE_NAME##Virtual(Jnjvm* vm, UserClass* cl, JavaObject* obj, ...) { \ + va_list ap;\ + va_start(ap, obj);\ + TYPE res = invoke##TYPE_NAME##VirtualAP(vm, cl, obj, ap);\ + va_end(ap); \ + return res; \ +}\ +\ +TYPE JavaMethod::invoke##TYPE_NAME##Special(Jnjvm* vm, UserClass* cl, JavaObject* obj, ...) {\ + va_list ap;\ + va_start(ap, obj);\ + TYPE res = invoke##TYPE_NAME##SpecialAP(vm, cl, obj, ap);\ + va_end(ap); \ + return res; \ +}\ +\ +TYPE JavaMethod::invoke##TYPE_NAME##Static(Jnjvm* vm, UserClass* cl, ...) {\ + va_list ap;\ + va_start(ap, cl);\ + TYPE res = invoke##TYPE_NAME##StaticAP(vm, cl, ap);\ + va_end(ap); \ + return res; \ +}\ + +#else + +#define INVOKE(TYPE, TYPE_NAME, FUNC_TYPE_VIRTUAL_AP, FUNC_TYPE_STATIC_AP, FUNC_TYPE_VIRTUAL_BUF, FUNC_TYPE_STATIC_BUF) \ +\ +TYPE JavaMethod::invoke##TYPE_NAME##VirtualAP(Jnjvm* vm, UserClass* cl, JavaObject* obj, va_list ap) { \ + if (!cl->isReady()) { \ + cl->classLoader->loadName(cl->getName(), true, true); \ + cl->initialiseClass(vm); \ + } \ + \ + verifyNull(obj); \ + void* func = (((void***)obj)[0])[offset];\ + Signdef* sign = getSignature(); \ + JavaThread* th = JavaThread::get(); \ + th->startJava(); \ + TYPE res = 0; \ + res = ((FUNC_TYPE_VIRTUAL_AP)sign->getVirtualCallAP())(cl->getConstantPool(), func, obj, ap);\ + if (th->pendingException) { \ + th->throwFromJava(); \ + } \ + th->endJava(); \ + return res; \ +}\ +\ +TYPE JavaMethod::invoke##TYPE_NAME##SpecialAP(Jnjvm* vm, UserClass* cl, JavaObject* obj, va_list ap) {\ + if (!cl->isReady()) { \ + cl->classLoader->loadName(cl->getName(), true, true); \ + cl->initialiseClass(vm); \ + } \ + \ + verifyNull(obj);\ + void* func = this->compiledPtr();\ + Signdef* sign = getSignature(); \ + JavaThread* th = JavaThread::get(); \ + th->startJava(); \ + TYPE res = 0; \ + res = ((FUNC_TYPE_VIRTUAL_AP)sign->getVirtualCallAP())(cl->getConstantPool(), func, obj, ap);\ + if (th->pendingException) { \ + th->throwFromJava(); \ + } \ + th->endJava(); \ + return res; \ +}\ +\ +TYPE JavaMethod::invoke##TYPE_NAME##StaticAP(Jnjvm* vm, UserClass* cl, va_list ap) {\ + if (!cl->isReady()) { \ + cl->classLoader->loadName(cl->getName(), true, true); \ + cl->initialiseClass(vm); \ + } \ + \ + void* func = this->compiledPtr();\ + Signdef* sign = getSignature(); \ + JavaThread* th = JavaThread::get(); \ + th->startJava(); \ + TYPE res = 0; \ + res = ((FUNC_TYPE_STATIC_AP)sign->getStaticCallAP())(cl->getConstantPool(), func, ap);\ + if (th->pendingException) { \ + th->throwFromJava(); \ + } \ + th->endJava(); \ + return res; \ +}\ +\ +TYPE JavaMethod::invoke##TYPE_NAME##VirtualBuf(Jnjvm* vm, UserClass* cl, JavaObject* obj, void* buf) {\ + if (!cl->isReady()) { \ + cl->classLoader->loadName(cl->getName(), true, true); \ + cl->initialiseClass(vm); \ + } \ + \ + verifyNull(obj);\ + void* func = (((void***)obj)[0])[offset];\ + Signdef* sign = getSignature(); \ + JavaThread* th = JavaThread::get(); \ + th->startJava(); \ + TYPE res = 0; \ + res = ((FUNC_TYPE_VIRTUAL_BUF)sign->getVirtualCallBuf())(cl->getConstantPool(), func, obj, buf);\ + if (th->pendingException) { \ + th->throwFromJava(); \ + } \ + th->endJava(); \ + return res; \ +}\ +\ +TYPE JavaMethod::invoke##TYPE_NAME##SpecialBuf(Jnjvm* vm, UserClass* cl, JavaObject* obj, void* buf) {\ + if (!cl->isReady()) { \ + cl->classLoader->loadName(cl->getName(), true, true); \ + cl->initialiseClass(vm); \ + } \ + \ + verifyNull(obj);\ + void* func = this->compiledPtr();\ + Signdef* sign = getSignature(); \ + JavaThread* th = JavaThread::get(); \ + th->startJava(); \ + TYPE res = 0; \ + res = ((FUNC_TYPE_VIRTUAL_BUF)sign->getVirtualCallBuf())(cl->getConstantPool(), func, obj, buf);\ + if (th->pendingException) { \ + th->throwFromJava(); \ + } \ + th->endJava(); \ + return res; \ +}\ +\ +TYPE JavaMethod::invoke##TYPE_NAME##StaticBuf(Jnjvm* vm, UserClass* cl, void* buf) {\ + if (!cl->isReady()) { \ + cl->classLoader->loadName(cl->getName(), true, true); \ + cl->initialiseClass(vm); \ + } \ + \ + void* func = this->compiledPtr();\ + Signdef* sign = getSignature(); \ + JavaThread* th = JavaThread::get(); \ + th->startJava(); \ + TYPE res = 0; \ + res = ((FUNC_TYPE_STATIC_BUF)sign->getStaticCallBuf())(cl->getConstantPool(), func, buf);\ + if (th->pendingException) { \ + th->throwFromJava(); \ + } \ + th->endJava(); \ + return res; \ +}\ +\ +TYPE JavaMethod::invoke##TYPE_NAME##Virtual(Jnjvm* vm, UserClass* cl, JavaObject* obj, ...) { \ + va_list ap;\ + va_start(ap, obj);\ + TYPE res = invoke##TYPE_NAME##VirtualAP(vm, cl, obj, ap);\ + va_end(ap); \ + return res; \ +}\ +\ +TYPE JavaMethod::invoke##TYPE_NAME##Special(Jnjvm* vm, UserClass* cl, JavaObject* obj, ...) {\ + va_list ap;\ + va_start(ap, obj);\ + TYPE res = invoke##TYPE_NAME##SpecialAP(vm, cl, obj, ap);\ + va_end(ap); \ + return res; \ +}\ +\ +TYPE JavaMethod::invoke##TYPE_NAME##Static(Jnjvm* vm, UserClass* cl, ...) {\ + va_list ap;\ + va_start(ap, cl);\ + TYPE res = invoke##TYPE_NAME##StaticAP(vm, cl, ap);\ + va_end(ap); \ + return res; \ +}\ + +#endif +#endif + typedef uint32 (*uint32_virtual_ap)(UserConstantPool*, void*, JavaObject*, va_list); typedef sint64 (*sint64_virtual_ap)(UserConstantPool*, void*, JavaObject*, va_list); typedef float (*float_virtual_ap)(UserConstantPool*, void*, JavaObject*, va_list); Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaObject.cpp URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JavaObject.cpp?rev=64140&r1=64139&r2=64140&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/JavaObject.cpp (original) +++ vmkit/trunk/lib/JnJVM/VMCore/JavaObject.cpp Mon Feb 9 07:33:30 2009 @@ -78,7 +78,6 @@ extern "C" void printJavaObject(const JavaObject* obj, mvm::PrintBuffer* buf) { buf->write("JavaObject<"); CommonClass::printClassName(obj->getClass()->getName(), buf); - fprintf(stderr, "%p\n", ((void**)obj->getVirtualTable())[9]); buf->write(">"); } Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaRuntimeJIT.cpp URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JavaRuntimeJIT.cpp?rev=64140&r1=64139&r2=64140&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/JavaRuntimeJIT.cpp (original) +++ vmkit/trunk/lib/JnJVM/VMCore/JavaRuntimeJIT.cpp Mon Feb 9 07:33:30 2009 @@ -338,10 +338,12 @@ mvm::Allocator& allocator = th->getJVM()->gcAllocator; allocator.freeTemporaryMemory(buf); +#ifdef DWARF_EXCEPTIONS // If there's an exception, throw it now. if (JavaThread::get()->pendingException) { th->throwPendingException(); } +#endif } // Never throws. @@ -401,7 +403,7 @@ } // Creates a Java object and then throws it. -extern "C" void jnjvmNullPointerException() { +extern "C" JavaObject* jnjvmNullPointerException() { JavaObject *exc = 0; JavaThread *th = JavaThread::get(); @@ -412,11 +414,17 @@ END_NATIVE_EXCEPTION +#ifdef DWARF_EXCEPTIONS th->throwException(exc); +#else + th->pendingException = exc; +#endif + + return exc; } // Creates a Java object and then throws it. -extern "C" void negativeArraySizeException(sint32 val) { +extern "C" JavaObject* negativeArraySizeException(sint32 val) { JavaObject *exc = 0; JavaThread *th = JavaThread::get(); @@ -426,11 +434,17 @@ END_NATIVE_EXCEPTION +#ifdef DWARF_EXCEPTIONS th->throwException(exc); +#else + th->pendingException = exc; +#endif + + return exc; } // Creates a Java object and then throws it. -extern "C" void outOfMemoryError(sint32 val) { +extern "C" JavaObject* outOfMemoryError(sint32 val) { JavaObject *exc = 0; JavaThread *th = JavaThread::get(); @@ -440,11 +454,18 @@ END_NATIVE_EXCEPTION +#ifdef DWARF_EXCEPTIONS th->throwException(exc); +#else + th->pendingException = exc; +#endif + + return exc; } // Creates a Java object and then throws it. -extern "C" void jnjvmClassCastException(JavaObject* obj, UserCommonClass* cl) { +extern "C" JavaObject* jnjvmClassCastException(JavaObject* obj, + UserCommonClass* cl) { JavaObject *exc = 0; JavaThread *th = JavaThread::get(); @@ -454,11 +475,18 @@ END_NATIVE_EXCEPTION +#ifdef DWARF_EXCEPTIONS th->throwException(exc); +#else + th->pendingException = exc; +#endif + + return exc; } // Creates a Java object and then throws it. -extern "C" void indexOutOfBoundsException(JavaObject* obj, sint32 index) { +extern "C" JavaObject* indexOutOfBoundsException(JavaObject* obj, + sint32 index) { JavaObject *exc = 0; JavaThread *th = JavaThread::get(); @@ -468,7 +496,13 @@ END_NATIVE_EXCEPTION +#ifdef DWARF_EXCEPTIONS th->throwException(exc); +#else + th->pendingException = exc; +#endif + + return exc; } extern "C" void printMethodStart(JavaMethod* meth) { Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaThread.h URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JavaThread.h?rev=64140&r1=64139&r2=64140&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/JavaThread.h (original) +++ vmkit/trunk/lib/JnJVM/VMCore/JavaThread.h Mon Feb 9 07:33:30 2009 @@ -179,8 +179,10 @@ /// throwFromNative - Throw an exception after executing Native code. /// void throwFromNative() { +#ifdef DWARF_EXCEPTIONS addresses.pop_back(); throwPendingException(); +#endif } /// throwFromJava - Throw an exception after executing Java code. Modified: vmkit/trunk/lib/Mvm/Runtime/JIT.cpp URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/Mvm/Runtime/JIT.cpp?rev=64140&r1=64139&r2=64140&view=diff ============================================================================== --- vmkit/trunk/lib/Mvm/Runtime/JIT.cpp (original) +++ vmkit/trunk/lib/Mvm/Runtime/JIT.cpp Mon Feb 9 07:33:30 2009 @@ -42,7 +42,11 @@ void MvmModule::initialise(bool Fast, Module* M, TargetMachine* T) { llvm::NoFramePointerElim = true; +#if DWARF_EXCEPTIONS llvm::ExceptionHandling = true; +#else + llvm::ExceptionHandling = false; +#endif if (!M) { globalModule = new llvm::Module("bootstrap module"); globalModuleProvider = new ExistingModuleProvider (globalModule); From nicolas.geoffray at lip6.fr Tue Feb 10 02:46:03 2009 From: nicolas.geoffray at lip6.fr (Nicolas Geoffray) Date: Tue, 10 Feb 2009 10:46:03 -0000 Subject: [vmkit-commits] [vmkit] r64211 - in /vmkit/trunk: Makefile.config.in autoconf/configure.ac Message-ID: <200902101046.n1AAk4MT000986@zion.cs.uiuc.edu> Author: geoffray Date: Tue Feb 10 04:45:54 2009 New Revision: 64211 URL: http://llvm.org/viewvc/llvm-project?rev=64211&view=rev Log: Check at configure time if we are building on a platform without 64bit cas. Modified: vmkit/trunk/Makefile.config.in vmkit/trunk/autoconf/configure.ac Modified: vmkit/trunk/Makefile.config.in URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/Makefile.config.in?rev=64211&r1=64210&r2=64211&view=diff ============================================================================== --- vmkit/trunk/Makefile.config.in (original) +++ vmkit/trunk/Makefile.config.in Tue Feb 10 04:45:54 2009 @@ -11,3 +11,4 @@ ISOLATE_BUILD = @ISOLATE_BUILD@ SERVICE_BUILD = @SERVICE_BUILD@ SINGLE_BUILD = @SINGLE_BUILD@ +WITH_64 = @WITH_64@ Modified: vmkit/trunk/autoconf/configure.ac URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/autoconf/configure.ac?rev=64211&r1=64210&r2=64211&view=diff ============================================================================== --- vmkit/trunk/autoconf/configure.ac (original) +++ vmkit/trunk/autoconf/configure.ac Tue Feb 10 04:45:54 2009 @@ -168,6 +168,21 @@ fi dnl ************************************************************************** +dnl Architecture +dnl ************************************************************************** + +case $target_cpu in + powerpc) + AC_DEFINE([WITH_64], [0], [Building on a platform without 64bit cas]) + AC_SUBST([WITH_64], [0]);; + *) + AC_DEFINE([WITH_64], [1], [Building on a platform with 64bit cas]) + AC_SUBST([WITH_64], [1]);; +esac + + + +dnl ************************************************************************** dnl VVM GC type dnl ************************************************************************** AC_ARG_WITH(gc, From nicolas.geoffray at lip6.fr Tue Feb 10 02:55:56 2009 From: nicolas.geoffray at lip6.fr (Nicolas Geoffray) Date: Tue, 10 Feb 2009 10:55:56 -0000 Subject: [vmkit-commits] [vmkit] r64212 - /vmkit/trunk/configure Message-ID: <200902101055.n1AAtwsj001337@zion.cs.uiuc.edu> Author: geoffray Date: Tue Feb 10 04:55:40 2009 New Revision: 64212 URL: http://llvm.org/viewvc/llvm-project?rev=64212&view=rev Log: Regnerate. Modified: vmkit/trunk/configure Modified: vmkit/trunk/configure URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/configure?rev=64212&r1=64211&r2=64212&view=diff ============================================================================== --- vmkit/trunk/configure (original) +++ vmkit/trunk/configure Tue Feb 10 04:55:40 2009 @@ -681,6 +681,7 @@ CPP GREP EGREP +WITH_64 GC_MMAP2 GC_BOEHM GC_MULTI_MMAP @@ -3878,6 +3879,28 @@ fi +case $target_cpu in + powerpc) + +cat >>confdefs.h <<\_ACEOF +#define WITH_64 0 +_ACEOF + + WITH_64=0 +;; + *) + +cat >>confdefs.h <<\_ACEOF +#define WITH_64 1 +_ACEOF + + WITH_64=1 +;; +esac + + + + # Check whether --with-gc was given. if test "${with_gc+set}" = set; then withval=$with_gc; gc=$withval @@ -7877,6 +7900,7 @@ CPP!$CPP$ac_delim GREP!$GREP$ac_delim EGREP!$EGREP$ac_delim +WITH_64!$WITH_64$ac_delim GC_MMAP2!$GC_MMAP2$ac_delim GC_BOEHM!$GC_BOEHM$ac_delim GC_MULTI_MMAP!$GC_MULTI_MMAP$ac_delim @@ -7910,7 +7934,6 @@ DATE!$DATE$ac_delim FIND!$FIND$ac_delim MKDIR!$MKDIR$ac_delim -MV!$MV$ac_delim _ACEOF if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 97; then @@ -7952,6 +7975,7 @@ ac_delim='%!_!# ' for ac_last_try in false false false false false :; do cat >conf$$subs.sed <<_ACEOF +MV!$MV$ac_delim RANLIB!$RANLIB$ac_delim RM!$RM$ac_delim SED!$SED$ac_delim @@ -7969,7 +7993,7 @@ LTLIBOBJS!$LTLIBOBJS$ac_delim _ACEOF - if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 15; then + if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 16; then break elif $ac_last_try; then { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 From nicolas.geoffray at lip6.fr Tue Feb 10 02:58:02 2009 From: nicolas.geoffray at lip6.fr (Nicolas Geoffray) Date: Tue, 10 Feb 2009 10:58:02 -0000 Subject: [vmkit-commits] [vmkit] r64213 - in /vmkit/trunk: Makefile.rules lib/Mvm/Runtime/LLVMAssembly.ll lib/Mvm/Runtime/LLVMAssembly64.ll lib/Mvm/Runtime/Makefile Message-ID: <200902101058.n1AAw3pU001412@zion.cs.uiuc.edu> Author: geoffray Date: Tue Feb 10 04:58:02 2009 New Revision: 64213 URL: http://llvm.org/viewvc/llvm-project?rev=64213&view=rev Log: Find at compile-time whether we should compile atomit 64bits. Added: vmkit/trunk/lib/Mvm/Runtime/LLVMAssembly64.ll Modified: vmkit/trunk/Makefile.rules vmkit/trunk/lib/Mvm/Runtime/LLVMAssembly.ll vmkit/trunk/lib/Mvm/Runtime/Makefile Modified: vmkit/trunk/Makefile.rules URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/Makefile.rules?rev=64213&r1=64212&r2=64213&view=diff ============================================================================== --- vmkit/trunk/Makefile.rules (original) +++ vmkit/trunk/Makefile.rules Tue Feb 10 04:58:02 2009 @@ -24,7 +24,10 @@ LLVMAssembly.o : $(LLVMAS) $(LLC) $(VMKIT_ASSEMBLY) -LLVMAssembly.s : LLVMAssembly.ll +LLVMAssembly.gen.ll : $(VMKIT_ASSEMBLY) + $(Verb) cat $(VMKIT_ASSEMBLY) > LLVMAssembly.gen.ll + +LLVMAssembly.s : LLVMAssembly.gen.ll $(Echo) "Building LLVM assembly with $(VMKIT_ASSEMBLY)" $(Verb) $(LLVMAS) -f $( Author: geoffray Date: Wed Feb 11 09:34:45 2009 New Revision: 64303 URL: http://llvm.org/viewvc/llvm-project?rev=64303&view=rev Log: Inline very small methods, and don't call Object.init since it is known to be empty. Modified: vmkit/trunk/lib/JnJVM/VMCore/ExceptionsCheck.inc vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.cpp vmkit/trunk/lib/JnJVM/VMCore/JavaUpcalls.cpp vmkit/trunk/lib/JnJVM/VMCore/JavaUpcalls.h Modified: vmkit/trunk/lib/JnJVM/VMCore/ExceptionsCheck.inc URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/ExceptionsCheck.inc?rev=64303&r1=64302&r2=64303&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/ExceptionsCheck.inc (original) +++ vmkit/trunk/lib/JnJVM/VMCore/ExceptionsCheck.inc Wed Feb 11 09:34:45 2009 @@ -148,9 +148,8 @@ BranchInst::Create(currentExceptionBlock, currentBlock); } else { if (endNode) { - const FunctionType *funcType = llvmFunction->getFunctionType(); - const Type* returnType = funcType->getReturnType(); - endNode->addIncoming(Constant::getNullValue(returnType), currentBlock); + endNode->addIncoming(Constant::getNullValue(endNode->getType()), + currentBlock); } BranchInst::Create(endBlock, currentBlock); } @@ -172,9 +171,8 @@ BranchInst::Create(currentExceptionBlock, currentBlock); } else { if (endNode) { - const FunctionType *funcType = llvmFunction->getFunctionType(); - const Type* returnType = funcType->getReturnType(); - endNode->addIncoming(Constant::getNullValue(returnType), currentBlock); + endNode->addIncoming(Constant::getNullValue(endNode->getType()), + currentBlock); } BranchInst::Create(endBlock, currentBlock); } @@ -190,9 +188,8 @@ BranchInst::Create(currentExceptionBlock, currentBlock); } else { if (endNode) { - const FunctionType *funcType = llvmFunction->getFunctionType(); - const Type* returnType = funcType->getReturnType(); - endNode->addIncoming(Constant::getNullValue(returnType), currentBlock); + endNode->addIncoming(Constant::getNullValue(endNode->getType()), + currentBlock); } BranchInst::Create(endBlock, currentBlock); } @@ -484,9 +481,7 @@ endExceptionBlock->eraseFromParent(); } else { if (endNode) { - const FunctionType *funcType = llvmFunction->getFunctionType(); - const Type* returnType = funcType->getReturnType(); - endNode->addIncoming(Constant::getNullValue(returnType), + endNode->addIncoming(Constant::getNullValue(endNode->getType()), endExceptionBlock); } BranchInst::Create(endBlock, endExceptionBlock); Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.cpp URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.cpp?rev=64303&r1=64302&r2=64303&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.cpp (original) +++ vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.cpp Wed Feb 11 09:34:45 2009 @@ -62,9 +62,11 @@ } bool JavaJIT::canBeInlined(JavaMethod* meth) { + JnjvmClassLoader* loader = meth->classDef->classLoader; return (meth->canBeInlined && meth != compilingMethod && inlineMethods[meth] == 0 && - meth->classDef->classLoader == compilingClass->classLoader); + (loader == compilingClass->classLoader || + loader == compilingClass->classLoader->bootstrapLoader)); } void JavaJIT::invokeVirtual(uint16 index) { @@ -98,10 +100,14 @@ JITVerifyNull(args[0]); BasicBlock* endBlock = 0; PHINode* node = 0; - if (meth && !isAbstract(meth->access) && canBeInlined(meth)) { +#if 0 + if (meth && !isAbstract(meth->access)) { Value* cl = CallInst::Create(module->GetClassFunction, args[0], "", currentBlock); Value* cl2 = module->getNativeClass(meth->classDef); + if (cl2->getType() != module->JavaCommonClassType) { + cl2 = new BitCastInst(cl2, module->JavaCommonClassType, "", currentBlock); + } Value* test = new ICmpInst(ICmpInst::ICMP_EQ, cl, cl2, "", currentBlock); @@ -110,7 +116,13 @@ endBlock = createBasicBlock("end virtual invoke"); BranchInst::Create(trueBlock, falseBlock, test, currentBlock); currentBlock = trueBlock; - Value* res = invokeInline(meth, args); + Value* res = 0; + if (canBeInlined(meth)) { + res = invokeInline(meth, args); + } else { + Function* func = module->getMethod(meth); + res = invoke(func, args, "", currentBlock); + } BranchInst::Create(endBlock, currentBlock); if (retType != Type::VoidTy) { node = PHINode::Create(virtualType->getReturnType(), "", endBlock); @@ -118,7 +130,7 @@ } currentBlock = falseBlock; } - +#endif Value* VT = CallInst::Create(module->GetVTFunction, args[0], "", currentBlock); @@ -486,8 +498,7 @@ std::vector& args) { PRINT_DEBUG(JNJVM_COMPILE, 1, COLOR_NORMAL, "inline compile %s\n", compilingMethod->printString()); - - + Attribut* codeAtt = compilingMethod->lookupAttribut(Attribut::codeAttribut); if (!codeAtt) { @@ -512,7 +523,7 @@ endBlock = createBasicBlock("end"); currentBlock = curBB; - endExceptionBlock = 0; + endExceptionBlock = endExBlock; opcodeInfos = (Opinfo*)alloca(codeLen * sizeof(Opinfo)); memset(opcodeInfos, 0, codeLen * sizeof(Opinfo)); @@ -574,6 +585,8 @@ new StoreInst(*i, objectLocals[index], false, currentBlock); } } + + readExceptionTable(reader, codeLen); exploreOpcodes(&compilingClass->bytes->elements[start], codeLen); nbEnveloppes = 0; @@ -751,7 +764,7 @@ } #endif - unsigned nbe = readExceptionTable(reader, codeLen); + readExceptionTable(reader, codeLen); exploreOpcodes(&compilingClass->bytes->elements[start], codeLen); compilingMethod->enveloppes = @@ -844,8 +857,10 @@ PRINT_DEBUG(JNJVM_COMPILE, 1, COLOR_NORMAL, "--> end compiling %s\n", compilingMethod->printString()); - if (nbe == 0 && codeLen < 50 && !callsStackWalker) - compilingMethod->canBeInlined = false; +#ifndef DWARF_EXCEPTIONS + if (codeLen < 5 && !callsStackWalker) + compilingMethod->canBeInlined = true; +#endif return llvmFunction; } @@ -1193,6 +1208,7 @@ Signdef* signature = 0; const UTF8* name = 0; const UTF8* cl = 0; + ctpInfo->nameOfStaticOrSpecialMethod(index, cl, name, signature); LLVMSignatureInfo* LSI = module->getSignatureInfo(signature); const llvm::FunctionType* virtualType = LSI->getVirtualType(); @@ -1201,6 +1217,14 @@ std::vector args; FunctionType::param_iterator it = virtualType->param_end(); makeArgs(it, index, args, signature->nbArguments + 1); + + Function* func = + (Function*)ctpInfo->infoOfStaticOrSpecialMethod(index, ACC_VIRTUAL, + signature, meth); + + if (meth == compilingClass->classLoader->bootstrapLoader->upcalls->InitObject) + return; + JITVerifyNull(args[0]); #if defined(ISOLATE_SHARING) @@ -1228,9 +1252,6 @@ currentBlock = trueCl; args.push_back(node); #endif - Function* func = - (Function*)ctpInfo->infoOfStaticOrSpecialMethod(index, ACC_VIRTUAL, - signature, meth); if (!meth) { // Make sure the class is loaded before materializing the method. Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaUpcalls.cpp URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JavaUpcalls.cpp?rev=64303&r1=64302&r2=64303&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/JavaUpcalls.cpp (original) +++ vmkit/trunk/lib/JnJVM/VMCore/JavaUpcalls.cpp Wed Feb 11 09:34:45 2009 @@ -172,6 +172,7 @@ JavaMethod* Classpath::InitStackOverflowError; JavaMethod* Classpath::InitUnknownError; JavaMethod* Classpath::InitClassNotFoundException; +JavaMethod* Classpath::InitObject; JavaMethod* Classpath::ErrorWithExcpNoClassDefFoundError; JavaMethod* Classpath::ErrorWithExcpExceptionInInitializerError; @@ -573,6 +574,8 @@ UPCALL_METHOD_WITH_EXCEPTION(loader, ExceptionInInitializerError); UPCALL_METHOD_WITH_EXCEPTION(loader, InvocationTargetException); + InitObject = UPCALL_METHOD(loader, "java/lang/Object", "", "()V", + ACC_VIRTUAL); newThread = UPCALL_CLASS(loader, "java/lang/Thread"); Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaUpcalls.h URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JavaUpcalls.h?rev=64303&r1=64302&r2=64303&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/JavaUpcalls.h (original) +++ vmkit/trunk/lib/JnJVM/VMCore/JavaUpcalls.h Wed Feb 11 09:34:45 2009 @@ -205,6 +205,8 @@ ISOLATE_STATIC JavaMethod* InitUnknownError; ISOLATE_STATIC JavaMethod* InitClassNotFoundException; + ISOLATE_STATIC JavaMethod* InitObject; + ISOLATE_STATIC JavaMethod* ErrorWithExcpNoClassDefFoundError; ISOLATE_STATIC JavaMethod* ErrorWithExcpExceptionInInitializerError; ISOLATE_STATIC JavaMethod* ErrorWithExcpInvocationTargetException; From nicolas.geoffray at lip6.fr Tue Feb 17 03:45:08 2009 From: nicolas.geoffray at lip6.fr (Nicolas Geoffray) Date: Tue, 17 Feb 2009 11:45:08 -0000 Subject: [vmkit-commits] [vmkit] r64762 - /vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.cpp Message-ID: <200902171145.n1HBj9So030440@zion.cs.uiuc.edu> Author: geoffray Date: Tue Feb 17 05:45:03 2009 New Revision: 64762 URL: http://llvm.org/viewvc/llvm-project?rev=64762&view=rev Log: Put allocas from inline'd functions at the entry point of the function so that Mem2Reg can run on them. Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.cpp Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.cpp URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.cpp?rev=64762&r1=64761&r2=64762&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.cpp (original) +++ vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.cpp Tue Feb 17 05:45:03 2009 @@ -530,14 +530,30 @@ for (uint32 i = 0; i < codeLen; ++i) { opcodeInfos[i].exceptionBlock = endExBlock; } + + BasicBlock* firstBB = llvmFunction->begin(); - for (int i = 0; i < maxLocals; i++) { - intLocals.push_back(new AllocaInst(Type::Int32Ty, "", currentBlock)); - doubleLocals.push_back(new AllocaInst(Type::DoubleTy, "", currentBlock)); - longLocals.push_back(new AllocaInst(Type::Int64Ty, "", currentBlock)); - floatLocals.push_back(new AllocaInst(Type::FloatTy, "", currentBlock)); - objectLocals.push_back(new AllocaInst(module->JavaObjectType, "", - currentBlock)); + if (firstBB->begin() != firstBB->end()) { + Instruction* firstInstruction = firstBB->begin(); + + for (int i = 0; i < maxLocals; i++) { + intLocals.push_back(new AllocaInst(Type::Int32Ty, "", firstInstruction)); + doubleLocals.push_back(new AllocaInst(Type::DoubleTy, "", + firstInstruction)); + longLocals.push_back(new AllocaInst(Type::Int64Ty, "", firstInstruction)); + floatLocals.push_back(new AllocaInst(Type::FloatTy, "", firstInstruction)); + objectLocals.push_back(new AllocaInst(module->JavaObjectType, "", + firstInstruction)); + } + } else { + for (int i = 0; i < maxLocals; i++) { + intLocals.push_back(new AllocaInst(Type::Int32Ty, "", firstBB)); + doubleLocals.push_back(new AllocaInst(Type::DoubleTy, "", firstBB)); + longLocals.push_back(new AllocaInst(Type::Int64Ty, "", firstBB)); + floatLocals.push_back(new AllocaInst(Type::FloatTy, "", firstBB)); + objectLocals.push_back(new AllocaInst(module->JavaObjectType, "", + firstBB)); + } } uint32 index = 0; From nicolas.geoffray at lip6.fr Wed Feb 18 01:34:33 2009 From: nicolas.geoffray at lip6.fr (Nicolas Geoffray) Date: Wed, 18 Feb 2009 09:34:33 -0000 Subject: [vmkit-commits] [vmkit] r64913 - in /vmkit/trunk/lib/JnJVM: LLVMRuntime/runtime-default.ll VMCore/JavaClass.h VMCore/JnjvmModule.cpp VMCore/JnjvmModule.h VMCore/LowerConstantCalls.cpp Message-ID: <200902180934.n1I9YYiM003874@zion.cs.uiuc.edu> Author: geoffray Date: Wed Feb 18 03:34:24 2009 New Revision: 64913 URL: http://llvm.org/viewvc/llvm-project?rev=64913&view=rev Log: Save one compare instruction in the initialization check by storing the info as a bool in the per-task class information. Modified: vmkit/trunk/lib/JnJVM/LLVMRuntime/runtime-default.ll vmkit/trunk/lib/JnJVM/VMCore/JavaClass.h vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.cpp vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.h vmkit/trunk/lib/JnJVM/VMCore/LowerConstantCalls.cpp Modified: vmkit/trunk/lib/JnJVM/LLVMRuntime/runtime-default.ll URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/LLVMRuntime/runtime-default.ll?rev=64913&r1=64912&r2=64913&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/LLVMRuntime/runtime-default.ll (original) +++ vmkit/trunk/lib/JnJVM/LLVMRuntime/runtime-default.ll Wed Feb 18 03:34:24 2009 @@ -30,8 +30,9 @@ ;;; The task class mirror. ;;; Field 1: The class state -;;; Field 2: The static instance -%TaskClassMirror = type { i32, i8* } +;;; Field 2: The initialization state +;;; Field 3: The static instance +%TaskClassMirror = type { i8, i1, i8* } ;;; Field 0: the VT of threads ;;; Field 1: next Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaClass.h URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JavaClass.h?rev=64913&r1=64912&r2=64913&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/JavaClass.h (original) +++ vmkit/trunk/lib/JnJVM/VMCore/JavaClass.h Wed Feb 18 03:34:24 2009 @@ -47,16 +47,13 @@ /// used (i.e allocating instances of the class, calling methods of the class /// and accessing static fields of the class) when it is in the ready state. /// -typedef enum JavaState { - loaded = 0, /// The .class file has been found. - classRead = 1, /// The .class file has been read. - resolved = 2, /// The class has been resolved. - vmjc = 3, /// The class is defined in a shared library. - inClinit = 4, /// The class is cliniting. - ready = 5, /// The class is ready to be used. - erroneous = 6, /// The class is in an erroneous state. - dontuseenums = 0xffffffff /// dummy value to force the enum to be int32 -} JavaState; +#define loaded 0 /// The .class file has been found. +#define classRead 1 /// The .class file has been read. +#define resolved 2 /// The class has been resolved. +#define vmjc 3 /// The class is defined in a shared library. +#define inClinit 4 /// The class is cliniting. +#define ready 5 /// The class is ready to be used. +#define erroneous 6 /// The class is in an erroneous state. /// Attribut - This class represents JVM attributes to Java class, methods and @@ -124,9 +121,12 @@ class TaskClassMirror { public: - /// status - The initialization state. + /// status - The state. /// - JavaState status; + uint8 status; + + /// initialized - Is the class initialized? + bool initialized; /// staticInstance - Memory that holds the static variables of the class. /// @@ -745,14 +745,15 @@ /// getInitializationState - Get the state of the class. /// - JavaState getInitializationState() { + uint8 getInitializationState() { return IsolateInfo[0].status; } /// setInitializationState - Set the state of the class. /// - void setInitializationState(JavaState st) { + void setInitializationState(uint8 st) { IsolateInfo[0].status = st; + if (st == ready) IsolateInfo[0].initialized = true; } /// isReady - Has this class been initialized? @@ -824,11 +825,11 @@ getCurrentTaskClassMirror().staticInstance = val; } - JavaState getInitializationState() { + uint8 getInitializationState() { return getCurrentTaskClassMirror().status; } - void setInitializationState(JavaState st) { + void setInitializationState(uint8 st) { getCurrentTaskClassMirror().status = st; } Modified: vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.cpp URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.cpp?rev=64913&r1=64912&r2=64913&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.cpp (original) +++ vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.cpp Wed Feb 18 03:34:24 2009 @@ -92,6 +92,7 @@ llvm::ConstantInt* JnjvmModule::OffsetTaskClassMirrorInClassConstant; llvm::ConstantInt* JnjvmModule::OffsetStaticInstanceInTaskClassMirrorConstant; llvm::ConstantInt* JnjvmModule::OffsetStatusInTaskClassMirrorConstant; +llvm::ConstantInt* JnjvmModule::OffsetInitializedInTaskClassMirrorConstant; llvm::ConstantInt* JnjvmModule::OffsetJavaExceptionInThreadConstant; llvm::ConstantInt* JnjvmModule::OffsetCXXExceptionInThreadConstant; llvm::ConstantInt* JnjvmModule::ClassReadyConstant; @@ -2019,13 +2020,14 @@ OffsetObjectSizeInClassConstant = mvm::MvmModule::constantOne; OffsetVTInClassConstant = mvm::MvmModule::constantTwo; OffsetTaskClassMirrorInClassConstant = mvm::MvmModule::constantThree; - OffsetStaticInstanceInTaskClassMirrorConstant = mvm::MvmModule::constantOne; + OffsetStaticInstanceInTaskClassMirrorConstant = mvm::MvmModule::constantTwo; OffsetStatusInTaskClassMirrorConstant = mvm::MvmModule::constantZero; + OffsetInitializedInTaskClassMirrorConstant = mvm::MvmModule::constantOne; OffsetJavaExceptionInThreadConstant = ConstantInt::get(Type::Int32Ty, 9); OffsetCXXExceptionInThreadConstant = ConstantInt::get(Type::Int32Ty, 10); - ClassReadyConstant = ConstantInt::get(Type::Int32Ty, ready); + ClassReadyConstant = ConstantInt::get(Type::Int8Ty, ready); if (staticCompilation) { Modified: vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.h URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.h?rev=64913&r1=64912&r2=64913&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.h (original) +++ vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.h Wed Feb 18 03:34:24 2009 @@ -365,6 +365,7 @@ static llvm::ConstantInt* OffsetDisplayInClassConstant; static llvm::ConstantInt* OffsetTaskClassMirrorInClassConstant; static llvm::ConstantInt* OffsetStaticInstanceInTaskClassMirrorConstant; + static llvm::ConstantInt* OffsetInitializedInTaskClassMirrorConstant; static llvm::ConstantInt* OffsetStatusInTaskClassMirrorConstant; static llvm::ConstantInt* OffsetJavaExceptionInThreadConstant; Modified: vmkit/trunk/lib/JnJVM/VMCore/LowerConstantCalls.cpp URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/LowerConstantCalls.cpp?rev=64913&r1=64912&r2=64913&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/LowerConstantCalls.cpp (original) +++ vmkit/trunk/lib/JnJVM/VMCore/LowerConstantCalls.cpp Wed Feb 18 03:34:24 2009 @@ -280,15 +280,13 @@ Value* Cl = Call.getArgument(0); Value* TCM = getTCM(module, Call.getArgument(0), CI); - Value* GEP[2] = { module->constantZero, - module->OffsetStatusInTaskClassMirrorConstant }; + Value* GEP[2] = + { module->constantZero, + module->OffsetInitializedInTaskClassMirrorConstant }; Value* StatusPtr = GetElementPtrInst::Create(TCM, GEP, GEP + 2, "", CI); - Value* Status = new LoadInst(StatusPtr, "", CI); - Value* test = new ICmpInst(ICmpInst::ICMP_EQ, Status, - module->ClassReadyConstant, - "", CI); + Value* test = new LoadInst(StatusPtr, "", CI); BasicBlock* trueCl = BasicBlock::Create("Initialized", &F); BasicBlock* falseCl = BasicBlock::Create("Uninitialized", &F); From nicolas.geoffray at lip6.fr Thu Feb 19 08:02:49 2009 From: nicolas.geoffray at lip6.fr (Nicolas Geoffray) Date: Thu, 19 Feb 2009 16:02:49 -0000 Subject: [vmkit-commits] [vmkit] r65045 - /vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.cpp Message-ID: <200902191602.n1JG2nup021500@zion.cs.uiuc.edu> Author: geoffray Date: Thu Feb 19 10:02:48 2009 New Revision: 65045 URL: http://llvm.org/viewvc/llvm-project?rev=65045&view=rev Log: Fix AOT with the new Task class mirror type. Modified: vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.cpp Modified: vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.cpp URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.cpp?rev=65045&r1=65044&r2=65045&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.cpp (original) +++ vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.cpp Thu Feb 19 10:02:48 2009 @@ -1015,7 +1015,8 @@ assert(TCMTy && "Malformed type"); uint32 status = cl->needsInitialisationCheck() ? vmjc : ready; - TempElts.push_back(ConstantInt::get(Type::Int32Ty, status)); + TempElts.push_back(ConstantInt::get(Type::Int8Ty, status)); + TempElts.push_back(ConstantInt::get(Type::Int1Ty, status == ready ? 1 : 0)); TempElts.push_back(getStaticInstance(cl)); Constant* CStr[1] = { ConstantStruct::get(TCMTy, TempElts) }; TempElts.clear(); From nicolas.geoffray at lip6.fr Mon Feb 23 05:37:56 2009 From: nicolas.geoffray at lip6.fr (Nicolas Geoffray) Date: Mon, 23 Feb 2009 13:37:56 -0000 Subject: [vmkit-commits] [vmkit] r65316 - /vmkit/trunk/lib/JnJVM/Classpath/ClasspathField.cpp Message-ID: <200902231337.n1NDbusr027089@zion.cs.uiuc.edu> Author: geoffray Date: Mon Feb 23 07:37:55 2009 New Revision: 65316 URL: http://llvm.org/viewvc/llvm-project?rev=65316&view=rev Log: Fix mindo. Modified: vmkit/trunk/lib/JnJVM/Classpath/ClasspathField.cpp Modified: vmkit/trunk/lib/JnJVM/Classpath/ClasspathField.cpp URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/Classpath/ClasspathField.cpp?rev=65316&r1=65315&r2=65316&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/Classpath/ClasspathField.cpp (original) +++ vmkit/trunk/lib/JnJVM/Classpath/ClasspathField.cpp Mon Feb 23 07:37:55 2009 @@ -223,16 +223,16 @@ if (prim->isByte()) res = (jfloat)field->getInt8Field(Obj); else if (prim->isInt()) - res = (jfloat)field->getInt32Field((JavaObject*)obj); + res = (jfloat)field->getInt32Field(Obj); else if (prim->isShort()) - res = (jfloat)field->getInt16Field((JavaObject*)obj); + res = (jfloat)field->getInt16Field(Obj); else if (prim->isLong()) - res = (jfloat)field->getLongField((JavaObject*)obj); + res = (jfloat)field->getLongField(Obj); else if (prim->isChar()) // Cast to uint32 because char is unsigned. - res = (jfloat)(uint32)field->getInt16Field((JavaObject*)obj); + res = (jfloat)(uint32)field->getInt16Field(Obj); else if (prim->isFloat()) - res = (jfloat)field->getFloatField((JavaObject*)obj); + res = (jfloat)field->getFloatField(Obj); else vm->illegalArgumentException(""); } else { @@ -311,7 +311,7 @@ if (type->isPrimitive()) { const PrimitiveTypedef* prim = (PrimitiveTypedef*)type; if (prim->isChar()) - res = (uint16)field->getInt16Field((JavaObject*)obj); + res = (uint16)field->getInt16Field(Obj); else vm->illegalArgumentException(""); } else { From nicolas.geoffray at lip6.fr Mon Feb 23 08:39:54 2009 From: nicolas.geoffray at lip6.fr (Nicolas Geoffray) Date: Mon, 23 Feb 2009 16:39:54 -0000 Subject: [vmkit-commits] [vmkit] r65320 - in /vmkit/trunk/lib/JnJVM/VMCore: JavaJIT.cpp JnjvmModule.cpp JnjvmModule.h Message-ID: <200902231639.n1NGdsCr001015@zion.cs.uiuc.edu> Author: geoffray Date: Mon Feb 23 10:39:54 2009 New Revision: 65320 URL: http://llvm.org/viewvc/llvm-project?rev=65320&view=rev Log: Optimization of final static fields. Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.cpp vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.cpp vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.h Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.cpp URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.cpp?rev=65320&r1=65319&r2=65320&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.cpp (original) +++ vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.cpp Mon Feb 23 10:39:54 2009 @@ -1536,7 +1536,7 @@ Value* ptr = llvm::GetElementPtrInst::Create(objectConvert, args, args + 2, "", currentBlock); - return ptr; + return ptr; } const Type* Pty = module->arrayPtrType; @@ -1616,7 +1616,51 @@ Value* ptr = ldResolved(index, true, 0, type, LAI.llvmTypePtr); - push(new LoadInst(ptr, "", currentBlock), sign->isUnsigned()); + JnjvmBootstrapLoader* JBL = compilingClass->classLoader->bootstrapLoader; + bool final = false; + if (!compilingMethod->name->equals(JBL->clinitName)) { + JavaField* field = compilingClass->ctpInfo->lookupField(index, true); + if (field && field->classDef->isReady()) final = isFinal(field->access); + if (final) { + void* Obj = field->classDef->getStaticInstance(); + if (sign->isPrimitive()) { + const PrimitiveTypedef* prim = (PrimitiveTypedef*)sign; + if (prim->isInt()) { + sint32 val = field->getInt32Field(Obj); + push(ConstantInt::get(Type::Int32Ty, val), false); + } else if (prim->isByte()) { + sint8 val = (sint8)field->getInt8Field(Obj); + push(ConstantInt::get(Type::Int8Ty, val), false); + } else if (prim->isBool()) { + uint8 val = (uint8)field->getInt8Field(Obj); + push(ConstantInt::get(Type::Int8Ty, val), true); + } else if (prim->isShort()) { + sint16 val = (sint16)field->getInt16Field(Obj); + push(ConstantInt::get(Type::Int16Ty, val), false); + } else if (prim->isChar()) { + uint16 val = (uint16)field->getInt16Field(Obj); + push(ConstantInt::get(Type::Int16Ty, val), true); + } else if (prim->isLong()) { + sint64 val = (sint64)field->getLongField(Obj); + push(ConstantInt::get(Type::Int64Ty, val), false); + } else if (prim->isFloat()) { + float val = (float)field->getFloatField(Obj); + push(ConstantFP::get(Type::FloatTy, val), false); + } else if (prim->isDouble()) { + double val = (double)field->getDoubleField(Obj); + push(ConstantFP::get(Type::DoubleTy, val), false); + } else { + abort(); + } + } else { + JavaObject* val = field->getObjectField(Obj); + Value* V = module->getFinalObject(val); + push(V, false); + } + } + } + + if (!final) push(new LoadInst(ptr, "", currentBlock), sign->isUnsigned()); if (type == Type::Int64Ty || type == Type::DoubleTy) { push(module->constantZero, false); } Modified: vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.cpp URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.cpp?rev=65320&r1=65319&r2=65320&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.cpp (original) +++ vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.cpp Mon Feb 23 10:39:54 2009 @@ -310,6 +310,23 @@ } } +Constant* JnjvmModule::getFinalObject(JavaObject* obj) { + if (staticCompilation) { + final_object_iterator End = finalObjects.end(); + final_object_iterator I = finalObjects.find(obj); + if (I == End) { + abort(); + return 0; + } else { + return I->second; + } + + } else { + Constant* CI = ConstantInt::get(Type::Int64Ty, uint64(obj)); + return ConstantExpr::getIntToPtr(CI, JavaObjectType); + } +} + Constant* JnjvmModule::CreateConstantFromStaticInstance(Class* cl) { LLVMClassInfo* LCI = getClassInfo(cl); const Type* Ty = LCI->getStaticType(); @@ -604,7 +621,7 @@ } #endif -Constant* JnjvmModule::CreateConstantForJavaObject(CommonClass* cl) { +Constant* JnjvmModule::CreateConstantForBaseObject(CommonClass* cl) { const StructType* STy = dyn_cast(JavaObjectType->getContainedType(0)); @@ -646,7 +663,7 @@ std::vector Elmts; // JavaObject - Elmts.push_back(CreateConstantForJavaObject(javaClass)); + Elmts.push_back(CreateConstantForBaseObject(javaClass)); // signers Elmts.push_back(Constant::getNullValue(JavaObjectType)); @@ -665,6 +682,104 @@ return ConstantStruct::get(STy, Elmts); } +Constant* JnjvmModule::CreateConstantFromJavaObject(JavaObject* obj) { + CommonClass* cl = obj->getClass(); + + if (cl->isArray()) { + Classpath* upcalls = cl->classLoader->bootstrapLoader->upcalls; + CommonClass* subClass = cl->asArrayClass()->baseClass(); + if (subClass->isPrimitive()) { + if (subClass == upcalls->OfBool) { + return CreateConstantFromArray((ArrayUInt8*)obj, + Type::Int8Ty); + } else if (subClass == upcalls->OfByte) { + return CreateConstantFromArray((ArraySInt8*)obj, + Type::Int8Ty); + } else if (subClass == upcalls->OfShort) { + return CreateConstantFromArray((ArraySInt16*)obj, + Type::Int16Ty); + } else if (subClass == upcalls->OfChar) { + return CreateConstantFromArray((ArrayUInt16*)obj, + Type::Int16Ty); + } else if (subClass == upcalls->OfInt) { + return CreateConstantFromArray((ArraySInt32*)obj, + Type::Int32Ty); + } else if (subClass == upcalls->OfFloat) { + return CreateConstantFromArray((ArrayFloat*)obj, + Type::FloatTy); + } else if (subClass == upcalls->OfLong) { + return CreateConstantFromArray((ArrayLong*)obj, + Type::Int64Ty); + } else if (subClass == upcalls->OfDouble) { + return CreateConstantFromArray((ArrayDouble*)obj, + Type::DoubleTy); + } else { + abort(); + } + } else { + return CreateConstantFromArray((ArrayObject*)obj, + JavaObjectType); + } + } else { + + std::vector Elmts; + + // JavaObject + Constant* CurConstant = CreateConstantForBaseObject(obj->getClass()); + + for (uint32 j = 0; j <= cl->depth; ++j) { + std::vector TempElts; + Elmts.push_back(CurConstant); + TempElts.push_back(CurConstant); + Class* curCl = cl->display[j]->asClass(); + LLVMClassInfo* LCI = getClassInfo(curCl); + const StructType* STy = + dyn_cast(LCI->getVirtualType()->getContainedType(0)); + + for (uint32 i = 0; i < curCl->nbVirtualFields; ++i) { + JavaField& field = curCl->virtualFields[i]; + const Typedef* type = field.getSignature(); + if (type->isPrimitive()) { + const PrimitiveTypedef* prim = (PrimitiveTypedef*)type; + if (prim->isBool() || prim->isByte()) { + ConstantInt* CI = ConstantInt::get(Type::Int8Ty, + field.getInt8Field(obj)); + TempElts.push_back(CI); + } else if (prim->isShort() || prim->isChar()) { + ConstantInt* CI = ConstantInt::get(Type::Int16Ty, + field.getInt16Field(obj)); + TempElts.push_back(CI); + } else if (prim->isInt()) { + ConstantInt* CI = ConstantInt::get(Type::Int32Ty, + field.getInt32Field(obj)); + TempElts.push_back(CI); + } else if (prim->isLong()) { + ConstantInt* CI = ConstantInt::get(Type::Int64Ty, + field.getLongField(obj)); + TempElts.push_back(CI); + } else if (prim->isFloat()) { + ConstantInt* CI = ConstantInt::get(Type::FloatTy, + field.getFloatField(obj)); + TempElts.push_back(CI); + } else if (prim->isDouble()) { + ConstantInt* CI = ConstantInt::get(Type::DoubleTy, + field.getDoubleField(obj)); + TempElts.push_back(CI); + } else { + abort(); + } + } else { + Constant* C = getFinalObject(field.getObjectField(obj)); + TempElts.push_back(C); + } + } + CurConstant = ConstantStruct::get(STy, TempElts); + } + + return CurConstant; + } +} + Constant* JnjvmModule::CreateConstantFromJavaString(JavaString* str) { Class* cl = (Class*)str->getClass(); LLVMClassInfo* LCI = (LLVMClassInfo*)getClassInfo(cl); @@ -673,7 +788,7 @@ std::vector Elmts; - Elmts.push_back(CreateConstantForJavaObject(cl)); + Elmts.push_back(CreateConstantForBaseObject(cl)); Constant* Array = getUTF8(str->value); Constant* ObjGEPs[2] = { constantZero, constantZero }; @@ -1213,6 +1328,38 @@ return ConstantStruct::get(STy, ClassElts); } +template +Constant* JnjvmModule::CreateConstantFromArray(T* val, const llvm::Type* Ty) { + std::vector Elemts; + const ArrayType* ATy = ArrayType::get(Ty, val->size); + Elemts.push_back(JavaObjectType->getContainedType(0)); + Elemts.push_back(pointerSizeType == Type::Int32Ty ? Type::Int32Ty : + Type::Int64Ty); + + Elemts.push_back(ATy); + + const StructType* STy = StructType::get(Elemts); + + std::vector Cts; + Cts.push_back(CreateConstantForBaseObject(val->getClass())); + Cts.push_back(ConstantInt::get(pointerSizeType, val->size)); + + std::vector Vals; + for (sint32 i = 0; i < val->size; ++i) { + if (Ty->isInteger()) { + Vals.push_back(ConstantInt::get(Ty, (uint64)val->elements[i])); + } else if (Ty->isFloatingPoint()) { + Vals.push_back(ConstantFP::get(Ty, (double)(size_t)val->elements[i])); + } else { + Vals.push_back(getFinalObject((JavaObject*)(size_t)val->elements[i])); + } + } + + Cts.push_back(ConstantArray::get(ATy, Vals)); + + return ConstantStruct::get(STy, Cts); +} + Constant* JnjvmModule::CreateConstantFromUTF8(const UTF8* val) { std::vector Elemts; const ArrayType* ATy = ArrayType::get(Type::Int16Ty, val->size); @@ -1225,7 +1372,7 @@ const StructType* STy = StructType::get(Elemts); std::vector Cts; - Cts.push_back(CreateConstantForJavaObject(&ArrayOfChar)); + Cts.push_back(CreateConstantForBaseObject(&ArrayOfChar)); Cts.push_back(ConstantInt::get(pointerSizeType, val->size)); std::vector Vals; Modified: vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.h URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.h?rev=65320&r1=65319&r2=65320&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.h (original) +++ vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.h Mon Feb 23 10:39:54 2009 @@ -192,6 +192,10 @@ std::map nativeFunctions; std::map utf8s; std::map virtualMethods; + std::map finalObjects; + + typedef std::map::iterator + final_object_iterator; typedef std::map::iterator method_iterator; @@ -411,6 +415,7 @@ void initialise(); void printStats(); + llvm::Constant* getFinalObject(JavaObject* obj); llvm::Constant* getNativeClass(CommonClass* cl); llvm::Constant* getJavaClass(CommonClass* cl); llvm::Constant* getStaticInstance(Class* cl); @@ -458,8 +463,13 @@ llvm::Constant* CreateConstantFromStaticInstance(Class* cl); llvm::Constant* CreateConstantFromJavaString(JavaString* str); llvm::Constant* CreateConstantFromJavaClass(CommonClass* cl); - llvm::Constant* CreateConstantForJavaObject(CommonClass* cl); + llvm::Constant* CreateConstantForBaseObject(CommonClass* cl); + llvm::Constant* CreateConstantFromJavaObject(JavaObject* obj); llvm::Constant* getUTF8(const UTF8* val); + + template + llvm::Constant* CreateConstantFromArray(T* val, const llvm::Type* Ty); + }; From nicolas.geoffray at lip6.fr Mon Feb 23 09:18:29 2009 From: nicolas.geoffray at lip6.fr (Nicolas Geoffray) Date: Mon, 23 Feb 2009 17:18:29 -0000 Subject: [vmkit-commits] [vmkit] r65324 - in /vmkit/trunk/lib/JnJVM: LLVMRuntime/runtime-default.ll VMCore/JavaJIT.cpp VMCore/JnjvmModule.cpp VMCore/JnjvmModule.h VMCore/LowerConstantCalls.cpp Message-ID: <200902231718.n1NHITue002415@zion.cs.uiuc.edu> Author: geoffray Date: Mon Feb 23 11:18:28 2009 New Revision: 65324 URL: http://llvm.org/viewvc/llvm-project?rev=65324&view=rev Log: Optimization of final virtual fields. Modified: vmkit/trunk/lib/JnJVM/LLVMRuntime/runtime-default.ll vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.cpp vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.cpp vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.h vmkit/trunk/lib/JnJVM/VMCore/LowerConstantCalls.cpp Modified: vmkit/trunk/lib/JnJVM/LLVMRuntime/runtime-default.ll URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/LLVMRuntime/runtime-default.ll?rev=65324&r1=65323&r2=65324&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/LLVMRuntime/runtime-default.ll (original) +++ vmkit/trunk/lib/JnJVM/LLVMRuntime/runtime-default.ll Mon Feb 23 11:18:28 2009 @@ -191,6 +191,14 @@ declare %JavaCommonClass* @getArrayClass(%JavaCommonClass*, %JavaCommonClass**) readnone +declare i8 @getFinalInt8Field(i8*) readnone +declare i16 @getFinalInt16Field(i16*) readnone +declare i32 @getFinalInt32Field(i32*) readnone +declare i64 @getFinalLongField(i64*) readnone +declare double @getFinalDoubleField(double*) readnone +declare float @getFinalFloatField(float*) readnone +declare %JavaObject* @getFinalObjectField(%JavaObject**) readnone + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Exception methods ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.cpp URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.cpp?rev=65324&r1=65323&r2=65324&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.cpp (original) +++ vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.cpp Mon Feb 23 11:18:28 2009 @@ -1696,8 +1696,43 @@ JITVerifyNull(obj); Value* ptr = ldResolved(index, false, obj, type, LAI.llvmTypePtr); + + JnjvmBootstrapLoader* JBL = compilingClass->classLoader->bootstrapLoader; + bool final = false; + if (!compilingMethod->name->equals(JBL->initName)) { + JavaField* field = compilingClass->ctpInfo->lookupField(index, false); + if (field) final = isFinal(field->access); + if (final) { + Function* F = 0; + if (sign->isPrimitive()) { + const PrimitiveTypedef* prim = (PrimitiveTypedef*)sign; + if (prim->isInt()) { + F = module->GetFinalInt32FieldFunction; + } else if (prim->isByte()) { + F = module->GetFinalInt8FieldFunction; + } else if (prim->isBool()) { + F = module->GetFinalInt8FieldFunction; + } else if (prim->isShort()) { + F = module->GetFinalInt16FieldFunction; + } else if (prim->isChar()) { + F = module->GetFinalInt16FieldFunction; + } else if (prim->isLong()) { + F = module->GetFinalLongFieldFunction; + } else if (prim->isFloat()) { + F = module->GetFinalFloatFieldFunction; + } else if (prim->isDouble()) { + F = module->GetFinalDoubleFieldFunction; + } else { + abort(); + } + } else { + F = module->GetFinalObjectFieldFunction; + } + push(CallInst::Create(F, ptr, "", currentBlock), sign->isUnsigned()); + } + } - push(new LoadInst(ptr, "", currentBlock), sign->isUnsigned()); + if (!final) push(new LoadInst(ptr, "", currentBlock), sign->isUnsigned()); if (type == Type::Int64Ty || type == Type::DoubleTy) { push(module->constantZero, false); } Modified: vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.cpp URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.cpp?rev=65324&r1=65323&r2=65324&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.cpp (original) +++ vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.cpp Mon Feb 23 11:18:28 2009 @@ -2356,7 +2356,14 @@ ThrowExceptionFunction = module->getFunction("JavaThreadThrowException"); GetArrayClassFunction = module->getFunction("getArrayClass"); - + + GetFinalInt8FieldFunction = module->getFunction("getFinalInt8Field"); + GetFinalInt16FieldFunction = module->getFunction("getFinalInt16Field"); + GetFinalInt32FieldFunction = module->getFunction("getFinalInt32Field"); + GetFinalLongFieldFunction = module->getFunction("getFinalLongField"); + GetFinalFloatFieldFunction = module->getFunction("getFinalFloatField"); + GetFinalDoubleFieldFunction = module->getFunction("getFinalDoubleField"); + GetFinalObjectFieldFunction = module->getFunction("getFinalObjectField"); #ifdef ISOLATE StringLookupFunction = module->getFunction("stringLookup"); Modified: vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.h URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.h?rev=65324&r1=65323&r2=65324&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.h (original) +++ vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.h Mon Feb 23 11:18:28 2009 @@ -362,6 +362,14 @@ llvm::Function* GetLockFunction; llvm::Function* OverflowThinLockFunction; + + llvm::Function* GetFinalInt8FieldFunction; + llvm::Function* GetFinalInt16FieldFunction; + llvm::Function* GetFinalInt32FieldFunction; + llvm::Function* GetFinalLongFieldFunction; + llvm::Function* GetFinalFloatFieldFunction; + llvm::Function* GetFinalDoubleFieldFunction; + llvm::Function* GetFinalObjectFieldFunction; static llvm::ConstantInt* OffsetObjectSizeInClassConstant; static llvm::ConstantInt* OffsetVTInClassConstant; Modified: vmkit/trunk/lib/JnJVM/VMCore/LowerConstantCalls.cpp URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/LowerConstantCalls.cpp?rev=65324&r1=65323&r2=65324&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/LowerConstantCalls.cpp (original) +++ vmkit/trunk/lib/JnJVM/VMCore/LowerConstantCalls.cpp Mon Feb 23 11:18:28 2009 @@ -461,6 +461,18 @@ V == module->ForceLoadedCheckFunction ) { Changed = true; CI->eraseFromParent(); + } else if (V == module->GetFinalInt8FieldFunction || + V == module->GetFinalInt16FieldFunction || + V == module->GetFinalInt32FieldFunction || + V == module->GetFinalLongFieldFunction || + V == module->GetFinalFloatFieldFunction || + V == module->GetFinalDoubleFieldFunction || + V == module->GetFinalObjectFieldFunction) { + Changed = true; + Value* val = Call.getArgument(0); + Value* res = new LoadInst(val, "", CI); + CI->replaceAllUsesWith(res); + CI->eraseFromParent(); } #ifdef ISOLATE_SHARING else if (V == module->GetCtpClassFunction) { From nicolas.geoffray at lip6.fr Mon Feb 23 09:55:58 2009 From: nicolas.geoffray at lip6.fr (Nicolas Geoffray) Date: Mon, 23 Feb 2009 17:55:58 -0000 Subject: [vmkit-commits] [vmkit] r65329 - in /vmkit/trunk/lib/JnJVM/VMCore: JavaJIT.cpp JavaJIT.h JnjvmModule.cpp JnjvmModule.h Message-ID: <200902231755.n1NHtwW1003660@zion.cs.uiuc.edu> Author: geoffray Date: Mon Feb 23 11:55:58 2009 New Revision: 65329 URL: http://llvm.org/viewvc/llvm-project?rev=65329&view=rev Log: Devirtualize virtual calls to final fields. Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.cpp vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.h vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.cpp vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.h Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.cpp URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.cpp?rev=65329&r1=65328&r2=65329&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.cpp (original) +++ vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.cpp Mon Feb 23 11:55:58 2009 @@ -77,18 +77,25 @@ ctpInfo->infoOfMethod(index, ACC_VIRTUAL, cl, meth); if ((cl && isFinal(cl->access)) || - (meth && (isFinal(meth->access) || isPrivate(meth->access)))) + (meth && (isFinal(meth->access) || isPrivate(meth->access)))) { return invokeSpecial(index); + } // If the method is in fact a method defined in an interface, // call invokeInterface instead. if (meth && isInterface(meth->classDef->access)) { return invokeInterface(index, true); } - -#if !defined(WITHOUT_VTABLE) + const UTF8* name = 0; Signdef* signature = ctpInfo->infoOfInterfaceOrVirtualMethod(index, name); + Value* obj = stack[signature->nbArguments].first; + JavaObject* source = module->getFinalObject(obj); + if (source) { + return invokeSpecial(index, source->getClass()); + } + +#if !defined(WITHOUT_VTABLE) Typedef* retTypedef = signature->getReturnType(); std::vector args; // size = [signature->nbIn + 3]; LLVMSignatureInfo* LSI = module->getSignatureInfo(signature); @@ -96,8 +103,9 @@ FunctionType::param_iterator it = virtualType->param_end(); makeArgs(it, index, args, signature->nbArguments + 1); const llvm::Type* retType = virtualType->getReturnType(); - - JITVerifyNull(args[0]); + + JITVerifyNull(args[0]); + BasicBlock* endBlock = 0; PHINode* node = 0; #if 0 @@ -1218,7 +1226,7 @@ return ret; } -void JavaJIT::invokeSpecial(uint16 index) { +void JavaJIT::invokeSpecial(uint16 index, CommonClass* finalCl) { JavaConstantPool* ctpInfo = compilingClass->ctpInfo; JavaMethod* meth = 0; Signdef* signature = 0; @@ -1230,13 +1238,27 @@ const llvm::FunctionType* virtualType = LSI->getVirtualType(); llvm::Instruction* val = 0; - std::vector args; + std::vector args; FunctionType::param_iterator it = virtualType->param_end(); makeArgs(it, index, args, signature->nbArguments + 1); + Function* func = 0; + + if (finalCl) { + Class* lookup = finalCl->isArray() ? finalCl->super : finalCl->asClass(); + + meth = lookup->lookupMethodDontThrow(name, signature->keyName, false, true, + 0); + if (meth) { + // don't throw if no meth, the exception will be thrown just in time + JnjvmModule* M = compilingClass->classLoader->getModule(); + func = M->getMethod(meth); + } + } - Function* func = - (Function*)ctpInfo->infoOfStaticOrSpecialMethod(index, ACC_VIRTUAL, - signature, meth); + if (!func) { + func = (Function*)ctpInfo->infoOfStaticOrSpecialMethod(index, ACC_VIRTUAL, + signature, meth); + } if (meth == compilingClass->classLoader->bootstrapLoader->upcalls->InitObject) return; Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.h URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.h?rev=65329&r1=65328&r2=65329&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.h (original) +++ vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.h Mon Feb 23 11:55:58 2009 @@ -365,7 +365,7 @@ void invokeInterface(uint16 index, bool buggyVirtual = false); /// invokeSpecial - Invoke an instance Java method directly. - void invokeSpecial(uint16 index); + void invokeSpecial(uint16 index, CommonClass* finalCl = 0); /// invokeStatic - Invoke a static Java method. void invokeStatic(uint16 index); Modified: vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.cpp URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.cpp?rev=65329&r1=65328&r2=65329&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.cpp (original) +++ vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.cpp Mon Feb 23 11:55:58 2009 @@ -310,6 +310,21 @@ } } +JavaObject* JnjvmModule::getFinalObject(llvm::Value* obj) { + if (staticCompilation) { + abort(); + } else { + if (ConstantExpr* CE = dyn_cast(obj)) { + if (ConstantInt* C = dyn_cast(CE->getOperand(0))) { + return (JavaObject*)C->getZExtValue(); + } + } + } + return 0; +} + + + Constant* JnjvmModule::getFinalObject(JavaObject* obj) { if (staticCompilation) { final_object_iterator End = finalObjects.end(); Modified: vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.h URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.h?rev=65329&r1=65328&r2=65329&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.h (original) +++ vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.h Mon Feb 23 11:55:58 2009 @@ -424,6 +424,7 @@ void printStats(); llvm::Constant* getFinalObject(JavaObject* obj); + JavaObject* getFinalObject(llvm::Value* C); llvm::Constant* getNativeClass(CommonClass* cl); llvm::Constant* getJavaClass(CommonClass* cl); llvm::Constant* getStaticInstance(Class* cl); From nicolas.geoffray at lip6.fr Mon Feb 23 09:59:47 2009 From: nicolas.geoffray at lip6.fr (Nicolas Geoffray) Date: Mon, 23 Feb 2009 17:59:47 -0000 Subject: [vmkit-commits] [vmkit] r65330 - /vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.cpp Message-ID: <200902231759.n1NHxlte003794@zion.cs.uiuc.edu> Author: geoffray Date: Mon Feb 23 11:59:47 2009 New Revision: 65330 URL: http://llvm.org/viewvc/llvm-project?rev=65330&view=rev Log: Unbreak vmjc. Modified: vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.cpp Modified: vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.cpp URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.cpp?rev=65330&r1=65329&r2=65330&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.cpp (original) +++ vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.cpp Mon Feb 23 11:59:47 2009 @@ -312,7 +312,7 @@ JavaObject* JnjvmModule::getFinalObject(llvm::Value* obj) { if (staticCompilation) { - abort(); + // TODO } else { if (ConstantExpr* CE = dyn_cast(obj)) { if (ConstantInt* C = dyn_cast(CE->getOperand(0))) { From nicolas.geoffray at lip6.fr Mon Feb 23 13:17:38 2009 From: nicolas.geoffray at lip6.fr (Nicolas Geoffray) Date: Mon, 23 Feb 2009 21:17:38 -0000 Subject: [vmkit-commits] [vmkit] r65338 - /vmkit/trunk/lib/JnJVM/VMCore/Zip.cpp Message-ID: <200902232117.n1NLHcGp012037@zion.cs.uiuc.edu> Author: geoffray Date: Mon Feb 23 15:17:38 2009 New Revision: 65338 URL: http://llvm.org/viewvc/llvm-project?rev=65338&view=rev Log: Return after copying the raw data. Modified: vmkit/trunk/lib/JnJVM/VMCore/Zip.cpp Modified: vmkit/trunk/lib/JnJVM/VMCore/Zip.cpp URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/Zip.cpp?rev=65338&r1=65337&r2=65338&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/Zip.cpp (original) +++ vmkit/trunk/lib/JnJVM/VMCore/Zip.cpp Mon Feb 23 15:17:38 2009 @@ -180,6 +180,7 @@ if (file->compressionMethod == ZIP_STORE) { memcpy(ptr, &(reader.bytes->elements[reader.cursor]), file->ucsize); + return 1; } else if (file->compressionMethod == ZIP_DEFLATE) { z_stream stre; sint32 err = 0; From nicolas.geoffray at lip6.fr Mon Feb 23 13:21:50 2009 From: nicolas.geoffray at lip6.fr (Nicolas Geoffray) Date: Mon, 23 Feb 2009 21:21:50 -0000 Subject: [vmkit-commits] [vmkit] r65339 - in /vmkit/trunk/lib/JnJVM/VMCore: JavaClass.cpp JavaClass.h Message-ID: <200902232121.n1NLLo3T012167@zion.cs.uiuc.edu> Author: geoffray Date: Mon Feb 23 15:21:49 2009 New Revision: 65339 URL: http://llvm.org/viewvc/llvm-project?rev=65339&view=rev Log: Provide static functions to create jni function names. Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaClass.cpp vmkit/trunk/lib/JnJVM/VMCore/JavaClass.h Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaClass.cpp URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JavaClass.cpp?rev=65339&r1=65338&r2=65339&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/JavaClass.cpp (original) +++ vmkit/trunk/lib/JnJVM/VMCore/JavaClass.cpp Mon Feb 23 15:21:49 2009 @@ -1092,9 +1092,10 @@ return cl; } -void JavaMethod::jniConsFromMeth(char* buf) const { - const UTF8* jniConsClName = classDef->name; - const UTF8* jniConsName = name; +void JavaMethod::jniConsFromMeth(char* buf, const UTF8* jniConsClName, + const UTF8* jniConsName, + const UTF8* jniConsType, + bool synthetic) { sint32 clen = jniConsClName->size; sint32 mnlen = jniConsName->size; @@ -1135,10 +1136,10 @@ } -void JavaMethod::jniConsFromMethOverloaded(char* buf) const { - const UTF8* jniConsClName = classDef->name; - const UTF8* jniConsName = name; - const UTF8* jniConsType = type; +void JavaMethod::jniConsFromMethOverloaded(char* buf, const UTF8* jniConsClName, + const UTF8* jniConsName, + const UTF8* jniConsType, + bool synthetic) { sint32 clen = jniConsClName->size; sint32 mnlen = jniConsName->size; @@ -1204,7 +1205,7 @@ } } - if (isSynthetic(access)) { + if (synthetic) { ptr[0] = 'S'; ++ptr; } Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaClass.h URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JavaClass.h?rev=65339&r1=65338&r2=65339&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/JavaClass.h (original) +++ vmkit/trunk/lib/JnJVM/VMCore/JavaClass.h Mon Feb 23 15:21:49 2009 @@ -1032,12 +1032,30 @@ /// jniConsFromMeth - Construct the JNI name of this method as if /// there is no other function in the class with the same name. /// - void jniConsFromMeth(char* buf) const; + void jniConsFromMeth(char* buf) const { + jniConsFromMeth(buf, classDef->name, name, type, isSynthetic(access)); + } /// jniConsFromMethOverloaded - Construct the JNI name of this method /// as if its name is overloaded in the class. /// - void jniConsFromMethOverloaded(char* buf) const; + void jniConsFromMethOverloaded(char* buf) const { + jniConsFromMethOverloaded(buf, classDef->name, name, type, + isSynthetic(access)); + } + + /// jniConsFromMeth - Construct the non-overloaded JNI name with + /// the given name and type. + /// + static void jniConsFromMeth(char* buf, const UTF8* clName, const UTF8* name, + const UTF8* sign, bool synthetic); + + /// jniConsFromMethOverloaded - Construct the overloaded JNI name with + /// the given name and type. + /// + static void jniConsFromMethOverloaded(char* buf, const UTF8* clName, + const UTF8* name, const UTF8* sign, + bool synthetic); /// getParameterTypes - Get the java.lang.Class of the parameters of /// the method, with the given class loader. From nicolas.geoffray at lip6.fr Wed Feb 25 03:13:29 2009 From: nicolas.geoffray at lip6.fr (Nicolas Geoffray) Date: Wed, 25 Feb 2009 11:13:29 -0000 Subject: [vmkit-commits] [vmkit] r65441 - /vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.h Message-ID: <200902251113.n1PBDUYN014557@zion.cs.uiuc.edu> Author: geoffray Date: Wed Feb 25 05:13:23 2009 New Revision: 65441 URL: http://llvm.org/viewvc/llvm-project?rev=65441&view=rev Log: Add some compilation flags for AOT. Modified: vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.h Modified: vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.h URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.h?rev=65441&r1=65440&r2=65441&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.h (original) +++ vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.h Wed Feb 25 05:13:23 2009 @@ -232,6 +232,7 @@ bool staticCompilation; + bool enabledException; #ifdef WITH_TRACER llvm::Function* makeTracer(Class* cl, bool stat); @@ -249,11 +250,23 @@ public: static llvm::Function* NativeLoader; + + bool generateTracers; + bool generateStubs; + bool assumeCompiled; bool isStaticCompiling() { return staticCompilation; } + bool hasExceptionsEnabled() { + return enabledException; + } + + void disableExceptions() { + enabledException = false; + } + void setIsStaticCompiling(bool sc) { staticCompilation = sc; } From nicolas.geoffray at lip6.fr Wed Feb 25 03:14:51 2009 From: nicolas.geoffray at lip6.fr (Nicolas Geoffray) Date: Wed, 25 Feb 2009 11:14:51 -0000 Subject: [vmkit-commits] [vmkit] r65442 - /vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.cpp Message-ID: <200902251114.n1PBEpf9014607@zion.cs.uiuc.edu> Author: geoffray Date: Wed Feb 25 05:14:50 2009 New Revision: 65442 URL: http://llvm.org/viewvc/llvm-project?rev=65442&view=rev Log: Change the way of emitting things during AOT based on the module flags. Modified: vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.cpp Modified: vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.cpp URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.cpp?rev=65442&r1=65441&r2=65442&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.cpp (original) +++ vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.cpp Wed Feb 25 05:14:50 2009 @@ -123,7 +123,9 @@ if (staticCompilation) { if (classDef->isClass() || - (classDef->isArray() && isCompiling(classDef))) { + (classDef->isArray() && isCompiling(classDef)) || + (assumeCompiled && !(classDef->isArray() && + classDef->asArrayClass()->baseClass()->isPrimitive()))) { native_class_iterator End = nativeClasses.end(); native_class_iterator I = nativeClasses.find(classDef); if (I == End) { @@ -139,7 +141,7 @@ new GlobalVariable(Ty, false, GlobalValue::ExternalLinkage, 0, classDef->printString(), this); - nativeClasses.insert(std::make_pair((Class*)classDef, varGV)); + nativeClasses.insert(std::make_pair(classDef, varGV)); if (classDef->isClass() && isCompiling(classDef->asClass())) { Constant* C = CreateConstantFromClass((Class*)classDef); @@ -554,6 +556,10 @@ #ifdef WITH_TRACER llvm::Function* JnjvmModule::makeTracer(Class* cl, bool stat) { + if (isStaticCompiling() && !generateTracers) { + return JavaObjectTracerFunction; + } + LLVMClassInfo* LCI = (LLVMClassInfo*)getClassInfo(cl); const Type* type = stat ? LCI->getStaticType() : LCI->getVirtualType(); JavaField* fields = 0; @@ -2311,6 +2317,10 @@ MvmModule(ModuleID) { staticCompilation = sc; + generateTracers = true; + generateStubs = true; + enabledException = true; + assumeCompiled = false; if (!VTType) initialise(); Module* module = initialModule; From nicolas.geoffray at lip6.fr Wed Feb 25 03:15:57 2009 From: nicolas.geoffray at lip6.fr (Nicolas Geoffray) Date: Wed, 25 Feb 2009 11:15:57 -0000 Subject: [vmkit-commits] [vmkit] r65443 - /vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.cpp Message-ID: <200902251115.n1PBFvKN014648@zion.cs.uiuc.edu> Author: geoffray Date: Wed Feb 25 05:15:57 2009 New Revision: 65443 URL: http://llvm.org/viewvc/llvm-project?rev=65443&view=rev Log: During AOT, get all the Functions before compiling them, so that an LLVM pass can reason on them. Modified: vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.cpp Modified: vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.cpp URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.cpp?rev=65443&r1=65442&r2=65443&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.cpp (original) +++ vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.cpp Wed Feb 25 05:15:57 2009 @@ -1102,21 +1102,23 @@ static void compileClass(Class* cl) { + JnjvmModule* Mod = cl->classLoader->getModule(); + // Make sure the class is emitted. - cl->classLoader->getModule()->getNativeClass(cl); + Mod->getNativeClass(cl); for (uint32 i = 0; i < cl->nbVirtualMethods; ++i) { JavaMethod& meth = cl->virtualMethods[i]; if (!isAbstract(meth.access)) cl->classLoader->getModuleProvider()->parseFunction(&meth); - meth.getSignature()->compileAllStubs(); + if (Mod->generateStubs) meth.getSignature()->compileAllStubs(); } for (uint32 i = 0; i < cl->nbStaticMethods; ++i) { JavaMethod& meth = cl->staticMethods[i]; if (!isAbstract(meth.access)) cl->classLoader->getModuleProvider()->parseFunction(&meth); - meth.getSignature()->compileAllStubs(); + if (Mod->generateStubs) meth.getSignature()->compileAllStubs(); } } @@ -1173,6 +1175,17 @@ Class* cl = *i; cl->resolveClass(); cl->setOwnerClass(JavaThread::get()); + + for (uint32 i = 0; i < cl->nbVirtualMethods; ++i) { + LLVMMethodInfo* LMI = M->getMethodInfo(&cl->virtualMethods[i]); + LMI->getMethod(); + } + + for (uint32 i = 0; i < cl->nbStaticMethods; ++i) { + LLVMMethodInfo* LMI = M->getMethodInfo(&cl->staticMethods[i]); + LMI->getMethod(); + } + } for (std::vector::iterator i = classes.begin(), e = classes.end(); From nicolas.geoffray at lip6.fr Wed Feb 25 03:17:53 2009 From: nicolas.geoffray at lip6.fr (Nicolas Geoffray) Date: Wed, 25 Feb 2009 11:17:53 -0000 Subject: [vmkit-commits] [vmkit] r65444 - in /vmkit/trunk/lib/JnJVM/VMCore: ExceptionsCheck.inc JavaJIT.cpp JavaJITOpcodes.cpp Message-ID: <200902251117.n1PBHs0W014717@zion.cs.uiuc.edu> Author: geoffray Date: Wed Feb 25 05:17:51 2009 New Revision: 65444 URL: http://llvm.org/viewvc/llvm-project?rev=65444&view=rev Log: Disable exceptions if the module says so. Modified: vmkit/trunk/lib/JnJVM/VMCore/ExceptionsCheck.inc vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.cpp vmkit/trunk/lib/JnJVM/VMCore/JavaJITOpcodes.cpp Modified: vmkit/trunk/lib/JnJVM/VMCore/ExceptionsCheck.inc URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/ExceptionsCheck.inc?rev=65444&r1=65443&r2=65444&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/ExceptionsCheck.inc (original) +++ vmkit/trunk/lib/JnJVM/VMCore/ExceptionsCheck.inc Wed Feb 25 05:17:51 2009 @@ -4,33 +4,36 @@ Instruction* res = CallInst::Create(F, args.begin(), args.end(), Name, InsertAtEnd); - Value* threadId = getCurrentThread(); - Value* geps[2] = { module->constantZero, - module->OffsetJavaExceptionInThreadConstant }; + + if (module->hasExceptionsEnabled()) { + Value* threadId = getCurrentThread(); + Value* geps[2] = { module->constantZero, + module->OffsetJavaExceptionInThreadConstant }; - Value* javaExceptionPtr = GetElementPtrInst::Create(threadId, geps, - geps + 2, "", - currentBlock); + Value* javaExceptionPtr = GetElementPtrInst::Create(threadId, geps, + geps + 2, "", + currentBlock); - // Get the Java exception. - Value* obj = new LoadInst(javaExceptionPtr, "", currentBlock); + // Get the Java exception. + Value* obj = new LoadInst(javaExceptionPtr, "", currentBlock); - BasicBlock* ifNormal = createBasicBlock("no exception block"); + BasicBlock* ifNormal = createBasicBlock("no exception block"); - Constant* zero = module->JavaObjectNullConstant; - Value* test = new ICmpInst(ICmpInst::ICMP_NE, obj, zero, "", - currentBlock); + Constant* zero = module->JavaObjectNullConstant; + Value* test = new ICmpInst(ICmpInst::ICMP_NE, obj, zero, "", + currentBlock); - BranchInst::Create(currentExceptionBlock, ifNormal, test, currentBlock); + BranchInst::Create(currentExceptionBlock, ifNormal, test, currentBlock); - if (!currentExceptionBlock->empty()) { - Instruction* insn = currentExceptionBlock->begin(); - PHINode* node = dyn_cast(insn); - if (node) node->addIncoming(obj, currentBlock); - } + if (!currentExceptionBlock->empty()) { + Instruction* insn = currentExceptionBlock->begin(); + PHINode* node = dyn_cast(insn); + if (node) node->addIncoming(obj, currentBlock); + } - currentBlock = ifNormal; + currentBlock = ifNormal; + } return res; } @@ -39,32 +42,35 @@ BasicBlock *InsertAtEnd) { Instruction* res = CallInst::Create(F, arg1, Name, InsertAtEnd); - Value* threadId = getCurrentThread(); - Value* geps[2] = { module->constantZero, - module->OffsetJavaExceptionInThreadConstant }; + + if (module->hasExceptionsEnabled()) { + Value* threadId = getCurrentThread(); + Value* geps[2] = { module->constantZero, + module->OffsetJavaExceptionInThreadConstant }; - Value* javaExceptionPtr = GetElementPtrInst::Create(threadId, geps, - geps + 2, "", - currentBlock); + Value* javaExceptionPtr = GetElementPtrInst::Create(threadId, geps, + geps + 2, "", + currentBlock); - // Get the Java exception. - Value* obj = new LoadInst(javaExceptionPtr, "", currentBlock); + // Get the Java exception. + Value* obj = new LoadInst(javaExceptionPtr, "", currentBlock); - BasicBlock* ifNormal = createBasicBlock("no exception block"); + BasicBlock* ifNormal = createBasicBlock("no exception block"); - Constant* zero = module->JavaObjectNullConstant; - Value* test = new ICmpInst(ICmpInst::ICMP_NE, obj, zero, "", - currentBlock); + Constant* zero = module->JavaObjectNullConstant; + Value* test = new ICmpInst(ICmpInst::ICMP_NE, obj, zero, "", + currentBlock); - BranchInst::Create(currentExceptionBlock, ifNormal, test, currentBlock); + BranchInst::Create(currentExceptionBlock, ifNormal, test, currentBlock); - if (!currentExceptionBlock->empty()) { - Instruction* insn = currentExceptionBlock->begin(); - PHINode* node = dyn_cast(insn); - if (node) node->addIncoming(obj, currentBlock); - } + if (!currentExceptionBlock->empty()) { + Instruction* insn = currentExceptionBlock->begin(); + PHINode* node = dyn_cast(insn); + if (node) node->addIncoming(obj, currentBlock); + } - currentBlock = ifNormal; + currentBlock = ifNormal; + } return res; } @@ -76,32 +82,34 @@ Instruction* res = CallInst::Create(F, args, args + 2, Name, InsertAtEnd); - Value* threadId = getCurrentThread(); - Value* geps[2] = { module->constantZero, - module->OffsetJavaExceptionInThreadConstant }; + if (module->hasExceptionsEnabled()) { + Value* threadId = getCurrentThread(); + Value* geps[2] = { module->constantZero, + module->OffsetJavaExceptionInThreadConstant }; - Value* javaExceptionPtr = GetElementPtrInst::Create(threadId, geps, - geps + 2, "", - currentBlock); + Value* javaExceptionPtr = GetElementPtrInst::Create(threadId, geps, + geps + 2, "", + currentBlock); - // Get the Java exception. - Value* obj = new LoadInst(javaExceptionPtr, "", currentBlock); + // Get the Java exception. + Value* obj = new LoadInst(javaExceptionPtr, "", currentBlock); - BasicBlock* ifNormal = createBasicBlock("no exception block"); + BasicBlock* ifNormal = createBasicBlock("no exception block"); - Constant* zero = module->JavaObjectNullConstant; - Value* test = new ICmpInst(ICmpInst::ICMP_NE, obj, zero, "", - currentBlock); + Constant* zero = module->JavaObjectNullConstant; + Value* test = new ICmpInst(ICmpInst::ICMP_NE, obj, zero, "", + currentBlock); - BranchInst::Create(currentExceptionBlock, ifNormal, test, currentBlock); + BranchInst::Create(currentExceptionBlock, ifNormal, test, currentBlock); - if (!currentExceptionBlock->empty()) { - Instruction* insn = currentExceptionBlock->begin(); - PHINode* node = dyn_cast(insn); - if (node) node->addIncoming(obj, currentBlock); - } + if (!currentExceptionBlock->empty()) { + Instruction* insn = currentExceptionBlock->begin(); + PHINode* node = dyn_cast(insn); + if (node) node->addIncoming(obj, currentBlock); + } - currentBlock = ifNormal; + currentBlock = ifNormal; + } return res; } @@ -109,32 +117,35 @@ Instruction* JavaJIT::invoke(Value *F, const char* Name, BasicBlock *InsertAtEnd) { Instruction* res = llvm::CallInst::Create(F, Name, InsertAtEnd); - Value* threadId = getCurrentThread(); - Value* geps[2] = { module->constantZero, - module->OffsetJavaExceptionInThreadConstant }; + + if (module->hasExceptionsEnabled()) { + Value* threadId = getCurrentThread(); + Value* geps[2] = { module->constantZero, + module->OffsetJavaExceptionInThreadConstant }; - Value* javaExceptionPtr = GetElementPtrInst::Create(threadId, geps, - geps + 2, "", - currentBlock); + Value* javaExceptionPtr = GetElementPtrInst::Create(threadId, geps, + geps + 2, "", + currentBlock); - // Get the Java exception. - Value* obj = new LoadInst(javaExceptionPtr, "", currentBlock); + // Get the Java exception. + Value* obj = new LoadInst(javaExceptionPtr, "", currentBlock); - BasicBlock* ifNormal = createBasicBlock("no exception block"); + BasicBlock* ifNormal = createBasicBlock("no exception block"); - Constant* zero = module->JavaObjectNullConstant; - Value* test = new ICmpInst(ICmpInst::ICMP_NE, obj, zero, "", - currentBlock); + Constant* zero = module->JavaObjectNullConstant; + Value* test = new ICmpInst(ICmpInst::ICMP_NE, obj, zero, "", + currentBlock); - BranchInst::Create(currentExceptionBlock, ifNormal, test, currentBlock); + BranchInst::Create(currentExceptionBlock, ifNormal, test, currentBlock); - if (!currentExceptionBlock->empty()) { - Instruction* insn = currentExceptionBlock->begin(); - PHINode* node = dyn_cast(insn); - if (node) node->addIncoming(obj, currentBlock); - } + if (!currentExceptionBlock->empty()) { + Instruction* insn = currentExceptionBlock->begin(); + PHINode* node = dyn_cast(insn); + if (node) node->addIncoming(obj, currentBlock); + } - currentBlock = ifNormal; + currentBlock = ifNormal; + } return res; } Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.cpp URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.cpp?rev=65444&r1=65443&r2=65444&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.cpp (original) +++ vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.cpp Wed Feb 25 05:17:51 2009 @@ -882,7 +882,7 @@ compilingMethod->printString()); #ifndef DWARF_EXCEPTIONS - if (codeLen < 5 && !callsStackWalker) + if (codeLen < 5 && !callsStackWalker && !module->isStaticCompiling()) compilingMethod->canBeInlined = true; #endif @@ -970,18 +970,20 @@ void JavaJIT::JITVerifyNull(Value* obj) { - Constant* zero = module->JavaObjectNullConstant; - Value* test = new ICmpInst(ICmpInst::ICMP_EQ, obj, zero, "", - currentBlock); + if (module->hasExceptionsEnabled()) { + Constant* zero = module->JavaObjectNullConstant; + Value* test = new ICmpInst(ICmpInst::ICMP_EQ, obj, zero, "", + currentBlock); - BasicBlock* exit = createBasicBlock("verifyNullExit"); - BasicBlock* cont = createBasicBlock("verifyNullCont"); + BasicBlock* exit = createBasicBlock("verifyNullExit"); + BasicBlock* cont = createBasicBlock("verifyNullCont"); - BranchInst::Create(exit, cont, test, currentBlock); - currentBlock = exit; - throwException(module->NullPointerExceptionFunction, 0, 0); - currentBlock = cont; - + BranchInst::Create(exit, cont, test, currentBlock); + currentBlock = exit; + throwException(module->NullPointerExceptionFunction, 0, 0); + currentBlock = cont; + } + } Value* JavaJIT::verifyAndComputePtr(Value* obj, Value* index, @@ -992,7 +994,7 @@ index = new SExtInst(index, Type::Int32Ty, "", currentBlock); } - if (true) { + if (module->hasExceptionsEnabled()) { Value* size = arraySize(obj); Value* cmp = new ICmpInst(ICmpInst::ICMP_ULT, index, size, "", Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaJITOpcodes.cpp URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JavaJITOpcodes.cpp?rev=65444&r1=65443&r2=65444&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/JavaJITOpcodes.cpp (original) +++ vmkit/trunk/lib/JnJVM/VMCore/JavaJITOpcodes.cpp Wed Feb 25 05:17:51 2009 @@ -1896,28 +1896,30 @@ } Value* arg1 = popAsInt(); - Value* cmp = new ICmpInst(ICmpInst::ICMP_SLT, arg1, - module->constantZero, "", currentBlock); - - BasicBlock* BB1 = createBasicBlock(""); - BasicBlock* BB2 = createBasicBlock(""); - - BranchInst::Create(BB1, BB2, cmp, currentBlock); - currentBlock = BB1; - throwException(module->NegativeArraySizeExceptionFunction, arg1); - currentBlock = BB2; - - cmp = new ICmpInst(ICmpInst::ICMP_SGT, arg1, - module->MaxArraySizeConstant, - "", currentBlock); - - BB1 = createBasicBlock(""); - BB2 = createBasicBlock(""); - - BranchInst::Create(BB1, BB2, cmp, currentBlock); - currentBlock = BB1; - throwException(module->OutOfMemoryErrorFunction, arg1); - currentBlock = BB2; + if (module->hasExceptionsEnabled()) { + Value* cmp = new ICmpInst(ICmpInst::ICMP_SLT, arg1, + module->constantZero, "", currentBlock); + + BasicBlock* BB1 = createBasicBlock(""); + BasicBlock* BB2 = createBasicBlock(""); + + BranchInst::Create(BB1, BB2, cmp, currentBlock); + currentBlock = BB1; + throwException(module->NegativeArraySizeExceptionFunction, arg1); + currentBlock = BB2; + + cmp = new ICmpInst(ICmpInst::ICMP_SGT, arg1, + module->MaxArraySizeConstant, + "", currentBlock); + + BB1 = createBasicBlock(""); + BB2 = createBasicBlock(""); + + BranchInst::Create(BB1, BB2, cmp, currentBlock); + currentBlock = BB1; + throwException(module->OutOfMemoryErrorFunction, arg1); + currentBlock = BB2; + } Value* mult = BinaryOperator::CreateMul(arg1, sizeElement, "", currentBlock); @@ -1973,6 +1975,11 @@ } case CHECKCAST : + if (!module->hasExceptionsEnabled()) { + i += 2; + break; + } + case INSTANCEOF : { bool checkcast = (bytecodes[i] == CHECKCAST); From nicolas.geoffray at lip6.fr Wed Feb 25 04:44:48 2009 From: nicolas.geoffray at lip6.fr (Nicolas Geoffray) Date: Wed, 25 Feb 2009 12:44:48 -0000 Subject: [vmkit-commits] [vmkit] r65449 - in /vmkit/trunk/www: get_involved.html get_started.html index.html Message-ID: <200902251244.n1PCimL0017670@zion.cs.uiuc.edu> Author: geoffray Date: Wed Feb 25 06:44:46 2009 New Revision: 65449 URL: http://llvm.org/viewvc/llvm-project?rev=65449&view=rev Log: Update status. Modified: vmkit/trunk/www/get_involved.html vmkit/trunk/www/get_started.html vmkit/trunk/www/index.html Modified: vmkit/trunk/www/get_involved.html URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/www/get_involved.html?rev=65449&r1=65448&r2=65449&view=diff ============================================================================== --- vmkit/trunk/www/get_involved.html (original) +++ vmkit/trunk/www/get_involved.html Wed Feb 25 06:44:46 2009 @@ -77,11 +77,6 @@
  • Write a test-suite and nightly tester for vmkit: vmkit needs it!
  • -
  • Port vmkit to new architectures: currently, vmkit runs on linux/x86, -MacOSX/x86 and has some floating point issues on linux/powerpc . -See PR642. -
  • -
  • Implement a generational GC in llvm/vmkit: llvm has the interface for GC support for static compilation, but not just in time. And since llvm is object layout-agnostic, vmkit needs to plug in its object layout somewhere. @@ -94,10 +89,6 @@
  • Investigate hotspot-ing in llvm/vmkit: vmkit has a compile-only approach. This resuts in a high startup penalty.
  • -
  • Implement a llvm/clang/vmkit 'libgcc': vmkit uses the unwinding -runtime of GCC. So it is strongly dependent on GCC. Implementing the -unwind functions in llvm will help port vmkit to other compilers.
  • -

If you hit a bug with vmkit, it is very useful for us if you reduce the code Modified: vmkit/trunk/www/get_started.html URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/www/get_started.html?rev=65449&r1=65448&r2=65449&view=diff ============================================================================== --- vmkit/trunk/www/get_started.html (original) +++ vmkit/trunk/www/get_started.html Wed Feb 25 06:44:46 2009 @@ -85,7 +85,7 @@

  • svn co http://llvm.org/svn/llvm-project/llvm/trunk llvm
  • cd llvm
  • -
  • ./configure; make REQUIRES_EH=1
  • +
  • ./configure; make
Modified: vmkit/trunk/www/index.html URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/www/index.html?rev=65449&r1=65448&r2=65449&view=diff ============================================================================== --- vmkit/trunk/www/index.html (original) +++ vmkit/trunk/www/index.html Wed Feb 25 06:44:46 2009 @@ -122,6 +122,12 @@ Apache projects (e.g. OSGi Felix and Tomcat) and the SPECJVM98 benchmark. The CLI implementation is still in its early stages, but can execute simple applications.

+ +

The JVM has been tested on Linux/x64, Linux/x86, Linux/ppc32, MacOSX/x64, + MacOSX/x86, MacOSX/ppc32. The JVM may work on ppc64. Support for + Windows has not been investigated +

+

Get it and get involved!

From nicolas.geoffray at lip6.fr Wed Feb 25 05:44:51 2009 From: nicolas.geoffray at lip6.fr (Nicolas Geoffray) Date: Wed, 25 Feb 2009 13:44:51 -0000 Subject: [vmkit-commits] [vmkit] r65450 - /vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.h Message-ID: <200902251344.n1PDipuD019700@zion.cs.uiuc.edu> Author: geoffray Date: Wed Feb 25 07:44:50 2009 New Revision: 65450 URL: http://llvm.org/viewvc/llvm-project?rev=65450&view=rev Log: Fix includes. Modified: vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.h Modified: vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.h URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.h?rev=65450&r1=65449&r2=65450&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.h (original) +++ vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.h Wed Feb 25 07:44:50 2009 @@ -15,7 +15,6 @@ #include "mvm/JIT.h" #include "JavaClass.h" -#include "JavaConstantPool.h" #include "JavaTypes.h" #include "llvm/Module.h" @@ -36,6 +35,7 @@ class CommonClass; class Class; class Enveloppe; +class JavaConstantPool; class JavaField; class JavaMethod; class JavaObject; From nicolas.geoffray at lip6.fr Wed Feb 25 05:45:56 2009 From: nicolas.geoffray at lip6.fr (Nicolas Geoffray) Date: Wed, 25 Feb 2009 13:45:56 -0000 Subject: [vmkit-commits] [vmkit] r65451 - /vmkit/trunk/lib/JnJVM/VMCore/JavaConstantPool.h Message-ID: <200902251345.n1PDju58019790@zion.cs.uiuc.edu> Author: geoffray Date: Wed Feb 25 07:45:56 2009 New Revision: 65451 URL: http://llvm.org/viewvc/llvm-project?rev=65451&view=rev Log: Fix includes. Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaConstantPool.h Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaConstantPool.h URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JavaConstantPool.h?rev=65451&r1=65450&r2=65451&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/JavaConstantPool.h (original) +++ vmkit/trunk/lib/JnJVM/VMCore/JavaConstantPool.h Wed Feb 25 07:45:56 2009 @@ -10,7 +10,7 @@ #ifndef JNJVM_JAVA_CONSTANT_POOL_H #define JNJVM_JAVA_CONSTANT_POOL_H -#include "mvm/Object.h" +#include "mvm/Allocator.h" #include "types.h" From nicolas.geoffray at lip6.fr Wed Feb 25 05:53:39 2009 From: nicolas.geoffray at lip6.fr (Nicolas Geoffray) Date: Wed, 25 Feb 2009 13:53:39 -0000 Subject: [vmkit-commits] [vmkit] r65452 - in /vmkit/trunk/lib/JnJVM/VMCore: JavaTypes.cpp JavaTypes.h Message-ID: <200902251353.n1PDrdGN020158@zion.cs.uiuc.edu> Author: geoffray Date: Wed Feb 25 07:53:39 2009 New Revision: 65452 URL: http://llvm.org/viewvc/llvm-project?rev=65452&view=rev Log: Code cleanup. No functionality changes. Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaTypes.cpp vmkit/trunk/lib/JnJVM/VMCore/JavaTypes.h Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaTypes.cpp URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JavaTypes.cpp?rev=65452&r1=65451&r2=65452&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/JavaTypes.cpp (original) +++ vmkit/trunk/lib/JnJVM/VMCore/JavaTypes.cpp Wed Feb 25 07:53:39 2009 @@ -21,11 +21,11 @@ } void ArrayTypedef::tPrintBuf(mvm::PrintBuffer* buf) const { - CommonClass::printClassName(keyName, buf); + UserCommonClass::printClassName(keyName, buf); } void ObjectTypedef::tPrintBuf(mvm::PrintBuffer* buf) const { - CommonClass::printClassName(pseudoAssocClassName, buf); + UserCommonClass::printClassName(pseudoAssocClassName, buf); } const char* Typedef::printString() const { @@ -67,11 +67,11 @@ return buf->contents()->cString(); } -void Signdef::printWithSign(CommonClass* cl, const UTF8* name, +void Signdef::printWithSign(UserCommonClass* cl, const UTF8* name, mvm::PrintBuffer* buf) const { getReturnType()->tPrintBuf(buf); buf->write(" "); - CommonClass::printClassName(cl->name, buf); + UserCommonClass::printClassName(cl->name, buf); buf->write("::"); name->printUTF8(buf); humanPrintArgs(buf); Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaTypes.h URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JavaTypes.h?rev=65452&r1=65451&r2=65452&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/JavaTypes.h (original) +++ vmkit/trunk/lib/JnJVM/VMCore/JavaTypes.h Wed Feb 25 07:53:39 2009 @@ -13,24 +13,12 @@ #include "types.h" #include "mvm/Allocator.h" -#include "mvm/Object.h" - -#include "JnjvmClassLoader.h" namespace jnjvm { -class Classpath; -class ClassArray; -class CommonClass; -class JavaArray; -class JavaJIT; -class JavaObject; -class Jnjvm; -class JnjvmBootstrapLoader; +class UserCommonClass; class JnjvmClassLoader; -class UserClassArray; class UserClassPrimitive; -class UserCommonClass; class UTF8; class UTF8Map; @@ -288,7 +276,7 @@ /// printWithSign - Print the signature of a method with the method's class /// and name. /// - void printWithSign(CommonClass* cl, const UTF8* name, + void printWithSign(UserCommonClass* cl, const UTF8* name, mvm::PrintBuffer* buf) const; /// Signdef - Create a new Signdef. From nicolas.geoffray at lip6.fr Wed Feb 25 05:55:41 2009 From: nicolas.geoffray at lip6.fr (Nicolas Geoffray) Date: Wed, 25 Feb 2009 13:55:41 -0000 Subject: [vmkit-commits] [vmkit] r65453 - /vmkit/trunk/lib/JnJVM/VMCore/LockedMap.h Message-ID: <200902251355.n1PDtfhx020251@zion.cs.uiuc.edu> Author: geoffray Date: Wed Feb 25 07:55:40 2009 New Revision: 65453 URL: http://llvm.org/viewvc/llvm-project?rev=65453&view=rev Log: Code cleanup. Modified: vmkit/trunk/lib/JnJVM/VMCore/LockedMap.h Modified: vmkit/trunk/lib/JnJVM/VMCore/LockedMap.h URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/LockedMap.h?rev=65453&r1=65452&r2=65453&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/LockedMap.h (original) +++ vmkit/trunk/lib/JnJVM/VMCore/LockedMap.h Wed Feb 25 07:55:40 2009 @@ -23,7 +23,6 @@ #include "types.h" #include "mvm/Allocator.h" -#include "mvm/Object.h" #include "mvm/PrintBuffer.h" #include "mvm/Threads/Locks.h" @@ -31,7 +30,6 @@ namespace jnjvm { -class JavaObject; class JavaString; class Signdef; class Typedef; From nicolas.geoffray at lip6.fr Wed Feb 25 06:33:00 2009 From: nicolas.geoffray at lip6.fr (Nicolas Geoffray) Date: Wed, 25 Feb 2009 14:33:00 -0000 Subject: [vmkit-commits] [vmkit] r65454 - in /vmkit/trunk/lib/JnJVM/VMCore: JavaJIT.h JnjvmClassLoader.cpp JnjvmModule.cpp JnjvmModule.h JnjvmModuleProvider.cpp LowerConstantCalls.cpp Message-ID: <200902251433.n1PEX1qt021694@zion.cs.uiuc.edu> Author: geoffray Date: Wed Feb 25 08:33:00 2009 New Revision: 65454 URL: http://llvm.org/viewvc/llvm-project?rev=65454&view=rev Log: Fix includes and code cleanup. Set the array name when AOT. Create the StaticInitializer in CreateStaticInitializer, if not created. Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.h vmkit/trunk/lib/JnJVM/VMCore/JnjvmClassLoader.cpp vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.cpp vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.h vmkit/trunk/lib/JnJVM/VMCore/JnjvmModuleProvider.cpp vmkit/trunk/lib/JnJVM/VMCore/LowerConstantCalls.cpp Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.h URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.h?rev=65454&r1=65453&r2=65454&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.h (original) +++ vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.h Wed Feb 25 08:33:00 2009 @@ -21,6 +21,7 @@ #include "types.h" +#include "JavaClass.h" #include "JnjvmModule.h" namespace jnjvm { Modified: vmkit/trunk/lib/JnJVM/VMCore/JnjvmClassLoader.cpp URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JnjvmClassLoader.cpp?rev=65454&r1=65453&r2=65454&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/JnjvmClassLoader.cpp (original) +++ vmkit/trunk/lib/JnJVM/VMCore/JnjvmClassLoader.cpp Wed Feb 25 08:33:00 2009 @@ -40,6 +40,7 @@ #include "JavaConstantPool.h" #include "JavaString.h" #include "JavaThread.h" +#include "JavaTypes.h" #include "JavaUpcalls.h" #include "Jnjvm.h" #include "JnjvmClassLoader.h" Modified: vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.cpp URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.cpp?rev=65454&r1=65453&r2=65454&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.cpp (original) +++ vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.cpp Wed Feb 25 08:33:00 2009 @@ -19,6 +19,7 @@ #include "mvm/JIT.h" #include "JavaCache.h" +#include "JavaConstantPool.h" #include "JavaJIT.h" #include "JavaString.h" #include "JavaThread.h" @@ -164,7 +165,8 @@ GlobalVariable* varGV = new GlobalVariable(Ty, false, GlobalValue::InternalLinkage, - Constant::getNullValue(Ty), "", this); + Constant::getNullValue(Ty), + classDef->printString(), this); arrayClasses.insert(std::make_pair((ClassArray*)classDef, varGV)); return varGV; @@ -2584,6 +2586,15 @@ Function* GetClassArray = Function::Create(FTy, GlobalValue::ExternalLinkage, "vmjcGetClassArray", this); + if (!StaticInitializer) { + std::vector llvmArgs; + llvmArgs.push_back(ptrType); // class loader. + const FunctionType* FTy = FunctionType::get(Type::VoidTy, llvmArgs, false); + + StaticInitializer = Function::Create(FTy, GlobalValue::InternalLinkage, + "Init", this); + } + BasicBlock* currentBlock = BasicBlock::Create("enter", StaticInitializer); Function::arg_iterator loader = StaticInitializer->arg_begin(); @@ -2649,3 +2660,19 @@ } } } + +LLVMSignatureInfo* JnjvmModule::getSignatureInfo(Signdef* sign) { + return sign->getInfo(); +} + +LLVMClassInfo* JnjvmModule::getClassInfo(Class* cl) { + return cl->getInfo(); +} + +LLVMFieldInfo* JnjvmModule::getFieldInfo(JavaField* field) { + return field->getInfo(); +} + +LLVMMethodInfo* JnjvmModule::getMethodInfo(JavaMethod* method) { + return method->getInfo(); +} Modified: vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.h URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.h?rev=65454&r1=65453&r2=65454&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.h (original) +++ vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.h Wed Feb 25 08:33:00 2009 @@ -12,11 +12,9 @@ #include +#include "mvm/Allocator.h" #include "mvm/JIT.h" -#include "JavaClass.h" -#include "JavaTypes.h" - #include "llvm/Module.h" namespace llvm { @@ -34,12 +32,18 @@ class CacheNode; class CommonClass; class Class; +class ClassArray; +class ClassPrimitive; class Enveloppe; class JavaConstantPool; class JavaField; class JavaMethod; class JavaObject; +class JavaString; class JnjvmModule; +class Typedef; +class Signdef; +class UTF8; class LLVMAssessorInfo { public: @@ -414,22 +418,10 @@ static void setMethod(JavaMethod* meth, void* ptr, const char* name); static llvm::Function* getMethod(JavaMethod* meth); - static LLVMSignatureInfo* getSignatureInfo(Signdef* sign) { - return sign->getInfo(); - } - - static LLVMClassInfo* getClassInfo(Class* cl) { - return cl->getInfo(); - } - - static LLVMFieldInfo* getFieldInfo(JavaField* field) { - return field->getInfo(); - } - - static LLVMMethodInfo* getMethodInfo(JavaMethod* method) { - return method->getInfo(); - } - + static LLVMSignatureInfo* getSignatureInfo(Signdef* sign); + static LLVMClassInfo* getClassInfo(Class* cl); + static LLVMFieldInfo* getFieldInfo(JavaField* field); + static LLVMMethodInfo* getMethodInfo(JavaMethod* method); static LLVMAssessorInfo& getTypedefInfo(const Typedef* type); explicit JnjvmModule(const std::string &ModuleID, bool sc = false); Modified: vmkit/trunk/lib/JnJVM/VMCore/JnjvmModuleProvider.cpp URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JnjvmModuleProvider.cpp?rev=65454&r1=65453&r2=65454&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/JnjvmModuleProvider.cpp (original) +++ vmkit/trunk/lib/JnJVM/VMCore/JnjvmModuleProvider.cpp Wed Feb 25 08:33:00 2009 @@ -20,6 +20,7 @@ #include "JavaConstantPool.h" #include "JavaJIT.h" #include "JavaThread.h" +#include "JavaTypes.h" #include "Jnjvm.h" #include "JnjvmModule.h" #include "JnjvmModuleProvider.h" Modified: vmkit/trunk/lib/JnJVM/VMCore/LowerConstantCalls.cpp URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/LowerConstantCalls.cpp?rev=65454&r1=65453&r2=65454&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/LowerConstantCalls.cpp (original) +++ vmkit/trunk/lib/JnJVM/VMCore/LowerConstantCalls.cpp Wed Feb 25 08:33:00 2009 @@ -15,6 +15,7 @@ #include "llvm/Support/Compiler.h" #include "llvm/Support/Debug.h" +#include "JavaClass.h" #include "JnjvmModule.h" using namespace llvm; From nicolas.geoffray at lip6.fr Wed Feb 25 07:42:10 2009 From: nicolas.geoffray at lip6.fr (Nicolas Geoffray) Date: Wed, 25 Feb 2009 15:42:10 -0000 Subject: [vmkit-commits] [vmkit] r65457 - in /vmkit/trunk: include/jnjvm/ lib/JnJVM/Compiler/ lib/JnJVM/VMCore/ tools/jnjvm/ tools/vmjc/ tools/vmkit/ Message-ID: <200902251542.n1PFgBiG024325@zion.cs.uiuc.edu> Author: geoffray Date: Wed Feb 25 09:42:09 2009 New Revision: 65457 URL: http://llvm.org/viewvc/llvm-project?rev=65457&view=rev Log: Reorganize things so that tools can better access Java-specific files. Especially, a tool now has access to the JnjvmModule and JnjvmModuleProvider classes. Added: vmkit/trunk/include/jnjvm/ vmkit/trunk/include/jnjvm/JnjvmModule.h - copied unchanged from r65455, vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.h vmkit/trunk/include/jnjvm/JnjvmModuleProvider.h - copied unchanged from r65455, vmkit/trunk/lib/JnJVM/VMCore/JnjvmModuleProvider.h vmkit/trunk/include/jnjvm/OpcodeNames.def - copied, changed from r65455, vmkit/trunk/lib/JnJVM/VMCore/OpcodeNames.def vmkit/trunk/lib/JnJVM/Compiler/ vmkit/trunk/lib/JnJVM/Compiler/ExceptionsCheck.inc - copied unchanged from r65455, vmkit/trunk/lib/JnJVM/VMCore/ExceptionsCheck.inc vmkit/trunk/lib/JnJVM/Compiler/ExceptionsDwarf.inc - copied unchanged from r65455, vmkit/trunk/lib/JnJVM/VMCore/ExceptionsDwarf.inc vmkit/trunk/lib/JnJVM/Compiler/JavaJIT.cpp - copied, changed from r65455, vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.cpp vmkit/trunk/lib/JnJVM/Compiler/JavaJIT.h - copied, changed from r65455, vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.h vmkit/trunk/lib/JnJVM/Compiler/JavaJITOpcodes.cpp - copied, changed from r65455, vmkit/trunk/lib/JnJVM/VMCore/JavaJITOpcodes.cpp vmkit/trunk/lib/JnJVM/Compiler/JnjvmModule.cpp - copied, changed from r65455, vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.cpp vmkit/trunk/lib/JnJVM/Compiler/JnjvmModuleProvider.cpp - copied, changed from r65455, vmkit/trunk/lib/JnJVM/VMCore/JnjvmModuleProvider.cpp vmkit/trunk/lib/JnJVM/Compiler/LowerConstantCalls.cpp - copied, changed from r65455, vmkit/trunk/lib/JnJVM/VMCore/LowerConstantCalls.cpp Removed: vmkit/trunk/lib/JnJVM/VMCore/ExceptionsCheck.inc vmkit/trunk/lib/JnJVM/VMCore/ExceptionsDwarf.inc vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.cpp vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.h vmkit/trunk/lib/JnJVM/VMCore/JavaJITOpcodes.cpp vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.cpp vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.h vmkit/trunk/lib/JnJVM/VMCore/JnjvmModuleProvider.cpp vmkit/trunk/lib/JnJVM/VMCore/JnjvmModuleProvider.h vmkit/trunk/lib/JnJVM/VMCore/LowerConstantCalls.cpp vmkit/trunk/lib/JnJVM/VMCore/OpcodeNames.def Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaRuntimeJIT.cpp vmkit/trunk/lib/JnJVM/VMCore/Makefile vmkit/trunk/tools/jnjvm/Makefile vmkit/trunk/tools/vmjc/Makefile vmkit/trunk/tools/vmkit/Makefile Copied: vmkit/trunk/include/jnjvm/OpcodeNames.def (from r65455, vmkit/trunk/lib/JnJVM/VMCore/OpcodeNames.def) URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/include/jnjvm/OpcodeNames.def?p2=vmkit/trunk/include/jnjvm/OpcodeNames.def&p1=vmkit/trunk/lib/JnJVM/VMCore/OpcodeNames.def&r1=65455&r2=65457&rev=65457&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/OpcodeNames.def (original) +++ vmkit/trunk/include/jnjvm/OpcodeNames.def Wed Feb 25 09:42:09 2009 @@ -10,7 +10,7 @@ #ifndef OPCODE_NAMES_DEF #define OPCODE_NAMES_DEF -const char* jnjvm::JavaJIT::OpcodeNames[256] = { +static const char* OpcodeNames[256] = { "NOP", "ACONST_NULL", "ICONST_M1", Copied: vmkit/trunk/lib/JnJVM/Compiler/JavaJIT.cpp (from r65455, vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.cpp) URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/Compiler/JavaJIT.cpp?p2=vmkit/trunk/lib/JnJVM/Compiler/JavaJIT.cpp&p1=vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.cpp&r1=65455&r2=65457&rev=65457&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.cpp (original) +++ vmkit/trunk/lib/JnJVM/Compiler/JavaJIT.cpp Wed Feb 25 09:42:09 2009 @@ -38,6 +38,8 @@ #include "Jnjvm.h" #include "Reader.h" +#include "jnjvm/JnjvmModule.h" + using namespace jnjvm; using namespace llvm; Copied: vmkit/trunk/lib/JnJVM/Compiler/JavaJIT.h (from r65455, vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.h) URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/Compiler/JavaJIT.h?p2=vmkit/trunk/lib/JnJVM/Compiler/JavaJIT.h&p1=vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.h&r1=65455&r2=65457&rev=65457&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.h (original) +++ vmkit/trunk/lib/JnJVM/Compiler/JavaJIT.h Wed Feb 25 09:42:09 2009 @@ -22,12 +22,13 @@ #include "types.h" #include "JavaClass.h" -#include "JnjvmModule.h" +#include "jnjvm/JnjvmModule.h" namespace jnjvm { class Class; class JavaMethod; +class JnjvmModule; class Reader; class UTF8; Copied: vmkit/trunk/lib/JnJVM/Compiler/JavaJITOpcodes.cpp (from r65455, vmkit/trunk/lib/JnJVM/VMCore/JavaJITOpcodes.cpp) URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/Compiler/JavaJITOpcodes.cpp?p2=vmkit/trunk/lib/JnJVM/Compiler/JavaJITOpcodes.cpp&p1=vmkit/trunk/lib/JnJVM/VMCore/JavaJITOpcodes.cpp&r1=65455&r2=65457&rev=65457&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/JavaJITOpcodes.cpp (original) +++ vmkit/trunk/lib/JnJVM/Compiler/JavaJITOpcodes.cpp Wed Feb 25 09:42:09 2009 @@ -33,7 +33,11 @@ #include "JavaTypes.h" #include "Jnjvm.h" -#include "OpcodeNames.def" +#include "jnjvm/JnjvmModule.h" + +#if DEBUG > 0 +#include "jnjvm/OpcodeNames.def" +#endif using namespace jnjvm; using namespace llvm; Copied: vmkit/trunk/lib/JnJVM/Compiler/JnjvmModule.cpp (from r65455, vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.cpp) URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/Compiler/JnjvmModule.cpp?p2=vmkit/trunk/lib/JnJVM/Compiler/JnjvmModule.cpp&p1=vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.cpp&r1=65455&r2=65457&rev=65457&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.cpp (original) +++ vmkit/trunk/lib/JnJVM/Compiler/JnjvmModule.cpp Wed Feb 25 09:42:09 2009 @@ -26,10 +26,11 @@ #include "JavaTypes.h" #include "JavaUpcalls.h" #include "Jnjvm.h" -#include "JnjvmModule.h" -#include "JnjvmModuleProvider.h" #include "Reader.h" +#include "jnjvm/JnjvmModule.h" +#include "jnjvm/JnjvmModuleProvider.h" + #include using namespace jnjvm; Copied: vmkit/trunk/lib/JnJVM/Compiler/JnjvmModuleProvider.cpp (from r65455, vmkit/trunk/lib/JnJVM/VMCore/JnjvmModuleProvider.cpp) URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/Compiler/JnjvmModuleProvider.cpp?p2=vmkit/trunk/lib/JnJVM/Compiler/JnjvmModuleProvider.cpp&p1=vmkit/trunk/lib/JnJVM/VMCore/JnjvmModuleProvider.cpp&r1=65455&r2=65457&rev=65457&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/JnjvmModuleProvider.cpp (original) +++ vmkit/trunk/lib/JnJVM/Compiler/JnjvmModuleProvider.cpp Wed Feb 25 09:42:09 2009 @@ -22,8 +22,9 @@ #include "JavaThread.h" #include "JavaTypes.h" #include "Jnjvm.h" -#include "JnjvmModule.h" -#include "JnjvmModuleProvider.h" + +#include "jnjvm/JnjvmModule.h" +#include "jnjvm/JnjvmModuleProvider.h" using namespace llvm; using namespace jnjvm; Copied: vmkit/trunk/lib/JnJVM/Compiler/LowerConstantCalls.cpp (from r65455, vmkit/trunk/lib/JnJVM/VMCore/LowerConstantCalls.cpp) URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/Compiler/LowerConstantCalls.cpp?p2=vmkit/trunk/lib/JnJVM/Compiler/LowerConstantCalls.cpp&p1=vmkit/trunk/lib/JnJVM/VMCore/LowerConstantCalls.cpp&r1=65455&r2=65457&rev=65457&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/LowerConstantCalls.cpp (original) +++ vmkit/trunk/lib/JnJVM/Compiler/LowerConstantCalls.cpp Wed Feb 25 09:42:09 2009 @@ -16,7 +16,7 @@ #include "llvm/Support/Debug.h" #include "JavaClass.h" -#include "JnjvmModule.h" +#include "jnjvm/JnjvmModule.h" using namespace llvm; Removed: vmkit/trunk/lib/JnJVM/VMCore/ExceptionsCheck.inc URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/ExceptionsCheck.inc?rev=65456&view=auto ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/ExceptionsCheck.inc (original) +++ vmkit/trunk/lib/JnJVM/VMCore/ExceptionsCheck.inc (removed) @@ -1,524 +0,0 @@ -Instruction* JavaJIT::invoke(Value *F, std::vector& args, - const char* Name, - BasicBlock *InsertAtEnd) { - - Instruction* res = CallInst::Create(F, args.begin(), args.end(), Name, - InsertAtEnd); - - if (module->hasExceptionsEnabled()) { - Value* threadId = getCurrentThread(); - Value* geps[2] = { module->constantZero, - module->OffsetJavaExceptionInThreadConstant }; - - Value* javaExceptionPtr = GetElementPtrInst::Create(threadId, geps, - geps + 2, "", - currentBlock); - - // Get the Java exception. - Value* obj = new LoadInst(javaExceptionPtr, "", currentBlock); - - BasicBlock* ifNormal = createBasicBlock("no exception block"); - - Constant* zero = module->JavaObjectNullConstant; - Value* test = new ICmpInst(ICmpInst::ICMP_NE, obj, zero, "", - currentBlock); - - BranchInst::Create(currentExceptionBlock, ifNormal, test, currentBlock); - - - if (!currentExceptionBlock->empty()) { - Instruction* insn = currentExceptionBlock->begin(); - PHINode* node = dyn_cast(insn); - if (node) node->addIncoming(obj, currentBlock); - } - - currentBlock = ifNormal; - } - - return res; -} - -Instruction* JavaJIT::invoke(Value *F, Value* arg1, const char* Name, - BasicBlock *InsertAtEnd) { - - Instruction* res = CallInst::Create(F, arg1, Name, InsertAtEnd); - - if (module->hasExceptionsEnabled()) { - Value* threadId = getCurrentThread(); - Value* geps[2] = { module->constantZero, - module->OffsetJavaExceptionInThreadConstant }; - - Value* javaExceptionPtr = GetElementPtrInst::Create(threadId, geps, - geps + 2, "", - currentBlock); - - // Get the Java exception. - Value* obj = new LoadInst(javaExceptionPtr, "", currentBlock); - - BasicBlock* ifNormal = createBasicBlock("no exception block"); - - Constant* zero = module->JavaObjectNullConstant; - Value* test = new ICmpInst(ICmpInst::ICMP_NE, obj, zero, "", - currentBlock); - - BranchInst::Create(currentExceptionBlock, ifNormal, test, currentBlock); - - if (!currentExceptionBlock->empty()) { - Instruction* insn = currentExceptionBlock->begin(); - PHINode* node = dyn_cast(insn); - if (node) node->addIncoming(obj, currentBlock); - } - - currentBlock = ifNormal; - } - - return res; -} - -Instruction* JavaJIT::invoke(Value *F, Value* arg1, Value* arg2, - const char* Name, BasicBlock *InsertAtEnd) { - - Value* args[2] = { arg1, arg2 }; - - Instruction* res = CallInst::Create(F, args, args + 2, Name, InsertAtEnd); - - if (module->hasExceptionsEnabled()) { - Value* threadId = getCurrentThread(); - Value* geps[2] = { module->constantZero, - module->OffsetJavaExceptionInThreadConstant }; - - Value* javaExceptionPtr = GetElementPtrInst::Create(threadId, geps, - geps + 2, "", - currentBlock); - - // Get the Java exception. - Value* obj = new LoadInst(javaExceptionPtr, "", currentBlock); - - BasicBlock* ifNormal = createBasicBlock("no exception block"); - - Constant* zero = module->JavaObjectNullConstant; - Value* test = new ICmpInst(ICmpInst::ICMP_NE, obj, zero, "", - currentBlock); - - BranchInst::Create(currentExceptionBlock, ifNormal, test, currentBlock); - - if (!currentExceptionBlock->empty()) { - Instruction* insn = currentExceptionBlock->begin(); - PHINode* node = dyn_cast(insn); - if (node) node->addIncoming(obj, currentBlock); - } - - currentBlock = ifNormal; - } - - return res; -} - -Instruction* JavaJIT::invoke(Value *F, const char* Name, - BasicBlock *InsertAtEnd) { - Instruction* res = llvm::CallInst::Create(F, Name, InsertAtEnd); - - if (module->hasExceptionsEnabled()) { - Value* threadId = getCurrentThread(); - Value* geps[2] = { module->constantZero, - module->OffsetJavaExceptionInThreadConstant }; - - Value* javaExceptionPtr = GetElementPtrInst::Create(threadId, geps, - geps + 2, "", - currentBlock); - - // Get the Java exception. - Value* obj = new LoadInst(javaExceptionPtr, "", currentBlock); - - BasicBlock* ifNormal = createBasicBlock("no exception block"); - - Constant* zero = module->JavaObjectNullConstant; - Value* test = new ICmpInst(ICmpInst::ICMP_NE, obj, zero, "", - currentBlock); - - BranchInst::Create(currentExceptionBlock, ifNormal, test, currentBlock); - - if (!currentExceptionBlock->empty()) { - Instruction* insn = currentExceptionBlock->begin(); - PHINode* node = dyn_cast(insn); - if (node) node->addIncoming(obj, currentBlock); - } - - currentBlock = ifNormal; - } - - return res; -} - -void JavaJIT::throwException(llvm::Function* F, Value* arg1) { - Value* obj = CallInst::Create(F, arg1, "", currentBlock); - if (currentExceptionBlock != endExceptionBlock) { - Instruction* insn = currentExceptionBlock->begin(); - PHINode* node = dyn_cast(insn); - if (node) node->addIncoming(obj, currentBlock); - BranchInst::Create(currentExceptionBlock, currentBlock); - } else { - if (endNode) { - endNode->addIncoming(Constant::getNullValue(endNode->getType()), - currentBlock); - } - BranchInst::Create(endBlock, currentBlock); - } -} - -void JavaJIT::throwException(Value* obj) { - Value* threadId = getCurrentThread(); - Value* geps[2] = { module->constantZero, - module->OffsetJavaExceptionInThreadConstant }; - - Value* javaExceptionPtr = GetElementPtrInst::Create(threadId, geps, - geps + 2, "", - currentBlock); - new StoreInst(obj, javaExceptionPtr, currentBlock); - if (currentExceptionBlock != endExceptionBlock) { - Instruction* insn = currentExceptionBlock->begin(); - PHINode* node = dyn_cast(insn); - if (node) node->addIncoming(obj, currentBlock); - BranchInst::Create(currentExceptionBlock, currentBlock); - } else { - if (endNode) { - endNode->addIncoming(Constant::getNullValue(endNode->getType()), - currentBlock); - } - BranchInst::Create(endBlock, currentBlock); - } -} - -void JavaJIT::throwException(llvm::Function* F, Value** args, - uint32 nbArgs) { - Value* obj = CallInst::Create(F, args, args + nbArgs, "", currentBlock); - if (currentExceptionBlock != endExceptionBlock) { - Instruction* insn = currentExceptionBlock->begin(); - PHINode* node = dyn_cast(insn); - if (node) node->addIncoming(obj, currentBlock); - BranchInst::Create(currentExceptionBlock, currentBlock); - } else { - if (endNode) { - endNode->addIncoming(Constant::getNullValue(endNode->getType()), - currentBlock); - } - BranchInst::Create(endBlock, currentBlock); - } -} - -/// 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; - - /// 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; - -}; - -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; - - // 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) { - Handler* ex = &handlers[i]; - ex->startpc = reader.readU2(); - ex->endpc = reader.readU2(); - ex->handlerpc = reader.readU2(); - - ex->catche = reader.readU2(); - -#ifndef ISOLATE_SHARING - 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 { - ex->catchClass = Classpath::newThrowable; - } -#endif - - ex->tester = createBasicBlock("testException"); - - // PHI Node for the exception object - PHINode::Create(JnjvmModule::JavaObjectType, "", ex->tester); - - // 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 == endExceptionBlock) { - opcodeInfos[i].exceptionBlock = ex->tester; - } - } - - // 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"); - } - - // Set the Java handler for this exception. - ex->javaHandler = opcodeInfos[ex->handlerpc].newBlock; - - if (ex->javaHandler->empty()) { - PHINode::Create(JnjvmModule::JavaObjectType, "", ex->javaHandler); - } - - } - - // Loop over all handlers to implement their tester. - for (sint16 i = 0; i < nbe - sync; ++i) { - Handler* cur = &handlers[i]; - BasicBlock* bbNext = 0; - PHINode* javaNode = 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) { - 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 = endExceptionBlock; - } else { - // 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; - javaNode = dyn_cast(bbNext->begin()); - assert(javaNode); - } - } else { - // If there's no handler after us, we jump to the end handler. - bbNext = endExceptionBlock; - } - - currentBlock = cur->tester; - - Value* clVar = 0; -#ifdef ISOLATE_SHARING - // We're dealing with exceptions, don't catch the exception if the class can - // not be found. - if (cur->catche) clVar = getResolvedClass(cur->catche, false, false, 0); - else clVar = CallInst::Create(module->GetJnjvmExceptionClassFunction, - isolateLocal, "", currentBlock); -#else - // We know catchClass exists because we have loaded all exceptions catched - // by the method when we loaded the class that defined this method. - clVar = module->getNativeClass(cur->catchClass); -#endif - if (clVar->getType() != module->JavaCommonClassType) - clVar = new BitCastInst(clVar, module->JavaCommonClassType, "", - currentBlock); - - -#ifdef SERVICE - // 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 = getCurrentThread(); - 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); - - currentBlock = continueBlock; - } -#endif - - // Get the Java exception. - Value* obj = currentBlock->begin(); - - Value* objCl = CallInst::Create(module->GetClassFunction, obj, "", - currentBlock); - - Value* depthCl = ConstantInt::get(Type::Int32Ty, cur->catchClass->depth); - Value* depthClObj = CallInst::Create(module->GetDepthFunction, objCl, "", - currentBlock); - - // Compare the exception with the exception class we catch. - Value* cmp = new ICmpInst(ICmpInst::ICMP_ULE, depthCl, depthClObj, "", - currentBlock); - - BasicBlock* supDepth = createBasicBlock("superior depth"); - - // Add the Java exception in the phi node of the next block. - if (javaNode) - javaNode->addIncoming(obj, currentBlock); - - BranchInst::Create(supDepth, bbNext, cmp, currentBlock); - - currentBlock = supDepth; - Value* inDisplay = CallInst::Create(module->GetDisplayFunction, - objCl, "", currentBlock); - - Value* displayArgs[2] = { inDisplay, depthCl }; - Value* clInDisplay = CallInst::Create(module->GetClassInDisplayFunction, - displayArgs, displayArgs + 2, "", - currentBlock); - - cmp = new ICmpInst(ICmpInst::ICMP_EQ, clInDisplay, clVar, "", - currentBlock); - - // Add the Java exception in the phi node of the handler. - Instruction* insn = cur->javaHandler->begin(); - PHINode* node = dyn_cast(insn); - assert(node && "malformed exceptions"); - node->addIncoming(obj, currentBlock); - - // Add the Java exception in the phi node of the next block. - if (javaNode) - javaNode->addIncoming(obj, currentBlock); - - // If we are catching this exception, then jump to the Java Handler, - // otherwise jump to our next handler. - BranchInst::Create(cur->javaHandler, bbNext, cmp, currentBlock); - - currentBlock = cur->javaHandler; - - // First thing in the handler: clear the exception. - Value* geps[2] = { module->constantZero, - module->OffsetJavaExceptionInThreadConstant }; - Value* threadId = getCurrentThread(); - Value* javaExceptionPtr = GetElementPtrInst::Create(threadId, geps, - geps + 2, "", - currentBlock); - - // Clear exceptions. - new StoreInst(module->JavaObjectNullConstant, javaExceptionPtr, - currentBlock); - -#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; - currentBlock = cur->javaHandler; - if (loader != loader->bootstrapLoader) { - threadId = getCurrentThread(); - - 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; - -} - -void JavaJIT::finishExceptions() { - pred_iterator PI = pred_begin(endExceptionBlock); - pred_iterator PE = pred_end(endExceptionBlock); - if (PI == PE) { - endExceptionBlock->eraseFromParent(); - } else { - if (endNode) { - endNode->addIncoming(Constant::getNullValue(endNode->getType()), - endExceptionBlock); - } - BranchInst::Create(endBlock, endExceptionBlock); - } - - - PI = pred_begin(unifiedUnreachable); - PE = pred_end(unifiedUnreachable); - if (PI == PE) { - unifiedUnreachable->eraseFromParent(); - } else { - new UnreachableInst(unifiedUnreachable); - } - - for (Function::iterator BI = llvmFunction->begin(), BE = llvmFunction->end(); - BI != BE; BI++) { - PI = pred_begin(BI); - PE = pred_end(BI); - if (PI == PE) { - Instruction* insn = BI->begin(); - PHINode* node = dyn_cast(insn); - if (node) { - node->replaceAllUsesWith(Constant::getNullValue(node->getType())); - node->eraseFromParent(); - } - } - } - -} Removed: vmkit/trunk/lib/JnJVM/VMCore/ExceptionsDwarf.inc URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/ExceptionsDwarf.inc?rev=65456&view=auto ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/ExceptionsDwarf.inc (original) +++ vmkit/trunk/lib/JnJVM/VMCore/ExceptionsDwarf.inc (removed) @@ -1,581 +0,0 @@ -Instruction* JavaJIT::invoke(Value *F, std::vector& args, - const char* Name, - BasicBlock *InsertAtEnd) { - - // means: is there a handler for me? - if (currentExceptionBlock != endExceptionBlock) { - BasicBlock* ifNormal = createBasicBlock("no exception block"); - currentBlock = ifNormal; - return llvm::InvokeInst::Create(F, ifNormal, currentExceptionBlock, - args.begin(), - args.end(), Name, InsertAtEnd); - } else { - return llvm::CallInst::Create(F, args.begin(), args.end(), Name, InsertAtEnd); - } -} - -Instruction* JavaJIT::invoke(Value *F, Value* arg1, const char* Name, - BasicBlock *InsertAtEnd) { - - // means: is there a handler for me? - if (currentExceptionBlock != endExceptionBlock) { - BasicBlock* ifNormal = createBasicBlock("no exception block"); - currentBlock = ifNormal; - Value* arg[1] = { arg1 }; - return InvokeInst::Create(F, ifNormal, currentExceptionBlock, - arg, arg + 1, Name, InsertAtEnd); - } else { - return CallInst::Create(F, arg1, Name, InsertAtEnd); - } -} - -Instruction* JavaJIT::invoke(Value *F, Value* arg1, Value* arg2, - const char* Name, BasicBlock *InsertAtEnd) { - - Value* args[2] = { arg1, arg2 }; - - // means: is there a handler for me? - if (currentExceptionBlock != endExceptionBlock) { - BasicBlock* ifNormal = createBasicBlock("no exception block"); - currentBlock = ifNormal; - return InvokeInst::Create(F, ifNormal, currentExceptionBlock, - args, args + 2, Name, InsertAtEnd); - } else { - return CallInst::Create(F, args, args + 2, Name, InsertAtEnd); - } -} - -Instruction* JavaJIT::invoke(Value *F, const char* Name, - BasicBlock *InsertAtEnd) { - // means: is there a handler for me? - if (currentExceptionBlock != endExceptionBlock) { - BasicBlock* ifNormal = createBasicBlock("no exception block"); - currentBlock = ifNormal; - Value* args[1]; - return llvm::InvokeInst::Create(F, ifNormal, currentExceptionBlock, - args, args, Name, - InsertAtEnd); - } else { - return llvm::CallInst::Create(F, Name, InsertAtEnd); - } -} - -void JavaJIT::throwException(llvm::Function* F, Value* arg1) { - if (currentExceptionBlock != endExceptionBlock) { - Value* exArgs[1] = { arg1 }; - InvokeInst::Create(F, unifiedUnreachable, - currentExceptionBlock, exArgs, exArgs + 1, - "", currentBlock); - } else { - CallInst::Create(F, arg1, "", currentBlock); - new UnreachableInst(currentBlock); - } -} - -void JavaJIT::throwException(Value* obj) { - Function* F = module->ThrowExceptionFunction; - if (currentExceptionBlock != endExceptionBlock) { - Value* exArgs[1] = { obj }; - InvokeInst::Create(F, unifiedUnreachable, - currentExceptionBlock, exArgs, exArgs + 1, - "", currentBlock); - } else { - CallInst::Create(F, obj, "", currentBlock); - new UnreachableInst(currentBlock); - } -} - -void JavaJIT::throwException(llvm::Function* F, Value** args, - uint32 nbArgs) { - if (currentExceptionBlock != endExceptionBlock) { - InvokeInst::Create(F, unifiedUnreachable, - currentExceptionBlock, args, args + nbArgs, - "", currentBlock); - } else { - CallInst::Create(F, args, args + nbArgs, "", currentBlock); - new UnreachableInst(currentBlock); - } -} - -/// 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, 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; - - 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; - if (isVirtual(compilingMethod->access)) { - argsSync = llvmFunction->arg_begin(); - } else { - 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", - trySynchronizeExceptionBlock); - Constant* C = ConstantExpr::getCast(Instruction::BitCast, - module->personality, PointerTy_0); - Value* int32_eh_select_params[3] = - { ptr_eh_ptr, C, module->constantPtrNull }; - CallInst::Create(module->exceptionSelector, int32_eh_select_params, - int32_eh_select_params + 3, "eh_select", - trySynchronizeExceptionBlock); - - 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; - } - } - } - - // 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) { - Handler* ex = &handlers[i]; - ex->startpc = reader.readU2(); - ex->endpc = reader.readU2(); - ex->handlerpc = reader.readU2(); - - ex->catche = reader.readU2(); - -#ifndef ISOLATE_SHARING - 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 { - ex->catchClass = Classpath::newThrowable; - } -#endif - - ex->catcher = createBasicBlock("testException"); - - // 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->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"); - } - - // Set the Java handler for this exception. - ex->javaHandler = opcodeInfos[ex->handlerpc].newBlock; - - // 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) { - 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->tester = createBasicBlock("realTestException"); - } else { - cur->tester = cur->catcher; - } - - // 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) { - 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) { - 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 { - // 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 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 = - CallInst::Create(module->llvmGetException, "eh_ptr", cur->catcher); - Constant* C = ConstantExpr::getCast(Instruction::BitCast, - module->personality, PointerTy_0); - Value* int32_eh_select_params[3] = - { ptr_eh_ptr, C, module->constantPtrNull }; - llvm::CallInst::Create(module->exceptionSelector, - int32_eh_select_params, - int32_eh_select_params + 3, "eh_select", - cur->catcher); - llvm::BranchInst::Create(cur->tester, cur->catcher); - cur->exceptionPHI->addIncoming(ptr_eh_ptr, cur->catcher); - } - - currentBlock = cur->tester; - - Value* clVar = 0; -#ifdef ISOLATE_SHARING - // We're dealing with exceptions, don't catch the exception if the class can - // not be found. - if (cur->catche) clVar = getResolvedClass(cur->catche, false, false, 0); - else clVar = CallInst::Create(module->GetJnjvmExceptionClassFunction, - isolateLocal, "", currentBlock); -#else - // We know catchClass exists because we have loaded all exceptions catched - // by the method when we loaded the class that defined this method. - clVar = module->getNativeClass(cur->catchClass); -#endif - if (clVar->getType() != module->JavaCommonClassType) - clVar = new BitCastInst(clVar, module->JavaCommonClassType, "", - currentBlock); - - -#ifdef SERVICE - // 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 = getCurrentThread(); - 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); - - currentBlock = continueBlock; - } -#endif - - Value* threadId = getCurrentThread(); - Value* geps[2] = { module->constantZero, - module->OffsetJavaExceptionInThreadConstant }; - - Value* javaExceptionPtr = GetElementPtrInst::Create(threadId, geps, - geps + 2, "", - currentBlock); - - // Get the Java exception. - Value* obj = new LoadInst(javaExceptionPtr, "", currentBlock); - - Value* objCl = CallInst::Create(module->GetClassFunction, obj, "", - currentBlock); - - Value* depthCl = ConstantInt::get(Type::Int32Ty, cur->catchClass->depth); - Value* depthClObj = CallInst::Create(module->GetDepthFunction, objCl, "", - currentBlock); - - // Compare the exception with the exception class we catch. - Value* cmp = new ICmpInst(ICmpInst::ICMP_ULE, depthCl, depthClObj, "", - currentBlock); - - BasicBlock* supDepth = createBasicBlock("superior depth"); - - BranchInst::Create(supDepth, bbNext, cmp, currentBlock); - - if (nodeNext) - nodeNext->addIncoming(cur->exceptionPHI, currentBlock); - - currentBlock = supDepth; - Value* inDisplay = CallInst::Create(module->GetDisplayFunction, - objCl, "", currentBlock); - - Value* displayArgs[2] = { inDisplay, depthCl }; - Value* clInDisplay = CallInst::Create(module->GetClassInDisplayFunction, - displayArgs, displayArgs + 2, "", - currentBlock); - - cmp = new ICmpInst(ICmpInst::ICMP_EQ, clInDisplay, clVar, "", - 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); - - currentBlock = cur->nativeHandler; - - threadId = getCurrentThread(); - javaExceptionPtr = GetElementPtrInst::Create(threadId, geps, geps + 2, "", - currentBlock); - - // Get the Java exception. - Value* exc = new LoadInst(javaExceptionPtr, "", currentBlock); - - Value* geps2[2] = { module->constantZero, - module->OffsetCXXExceptionInThreadConstant }; - - Value* cxxExceptionPtr = GetElementPtrInst::Create(threadId, geps2, - geps2 + 2, "", - currentBlock); - - // Clear exceptions. - new StoreInst(module->constantPtrNull, cxxExceptionPtr, currentBlock); - new StoreInst(module->JavaObjectNullConstant, javaExceptionPtr, - currentBlock); - - // 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(insn); - assert(node && "malformed exceptions"); - node->addIncoming(exc, cur->nativeHandler); - } - - -#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; - currentBlock = cur->javaHandler; - if (loader != loader->bootstrapLoader) { - threadId = getCurrentThread(); - - 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; - -} - -void JavaJIT::finishExceptions() { - pred_iterator PI = pred_begin(endExceptionBlock); - pred_iterator PE = pred_end(endExceptionBlock); - if (PI == PE) { - endExceptionBlock->eraseFromParent(); - } else { - Value* threadId = getCurrentThread(); - Value* geps2[2] = { module->constantZero, - module->OffsetCXXExceptionInThreadConstant }; - - Value* cxxExceptionPtr = GetElementPtrInst::Create(threadId, geps2, - geps2 + 2, "", - currentBlock); - cxxExceptionPtr = new LoadInst(cxxExceptionPtr, "", currentBlock); - llvm::CallInst::Create(module->unwindResume, cxxExceptionPtr, "", - currentBlock); - new UnreachableInst(currentBlock); - } - - PI = pred_begin(unifiedUnreachable); - PE = pred_end(unifiedUnreachable); - if (PI == PE) { - unifiedUnreachable->eraseFromParent(); - } else { - new UnreachableInst(unifiedUnreachable); - } - -} Removed: vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.cpp URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.cpp?rev=65456&view=auto ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.cpp (original) +++ vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.cpp (removed) @@ -1,1880 +0,0 @@ -//===----------- JavaJIT.cpp - Java just in time compiler -----------------===// -// -// JnJVM -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - - -#define DEBUG 0 -#define JNJVM_COMPILE 0 -#define JNJVM_EXECUTE 0 - -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "mvm/JIT.h" - -#include "debug.h" -#include "JavaArray.h" -#include "JavaCache.h" -#include "JavaClass.h" -#include "JavaConstantPool.h" -#include "JavaObject.h" -#include "JavaJIT.h" -#include "JavaString.h" -#include "JavaThread.h" -#include "JavaTypes.h" -#include "JavaUpcalls.h" -#include "Jnjvm.h" -#include "Reader.h" - -using namespace jnjvm; -using namespace llvm; - -static bool needsInitialisationCheck(Class* cl, Class* compilingClass) { -#ifdef SERVICE - return true; -#else - - if (cl->isReadyForCompilation() || compilingClass->subclassOf(cl)) { - return false; - } - - if (!cl->needsInitialisationCheck()) { - if (!cl->isReady()) { - cl->setInitializationState(ready); - } - return false; - } - - return true; -#endif -} - -bool JavaJIT::canBeInlined(JavaMethod* meth) { - JnjvmClassLoader* loader = meth->classDef->classLoader; - return (meth->canBeInlined && - meth != compilingMethod && inlineMethods[meth] == 0 && - (loader == compilingClass->classLoader || - loader == compilingClass->classLoader->bootstrapLoader)); -} - -void JavaJIT::invokeVirtual(uint16 index) { - - JavaConstantPool* ctpInfo = compilingClass->ctpInfo; - CommonClass* cl = 0; - JavaMethod* meth = 0; - ctpInfo->infoOfMethod(index, ACC_VIRTUAL, cl, meth); - - if ((cl && isFinal(cl->access)) || - (meth && (isFinal(meth->access) || isPrivate(meth->access)))) { - return invokeSpecial(index); - } - - // If the method is in fact a method defined in an interface, - // call invokeInterface instead. - if (meth && isInterface(meth->classDef->access)) { - return invokeInterface(index, true); - } - - const UTF8* name = 0; - Signdef* signature = ctpInfo->infoOfInterfaceOrVirtualMethod(index, name); - Value* obj = stack[signature->nbArguments].first; - JavaObject* source = module->getFinalObject(obj); - if (source) { - return invokeSpecial(index, source->getClass()); - } - -#if !defined(WITHOUT_VTABLE) - Typedef* retTypedef = signature->getReturnType(); - std::vector args; // size = [signature->nbIn + 3]; - LLVMSignatureInfo* LSI = module->getSignatureInfo(signature); - const llvm::FunctionType* virtualType = LSI->getVirtualType(); - FunctionType::param_iterator it = virtualType->param_end(); - makeArgs(it, index, args, signature->nbArguments + 1); - const llvm::Type* retType = virtualType->getReturnType(); - - JITVerifyNull(args[0]); - - BasicBlock* endBlock = 0; - PHINode* node = 0; -#if 0 - if (meth && !isAbstract(meth->access)) { - Value* cl = CallInst::Create(module->GetClassFunction, args[0], "", - currentBlock); - Value* cl2 = module->getNativeClass(meth->classDef); - if (cl2->getType() != module->JavaCommonClassType) { - cl2 = new BitCastInst(cl2, module->JavaCommonClassType, "", currentBlock); - } - - Value* test = new ICmpInst(ICmpInst::ICMP_EQ, cl, cl2, "", currentBlock); - - BasicBlock* trueBlock = createBasicBlock("true virtual invoke"); - BasicBlock* falseBlock = createBasicBlock("false virtual invoke"); - endBlock = createBasicBlock("end virtual invoke"); - BranchInst::Create(trueBlock, falseBlock, test, currentBlock); - currentBlock = trueBlock; - Value* res = 0; - if (canBeInlined(meth)) { - res = invokeInline(meth, args); - } else { - Function* func = module->getMethod(meth); - res = invoke(func, args, "", currentBlock); - } - BranchInst::Create(endBlock, currentBlock); - if (retType != Type::VoidTy) { - node = PHINode::Create(virtualType->getReturnType(), "", endBlock); - node->addIncoming(res, currentBlock); - } - currentBlock = falseBlock; - } -#endif - - Value* VT = CallInst::Create(module->GetVTFunction, args[0], "", - currentBlock); - Value* indexes2[2]; - indexes2[0] = module->constantZero; - -#ifdef ISOLATE_SHARING - Value* indexesCtp; //[3]; -#endif - if (meth) { - LLVMMethodInfo* LMI = module->getMethodInfo(meth); - ConstantInt* Offset = LMI->getOffset(); - indexes2[1] = Offset; -#ifdef ISOLATE_SHARING - indexesCtp = ConstantInt::get(Type::Int32Ty, - Offset->getZExtValue() * -1); -#endif - } else { - - Value* val = getConstantPoolAt(index, module->VirtualLookupFunction, - Type::Int32Ty, args[0], true); - indexes2[1] = val; -#ifdef ISOLATE_SHARING - Value* mul = BinaryOperator::CreateMul(val, module->constantMinusOne, - "", currentBlock); - indexesCtp = mul; -#endif - } - - Value* FuncPtr = GetElementPtrInst::Create(VT, indexes2, indexes2 + 2, "", - currentBlock); - - Value* Func = new LoadInst(FuncPtr, "", currentBlock); - - Func = new BitCastInst(Func, LSI->getVirtualPtrType(), "", currentBlock); -#ifdef ISOLATE_SHARING - Value* CTP = GetElementPtrInst::Create(VT, indexesCtp, "", currentBlock); - - CTP = new LoadInst(CTP, "", currentBlock); - CTP = new BitCastInst(CTP, module->ConstantPoolType, "", currentBlock); - args.push_back(CTP); -#endif - Value* val = invoke(Func, args, "", currentBlock); - - if (endBlock) { - if (node) { - node->addIncoming(val, currentBlock); - val = node; - } - BranchInst::Create(endBlock, currentBlock); - currentBlock = endBlock; - } - - if (retType != Type::VoidTy) { - push(val, retTypedef->isUnsigned()); - if (retType == Type::DoubleTy || retType == Type::Int64Ty) { - push(module->constantZero, false); - } - } - -#else - return invokeInterface(index); -#endif -} - -llvm::Value* JavaJIT::getCurrentThread() { - Value* FrameAddr = CallInst::Create(module->llvm_frameaddress, - module->constantZero, "", currentBlock); - Value* threadId = new PtrToIntInst(FrameAddr, module->pointerSizeType, "", - currentBlock); - threadId = BinaryOperator::CreateAnd(threadId, module->constantThreadIDMask, - "", currentBlock); - threadId = new IntToPtrInst(threadId, module->JavaThreadType, "", - currentBlock); - - return threadId; -} - - -llvm::Function* JavaJIT::nativeCompile(intptr_t natPtr) { - - PRINT_DEBUG(JNJVM_COMPILE, 1, COLOR_NORMAL, "native compile %s\n", - compilingMethod->printString()); - - bool stat = isStatic(compilingMethod->access); - - const FunctionType *funcType = llvmFunction->getFunctionType(); - - bool jnjvm = false; - - const UTF8* jniConsClName = compilingClass->name; - const UTF8* jniConsName = compilingMethod->name; - const UTF8* jniConsType = compilingMethod->type; - sint32 clen = jniConsClName->size; - sint32 mnlen = jniConsName->size; - sint32 mtlen = jniConsType->size; - - char* functionName = (char*)alloca(3 + JNI_NAME_PRE_LEN + - ((mnlen + clen + mtlen) << 1)); - if (!natPtr) - natPtr = compilingClass->classLoader->nativeLookup(compilingMethod, jnjvm, - functionName); - - if (!natPtr && !module->isStaticCompiling()) { - fprintf(stderr, "Native function %s not found. Probably " - "not implemented by JnJVM?\n", compilingMethod->printString()); - JavaThread::get()->getJVM()->unknownError("can not find native method %s", - compilingMethod->printString()); - } - - - Function* func = llvmFunction; - if (jnjvm) { - compilingMethod->setCompiledPtr((void*)natPtr, functionName); - return llvmFunction; - } - - currentExceptionBlock = endExceptionBlock = 0; - currentBlock = createBasicBlock("start"); - BasicBlock* executeBlock = createBasicBlock("execute"); - endBlock = createBasicBlock("end block"); - const llvm::Type* returnType = funcType->getReturnType(); - - Value* buf = llvm::CallInst::Create(module->GetSJLJBufferFunction, - "", currentBlock); - Value* test = llvm::CallInst::Create(module->setjmpLLVM, buf, "", - currentBlock); - test = new ICmpInst(ICmpInst::ICMP_EQ, test, module->constantZero, "", - currentBlock); - llvm::BranchInst::Create(executeBlock, endBlock, test, currentBlock); - - if (returnType != Type::VoidTy) { - endNode = llvm::PHINode::Create(returnType, "", endBlock); - endNode->addIncoming(Constant::getNullValue(returnType), - currentBlock); - } - - currentBlock = executeBlock; - if (isSynchro(compilingMethod->access)) - beginSynchronize(); - - - uint32 nargs = func->arg_size() + 1 + (stat ? 1 : 0); - std::vector nativeArgs; - - - Value* threadId = getCurrentThread(); - - Value* geps[2] = { module->constantZero, module->constantEight }; - - Value* jniEnv = GetElementPtrInst::Create(threadId, geps, geps + 2, "", - currentBlock); - - jniEnv = new BitCastInst(jniEnv, module->ptrType, "", currentBlock); - - nativeArgs.push_back(jniEnv); - - uint32 index = 0; - if (stat) { -#ifdef ISOLATE_SHARING - Value* val = getClassCtp(); - Value* res = CallInst::Create(module->GetClassDelegateeFunction, - val, "", currentBlock); - nativeArgs.push_back(res); -#else - Value* cl = module->getJavaClass(compilingClass); - nativeArgs.push_back(cl); -#endif - index = 2; - } else { - index = 1; - } - for (Function::arg_iterator i = func->arg_begin(); - index < nargs; ++i, ++index) { - - nativeArgs.push_back(i); - } - - Value* nativeFunc = module->getNativeFunction(compilingMethod, (void*)natPtr); - - if (module->isStaticCompiling()) { - Value* Arg = module->getMethodInClass(compilingMethod); - - // If the global variable is null, then load it. - BasicBlock* unloadedBlock = createBasicBlock(""); - BasicBlock* endBlock = createBasicBlock(""); - Value* test = new LoadInst(nativeFunc, "", currentBlock); - const llvm::Type* Ty = test->getType(); - PHINode* node = PHINode::Create(Ty, "", endBlock); - node->addIncoming(test, currentBlock); - Value* cmp = new ICmpInst(ICmpInst::ICMP_EQ, test, - Constant::getNullValue(Ty), "", currentBlock); - BranchInst::Create(unloadedBlock, endBlock, cmp, currentBlock); - currentBlock = unloadedBlock; - - Value* res = CallInst::Create(module->NativeLoader, Arg, "", currentBlock); - - res = new BitCastInst(res, Ty, "", currentBlock); - new StoreInst(res, nativeFunc, currentBlock); - node->addIncoming(res, currentBlock); - BranchInst::Create(endBlock, currentBlock); - currentBlock = endBlock; - nativeFunc = node; - } - - Value* FrameAddr = CallInst::Create(module->llvm_frameaddress, - module->constantZero, "", currentBlock); - - // When calling a native method, it may do whatever it wants with the - // frame pointer. Therefore make sure it's on the stack. x86_64 has - // this problem because it passes first arguments in registers. - // Therefore, it was overwriting the frame pointer when entering the - // native method. - Value* Temp = new AllocaInst(module->ptrType, "", currentBlock); - new StoreInst(FrameAddr, Temp, currentBlock); - Value* result = llvm::CallInst::Create(nativeFunc, nativeArgs.begin(), - nativeArgs.end(), "", currentBlock); - - if (returnType != Type::VoidTy) - endNode->addIncoming(result, currentBlock); - BranchInst::Create(endBlock, currentBlock); - - currentBlock = endBlock; - if (isSynchro(compilingMethod->access)) - endSynchronize(); - - CallInst::Create(module->JniProceedPendingExceptionFunction, "", - currentBlock); - - if (returnType != Type::VoidTy) - ReturnInst::Create(endNode, currentBlock); - else - ReturnInst::Create(currentBlock); - - PRINT_DEBUG(JNJVM_COMPILE, 1, COLOR_NORMAL, "end native compile %s\n", - compilingMethod->printString()); - - func->setLinkage(GlobalValue::ExternalLinkage); - - return llvmFunction; -} - -void JavaJIT::monitorEnter(Value* obj) { - - Value* gep[2] = { module->constantZero, - module->JavaObjectLockOffsetConstant }; - Value* lockPtr = GetElementPtrInst::Create(obj, gep, gep + 2, "", - currentBlock); - Value* lock = new LoadInst(lockPtr, "", currentBlock); - lock = new PtrToIntInst(lock, module->pointerSizeType, "", currentBlock); - Value* lockMask = BinaryOperator::CreateAnd(lock, - module->constantThreadFreeMask, - "", currentBlock); - Value* threadId = getCurrentThread(); - threadId = new PtrToIntInst(threadId, module->pointerSizeType, "", - currentBlock); - - Value* cmp = new ICmpInst(ICmpInst::ICMP_EQ, lockMask, threadId, "", - currentBlock); - - BasicBlock* ThinLockBB = createBasicBlock("thread local"); - BasicBlock* FatLockBB = createBasicBlock("fat lock"); - BasicBlock* EndLockBB = createBasicBlock("End lock"); - - BranchInst::Create(ThinLockBB, FatLockBB, cmp, currentBlock); - - currentBlock = ThinLockBB; - Value* increment = BinaryOperator::CreateAdd(lock, module->constantPtrOne, "", - currentBlock); - increment = new IntToPtrInst(increment, module->ptrType, "", currentBlock); - new StoreInst(increment, lockPtr, false, currentBlock); - BranchInst::Create(EndLockBB, currentBlock); - - currentBlock = FatLockBB; - - // Either it's a fat lock or there is contention or it's not thread local or - // it's locked at least once. - CallInst::Create(module->AquireObjectFunction, obj, "", currentBlock); - - BranchInst::Create(EndLockBB, currentBlock); - currentBlock = EndLockBB; -} - -void JavaJIT::monitorExit(Value* obj) { - Value* gep[2] = { module->constantZero, - module->JavaObjectLockOffsetConstant }; - Value* lockPtr = GetElementPtrInst::Create(obj, gep, gep + 2, "", - currentBlock); - Value* lock = new LoadInst(lockPtr, "", currentBlock); - lock = new PtrToIntInst(lock, module->pointerSizeType, "", currentBlock); - Value* lockMask = BinaryOperator::CreateAnd(lock, module->constantLockedMask, - "", currentBlock); - Value* threadId = getCurrentThread(); - threadId = new PtrToIntInst(threadId, module->pointerSizeType, "", - currentBlock); - Value* cmp = new ICmpInst(ICmpInst::ICMP_EQ, lockMask, threadId, "", - currentBlock); - - - BasicBlock* EndUnlock = createBasicBlock("end unlock"); - BasicBlock* ThinLockBB = createBasicBlock("desynchronize thin lock"); - BasicBlock* FatLockBB = createBasicBlock("fat lock"); - - BranchInst::Create(ThinLockBB, FatLockBB, cmp, currentBlock); - - // Locked by the thread, decrement. - currentBlock = ThinLockBB; - Value* decrement = BinaryOperator::CreateSub(lock, module->constantPtrOne, "", - currentBlock); - decrement = new IntToPtrInst(decrement, module->ptrType, "", currentBlock); - new StoreInst(decrement, lockPtr, false, currentBlock); - BranchInst::Create(EndUnlock, currentBlock); - - // Either it's a fat lock or there is contention or it's not thread local. - currentBlock = FatLockBB; - CallInst::Create(module->ReleaseObjectFunction, obj, "", currentBlock); - BranchInst::Create(EndUnlock, currentBlock); - currentBlock = EndUnlock; -} - -#ifdef ISOLATE_SHARING -Value* JavaJIT::getStaticInstanceCtp() { - Value* cl = getClassCtp(); - Value* indexes[2] = { module->constantZero, module->constantSeven }; - Value* arg1 = GetElementPtrInst::Create(cl, indexes, indexes + 2, - "", currentBlock); - arg1 = new LoadInst(arg1, "", false, currentBlock); - return arg1; - -} - -Value* JavaJIT::getClassCtp() { - Value* indexes = module->constantOne; - Value* arg1 = GetElementPtrInst::Create(ctpCache, indexes.begin(), - indexes.end(), "", currentBlock); - arg1 = new LoadInst(arg1, "", false, currentBlock); - arg1 = new BitCastInst(arg1, module->JavaClassType, "", currentBlock); - return arg1; -} -#endif - -void JavaJIT::beginSynchronize() { - Value* obj = 0; - if (isVirtual(compilingMethod->access)) { - obj = llvmFunction->arg_begin(); - } else { - obj = module->getJavaClass(compilingClass); - } - monitorEnter(obj); -} - -void JavaJIT::endSynchronize() { - Value* obj = 0; - if (isVirtual(compilingMethod->access)) { - obj = llvmFunction->arg_begin(); - } else { - obj = module->getJavaClass(compilingClass); - } - monitorExit(obj); -} - - -Instruction* JavaJIT::inlineCompile(BasicBlock*& curBB, - BasicBlock* endExBlock, - std::vector& args) { - PRINT_DEBUG(JNJVM_COMPILE, 1, COLOR_NORMAL, "inline compile %s\n", - compilingMethod->printString()); - - Attribut* codeAtt = compilingMethod->lookupAttribut(Attribut::codeAttribut); - - if (!codeAtt) { - Jnjvm* vm = JavaThread::get()->getJVM(); - vm->unknownError("unable to find the code attribut in %s", - compilingMethod->printString()); - } - - Reader reader(codeAtt, compilingClass->bytes); - /* uint16 maxStack = */ reader.readU2(); - uint16 maxLocals = reader.readU2(); - uint32 codeLen = reader.readU4(); - uint32 start = reader.cursor; - - reader.seek(codeLen, Reader::SeekCur); - - LLVMMethodInfo* LMI = module->getMethodInfo(compilingMethod); - assert(LMI); - Function* func = LMI->getMethod(); - - const Type* returnType = func->getReturnType(); - endBlock = createBasicBlock("end"); - - currentBlock = curBB; - endExceptionBlock = endExBlock; - - opcodeInfos = (Opinfo*)alloca(codeLen * sizeof(Opinfo)); - memset(opcodeInfos, 0, codeLen * sizeof(Opinfo)); - for (uint32 i = 0; i < codeLen; ++i) { - opcodeInfos[i].exceptionBlock = endExBlock; - } - - BasicBlock* firstBB = llvmFunction->begin(); - - if (firstBB->begin() != firstBB->end()) { - Instruction* firstInstruction = firstBB->begin(); - - for (int i = 0; i < maxLocals; i++) { - intLocals.push_back(new AllocaInst(Type::Int32Ty, "", firstInstruction)); - doubleLocals.push_back(new AllocaInst(Type::DoubleTy, "", - firstInstruction)); - longLocals.push_back(new AllocaInst(Type::Int64Ty, "", firstInstruction)); - floatLocals.push_back(new AllocaInst(Type::FloatTy, "", firstInstruction)); - objectLocals.push_back(new AllocaInst(module->JavaObjectType, "", - firstInstruction)); - } - } else { - for (int i = 0; i < maxLocals; i++) { - intLocals.push_back(new AllocaInst(Type::Int32Ty, "", firstBB)); - doubleLocals.push_back(new AllocaInst(Type::DoubleTy, "", firstBB)); - longLocals.push_back(new AllocaInst(Type::Int64Ty, "", firstBB)); - floatLocals.push_back(new AllocaInst(Type::FloatTy, "", firstBB)); - objectLocals.push_back(new AllocaInst(module->JavaObjectType, "", - firstBB)); - } - } - - uint32 index = 0; - uint32 count = 0; -#if defined(ISOLATE_SHARING) - uint32 max = args.size() - 2; -#else - uint32 max = args.size(); -#endif - Signdef* sign = compilingMethod->getSignature(); - Typedef* const* arguments = sign->getArgumentsType(); - uint32 type = 0; - std::vector::iterator i = args.begin(); - - if (isVirtual(compilingMethod->access)) { - new StoreInst(*i, objectLocals[0], false, currentBlock); - ++i; - ++index; - ++count; - } - - - for (;count < max; ++i, ++index, ++count, ++type) { - - const Typedef* cur = arguments[type]; - const Type* curType = (*i)->getType(); - - if (curType == Type::Int64Ty){ - new StoreInst(*i, longLocals[index], false, currentBlock); - ++index; - } else if (cur->isUnsigned()) { - new StoreInst(new ZExtInst(*i, Type::Int32Ty, "", currentBlock), - intLocals[index], false, currentBlock); - } else if (curType == Type::Int8Ty || curType == Type::Int16Ty) { - new StoreInst(new SExtInst(*i, Type::Int32Ty, "", currentBlock), - intLocals[index], false, currentBlock); - } else if (curType == Type::Int32Ty) { - new StoreInst(*i, intLocals[index], false, currentBlock); - } else if (curType == Type::DoubleTy) { - new StoreInst(*i, doubleLocals[index], false, currentBlock); - ++index; - } else if (curType == Type::FloatTy) { - new StoreInst(*i, floatLocals[index], false, currentBlock); - } else { - new StoreInst(*i, objectLocals[index], false, currentBlock); - } - } - - readExceptionTable(reader, codeLen); - - exploreOpcodes(&compilingClass->bytes->elements[start], codeLen); - nbEnveloppes = 0; - - if (returnType != Type::VoidTy) { - endNode = PHINode::Create(returnType, "", endBlock); - } - - compileOpcodes(&compilingClass->bytes->elements[start], codeLen); - - PRINT_DEBUG(JNJVM_COMPILE, 1, COLOR_NORMAL, "--> end inline compiling %s\n", - compilingMethod->printString()); - - curBB = endBlock; - return endNode; - -} - - -llvm::Function* JavaJIT::javaCompile() { - PRINT_DEBUG(JNJVM_COMPILE, 1, COLOR_NORMAL, "compiling %s\n", - compilingMethod->printString()); - - - Attribut* codeAtt = compilingMethod->lookupAttribut(Attribut::codeAttribut); - - if (!codeAtt) { - Jnjvm* vm = JavaThread::get()->getJVM(); - vm->unknownError("unable to find the code attribut in %s", - compilingMethod->printString()); - } - - Reader reader(codeAtt, compilingClass->bytes); - /* 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(); - const Type* returnType = funcType->getReturnType(); - - Function* func = llvmFunction; - - currentBlock = createBasicBlock("start"); - endExceptionBlock = createBasicBlock("endExceptionBlock"); - unifiedUnreachable = createBasicBlock("unifiedUnreachable"); - - opcodeInfos = (Opinfo*)alloca(codeLen * sizeof(Opinfo)); - memset(opcodeInfos, 0, codeLen * sizeof(Opinfo)); - for (uint32 i = 0; i < codeLen; ++i) { - opcodeInfos[i].exceptionBlock = endExceptionBlock; - } - -#if JNJVM_EXECUTE > 0 - { - Value* arg = module->getMethodInClass(compilingMethod); - - llvm::CallInst::Create(module->PrintMethodStartFunction, arg, "", - currentBlock); - } -#endif - - - - for (int i = 0; i < maxLocals; i++) { - intLocals.push_back(new AllocaInst(Type::Int32Ty, "", currentBlock)); - doubleLocals.push_back(new AllocaInst(Type::DoubleTy, "", currentBlock)); - longLocals.push_back(new AllocaInst(Type::Int64Ty, "", currentBlock)); - floatLocals.push_back(new AllocaInst(Type::FloatTy, "", currentBlock)); - objectLocals.push_back(new AllocaInst(module->JavaObjectType, "", - currentBlock)); - } - - uint32 index = 0; - uint32 count = 0; -#if defined(ISOLATE_SHARING) - uint32 max = func->arg_size() - 2; -#else - uint32 max = func->arg_size(); -#endif - Function::arg_iterator i = func->arg_begin(); - Signdef* sign = compilingMethod->getSignature(); - Typedef* const* arguments = sign->getArgumentsType(); - uint32 type = 0; - - if (isVirtual(compilingMethod->access)) { - new StoreInst(i, objectLocals[0], false, currentBlock); - ++i; - ++index; - ++count; - } - - for (;count < max; ++i, ++index, ++count, ++type) { - - const Typedef* cur = arguments[type]; - const llvm::Type* curType = i->getType(); - - if (curType == Type::Int64Ty){ - new StoreInst(i, longLocals[index], false, currentBlock); - ++index; - } else if (cur->isUnsigned()) { - new StoreInst(new ZExtInst(i, Type::Int32Ty, "", currentBlock), - intLocals[index], false, currentBlock); - } else if (curType == Type::Int8Ty || curType == Type::Int16Ty) { - new StoreInst(new SExtInst(i, Type::Int32Ty, "", currentBlock), - intLocals[index], false, currentBlock); - } else if (curType == Type::Int32Ty) { - new StoreInst(i, intLocals[index], false, currentBlock); - } else if (curType == Type::DoubleTy) { - new StoreInst(i, doubleLocals[index], false, currentBlock); - ++index; - } else if (curType == Type::FloatTy) { - new StoreInst(i, floatLocals[index], false, currentBlock); - } else { - new StoreInst(i, objectLocals[index], false, currentBlock); - } - } - -#if defined(ISOLATE_SHARING) - ctpCache = i; - Value* addrCtpCache = new AllocaInst(module->ConstantPoolType, "", - currentBlock); - /// make it volatile to be sure it's on the stack - new StoreInst(ctpCache, addrCtpCache, true, currentBlock); -#endif - - -#if defined(SERVICE) - JnjvmClassLoader* loader = compilingClass->classLoader; - Value* Cmp = 0; - Value* threadId = 0; - Value* OldIsolateID = 0; - Value* IsolateIDPtr = 0; - Value* OldIsolate = 0; - Value* NewIsolate = 0; - Value* IsolatePtr = 0; - if (loader != loader->bootstrapLoader && isPublic(compilingMethod->access)) { - threadId = getCurrentThread(); - - IsolateIDPtr = GetElementPtrInst::Create(threadId, module->constantThree, - "", currentBlock); - const Type* realType = PointerType::getUnqual(module->pointerSizeType); - IsolateIDPtr = new BitCastInst(IsolateIDPtr, realType, "", - currentBlock); - OldIsolateID = new LoadInst(IsolateIDPtr, "", currentBlock); - - Value* MyID = ConstantInt::get(module->pointerSizeType, - loader->getIsolate()->IsolateID); - Cmp = new ICmpInst(ICmpInst::ICMP_EQ, OldIsolateID, MyID, "", currentBlock); - - BasicBlock* EndBB = createBasicBlock("After service check"); - BasicBlock* ServiceBB = createBasicBlock("Begin service call"); - - BranchInst::Create(EndBB, ServiceBB, Cmp, currentBlock); - - currentBlock = ServiceBB; - - new StoreInst(MyID, IsolateIDPtr, currentBlock); - IsolatePtr = GetElementPtrInst::Create(threadId, module->constantFour, "", - currentBlock); - - OldIsolate = new LoadInst(IsolatePtr, "", currentBlock); - NewIsolate = module->getIsolate(loader->getIsolate(), currentBlock); - new StoreInst(NewIsolate, IsolatePtr, currentBlock); - -#if DEBUG - Value* GEP[2] = { OldIsolate, NewIsolate }; - CallInst::Create(module->ServiceCallStartFunction, GEP, GEP + 2, - "", currentBlock); -#endif - BranchInst::Create(EndBB, currentBlock); - currentBlock = EndBB; - } -#endif - - readExceptionTable(reader, codeLen); - - exploreOpcodes(&compilingClass->bytes->elements[start], codeLen); - compilingMethod->enveloppes = - new (compilingClass->classLoader->allocator) Enveloppe[nbEnveloppes]; - compilingMethod->nbEnveloppes = nbEnveloppes; - nbEnveloppes = 0; - - endBlock = createBasicBlock("end"); - - if (returnType != Type::VoidTy) { - endNode = llvm::PHINode::Create(returnType, "", endBlock); - } - - if (isSynchro(compilingMethod->access)) - beginSynchronize(); - - compileOpcodes(&compilingClass->bytes->elements[start], codeLen); - - assert(stack.size() == 0 && "Stack not empty after compiling bytecode"); - // Fix a javac(?) bug where a method only throws an exception and does - // not return. - pred_iterator PI = pred_begin(endBlock); - pred_iterator PE = pred_end(endBlock); - if (PI == PE && returnType != Type::VoidTy) { - Instruction* I = currentBlock->getTerminator(); - - if (isa(I)) { - I->eraseFromParent(); - BranchInst::Create(endBlock, currentBlock); - endNode->addIncoming(Constant::getNullValue(returnType), - currentBlock); - } else if (InvokeInst* II = dyn_cast(I)) { - II->setNormalDest(endBlock); - endNode->addIncoming(Constant::getNullValue(returnType), - currentBlock); - } - - } - currentBlock = endBlock; - - if (isSynchro(compilingMethod->access)) - endSynchronize(); - -#if JNJVM_EXECUTE > 0 - { - Value* arg = module->getMethodInClass(compilingMethod); - CallInst::Create(module->PrintMethodEndFunction, arg, "", currentBlock); - } -#endif - -#if defined(SERVICE) - if (Cmp) { - BasicBlock* EndBB = createBasicBlock("After service check"); - BasicBlock* ServiceBB = createBasicBlock("End Service call"); - - BranchInst::Create(EndBB, ServiceBB, Cmp, currentBlock); - - currentBlock = ServiceBB; - - new StoreInst(OldIsolateID, IsolateIDPtr, currentBlock); - new StoreInst(OldIsolate, IsolatePtr, currentBlock); - -#if DEBUG - Value* GEP[2] = { OldIsolate, NewIsolate }; - CallInst::Create(module->ServiceCallStopFunction, GEP, GEP + 2, - "", currentBlock); -#endif - BranchInst::Create(EndBB, currentBlock); - currentBlock = EndBB; - } -#endif - - PI = pred_begin(currentBlock); - PE = pred_end(currentBlock); - if (PI == PE) { - currentBlock->eraseFromParent(); - } else { - if (returnType != Type::VoidTy) - ReturnInst::Create(endNode, currentBlock); - else - ReturnInst::Create(currentBlock); - } - - currentBlock = endExceptionBlock; - - finishExceptions(); - - func->setLinkage(GlobalValue::ExternalLinkage); - - PRINT_DEBUG(JNJVM_COMPILE, 1, COLOR_NORMAL, "--> end compiling %s\n", - compilingMethod->printString()); - -#ifndef DWARF_EXCEPTIONS - if (codeLen < 5 && !callsStackWalker && !module->isStaticCompiling()) - compilingMethod->canBeInlined = true; -#endif - - return llvmFunction; -} - -void JavaJIT::compareFP(Value* val1, Value* val2, const Type* ty, bool l) { - Value* one = module->constantOne; - Value* zero = module->constantZero; - Value* minus = module->constantMinusOne; - - Value* c = new FCmpInst(FCmpInst::FCMP_UGT, val1, val2, "", currentBlock); - Value* r = llvm::SelectInst::Create(c, one, zero, "", currentBlock); - c = new FCmpInst(FCmpInst::FCMP_ULT, val1, val2, "", currentBlock); - r = llvm::SelectInst::Create(c, minus, r, "", currentBlock); - c = new FCmpInst(FCmpInst::FCMP_UNO, val1, val2, "", currentBlock); - r = llvm::SelectInst::Create(c, l ? one : minus, r, "", currentBlock); - - push(r, false); - -} - -void JavaJIT::loadConstant(uint16 index) { - JavaConstantPool* ctpInfo = compilingClass->ctpInfo; - uint8 type = ctpInfo->typeAt(index); - - if (type == JavaConstantPool::ConstantString) { -#if defined(ISOLATE) - if (compilingClass->classLoader != - compilingClass->classLoader->bootstrapLoader) { - const UTF8* utf8 = ctpInfo->UTF8At(ctpInfo->ctpDef[index]); - JavaString* str = compilingClass->classLoader->UTF8ToStr(utf8); - - Value* val = module->getString(str, currentBlock); - push(val, false); - } else { - - // Lookup the constant pool cache - Value* val = getConstantPoolAt(index, module->StringLookupFunction, - module->JavaObjectType, 0, false); - push(val, false); - } -#elif defined(ISOLATE_SHARING) - // Lookup the constant pool cache - Value* val = getConstantPoolAt(index, module->StringLookupFunction, - module->JavaObjectType, 0, false); - push(val, false); -#else - const UTF8* utf8 = ctpInfo->UTF8At(ctpInfo->ctpDef[index]); - JavaString* str = compilingClass->classLoader->UTF8ToStr(utf8); - - Value* val = module->getString(str); - push(val, false); -#endif - - } else if (type == JavaConstantPool::ConstantLong) { - push(ConstantInt::get(Type::Int64Ty, ctpInfo->LongAt(index)), - false); - } else if (type == JavaConstantPool::ConstantDouble) { - push(ConstantFP::get(Type::DoubleTy, ctpInfo->DoubleAt(index)), - false); - } else if (type == JavaConstantPool::ConstantInteger) { - push(ConstantInt::get(Type::Int32Ty, ctpInfo->IntegerAt(index)), - false); - } else if (type == JavaConstantPool::ConstantFloat) { - push(ConstantFP::get(Type::FloatTy, ctpInfo->FloatAt(index)), - false); - } else if (type == JavaConstantPool::ConstantClass) { - UserCommonClass* cl = 0; - Value* res = getResolvedCommonClass(index, false, &cl); - -#ifndef ISOLATE - if (cl || (module->isStaticCompiling() && module->isCompiling(cl))) - res = module->getJavaClass(cl); - else -#endif - - res = CallInst::Create(module->GetClassDelegateeFunction, res, "", - currentBlock); - push(res, false); - } else { - JavaThread::get()->getJVM()->unknownError("unknown type %d", type); - } -} - -void JavaJIT::JITVerifyNull(Value* obj) { - - if (module->hasExceptionsEnabled()) { - Constant* zero = module->JavaObjectNullConstant; - Value* test = new ICmpInst(ICmpInst::ICMP_EQ, obj, zero, "", - currentBlock); - - BasicBlock* exit = createBasicBlock("verifyNullExit"); - BasicBlock* cont = createBasicBlock("verifyNullCont"); - - BranchInst::Create(exit, cont, test, currentBlock); - currentBlock = exit; - throwException(module->NullPointerExceptionFunction, 0, 0); - currentBlock = cont; - } - -} - -Value* JavaJIT::verifyAndComputePtr(Value* obj, Value* index, - const Type* arrayType, bool verif) { - JITVerifyNull(obj); - - if (index->getType() != Type::Int32Ty) { - index = new SExtInst(index, Type::Int32Ty, "", currentBlock); - } - - if (module->hasExceptionsEnabled()) { - Value* size = arraySize(obj); - - Value* cmp = new ICmpInst(ICmpInst::ICMP_ULT, index, size, "", - currentBlock); - - BasicBlock* ifTrue = createBasicBlock("true verifyAndComputePtr"); - BasicBlock* ifFalse = createBasicBlock("false verifyAndComputePtr"); - - branch(cmp, ifTrue, ifFalse, currentBlock); - - currentBlock = ifFalse; - Value* args[2] = { obj, index }; - throwException(module->IndexOutOfBoundsExceptionFunction, args, 2); - currentBlock = ifTrue; - } - - Constant* zero = module->constantZero; - Value* val = new BitCastInst(obj, arrayType, "", currentBlock); - - Value* indexes[3] = { zero, module->JavaArrayElementsOffsetConstant, index }; - Value* ptr = GetElementPtrInst::Create(val, indexes, indexes + 3, "", - currentBlock); - - return ptr; - -} - -void JavaJIT::testPHINodes(BasicBlock* dest, BasicBlock* insert) { - if(dest->empty()) { - for (std::vector< std::pair >::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, "", currentBlock); - } else if (type == Type::Int8Ty || type == Type::Int16Ty) { - node = llvm::PHINode::Create(Type::Int32Ty, "", dest); - cur = new SExtInst(cur, Type::Int32Ty, "", currentBlock); - } else { - node = llvm::PHINode::Create(cur->getType(), "", dest); - } - assert(node->getType() == cur->getType() && "wrong 1"); - node->addIncoming(cur, insert); - } - } else { - std::vector< std::pair >::iterator stackit = stack.begin(); - for (BasicBlock::iterator i = dest->begin(), e = dest->end(); i != e; - ++i) { - if (!(isa(i))) { - break; - } else { - Instruction* ins = i; - Value* cur = stackit->first; - const Type* type = cur->getType(); - bool unsign = stackit->second; - - if (unsign) { - cur = new ZExtInst(cur, Type::Int32Ty, "", currentBlock); - } else if (type == Type::Int8Ty || type == Type::Int16Ty) { - cur = new SExtInst(cur, Type::Int32Ty, "", currentBlock); - } - assert(ins->getType() == cur->getType() && "wrong 2"); - ((PHINode*)ins)->addIncoming(cur, insert); - ++stackit; - } - } - } -} - -void JavaJIT::makeArgs(FunctionType::param_iterator it, - uint32 index, std::vector& Args, uint32 nb) { -#if defined(ISOLATE_SHARING) - nb += 1; -#endif - Args.reserve(nb + 2); - Value** args = (Value**)alloca(nb*sizeof(Value*)); -#if defined(ISOLATE_SHARING) - args[nb - 1] = isolateLocal; - sint32 start = nb - 2; - it--; - it--; -#else - sint32 start = nb - 1; -#endif - for (sint32 i = start; i >= 0; --i) { - it--; - if (it->get() == Type::Int64Ty || it->get() == Type::DoubleTy) { - pop(); - } - bool unsign = topSign(); - Value* tmp = pop(); - - const Type* type = it->get(); - if (tmp->getType() != type) { // int8 or int16 - convertValue(tmp, type, currentBlock, unsign); - } - args[i] = tmp; - - } - - for (uint32 i = 0; i < nb; ++i) { - Args.push_back(args[i]); - } - -} - -Instruction* JavaJIT::lowerMathOps(const UTF8* name, - std::vector& args) { - JnjvmBootstrapLoader* loader = compilingClass->classLoader->bootstrapLoader; - if (name->equals(loader->abs)) { - const Type* Ty = args[0]->getType(); - if (Ty == Type::Int32Ty) { - Constant* const_int32_9 = module->constantZero; - ConstantInt* const_int32_10 = module->constantMinusOne; - BinaryOperator* int32_tmpneg = - BinaryOperator::Create(Instruction::Sub, const_int32_9, args[0], - "tmpneg", currentBlock); - ICmpInst* int1_abscond = - new ICmpInst(ICmpInst::ICMP_SGT, args[0], const_int32_10, "abscond", - currentBlock); - return llvm::SelectInst::Create(int1_abscond, args[0], int32_tmpneg, - "abs", currentBlock); - } else if (Ty == Type::Int64Ty) { - Constant* const_int64_9 = module->constantLongZero; - ConstantInt* const_int64_10 = module->constantLongMinusOne; - - BinaryOperator* int64_tmpneg = - BinaryOperator::Create(Instruction::Sub, const_int64_9, args[0], - "tmpneg", currentBlock); - - ICmpInst* int1_abscond = new ICmpInst(ICmpInst::ICMP_SGT, args[0], - const_int64_10, "abscond", - currentBlock); - - return llvm::SelectInst::Create(int1_abscond, args[0], int64_tmpneg, - "abs", currentBlock); - } else if (Ty == Type::FloatTy) { - return llvm::CallInst::Create(module->func_llvm_fabs_f32, args[0], - "tmp1", currentBlock); - } else if (Ty == Type::DoubleTy) { - return llvm::CallInst::Create(module->func_llvm_fabs_f64, args[0], - "tmp1", currentBlock); - } - } else if (name->equals(loader->sqrt)) { - return llvm::CallInst::Create(module->func_llvm_sqrt_f64, args[0], - "tmp1", currentBlock); - } else if (name->equals(loader->sin)) { - return llvm::CallInst::Create(module->func_llvm_sin_f64, args[0], - "tmp1", currentBlock); - } else if (name->equals(loader->cos)) { - return llvm::CallInst::Create(module->func_llvm_cos_f64, args[0], - "tmp1", currentBlock); - } else if (name->equals(loader->tan)) { - return llvm::CallInst::Create(module->func_llvm_tan_f64, args[0], - "tmp1", currentBlock); - } else if (name->equals(loader->asin)) { - return llvm::CallInst::Create(module->func_llvm_asin_f64, args[0], - "tmp1", currentBlock); - } else if (name->equals(loader->acos)) { - return llvm::CallInst::Create(module->func_llvm_acos_f64, args[0], - "tmp1", currentBlock); - } else if (name->equals(loader->atan)) { - return llvm::CallInst::Create(module->func_llvm_atan_f64, args[0], - "tmp1", currentBlock); - } else if (name->equals(loader->atan2)) { - return llvm::CallInst::Create(module->func_llvm_atan2_f64, - args.begin(), args.end(), "tmp1", - currentBlock); - } else if (name->equals(loader->exp)) { - return llvm::CallInst::Create(module->func_llvm_exp_f64, args[0], - "tmp1", currentBlock); - } else if (name->equals(loader->log)) { - return llvm::CallInst::Create(module->func_llvm_log_f64, args[0], - "tmp1", currentBlock); - } else if (name->equals(loader->pow)) { - return llvm::CallInst::Create(module->func_llvm_pow_f64, args.begin(), - args.end(), "tmp1", currentBlock); - } else if (name->equals(loader->ceil)) { - return llvm::CallInst::Create(module->func_llvm_ceil_f64, args[0], "tmp1", - currentBlock); - } else if (name->equals(loader->floor)) { - return llvm::CallInst::Create(module->func_llvm_floor_f64, args[0], - "tmp1", currentBlock); - } else if (name->equals(loader->rint)) { - return llvm::CallInst::Create(module->func_llvm_rint_f64, args[0], - "tmp1", currentBlock); - } else if (name->equals(loader->cbrt)) { - return llvm::CallInst::Create(module->func_llvm_cbrt_f64, args[0], "tmp1", - currentBlock); - } else if (name->equals(loader->cosh)) { - return llvm::CallInst::Create(module->func_llvm_cosh_f64, args[0], "tmp1", - currentBlock); - } else if (name->equals(loader->expm1)) { - return llvm::CallInst::Create(module->func_llvm_expm1_f64, args[0], - "tmp1", currentBlock); - } else if (name->equals(loader->hypot)) { - return llvm::CallInst::Create(module->func_llvm_hypot_f64, args[0], - "tmp1", currentBlock); - } else if (name->equals(loader->log10)) { - return llvm::CallInst::Create(module->func_llvm_log10_f64, args[0], - "tmp1", currentBlock); - } else if (name->equals(loader->log1p)) { - return llvm::CallInst::Create(module->func_llvm_log1p_f64, args[0], - "tmp1", currentBlock); - } else if (name->equals(loader->sinh)) { - return llvm::CallInst::Create(module->func_llvm_sinh_f64, args[0], - "tmp1", currentBlock); - } else if (name->equals(loader->tanh)) { - return llvm::CallInst::Create(module->func_llvm_tanh_f64, args[0], - "tmp1", currentBlock); - } - - return 0; - -} - - -Instruction* JavaJIT::invokeInline(JavaMethod* meth, - std::vector& args) { - JavaJIT jit(meth, llvmFunction); - jit.unifiedUnreachable = unifiedUnreachable; - jit.inlineMethods = inlineMethods; - jit.inlineMethods[meth] = true; - jit.inlining = true; - Instruction* ret = jit.inlineCompile(currentBlock, - currentExceptionBlock, args); - inlineMethods[meth] = false; - return ret; -} - -void JavaJIT::invokeSpecial(uint16 index, CommonClass* finalCl) { - JavaConstantPool* ctpInfo = compilingClass->ctpInfo; - JavaMethod* meth = 0; - Signdef* signature = 0; - const UTF8* name = 0; - const UTF8* cl = 0; - - ctpInfo->nameOfStaticOrSpecialMethod(index, cl, name, signature); - LLVMSignatureInfo* LSI = module->getSignatureInfo(signature); - const llvm::FunctionType* virtualType = LSI->getVirtualType(); - llvm::Instruction* val = 0; - - std::vector args; - FunctionType::param_iterator it = virtualType->param_end(); - makeArgs(it, index, args, signature->nbArguments + 1); - Function* func = 0; - - if (finalCl) { - Class* lookup = finalCl->isArray() ? finalCl->super : finalCl->asClass(); - - meth = lookup->lookupMethodDontThrow(name, signature->keyName, false, true, - 0); - if (meth) { - // don't throw if no meth, the exception will be thrown just in time - JnjvmModule* M = compilingClass->classLoader->getModule(); - func = M->getMethod(meth); - } - } - - if (!func) { - func = (Function*)ctpInfo->infoOfStaticOrSpecialMethod(index, ACC_VIRTUAL, - signature, meth); - } - - if (meth == compilingClass->classLoader->bootstrapLoader->upcalls->InitObject) - return; - - JITVerifyNull(args[0]); - -#if defined(ISOLATE_SHARING) - const Type* Ty = module->ConstantPoolType; - Constant* Nil = Constant::getNullValue(Ty); - GlobalVariable* GV = new GlobalVariable(Ty, false, - GlobalValue::ExternalLinkage, Nil, - "", module); - Value* res = new LoadInst(GV, "", false, currentBlock); - Value* test = new ICmpInst(ICmpInst::ICMP_EQ, res, Nil, "", currentBlock); - - BasicBlock* trueCl = createBasicBlock("UserCtp OK"); - BasicBlock* falseCl = createBasicBlock("UserCtp Not OK"); - PHINode* node = llvm::PHINode::Create(Ty, "", trueCl); - node->addIncoming(res, currentBlock); - BranchInst::Create(falseCl, trueCl, test, currentBlock); - std::vector Args; - Args.push_back(ctpCache); - Args.push_back(ConstantInt::get(Type::Int32Ty, index)); - Args.push_back(GV); - res = CallInst::Create(module->SpecialCtpLookupFunction, Args.begin(), - Args.end(), "", falseCl); - node->addIncoming(res, falseCl); - BranchInst::Create(trueCl, falseCl); - currentBlock = trueCl; - args.push_back(node); -#endif - - if (!meth) { - // Make sure the class is loaded before materializing the method. - uint32 clIndex = ctpInfo->getClassIndexFromMethod(index); - UserCommonClass* cl = 0; - Value* Cl = getResolvedCommonClass(clIndex, false, &cl); - if (!cl) { - CallInst::Create(module->ForceLoadedCheckFunction, Cl, "", currentBlock); - } - } - - if (meth && canBeInlined(meth)) { - val = invokeInline(meth, args); - } else { - val = invoke(func, args, "", currentBlock); - } - - const llvm::Type* retType = virtualType->getReturnType(); - if (retType != Type::VoidTy) { - push(val, signature->getReturnType()->isUnsigned()); - if (retType == Type::DoubleTy || retType == Type::Int64Ty) { - push(module->constantZero, false); - } - } - -} - -void JavaJIT::invokeStatic(uint16 index) { - JavaConstantPool* ctpInfo = compilingClass->ctpInfo; - JavaMethod* meth = 0; - Signdef* signature = 0; - const UTF8* name = 0; - const UTF8* cl = 0; - ctpInfo->nameOfStaticOrSpecialMethod(index, cl, name, signature); - LLVMSignatureInfo* LSI = module->getSignatureInfo(signature); - const llvm::FunctionType* staticType = LSI->getStaticType(); - llvm::Instruction* val = 0; - - std::vector args; // size = [signature->nbIn + 2]; - FunctionType::param_iterator it = staticType->param_end(); - makeArgs(it, index, args, signature->nbArguments); - ctpInfo->markAsStaticCall(index); - - JnjvmBootstrapLoader* loader = compilingClass->classLoader->bootstrapLoader; - if (cl->equals(loader->mathName)) { - val = lowerMathOps(name, args); - } - - else if (cl->equals(loader->stackWalkerName)) { - callsStackWalker = true; - } - - if (!val) { - Function* func = (Function*) - ctpInfo->infoOfStaticOrSpecialMethod(index, ACC_STATIC, - signature, meth); - -#if defined(ISOLATE_SHARING) - Value* newCtpCache = getConstantPoolAt(index, - module->StaticCtpLookupFunction, - module->ConstantPoolType, 0, - false); - args.push_back(newCtpCache); -#endif - - uint32 clIndex = ctpInfo->getClassIndexFromMethod(index); - UserClass* cl = 0; - Value* Cl = getResolvedClass(clIndex, true, true, &cl); - if (!meth || (cl && needsInitialisationCheck(cl, compilingClass))) { - CallInst::Create(module->ForceInitialisationCheckFunction, Cl, "", - currentBlock); - } - - if (meth && canBeInlined(meth)) { - val = invokeInline(meth, args); - } else { - val = invoke(func, args, "", currentBlock); - } - - } - - const llvm::Type* retType = staticType->getReturnType(); - if (retType != Type::VoidTy) { - push(val, signature->getReturnType()->isUnsigned()); - if (retType == Type::DoubleTy || retType == Type::Int64Ty) { - push(module->constantZero, false); - } - } -} - -Value* JavaJIT::getConstantPoolAt(uint32 index, Function* resolver, - const Type* returnType, - Value* additionalArg, bool doThrow) { - -// This makes unswitch loop very unhappy time-wise, but makes GVN happy -// number-wise. IMO, it's better to have this than Unswitch. -#ifdef ISOLATE_SHARING - Value* CTP = ctpCache; - Value* Cl = GetElementPtrInst::Create(CTP, module->ConstantOne, "", - currentBlock); - Cl = new LoadInst(Cl, "", currentBlock); -#else - JavaConstantPool* ctp = compilingClass->ctpInfo; - Value* CTP = module->getConstantPool(ctp); - Value* Cl = module->getNativeClass(compilingClass); -#endif - - std::vector Args; - Args.push_back(resolver); - Args.push_back(CTP); - Args.push_back(Cl); - Args.push_back(ConstantInt::get(Type::Int32Ty, index)); - if (additionalArg) Args.push_back(additionalArg); - - Value* res = 0; - if (doThrow) { - res = invoke(module->GetConstantPoolAtFunction, Args, "", - currentBlock); - } else { - res = CallInst::Create(module->GetConstantPoolAtFunction, Args.begin(), - Args.end(), "", currentBlock); - } - - const Type* realType = - module->GetConstantPoolAtFunction->getReturnType(); - if (returnType == Type::Int32Ty) { - return new PtrToIntInst(res, Type::Int32Ty, "", currentBlock); - } else if (returnType != realType) { - return new BitCastInst(res, returnType, "", currentBlock); - } - - return res; -} - -Value* JavaJIT::getResolvedCommonClass(uint16 index, bool doThrow, - UserCommonClass** alreadyResolved) { - - JavaConstantPool* ctpInfo = compilingClass->ctpInfo; - CommonClass* cl = ctpInfo->getMethodClassIfLoaded(index); - Value* node = 0; - if (cl && (!cl->isClass() || cl->asClass()->isResolved())) { - if (alreadyResolved) *alreadyResolved = cl; - node = module->getNativeClass(cl); - // Since we only allocate for array classes that we own and - // ony primitive arrays are already allocated, verify that the class - // array is not external. - if (module->isStaticCompiling() && cl->isArray() && - node->getType() != module->JavaClassArrayType) { - node = new LoadInst(node, "", currentBlock); - } - if (node->getType() != module->JavaCommonClassType) { - node = new BitCastInst(node, module->JavaCommonClassType, "", - currentBlock); - } - } else { - node = getConstantPoolAt(index, module->ClassLookupFunction, - module->JavaCommonClassType, 0, doThrow); - } - - return node; -} - -Value* JavaJIT::getResolvedClass(uint16 index, bool clinit, bool doThrow, - Class** alreadyResolved) { - - JavaConstantPool* ctpInfo = compilingClass->ctpInfo; - Class* cl = (Class*)(ctpInfo->getMethodClassIfLoaded(index)); - Value* node = 0; - if (cl && cl->isResolved()) { - if (alreadyResolved) (*alreadyResolved) = cl; - node = module->getNativeClass(cl); - } else { - node = getConstantPoolAt(index, module->ClassLookupFunction, - module->JavaClassType, 0, doThrow); - } - - if (!(!clinit || (cl && !needsInitialisationCheck(cl, compilingClass)))) { - if (node->getType() != module->JavaClassType) { - node = new BitCastInst(node, module->JavaClassType, "", currentBlock); - } - return invoke(module->InitialisationCheckFunction, node, "", - currentBlock); - } else { - return node; - } -} - -void JavaJIT::invokeNew(uint16 index) { - - Class* cl = 0; - Value* Cl = getResolvedClass(index, true, true, &cl); - - Value* VT = 0; - Value* Size = 0; - - if (cl) { - VT = module->getVirtualTable(cl); - LLVMClassInfo* LCI = module->getClassInfo(cl); - Size = LCI->getVirtualSize(); - } else { - VT = CallInst::Create(module->GetVTFromClassFunction, Cl, "", - currentBlock); - Size = CallInst::Create(module->GetObjectSizeFromClassFunction, Cl, - "", currentBlock); - } - - Value* val = invoke(module->JavaObjectAllocateFunction, Size, VT, "", - currentBlock); - - // Set the class - - Value* gep[2] = { module->constantZero, - module->JavaObjectClassOffsetConstant }; - Value* GEP = GetElementPtrInst::Create(val, gep, gep + 2, "", - currentBlock); - Cl = new BitCastInst(Cl, module->JavaCommonClassType, "", currentBlock); - new StoreInst(Cl, GEP, currentBlock); - - Value* gep2[2] = { module->constantZero, - module->JavaObjectLockOffsetConstant }; - Value* lockPtr = GetElementPtrInst::Create(val, gep2, gep2 + 2, "", - currentBlock); - Value* threadId = getCurrentThread(); - threadId = new BitCastInst(threadId, module->ptrType, "", currentBlock); - new StoreInst(threadId, lockPtr, currentBlock); - - push(val, false); -} - -Value* JavaJIT::ldResolved(uint16 index, bool stat, Value* object, - const Type* fieldType, const Type* fieldTypePtr) { - JavaConstantPool* info = compilingClass->ctpInfo; - - JavaField* field = info->lookupField(index, stat); - if (field && field->classDef->isResolved()) { - LLVMClassInfo* LCI = (LLVMClassInfo*)module->getClassInfo(field->classDef); - LLVMFieldInfo* LFI = module->getFieldInfo(field); - const Type* type = 0; - if (stat) { - type = LCI->getStaticType(); - Value* Cl = module->getNativeClass(field->classDef); - bool needsCheck = needsInitialisationCheck(field->classDef, - compilingClass); - if (needsCheck) { - Cl = invoke(module->InitialisationCheckFunction, Cl, "", - currentBlock); - } -#if !defined(ISOLATE) && !defined(ISOLATE_SHARING) - if (needsCheck) { - CallInst::Create(module->ForceInitialisationCheckFunction, Cl, "", - currentBlock); - } - - object = module->getStaticInstance(field->classDef); -#else - object = CallInst::Create(module->GetStaticInstanceFunction, Cl, "", - currentBlock); -#endif - } else { - type = LCI->getVirtualType(); - } - - 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; - Constant* zero = module->constantZero; - - Function* func = stat ? module->StaticFieldLookupFunction : - module->VirtualFieldLookupFunction; - - const Type* returnType = 0; - if (stat) - returnType = module->ptrType; - else - returnType = Type::Int32Ty; - - Value* ptr = getConstantPoolAt(index, func, returnType, 0, true); - if (!stat) { - Value* tmp = new BitCastInst(object, Pty, "", currentBlock); - Value* args[2] = { zero, ptr }; - ptr = GetElementPtrInst::Create(tmp, args, args + 2, "", currentBlock); - } - - return new BitCastInst(ptr, fieldTypePtr, "", currentBlock); -} - -void JavaJIT::convertValue(Value*& val, const Type* t1, BasicBlock* currentBlock, - bool usign) { - const Type* t2 = val->getType(); - if (t1 != t2) { - if (t1->isInteger() && t2->isInteger()) { - if (t2->getPrimitiveSizeInBits() < t1->getPrimitiveSizeInBits()) { - if (usign) { - val = new ZExtInst(val, t1, "", currentBlock); - } else { - val = new SExtInst(val, t1, "", currentBlock); - } - } else { - val = new TruncInst(val, t1, "", currentBlock); - } - } else if (t1->isFloatingPoint() && t2->isFloatingPoint()) { - if (t2->getPrimitiveSizeInBits() < t1->getPrimitiveSizeInBits()) { - val = new FPExtInst(val, t1, "", currentBlock); - } else { - val = new FPTruncInst(val, t1, "", currentBlock); - } - } else if (isa(t1) && isa(t2)) { - val = new BitCastInst(val, t1, "", currentBlock); - } - } -} - - -void JavaJIT::setStaticField(uint16 index) { - bool unsign = topSign(); - Value* val = pop(); - - Typedef* sign = compilingClass->ctpInfo->infoOfField(index); - LLVMAssessorInfo& LAI = module->getTypedefInfo(sign); - const Type* type = LAI.llvmType; - - if (type == Type::Int64Ty || type == Type::DoubleTy) { - val = pop(); - } - - Value* ptr = ldResolved(index, true, 0, type, LAI.llvmTypePtr); - - if (type != val->getType()) { // int1, int8, int16 - convertValue(val, type, currentBlock, unsign); - } - - new StoreInst(val, ptr, false, currentBlock); -} - -void JavaJIT::getStaticField(uint16 index) { - Typedef* sign = compilingClass->ctpInfo->infoOfField(index); - LLVMAssessorInfo& LAI = module->getTypedefInfo(sign); - const Type* type = LAI.llvmType; - - Value* ptr = ldResolved(index, true, 0, type, LAI.llvmTypePtr); - - JnjvmBootstrapLoader* JBL = compilingClass->classLoader->bootstrapLoader; - bool final = false; - if (!compilingMethod->name->equals(JBL->clinitName)) { - JavaField* field = compilingClass->ctpInfo->lookupField(index, true); - if (field && field->classDef->isReady()) final = isFinal(field->access); - if (final) { - void* Obj = field->classDef->getStaticInstance(); - if (sign->isPrimitive()) { - const PrimitiveTypedef* prim = (PrimitiveTypedef*)sign; - if (prim->isInt()) { - sint32 val = field->getInt32Field(Obj); - push(ConstantInt::get(Type::Int32Ty, val), false); - } else if (prim->isByte()) { - sint8 val = (sint8)field->getInt8Field(Obj); - push(ConstantInt::get(Type::Int8Ty, val), false); - } else if (prim->isBool()) { - uint8 val = (uint8)field->getInt8Field(Obj); - push(ConstantInt::get(Type::Int8Ty, val), true); - } else if (prim->isShort()) { - sint16 val = (sint16)field->getInt16Field(Obj); - push(ConstantInt::get(Type::Int16Ty, val), false); - } else if (prim->isChar()) { - uint16 val = (uint16)field->getInt16Field(Obj); - push(ConstantInt::get(Type::Int16Ty, val), true); - } else if (prim->isLong()) { - sint64 val = (sint64)field->getLongField(Obj); - push(ConstantInt::get(Type::Int64Ty, val), false); - } else if (prim->isFloat()) { - float val = (float)field->getFloatField(Obj); - push(ConstantFP::get(Type::FloatTy, val), false); - } else if (prim->isDouble()) { - double val = (double)field->getDoubleField(Obj); - push(ConstantFP::get(Type::DoubleTy, val), false); - } else { - abort(); - } - } else { - JavaObject* val = field->getObjectField(Obj); - Value* V = module->getFinalObject(val); - push(V, false); - } - } - } - - if (!final) push(new LoadInst(ptr, "", currentBlock), sign->isUnsigned()); - if (type == Type::Int64Ty || type == Type::DoubleTy) { - push(module->constantZero, false); - } -} - -void JavaJIT::setVirtualField(uint16 index) { - bool unsign = topSign(); - Value* val = pop(); - Typedef* sign = compilingClass->ctpInfo->infoOfField(index); - LLVMAssessorInfo& LAI = module->getTypedefInfo(sign); - const Type* type = LAI.llvmType; - - if (type == Type::Int64Ty || type == Type::DoubleTy) { - val = pop(); - } - - Value* object = pop(); - JITVerifyNull(object); - Value* ptr = ldResolved(index, false, object, type, LAI.llvmTypePtr); - - if (type != val->getType()) { // int1, int8, int16 - convertValue(val, type, currentBlock, unsign); - } - - new StoreInst(val, ptr, false, currentBlock); -} - -void JavaJIT::getVirtualField(uint16 index) { - Typedef* sign = compilingClass->ctpInfo->infoOfField(index); - LLVMAssessorInfo& LAI = module->getTypedefInfo(sign); - const Type* type = LAI.llvmType; - Value* obj = pop(); - JITVerifyNull(obj); - - Value* ptr = ldResolved(index, false, obj, type, LAI.llvmTypePtr); - - JnjvmBootstrapLoader* JBL = compilingClass->classLoader->bootstrapLoader; - bool final = false; - if (!compilingMethod->name->equals(JBL->initName)) { - JavaField* field = compilingClass->ctpInfo->lookupField(index, false); - if (field) final = isFinal(field->access); - if (final) { - Function* F = 0; - if (sign->isPrimitive()) { - const PrimitiveTypedef* prim = (PrimitiveTypedef*)sign; - if (prim->isInt()) { - F = module->GetFinalInt32FieldFunction; - } else if (prim->isByte()) { - F = module->GetFinalInt8FieldFunction; - } else if (prim->isBool()) { - F = module->GetFinalInt8FieldFunction; - } else if (prim->isShort()) { - F = module->GetFinalInt16FieldFunction; - } else if (prim->isChar()) { - F = module->GetFinalInt16FieldFunction; - } else if (prim->isLong()) { - F = module->GetFinalLongFieldFunction; - } else if (prim->isFloat()) { - F = module->GetFinalFloatFieldFunction; - } else if (prim->isDouble()) { - F = module->GetFinalDoubleFieldFunction; - } else { - abort(); - } - } else { - F = module->GetFinalObjectFieldFunction; - } - push(CallInst::Create(F, ptr, "", currentBlock), sign->isUnsigned()); - } - } - - if (!final) push(new LoadInst(ptr, "", currentBlock), sign->isUnsigned()); - if (type == Type::Int64Ty || type == Type::DoubleTy) { - push(module->constantZero, false); - } -} - - -void JavaJIT::invokeInterface(uint16 index, bool buggyVirtual) { - - // Do the usual - JavaConstantPool* ctpInfo = compilingClass->ctpInfo; - const UTF8* name = 0; - Signdef* signature = ctpInfo->infoOfInterfaceOrVirtualMethod(index, name); - - LLVMSignatureInfo* LSI = module->getSignatureInfo(signature); - const llvm::FunctionType* virtualType = LSI->getVirtualType(); - const llvm::PointerType* virtualPtrType = LSI->getVirtualPtrType(); - - std::vector args; // size = [signature->nbIn + 3]; - - FunctionType::param_iterator it = virtualType->param_end(); - makeArgs(it, index, args, signature->nbArguments + 1); - - const llvm::Type* retType = virtualType->getReturnType(); - BasicBlock* endBlock = createBasicBlock("end virtual invoke"); - PHINode * node = 0; - if (retType != Type::VoidTy) { - node = PHINode::Create(retType, "", endBlock); - } - - JITVerifyNull(args[0]); - - Value* zero = module->constantZero; - Value* one = module->constantOne; - -#ifndef ISOLATE_SHARING - // ok now the cache - Enveloppe& enveloppe = buggyVirtual ? - *(new (compilingClass->classLoader->allocator) Enveloppe()) : - compilingMethod->enveloppes[nbEnveloppes++]; - if (!inlining) - enveloppe.initialise(compilingClass, name, signature->keyName); - - Value* llvmEnv = module->getEnveloppe(&enveloppe); -#else - Value* llvmEnv = getConstantPoolAt(index, - module->EnveloppeLookupFunction, - module->EnveloppeType, 0, false); -#endif - - Value* args1[2] = { zero, zero }; - Value* cachePtr = GetElementPtrInst::Create(llvmEnv, args1, args1 + 2, - "", currentBlock); - Value* cache = new LoadInst(cachePtr, "", currentBlock); - - Value* cl = CallInst::Create(module->GetClassFunction, args[0], "", - currentBlock); - Value* args3[2] = { zero, one }; - Value* lastCiblePtr = GetElementPtrInst::Create(cache, args3, args3 + 2, "", - currentBlock); - Value* lastCible = new LoadInst(lastCiblePtr, "", currentBlock); - - Value* cmp = new ICmpInst(ICmpInst::ICMP_EQ, cl, lastCible, "", currentBlock); - - BasicBlock* ifTrue = createBasicBlock("cache ok"); - BasicBlock* ifFalse = createBasicBlock("cache not ok"); - BranchInst::Create(ifTrue, ifFalse, cmp, currentBlock); - - currentBlock = ifFalse; - Value* _meth = invoke(module->InterfaceLookupFunction, cache, args[0], - "", ifFalse); - Value* meth = new BitCastInst(_meth, virtualPtrType, "", - currentBlock); -#ifdef ISOLATE_SHARING - Value* cache2 = new LoadInst(cachePtr, "", currentBlock); - Value* newCtpCache = CallInst::Create(module->GetCtpCacheNodeFunction, - cache2, "", currentBlock); - args.push_back(newCtpCache); -#endif - Value* ret = invoke(meth, args, "", currentBlock); - if (node) { - node->addIncoming(ret, currentBlock); - } - BranchInst::Create(endBlock, currentBlock); - - currentBlock = ifTrue; - - Value* methPtr = GetElementPtrInst::Create(cache, args1, args1 + 2, - "", currentBlock); - - _meth = new LoadInst(methPtr, "", currentBlock); - meth = new BitCastInst(_meth, virtualPtrType, "", currentBlock); - -#ifdef ISOLATE_SHARING - args.pop_back(); - cache = new LoadInst(cachePtr, "", currentBlock); - newCtpCache = CallInst::Create(module->GetCtpCacheNodeFunction, - cache, "", currentBlock); - args.push_back(newCtpCache); -#endif - ret = invoke(meth, args, "", currentBlock); - BranchInst::Create(endBlock, currentBlock); - - if (node) { - node->addIncoming(ret, currentBlock); - } - - currentBlock = endBlock; - if (node) { - push(node, signature->getReturnType()->isUnsigned()); - if (retType == Type::DoubleTy || retType == Type::Int64Ty) { - push(module->constantZero, false); - } - } -} - - -#ifdef DWARF_EXCEPTIONS -#include "ExceptionsDwarf.inc" -#else -#include "ExceptionsCheck.inc" -#endif Removed: vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.h URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.h?rev=65456&view=auto ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.h (original) +++ vmkit/trunk/lib/JnJVM/VMCore/JavaJIT.h (removed) @@ -1,632 +0,0 @@ -//===----------- JavaJIT.h - Java just in time compiler -------------------===// -// -// JnJVM -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef JNJVM_JAVA_JIT_H -#define JNJVM_JAVA_JIT_H - -#include -#include - -#include "llvm/BasicBlock.h" -#include "llvm/Function.h" -#include "llvm/Instructions.h" -#include "llvm/Type.h" -#include "llvm/Value.h" - -#include "types.h" - -#include "JavaClass.h" -#include "JnjvmModule.h" - -namespace jnjvm { - -class Class; -class JavaMethod; -class Reader; -class UTF8; - -/// 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; - - /// exceptionBlock - Never null, the exception destination of the - /// instruction. - /// - llvm::BasicBlock* exceptionBlock; -}; - - -/// 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; - compilingClass = meth->classDef; - module = compilingClass->classLoader->getModule(); - llvmFunction = func; - inlining = false; - callsStackWalker = false; - endNode = 0; - } - - /// 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 intLocals; - std::vector longLocals; - std::vector floatLocals; - std::vector doubleLocals; - std::vector 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); - - /// getCurrentThread - Emit code to get the current thread. - llvm::Value* getCurrentThread(); - -//===--------------------------- 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& args); - - - /// inlineMethods - Methods that are currently being inlined. The JIT - /// uses this map to not inline a method currently bein inlined. - std::map inlineMethods; - - /// inlining - Are we JITting a method inline? - bool inlining; - - /// canBeInlined - Can this method's body be inlined? - bool canBeInlined(JavaMethod* meth); - - /// callsStackWalker - Is the method calling a stack walker method? If it is, - /// then this method can not be inlined. - bool callsStackWalker; - - -//===------------------------- Bytecode parsing ---------------------------===// - - /// compileOpcodes - Parse the bytecode and create LLVM instructions. - void compileOpcodes(uint8* bytecodes, uint32 codeLength); - - /// 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); - - /// loadConstant - Load a constant from the _ldc bytecode. - void loadConstant(uint16 index); - -//===------------------------- Runtime exceptions -------------------------===// - - /// 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 - The compiler stack. We store the value and its sign. - std::vector< std::pair > 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 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; - } - - /// 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 = topSign(); - stack.pop_back(); - - if (ret->getType() != llvm::Type::Int32Ty) { - if (unsign) { - ret = new llvm::ZExtInst(ret, llvm::Type::Int32Ty, "", currentBlock); - } else { - ret = new llvm::SExtInst(ret, llvm::Type::Int32Ty, "", currentBlock); - } - } - return ret; - } - - /// popPair - Pop the pair on the stack and return it. - std::pair popPair() { - std::pair ret = stack.back(); - stack.pop_back(); - return ret; - } - -//===------------------------- Exception support --------------------------===// - - /// jsrs - The list of jsrs (jump subroutine) instructions. - std::vector jsrs; - - /// 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; - - /// throwException - Emit code to throw an exception. - void throwException(llvm::Function* F, llvm::Value** args, - uint32 nbArgs); - void throwException(llvm::Function* F, llvm::Value* arg1); - void throwException(llvm::Value* obj); - - /// finishExceptions - Emit code to unwind the current function if an - /// exception is thrown. - void finishExceptions(); -//===--------------------------- Control flow ----------------------------===// - - /// opcodeInfos - The informations for each instruction. - Opinfo* opcodeInfos; - - /// 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); - } - - /// 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) { - testPHINodes(ifTrue, insert); - testPHINodes(ifFalse, insert); - llvm::BranchInst::Create(ifTrue, ifFalse, test, insert); - } - - /// branch - Branch to a new block. Update PHI nodes accordingly. - void branch(llvm::BasicBlock* dest, llvm::BasicBlock* insert) { - testPHINodes(dest, insert); - llvm::BranchInst::Create(dest, insert); - } - - /// testPHINodes - Update PHI nodes when branching to a new block. - void testPHINodes(llvm::BasicBlock* dest, llvm::BasicBlock* insert); - - -//===-------------------------- Synchronization --------------------------===// - - /// 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); - -//===----------------------- 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); - -//===--------------------- 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); - - /// 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& result, uint32 nb); - - /// invokeVirtual - Invoke a Java virtual method. - void invokeVirtual(uint16 index); - - /// 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, CommonClass* finalCl = 0); - - /// 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& args); - - /// lowerMathOps - Map Java Math operations to LLVM intrinsics. - llvm::Instruction* lowerMathOps(const UTF8* name, - std::vector& args); - - /// invoke - invoke the LLVM method of a Java method. - llvm::Instruction* invoke(llvm::Value *F, std::vector&args, - const char* Name, - llvm::BasicBlock *InsertAtEnd); - llvm::Instruction* invoke(llvm::Value *F, llvm::Value *Actual1, - llvm::Value *Actual2, const char* Name, - llvm::BasicBlock *InsertAtEnd); - llvm::Instruction* invoke(llvm::Value *F, llvm::Value *Actual1, - const char* Name, llvm::BasicBlock *InsertAtEnd); - llvm::Instruction* invoke(llvm::Value *F, const char* Name, - llvm::BasicBlock *InsertAtEnd); - - /// nbEnveloppes - Number of enveloppes (ie invokeinterface) in this - /// method. - uint32 nbEnveloppes; - - - -#if defined(ISOLATE_SHARING) -//===----------------- Sharing bytecode support ---------------------------===// - - /// isolateLocal - The Jnjvm object that the method is currently executing. - llvm::Value* isolateLocal; - - /// 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 - -}; - -enum Opcode { - NOP = 0x00, - ACONST_NULL = 0x01, - ICONST_M1 = 0x02, - ICONST_0 = 0x03, - ICONST_1 = 0x04, - ICONST_2 = 0x05, - ICONST_3 = 0x06, - ICONST_4 = 0x07, - ICONST_5 = 0x08, - LCONST_0 = 0x09, - LCONST_1 = 0x0A, - FCONST_0 = 0x0B, - FCONST_1 = 0x0C, - FCONST_2 = 0x0D, - DCONST_0 = 0x0E, - DCONST_1 = 0x0F, - BIPUSH = 0x10, - SIPUSH = 0x11, - LDC = 0x12, - LDC_W = 0x13, - LDC2_W = 0x14, - ILOAD = 0x15, - LLOAD = 0x16, - FLOAD = 0x17, - DLOAD = 0x18, - ALOAD = 0x19, - ILOAD_0 = 0x1A, - ILOAD_1 = 0x1B, - ILOAD_2 = 0x1C, - ILOAD_3 = 0x1D, - LLOAD_0 = 0x1E, - LLOAD_1 = 0x1F, - LLOAD_2 = 0x20, - LLOAD_3 = 0x21, - FLOAD_0 = 0x22, - FLOAD_1 = 0x23, - FLOAD_2 = 0x24, - FLOAD_3 = 0x25, - DLOAD_0 = 0x26, - DLOAD_1 = 0x27, - DLOAD_2 = 0x28, - DLOAD_3 = 0x29, - ALOAD_0 = 0x2A, - ALOAD_1 = 0x2B, - ALOAD_2 = 0x2C, - ALOAD_3 = 0x2D, - IALOAD = 0x2E, - LALOAD = 0x2F, - FALOAD = 0x30, - DALOAD = 0x31, - AALOAD = 0x32, - BALOAD = 0x33, - CALOAD = 0x34, - SALOAD = 0x35, - ISTORE = 0x36, - LSTORE = 0x37, - FSTORE = 0x38, - DSTORE = 0x39, - ASTORE = 0x3A, - ISTORE_0 = 0x3B, - ISTORE_1 = 0x3C, - ISTORE_2 = 0x3D, - ISTORE_3 = 0x3E, - LSTORE_0 = 0x3F, - LSTORE_1 = 0x40, - LSTORE_2 = 0x41, - LSTORE_3 = 0x42, - FSTORE_0 = 0x43, - FSTORE_1 = 0x44, - FSTORE_2 = 0x45, - FSTORE_3 = 0x46, - DSTORE_0 = 0x47, - DSTORE_1 = 0x48, - DSTORE_2 = 0x49, - DSTORE_3 = 0x4A, - ASTORE_0 = 0x4B, - ASTORE_1 = 0x4C, - ASTORE_2 = 0x4D, - ASTORE_3 = 0x4E, - IASTORE = 0x4F, - LASTORE = 0x50, - FASTORE = 0x51, - DASTORE = 0x52, - AASTORE = 0x53, - BASTORE = 0x54, - CASTORE = 0x55, - SASTORE = 0x56, - POP = 0x57, - POP2 = 0x58, - DUP = 0x59, - DUP_X1 = 0x5A, - DUP_X2 = 0x5B, - DUP2 = 0x5C, - DUP2_X1 = 0x5D, - DUP2_X2 = 0x5E, - SWAP = 0x5F, - IADD = 0x60, - LADD = 0x61, - FADD = 0x62, - DADD = 0x63, - ISUB = 0x64, - LSUB = 0x65, - FSUB = 0x66, - DSUB = 0x67, - IMUL = 0x68, - LMUL = 0x69, - FMUL = 0x6A, - DMUL = 0x6B, - IDIV = 0x6C, - LDIV = 0x6D, - FDIV = 0x6E, - DDIV = 0x6F, - IREM = 0x70, - LREM = 0x71, - FREM = 0x72, - DREM = 0x73, - INEG = 0x74, - LNEG = 0x75, - FNEG = 0x76, - DNEG = 0x77, - ISHL = 0x78, - LSHL = 0x79, - ISHR = 0x7A, - LSHR = 0x7B, - IUSHR = 0x7C, - LUSHR = 0x7D, - IAND = 0x7E, - LAND = 0x7F, - IOR = 0x80, - LOR = 0x81, - IXOR = 0x82, - LXOR = 0x83, - IINC = 0x84, - I2L = 0x85, - I2F = 0x86, - I2D = 0x87, - L2I = 0x88, - L2F = 0x89, - L2D = 0x8A, - F2I = 0x8B, - F2L = 0x8C, - F2D = 0x8D, - D2I = 0x8E, - D2L = 0x8F, - D2F = 0x90, - I2B = 0x91, - I2C = 0x92, - I2S = 0x93, - LCMP = 0x94, - FCMPL = 0x95, - FCMPG = 0x96, - DCMPL = 0x97, - DCMPG = 0x98, - IFEQ = 0x99, - IFNE = 0x9A, - IFLT = 0x9B, - IFGE = 0x9C, - IFGT = 0x9D, - IFLE = 0x9E, - IF_ICMPEQ = 0x9F, - IF_ICMPNE = 0xA0, - IF_ICMPLT = 0xA1, - IF_ICMPGE = 0xA2, - IF_ICMPGT = 0xA3, - IF_ICMPLE = 0xA4, - IF_ACMPEQ = 0xA5, - IF_ACMPNE = 0xA6, - GOTO = 0xA7, - JSR = 0xA8, - RET = 0xA9, - TABLESWITCH = 0xAA, - LOOKUPSWITCH = 0xAB, - IRETURN = 0xAC, - LRETURN = 0xAD, - FRETURN = 0xAE, - DRETURN = 0xAF, - ARETURN = 0xB0, - RETURN = 0xB1, - GETSTATIC = 0xB2, - PUTSTATIC = 0xB3, - GETFIELD = 0xB4, - PUTFIELD = 0xB5, - INVOKEVIRTUAL = 0xB6, - INVOKESPECIAL = 0xB7, - INVOKESTATIC = 0xB8, - INVOKEINTERFACE = 0xB9, - UNUSED = 0xBA, - NEW = 0xBB, - NEWARRAY = 0xBC, - ANEWARRAY = 0xBD, - ARRAYLENGTH = 0xBE, - ATHROW = 0xBF, - CHECKCAST = 0xC0, - INSTANCEOF = 0xC1, - MONITORENTER = 0xC2, - MONITOREXIT = 0xC3, - WIDE = 0xC4, - MULTIANEWARRAY = 0xC5, - IFNULL = 0xC6, - IFNONNULL = 0xC7, - GOTO_W = 0xC8, - JSR_W = 0xC9, - BREAKPOINT = 0xCA, - IMPDEP1 = 0xFE, - IMPDEP2 = 0xFF -}; - -} // end namespace jnjvm - -#endif Removed: vmkit/trunk/lib/JnJVM/VMCore/JavaJITOpcodes.cpp URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JavaJITOpcodes.cpp?rev=65456&view=auto ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/JavaJITOpcodes.cpp (original) +++ vmkit/trunk/lib/JnJVM/VMCore/JavaJITOpcodes.cpp (removed) @@ -1,2518 +0,0 @@ -//===---- JavaJITOpcodes.cpp - Reads and compiles opcodes -----------------===// -// -// JnJVM -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#define DEBUG 0 -#define JNJVM_COMPILE 0 -#define JNJVM_EXECUTE 0 - -#include - -#include -#include -#include -#include -#include -#include - -#include "mvm/JIT.h" - -#include "debug.h" - -#include "JavaArray.h" -#include "JavaClass.h" -#include "JavaConstantPool.h" -#include "JavaObject.h" -#include "JavaJIT.h" -#include "JavaThread.h" -#include "JavaTypes.h" -#include "Jnjvm.h" - -#include "OpcodeNames.def" - -using namespace jnjvm; -using namespace llvm; - -uint8 arrayType(unsigned int t) { - if (t == JavaArray::T_CHAR) { - return I_CHAR; - } else if (t == JavaArray::T_BOOLEAN) { - return I_BOOL; - } else if (t == JavaArray::T_INT) { - return I_INT; - } else if (t == JavaArray::T_SHORT) { - return I_SHORT; - } else if (t == JavaArray::T_BYTE) { - return I_BYTE; - } else if (t == JavaArray::T_FLOAT) { - return I_FLOAT; - } else if (t == JavaArray::T_LONG) { - return I_LONG; - } else if (t == JavaArray::T_DOUBLE) { - return I_DOUBLE; - } else { - JavaThread::get()->getJVM()->unknownError("unknown array type %d\n", t); - return 0; - } -} - -static inline sint8 readS1(uint8* bytecode, uint32& i) { - return ((sint8*)bytecode)[++i]; -} - -static inline uint8 readU1(uint8* bytecode, uint32& i) { - return bytecode[++i]; -} - -static inline sint16 readS2(uint8* bytecode, uint32& i) { - sint16 val = readS1(bytecode, i) << 8; - return val | readU1(bytecode, i); -} - -static inline uint16 readU2(uint8* bytecode, uint32& i) { - uint16 val = readU1(bytecode, i) << 8; - return val | readU1(bytecode, i); -} - -static inline sint32 readS4(uint8* bytecode, uint32& i) { - sint32 val = readU2(bytecode, i) << 16; - return val | readU2(bytecode, i); -} - - -static inline uint32 readU4(uint8* bytecode, uint32& i) { - return readS4(bytecode, i); -} - -static inline uint32 WREAD_U1(uint8* array, bool init, uint32 &i, bool& wide) { - if (wide) { - wide = init; - return readU2(array, i); - } else { - return readU1(array, i); - } -} - -static inline sint32 WREAD_S1(uint8* array, bool init, uint32 &i, bool &wide) { - if (wide) { - wide = init; - return readS2(array, i); - } else { - return readS1(array, i); - } -} - -static inline uint32 WCALC(uint32 n, bool& wide) { - if (wide) { - wide = false; - return n << 1; - } else { - return n; - } -} - -void JavaJIT::compileOpcodes(uint8* bytecodes, uint32 codeLength) { - bool wide = false; - uint32 jsrIndex = 0; - for(uint32 i = 0; i < codeLength; ++i) { - - PRINT_DEBUG(JNJVM_COMPILE, 1, COLOR_NORMAL, "\t[at %5d] %-5d ", i, - bytecodes[i]); - PRINT_DEBUG(JNJVM_COMPILE, 1, LIGHT_BLUE, "compiling "); - PRINT_DEBUG(JNJVM_COMPILE, 1, LIGHT_CYAN, OpcodeNames[bytecodes[i]]); - PRINT_DEBUG(JNJVM_COMPILE, 1, LIGHT_BLUE, "\n"); - - Opinfo* opinfo = &(opcodeInfos[i]); - if (opinfo->newBlock) { - if (currentBlock->getTerminator() == 0) { - branch(opinfo->newBlock, currentBlock); - } - - stack.clear(); - for (BasicBlock::iterator i = opinfo->newBlock->begin(), - e = opinfo->newBlock->end(); i != e; ++i) { - if (!(isa(i))) { - break; - } else { - stack.push_back(std::make_pair(i, false)); - } - } - - currentBlock = opinfo->newBlock; - } - currentExceptionBlock = opinfo->exceptionBlock; - - // To prevent a gcj bug with useless goto - if (currentBlock->getTerminator() != 0) { - currentBlock = createBasicBlock("gcj bug"); - } -#if JNJVM_EXECUTE > 1 - { - Value* args[3] = { - ConstantInt::get(Type::Int32Ty, (int64_t)bytecodes[i]), - ConstantInt::get(Type::Int32Ty, (int64_t)i), - module->getMethodInClass(compilingMethod) - }; - - - CallInst::Create(module->PrintExecutionFunction, args, args + 3, "", - currentBlock); - } -#endif - - switch (bytecodes[i]) { - - case NOP : break; - - case ACONST_NULL : - push(module->JavaObjectNullConstant, false); - break; - - case ICONST_M1 : - push(module->constantMinusOne, false); - break; - - case ICONST_0 : - push(module->constantZero, false); - break; - - case ICONST_1 : - push(module->constantOne, false); - break; - - case ICONST_2 : - push(module->constantTwo, false); - break; - - case ICONST_3 : - push(module->constantThree, false); - break; - - case ICONST_4 : - push(module->constantFour, false); - break; - - case ICONST_5 : - push(module->constantFive, false); - break; - - case LCONST_0 : - push(module->constantLongZero, false); - push(module->constantZero, false); - break; - - case LCONST_1 : - push(module->constantLongOne, false); - push(module->constantZero, false); - break; - - case FCONST_0 : - push(module->constantFloatZero, false); - break; - - case FCONST_1 : - push(module->constantFloatOne, false); - break; - - case FCONST_2 : - push(module->constantFloatTwo, false); - break; - - case DCONST_0 : - push(module->constantDoubleZero, false); - push(module->constantZero, false); - break; - - case DCONST_1 : - push(module->constantDoubleOne, false); - push(module->constantZero, false); - break; - - case BIPUSH : - push(ConstantExpr::getSExt(ConstantInt::get(Type::Int8Ty, - bytecodes[++i]), - Type::Int32Ty), false); - break; - - case SIPUSH : - push(ConstantExpr::getSExt(ConstantInt::get(Type::Int16Ty, - readS2(bytecodes, i)), - Type::Int32Ty), false); - break; - - case LDC : - loadConstant(bytecodes[++i]); - break; - - case LDC_W : - loadConstant(readS2(bytecodes, i)); - break; - - case LDC2_W : - loadConstant(readS2(bytecodes, i)); - push(module->constantZero, false); - break; - - case ILOAD : - push(new LoadInst(intLocals[WREAD_U1(bytecodes, false, i, wide)], "", - currentBlock), false); - break; - - case LLOAD : - 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, wide)], "", - currentBlock), false); - break; - - case DLOAD : - 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, wide)], "", - currentBlock), false); - break; - - case ILOAD_0 : - push(new LoadInst(intLocals[0], "", currentBlock), false); - break; - - case ILOAD_1 : - push(new LoadInst(intLocals[1], "", currentBlock), false); - break; - - case ILOAD_2 : - push(new LoadInst(intLocals[2], "", currentBlock), false); - break; - - case ILOAD_3 : - push(new LoadInst(intLocals[3], "", currentBlock), false); - break; - - case LLOAD_0 : - push(new LoadInst(longLocals[0], "", currentBlock), - false); - push(module->constantZero, false); - break; - - case LLOAD_1 : - push(new LoadInst(longLocals[1], "", currentBlock), - false); - push(module->constantZero, false); - break; - - case LLOAD_2 : - push(new LoadInst(longLocals[2], "", currentBlock), - false); - push(module->constantZero, false); - break; - - case LLOAD_3 : - push(new LoadInst(longLocals[3], "", currentBlock), - false); - push(module->constantZero, false); - break; - - case FLOAD_0 : - push(new LoadInst(floatLocals[0], "", currentBlock), - false); - break; - - case FLOAD_1 : - push(new LoadInst(floatLocals[1], "", currentBlock), - false); - break; - - case FLOAD_2 : - push(new LoadInst(floatLocals[2], "", currentBlock), - false); - break; - - case FLOAD_3 : - push(new LoadInst(floatLocals[3], "", currentBlock), - false); - break; - - case DLOAD_0 : - push(new LoadInst(doubleLocals[0], "", currentBlock), - false); - push(module->constantZero, false); - break; - - case DLOAD_1 : - push(new LoadInst(doubleLocals[1], "", currentBlock), - false); - push(module->constantZero, false); - break; - - case DLOAD_2 : - push(new LoadInst(doubleLocals[2], "", currentBlock), - false); - push(module->constantZero, false); - break; - - case DLOAD_3 : - push(new LoadInst(doubleLocals[3], "", currentBlock), - false); - push(module->constantZero, false); - break; - - case ALOAD_0 : - push(new LoadInst(objectLocals[0], "", currentBlock), - false); - break; - - case ALOAD_1 : - push(new LoadInst(objectLocals[1], "", currentBlock), - false); - break; - - case ALOAD_2 : - push(new LoadInst(objectLocals[2], "", currentBlock), - false); - break; - - case ALOAD_3 : - push(new LoadInst(objectLocals[3], "", currentBlock), - false); - break; - - case IALOAD : { - Value* index = pop(); - Value* obj = pop(); - Value* ptr = verifyAndComputePtr(obj, index, - module->JavaArraySInt32Type); - push(new LoadInst(ptr, "", currentBlock), false); - break; - } - - case LALOAD : { - Value* index = pop(); - Value* obj = pop(); - Value* ptr = verifyAndComputePtr(obj, index, - module->JavaArrayLongType); - push(new LoadInst(ptr, "", currentBlock), false); - push(module->constantZero, false); - break; - } - - case FALOAD : { - Value* index = pop(); - Value* obj = pop(); - Value* ptr = verifyAndComputePtr(obj, index, - module->JavaArrayFloatType); - push(new LoadInst(ptr, "", currentBlock), false); - break; - } - - case DALOAD : { - Value* index = pop(); - Value* obj = pop(); - Value* ptr = verifyAndComputePtr(obj, index, - module->JavaArrayDoubleType); - push(new LoadInst(ptr, "", currentBlock), false); - push(module->constantZero, false); - break; - } - - case AALOAD : { - Value* index = pop(); - Value* obj = pop(); - Value* ptr = verifyAndComputePtr(obj, index, - module->JavaArrayObjectType); - push(new LoadInst(ptr, "", currentBlock), false); - break; - } - - case BALOAD : { - Value* index = pop(); - Value* obj = pop(); - Value* ptr = verifyAndComputePtr(obj, index, - module->JavaArraySInt8Type); - Value* val = new LoadInst(ptr, "", currentBlock); - push(new SExtInst(val, Type::Int32Ty, "", currentBlock), - false); - break; - } - - case CALOAD : { - Value* index = pop(); - Value* obj = pop(); - Value* ptr = verifyAndComputePtr(obj, index, - module->JavaArrayUInt16Type); - Value* val = new LoadInst(ptr, "", currentBlock); - push(new ZExtInst(val, Type::Int32Ty, "", currentBlock), - false); - break; - } - - case SALOAD : { - Value* index = pop(); - Value* obj = pop(); - Value* ptr = verifyAndComputePtr(obj, index, - module->JavaArraySInt16Type); - Value* val = new LoadInst(ptr, "", currentBlock); - push(new SExtInst(val, Type::Int32Ty, "", currentBlock), - false); - break; - } - - case ISTORE : { - Value* val = popAsInt(); - 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, wide)], - false, currentBlock); - break; - - case FSTORE : - 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, wide)], - false, currentBlock); - break; - - case ASTORE : - new StoreInst(pop(), objectLocals[WREAD_U1(bytecodes, false, i, wide)], - false, currentBlock); - break; - - case ISTORE_0 : { - Value* val = pop(); - if (val->getType() != Type::Int32Ty) // int8 and int16 - val = new ZExtInst(val, Type::Int32Ty, "", currentBlock); - new StoreInst(val, intLocals[0], false, currentBlock); - break; - } - - case ISTORE_1 : { - Value* val = pop(); - if (val->getType() != Type::Int32Ty) // int8 and int16 - val = new ZExtInst(val, Type::Int32Ty, "", currentBlock); - new StoreInst(val, intLocals[1], false, currentBlock); - break; - } - - case ISTORE_2 : { - Value* val = pop(); - if (val->getType() != Type::Int32Ty) // int8 and int16 - val = new ZExtInst(val, Type::Int32Ty, "", currentBlock); - new StoreInst(val, intLocals[2], false, currentBlock); - break; - } - - case ISTORE_3 : { - Value* val = pop(); - if (val->getType() != Type::Int32Ty) // int8 and int16 - val = new ZExtInst(val, Type::Int32Ty, "", currentBlock); - new StoreInst(val, intLocals[3], false, currentBlock); - break; - } - - case LSTORE_0 : - pop(); // remove the 0 on the stack - new StoreInst(pop(), longLocals[0], false, currentBlock); - break; - - case LSTORE_1 : - pop(); // remove the 0 on the stack - new StoreInst(pop(), longLocals[1], false, currentBlock); - break; - - case LSTORE_2 : - pop(); // remove the 0 on the stack - new StoreInst(pop(), longLocals[2], false, currentBlock); - break; - - case LSTORE_3 : - pop(); // remove the 0 on the stack - new StoreInst(pop(), longLocals[3], false, currentBlock); - break; - - case FSTORE_0 : - new StoreInst(pop(), floatLocals[0], false, currentBlock); - break; - - case FSTORE_1 : - new StoreInst(pop(), floatLocals[1], false, currentBlock); - break; - - case FSTORE_2 : - new StoreInst(pop(), floatLocals[2], false, currentBlock); - break; - - case FSTORE_3 : - new StoreInst(pop(), floatLocals[3], false, currentBlock); - break; - - case DSTORE_0 : - pop(); // remove the 0 on the stack - new StoreInst(pop(), doubleLocals[0], false, currentBlock); - break; - - case DSTORE_1 : - pop(); // remove the 0 on the stack - new StoreInst(pop(), doubleLocals[1], false, currentBlock); - break; - - case DSTORE_2 : - pop(); // remove the 0 on the stack - new StoreInst(pop(), doubleLocals[2], false, currentBlock); - break; - - case DSTORE_3 : - pop(); // remove the 0 on the stack - new StoreInst(pop(), doubleLocals[3], false, currentBlock); - break; - - case ASTORE_0 : - new StoreInst(pop(), objectLocals[0], false, currentBlock); - break; - - case ASTORE_1 : - new StoreInst(pop(), objectLocals[1], false, currentBlock); - break; - - case ASTORE_2 : - new StoreInst(pop(), objectLocals[2], false, currentBlock); - break; - - case ASTORE_3 : - new StoreInst(pop(), objectLocals[3], false, currentBlock); - break; - - case IASTORE : { - Value* val = popAsInt(); - Value* index = popAsInt(); - Value* obj = pop(); - Value* ptr = verifyAndComputePtr(obj, index, - module->JavaArraySInt32Type); - new StoreInst(val, ptr, false, currentBlock); - break; - } - - case LASTORE : { - pop(); // remove the 0 on stack - Value* val = pop(); - Value* index = pop(); - Value* obj = pop(); - Value* ptr = verifyAndComputePtr(obj, index, - module->JavaArrayLongType); - new StoreInst(val, ptr, false, currentBlock); - break; - } - - case FASTORE : { - Value* val = pop(); - Value* index = pop(); - Value* obj = pop(); - Value* ptr = verifyAndComputePtr(obj, index, - module->JavaArrayFloatType); - new StoreInst(val, ptr, false, currentBlock); - break; - } - - case DASTORE : { - pop(); // remove the 0 on stack - Value* val = pop(); - Value* index = pop(); - Value* obj = pop(); - Value* ptr = verifyAndComputePtr(obj, index, - module->JavaArrayDoubleType); - new StoreInst(val, ptr, false, currentBlock); - break; - } - - case AASTORE : { - Value* val = pop(); - Value* index = pop(); - Value* obj = pop(); - Value* ptr = verifyAndComputePtr(obj, index, - module->JavaArrayObjectType); - new StoreInst(val, ptr, false, currentBlock); - break; - } - - case BASTORE : { - Value* val = pop(); - if (val->getType() != Type::Int8Ty) { - val = new TruncInst(val, Type::Int8Ty, "", currentBlock); - } - Value* index = pop(); - Value* obj = pop(); - Value* ptr = verifyAndComputePtr(obj, index, - module->JavaArraySInt8Type); - new StoreInst(val, ptr, false, currentBlock); - break; - } - - case CASTORE : { - Value* val = pop(); - const Type* type = val->getType(); - if (type == Type::Int32Ty) { - val = new TruncInst(val, Type::Int16Ty, "", currentBlock); - } else if (type == Type::Int8Ty) { - val = new ZExtInst(val, Type::Int16Ty, "", currentBlock); - } - Value* index = pop(); - Value* obj = pop(); - Value* ptr = verifyAndComputePtr(obj, index, - module->JavaArrayUInt16Type); - new StoreInst(val, ptr, false, currentBlock); - break; - } - - case SASTORE : { - Value* val = pop(); - const Type* type = val->getType(); - if (type == Type::Int32Ty) { - val = new TruncInst(val, Type::Int16Ty, "", currentBlock); - } else if (type == Type::Int8Ty) { - val = new SExtInst(val, Type::Int16Ty, "", currentBlock); - } - Value* index = pop(); - Value* obj = pop(); - Value* ptr = verifyAndComputePtr(obj, index, - module->JavaArraySInt16Type); - new StoreInst(val, ptr, false, currentBlock); - break; - } - - case POP : - pop(); - break; - - case POP2 : - pop(); pop(); - break; - - case DUP : - push(top(), topSign()); - break; - - case DUP_X1 : { - std::pair one = popPair(); - std::pair two = popPair(); - push(one); - push(two); - push(one); - break; - } - - case DUP_X2 : { - std::pair one = popPair(); - std::pair two = popPair(); - std::pair three = popPair(); - push(one); - push(three); - push(two); - push(one); - break; - } - - case DUP2 : - push(stack[stackSize() - 2]); - push(stack[stackSize() - 2]); - break; - - case DUP2_X1 : { - std::pair one = popPair(); - std::pair two = popPair(); - std::pair three = popPair(); - - push(two); - push(one); - - push(three); - push(two); - push(one); - - break; - } - - case DUP2_X2 : { - std::pair one = popPair(); - std::pair two = popPair(); - std::pair three = popPair(); - std::pair four = popPair(); - - push(two); - push(one); - - push(four); - push(three); - push(two); - push(one); - - break; - } - - case SWAP : { - std::pair one = popPair(); - std::pair two = popPair(); - push(one); - push(two); - break; - } - - case IADD : { - Value* val2 = popAsInt(); - Value* val1 = popAsInt(); - push(BinaryOperator::CreateAdd(val1, val2, "", currentBlock), - false); - break; - } - - case LADD : { - pop(); - llvm::Value* val2 = pop(); - pop(); - llvm::Value* val1 = pop(); - push(BinaryOperator::CreateAdd(val1, val2, "", currentBlock), - false); - push(module->constantZero, false); - break; - } - - case FADD : { - Value* val2 = pop(); - Value* val1 = pop(); - push(BinaryOperator::CreateAdd(val1, val2, "", currentBlock), - false); - break; - } - - case DADD : { - pop(); - llvm::Value* val2 = pop(); - pop(); - llvm::Value* val1 = pop(); - push(BinaryOperator::CreateAdd(val1, val2, "", currentBlock), - false); - push(module->constantZero, false); - break; - } - - case ISUB : { - Value* val2 = popAsInt(); - Value* val1 = popAsInt(); - push(BinaryOperator::CreateSub(val1, val2, "", currentBlock), - false); - break; - } - case LSUB : { - pop(); - llvm::Value* val2 = pop(); - pop(); - llvm::Value* val1 = pop(); - push(BinaryOperator::CreateSub(val1, val2, "", currentBlock), - false); - push(module->constantZero, false); - break; - } - - case FSUB : { - Value* val2 = pop(); - Value* val1 = pop(); - push(BinaryOperator::CreateSub(val1, val2, "", currentBlock), - false); - break; - } - - case DSUB : { - pop(); - llvm::Value* val2 = pop(); - pop(); - llvm::Value* val1 = pop(); - push(BinaryOperator::CreateSub(val1, val2, "", currentBlock), - false); - push(module->constantZero, false); - break; - } - - case IMUL : { - Value* val2 = popAsInt(); - Value* val1 = popAsInt(); - push(BinaryOperator::CreateMul(val1, val2, "", currentBlock), - false); - break; - } - - case LMUL : { - pop(); - llvm::Value* val2 = pop(); - pop(); - llvm::Value* val1 = pop(); - push(BinaryOperator::CreateMul(val1, val2, "", currentBlock), - false); - push(module->constantZero, false); - break; - } - - case FMUL : { - Value* val2 = pop(); - Value* val1 = pop(); - push(BinaryOperator::CreateMul(val1, val2, "", currentBlock), - false); - break; - } - - case DMUL : { - pop(); - llvm::Value* val2 = pop(); - pop(); - llvm::Value* val1 = pop(); - push(BinaryOperator::CreateMul(val1, val2, "", currentBlock), - false); - push(module->constantZero, false); - break; - } - - case IDIV : { - Value* val2 = popAsInt(); - Value* val1 = popAsInt(); - push(BinaryOperator::CreateSDiv(val1, val2, "", currentBlock), - false); - break; - } - - case LDIV : { - pop(); - llvm::Value* val2 = pop(); - pop(); - llvm::Value* val1 = pop(); - push(BinaryOperator::CreateSDiv(val1, val2, "", currentBlock), - false); - push(module->constantZero, false); - break; - } - - case FDIV : { - Value* val2 = pop(); - Value* val1 = pop(); - push(BinaryOperator::CreateFDiv(val1, val2, "", currentBlock), - false); - break; - } - - case DDIV : { - pop(); - llvm::Value* val2 = pop(); - pop(); - llvm::Value* val1 = pop(); - push(BinaryOperator::CreateFDiv(val1, val2, "", currentBlock), - false); - push(module->constantZero, false); - break; - } - - case IREM : { - Value* val2 = popAsInt(); - Value* val1 = popAsInt(); - push(BinaryOperator::CreateSRem(val1, val2, "", currentBlock), - false); - break; - } - - case LREM : { - pop(); - llvm::Value* val2 = pop(); - pop(); - llvm::Value* val1 = pop(); - push(BinaryOperator::CreateSRem(val1, val2, "", currentBlock), - false); - push(module->constantZero, false); - break; - } - - case FREM : { - Value* val2 = pop(); - Value* val1 = pop(); - push(BinaryOperator::CreateFRem(val1, val2, "", currentBlock), - false); - break; - } - - case DREM : { - pop(); - llvm::Value* val2 = pop(); - pop(); - llvm::Value* val1 = pop(); - push(BinaryOperator::CreateFRem(val1, val2, "", currentBlock), - false); - push(module->constantZero, false); - break; - } - - case INEG : - push(BinaryOperator::CreateSub( - module->constantZero, - popAsInt(), "", currentBlock), - false); - break; - - case LNEG : { - pop(); - push(BinaryOperator::CreateSub( - module->constantLongZero, - pop(), "", currentBlock), false); - push(module->constantZero, false); - break; - } - - case FNEG : - push(BinaryOperator::CreateSub( - module->constantFloatMinusZero, - pop(), "", currentBlock), false); - break; - - case DNEG : { - pop(); - push(BinaryOperator::CreateSub( - module->constantDoubleMinusZero, - pop(), "", currentBlock), false); - push(module->constantZero, false); - break; - } - - case ISHL : { - Value* val2 = popAsInt(); - Value* val1 = popAsInt(); - push(BinaryOperator::CreateShl(val1, val2, "", currentBlock), - false); - break; - } - - case LSHL : { - Value* val2 = new ZExtInst(pop(), Type::Int64Ty, "", currentBlock); - pop(); // remove the 0 on the stack - Value* val1 = pop(); - push(BinaryOperator::CreateShl(val1, val2, "", currentBlock), - false); - push(module->constantZero, false); - break; - } - - case ISHR : { - Value* val2 = popAsInt(); - Value* val1 = popAsInt(); - push(BinaryOperator::CreateAShr(val1, val2, "", currentBlock), - false); - break; - } - - case LSHR : { - Value* val2 = new ZExtInst(pop(), Type::Int64Ty, "", currentBlock); - pop(); // remove the 0 on the stack - Value* val1 = pop(); - push(BinaryOperator::CreateAShr(val1, val2, "", currentBlock), - false); - push(module->constantZero, false); - break; - } - - case IUSHR : { - Value* val2 = popAsInt(); - Value* val1 = popAsInt(); - Value* mask = ConstantInt::get(Type::Int32Ty, 0x1F); - val2 = BinaryOperator::CreateAnd(val2, mask, "", currentBlock); - push(BinaryOperator::CreateLShr(val1, val2, "", currentBlock), - false); - break; - } - - case LUSHR : { - Value* val2 = new ZExtInst(pop(), Type::Int64Ty, "", currentBlock); - Value* mask = ConstantInt::get(Type::Int64Ty, 0x3F); - val2 = BinaryOperator::CreateAnd(val2, mask, "", currentBlock); - pop(); // remove the 0 on the stack - Value* val1 = pop(); - push(BinaryOperator::CreateLShr(val1, val2, "", currentBlock), - false); - push(module->constantZero, false); - break; - } - - case IAND : { - Value* val2 = popAsInt(); - Value* val1 = popAsInt(); - push(BinaryOperator::CreateAnd(val1, val2, "", currentBlock), - false); - break; - } - - case LAND : { - pop(); - Value* val2 = pop(); - pop(); // remove the 0 on the stack - Value* val1 = pop(); - push(BinaryOperator::CreateAnd(val1, val2, "", currentBlock), - false); - push(module->constantZero, false); - break; - } - - case IOR : { - Value* val2 = popAsInt(); - Value* val1 = popAsInt(); - push(BinaryOperator::CreateOr(val1, val2, "", currentBlock), - false); - break; - } - - case LOR : { - pop(); - Value* val2 = pop(); - pop(); // remove the 0 on the stack - Value* val1 = pop(); - push(BinaryOperator::CreateOr(val1, val2, "", currentBlock), - false); - push(module->constantZero, false); - break; - } - - case IXOR : { - Value* val2 = popAsInt(); - Value* val1 = popAsInt(); - push(BinaryOperator::CreateXor(val1, val2, "", currentBlock), - false); - break; - } - - case LXOR : { - pop(); - Value* val2 = pop(); - pop(); // remove the 0 on the stack - Value* val1 = pop(); - push(BinaryOperator::CreateXor(val1, val2, "", currentBlock), - false); - push(module->constantZero, false); - break; - } - - case IINC : { - 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), "", - currentBlock); - new StoreInst(add, intLocals[idx], false, currentBlock); - break; - } - - case I2L : - push(new SExtInst(pop(), llvm::Type::Int64Ty, "", currentBlock), - false); - push(module->constantZero, false); - break; - - case I2F : - push(new SIToFPInst(pop(), llvm::Type::FloatTy, "", currentBlock), - false); - break; - - case I2D : - push(new SIToFPInst(pop(), llvm::Type::DoubleTy, "", currentBlock), - false); - push(module->constantZero, false); - break; - - case L2I : - pop(); - push(new TruncInst(pop(), llvm::Type::Int32Ty, "", currentBlock), - false); - break; - - case L2F : - pop(); - push(new SIToFPInst(pop(), llvm::Type::FloatTy, "", currentBlock), - false); - break; - - case L2D : - pop(); - push(new SIToFPInst(pop(), llvm::Type::DoubleTy, "", currentBlock), - false); - push(module->constantZero, false); - break; - - case F2I : { - llvm::Value* val = pop(); - llvm::Value* test = new FCmpInst(FCmpInst::FCMP_ONE, val, val, "", - currentBlock); - - BasicBlock* res = createBasicBlock("F2I"); - PHINode* node = PHINode::Create(llvm::Type::Int32Ty, "", res); - node->addIncoming(module->constantZero, currentBlock); - BasicBlock* cont = createBasicBlock("F2I"); - - BranchInst::Create(res, cont, test, currentBlock); - - currentBlock = cont; - - test = new FCmpInst(FCmpInst::FCMP_OGE, val, - module->constantMaxIntFloat, - "", currentBlock); - - cont = createBasicBlock("F2I"); - - BranchInst::Create(res, cont, test, currentBlock); - node->addIncoming(module->constantMaxInt, - currentBlock); - - currentBlock = cont; - - test = new FCmpInst(FCmpInst::FCMP_OLE, val, - module->constantMinIntFloat, - "", currentBlock); - - cont = createBasicBlock("F2I"); - - BranchInst::Create(res, cont, test, currentBlock); - node->addIncoming(module->constantMinInt, currentBlock); - - currentBlock = cont; - llvm::Value* newVal = new FPToSIInst(val, Type::Int32Ty, "", - currentBlock); - BranchInst::Create(res, currentBlock); - - node->addIncoming(newVal, currentBlock); - - currentBlock = res; - - push(node, false); - break; - } - - case F2L : { - llvm::Value* val = pop(); - llvm::Value* test = new FCmpInst(FCmpInst::FCMP_ONE, val, val, "", - currentBlock); - - BasicBlock* res = createBasicBlock("F2L"); - PHINode* node = PHINode::Create(llvm::Type::Int64Ty, "", res); - node->addIncoming(module->constantLongZero, currentBlock); - BasicBlock* cont = createBasicBlock("F2L"); - - BranchInst::Create(res, cont, test, currentBlock); - - currentBlock = cont; - - test = new FCmpInst(FCmpInst::FCMP_OGE, val, - module->constantMaxLongFloat, - "", currentBlock); - - cont = createBasicBlock("F2L"); - - BranchInst::Create(res, cont, test, currentBlock); - node->addIncoming(module->constantMaxLong, currentBlock); - - currentBlock = cont; - - test = new FCmpInst(FCmpInst::FCMP_OLE, val, - module->constantMinLongFloat, "", currentBlock); - - cont = createBasicBlock("F2L"); - - BranchInst::Create(res, cont, test, currentBlock); - node->addIncoming(module->constantMinLong, currentBlock); - - currentBlock = cont; - llvm::Value* newVal = new FPToSIInst(val, Type::Int64Ty, "", - currentBlock); - BranchInst::Create(res, currentBlock); - - node->addIncoming(newVal, currentBlock); - - currentBlock = res; - - push(node, false); - push(module->constantZero, false); - break; - } - - case F2D : - push(new FPExtInst(pop(), llvm::Type::DoubleTy, "", currentBlock), - false); - push(module->constantZero, false); - break; - - case D2I : { - pop(); // remove the 0 on the stack - llvm::Value* val = pop(); - llvm::Value* test = new FCmpInst(FCmpInst::FCMP_ONE, val, val, "", - currentBlock); - - BasicBlock* res = createBasicBlock("D2I"); - PHINode* node = PHINode::Create(llvm::Type::Int32Ty, "", res); - node->addIncoming(module->constantZero, currentBlock); - BasicBlock* cont = createBasicBlock("D2I"); - - BranchInst::Create(res, cont, test, currentBlock); - - currentBlock = cont; - - test = new FCmpInst(FCmpInst::FCMP_OGE, val, - module->constantMaxIntDouble, - "", currentBlock); - - cont = createBasicBlock("D2I"); - - BranchInst::Create(res, cont, test, currentBlock); - node->addIncoming(module->constantMaxInt, currentBlock); - - currentBlock = cont; - - test = new FCmpInst(FCmpInst::FCMP_OLE, val, - module->constantMinIntDouble, - "", currentBlock); - - cont = createBasicBlock("D2I"); - - BranchInst::Create(res, cont, test, currentBlock); - node->addIncoming(module->constantMinInt, currentBlock); - - currentBlock = cont; - llvm::Value* newVal = new FPToSIInst(val, Type::Int32Ty, "", - currentBlock); - BranchInst::Create(res, currentBlock); - - node->addIncoming(newVal, currentBlock); - - currentBlock = res; - - push(node, false); - - break; - } - - case D2L : { - pop(); // remove the 0 on the stack - llvm::Value* val = pop(); - llvm::Value* test = new FCmpInst(FCmpInst::FCMP_ONE, val, val, "", - currentBlock); - - BasicBlock* res = createBasicBlock("D2L"); - PHINode* node = PHINode::Create(llvm::Type::Int64Ty, "", res); - node->addIncoming(module->constantLongZero, currentBlock); - BasicBlock* cont = createBasicBlock("D2L"); - - BranchInst::Create(res, cont, test, currentBlock); - - currentBlock = cont; - - test = new FCmpInst(FCmpInst::FCMP_OGE, val, - module->constantMaxLongDouble, - "", currentBlock); - - cont = createBasicBlock("D2L"); - - BranchInst::Create(res, cont, test, currentBlock); - node->addIncoming(module->constantMaxLong, currentBlock); - - currentBlock = cont; - - test = - new FCmpInst(FCmpInst::FCMP_OLE, val, module->constantMinLongDouble, - "", currentBlock); - - cont = createBasicBlock("D2L"); - - BranchInst::Create(res, cont, test, currentBlock); - node->addIncoming(module->constantMinLong, currentBlock); - - currentBlock = cont; - llvm::Value* newVal = new FPToSIInst(val, Type::Int64Ty, "", - currentBlock); - BranchInst::Create(res, currentBlock); - - node->addIncoming(newVal, currentBlock); - - currentBlock = res; - - push(node, false); - push(module->constantZero, false); - break; - } - - case D2F : - pop(); // remove the 0 on the stack - push(new FPTruncInst(pop(), llvm::Type::FloatTy, "", currentBlock), - false); - break; - - case I2B : { - Value* val = pop(); - if (val->getType() == Type::Int32Ty) { - val = new TruncInst(val, llvm::Type::Int8Ty, "", currentBlock); - } - push(new SExtInst(val, llvm::Type::Int32Ty, "", currentBlock), - false); - break; - } - - case I2C : { - Value* val = pop(); - if (val->getType() == Type::Int32Ty) { - val = new TruncInst(val, llvm::Type::Int16Ty, "", currentBlock); - } - push(new ZExtInst(val, llvm::Type::Int32Ty, "", currentBlock), - false); - break; - } - - case I2S : { - Value* val = pop(); - if (val->getType() == Type::Int32Ty) { - val = new TruncInst(val, llvm::Type::Int16Ty, "", currentBlock); - } - push(new SExtInst(val, llvm::Type::Int32Ty, "", currentBlock), - false); - break; - } - - case LCMP : { - pop(); - llvm::Value* val2 = pop(); - pop(); - llvm::Value* val1 = pop(); - - llvm::Value* test = new ICmpInst(ICmpInst::ICMP_EQ, val1, val2, "", - currentBlock); - - BasicBlock* cont = createBasicBlock("LCMP"); - BasicBlock* res = createBasicBlock("LCMP"); - PHINode* node = PHINode::Create(llvm::Type::Int32Ty, "", res); - node->addIncoming(module->constantZero, currentBlock); - - BranchInst::Create(res, cont, test, currentBlock); - currentBlock = cont; - - test = new ICmpInst(ICmpInst::ICMP_SLT, val1, val2, "", currentBlock); - node->addIncoming(module->constantMinusOne, currentBlock); - - cont = createBasicBlock("LCMP"); - BranchInst::Create(res, cont, test, currentBlock); - currentBlock = cont; - node->addIncoming(module->constantOne, currentBlock); - BranchInst::Create(res, currentBlock); - currentBlock = res; - - push(node, false); - break; - } - - case FCMPL : { - llvm::Value* val2 = pop(); - llvm::Value* val1 = pop(); - compareFP(val1, val2, Type::FloatTy, false); - break; - } - - case FCMPG : { - llvm::Value* val2 = pop(); - llvm::Value* val1 = pop(); - compareFP(val1, val2, Type::FloatTy, true); - break; - } - - case DCMPL : { - pop(); - llvm::Value* val2 = pop(); - pop(); - llvm::Value* val1 = pop(); - - compareFP(val1, val2, Type::DoubleTy, false); - break; - } - - case DCMPG : { - pop(); - llvm::Value* val2 = pop(); - pop(); - llvm::Value* val1 = pop(); - - compareFP(val1, val2, Type::DoubleTy, false); - break; - } - - case IFEQ : { - uint32 tmp = i; - BasicBlock* ifTrue = opcodeInfos[tmp + readS2(bytecodes, i)].newBlock; - - Value* op = pop(); - const Type* type = op->getType(); - Constant* val = Constant::getNullValue(type); - llvm::Value* test = new ICmpInst(ICmpInst::ICMP_EQ, op, val, "", - currentBlock); - BasicBlock* ifFalse = createBasicBlock("false IFEQ"); - branch(test, ifTrue, ifFalse, currentBlock); - currentBlock = ifFalse; - break; - } - - case IFNE : { - uint32 tmp = i; - BasicBlock* ifTrue = opcodeInfos[tmp + readS2(bytecodes, i)].newBlock; - - Value* op = pop(); - const Type* type = op->getType(); - Constant* val = Constant::getNullValue(type); - llvm::Value* test = new ICmpInst(ICmpInst::ICMP_NE, op, val, "", - currentBlock); - BasicBlock* ifFalse = createBasicBlock("false IFNE"); - branch(test, ifTrue, ifFalse, currentBlock); - currentBlock = ifFalse; - break; - } - - case IFLT : { - uint32 tmp = i; - BasicBlock* ifTrue = opcodeInfos[tmp + readS2(bytecodes, i)].newBlock; - Value* op = pop(); - const Type* type = op->getType(); - Constant* val = Constant::getNullValue(type); - llvm::Value* test = new ICmpInst(ICmpInst::ICMP_SLT, op, val, "", - currentBlock); - BasicBlock* ifFalse = createBasicBlock("false IFLT"); - branch(test, ifTrue, ifFalse, currentBlock); - currentBlock = ifFalse; - break; - } - - case IFGE : { - uint32 tmp = i; - BasicBlock* ifTrue = opcodeInfos[tmp + readS2(bytecodes, i)].newBlock; - Value* op = pop(); - const Type* type = op->getType(); - Constant* val = Constant::getNullValue(type); - llvm::Value* test = new ICmpInst(ICmpInst::ICMP_SGE, op, val, "", - currentBlock); - BasicBlock* ifFalse = createBasicBlock("false IFGE"); - branch(test, ifTrue, ifFalse, currentBlock); - currentBlock = ifFalse; - break; - } - - case IFGT : { - uint32 tmp = i; - BasicBlock* ifTrue = opcodeInfos[tmp + readS2(bytecodes, i)].newBlock; - Value* op = pop(); - const Type* type = op->getType(); - Constant* val = Constant::getNullValue(type); - llvm::Value* test = new ICmpInst(ICmpInst::ICMP_SGT, op, val, "", - currentBlock); - BasicBlock* ifFalse = createBasicBlock("false IFGT"); - branch(test, ifTrue, ifFalse, currentBlock); - currentBlock = ifFalse; - break; - } - - case IFLE : { - uint32 tmp = i; - BasicBlock* ifTrue = opcodeInfos[tmp + readS2(bytecodes, i)].newBlock; - Value* op = pop(); - const Type* type = op->getType(); - Constant* val = Constant::getNullValue(type); - llvm::Value* test = new ICmpInst(ICmpInst::ICMP_SLE, op, val, "", - currentBlock); - BasicBlock* ifFalse = createBasicBlock("false IFLE"); - branch(test, ifTrue, ifFalse, currentBlock); - currentBlock = ifFalse; - break; - } - - case IF_ICMPEQ : { - Value *val2 = popAsInt(); - Value *val1 = popAsInt(); - uint32 tmp = i; - BasicBlock* ifTrue = opcodeInfos[tmp + readS2(bytecodes, i)].newBlock; - llvm::Value* test = new ICmpInst(ICmpInst::ICMP_EQ, val1, val2, "", - currentBlock); - BasicBlock* ifFalse = createBasicBlock("false IF_ICMPEQ"); - branch(test, ifTrue, ifFalse, currentBlock); - currentBlock = ifFalse; - break; - } - - case IF_ICMPNE : { - Value *val2 = popAsInt(); - Value *val1 = popAsInt(); - uint32 tmp = i; - BasicBlock* ifTrue = opcodeInfos[tmp + readS2(bytecodes, i)].newBlock; - llvm::Value* test = new ICmpInst(ICmpInst::ICMP_NE, val1, val2, "", - currentBlock); - BasicBlock* ifFalse = createBasicBlock("false IF_ICMPNE"); - branch(test, ifTrue, ifFalse, currentBlock); - currentBlock = ifFalse; - break; - } - - case IF_ICMPLT : { - Value *val2 = popAsInt(); - Value *val1 = popAsInt(); - uint32 tmp = i; - BasicBlock* ifTrue = opcodeInfos[tmp + readS2(bytecodes, i)].newBlock; - llvm::Value* test = new ICmpInst(ICmpInst::ICMP_SLT, val1, val2, "", - currentBlock); - BasicBlock* ifFalse = createBasicBlock("false IF_IFCMPLT"); - branch(test, ifTrue, ifFalse, currentBlock); - currentBlock = ifFalse; - break; - } - - case IF_ICMPGE : { - Value *val2 = popAsInt(); - Value *val1 = popAsInt(); - uint32 tmp = i; - BasicBlock* ifTrue = opcodeInfos[tmp + readS2(bytecodes, i)].newBlock; - llvm::Value* test = new ICmpInst(ICmpInst::ICMP_SGE, val1, val2, "", - currentBlock); - BasicBlock* ifFalse = createBasicBlock("false IF_ICMPGE"); - branch(test, ifTrue, ifFalse, currentBlock); - currentBlock = ifFalse; - break; - } - - case IF_ICMPGT : { - Value *val2 = popAsInt(); - Value *val1 = popAsInt(); - uint32 tmp = i; - BasicBlock* ifTrue = opcodeInfos[tmp + readS2(bytecodes, i)].newBlock; - llvm::Value* test = new ICmpInst(ICmpInst::ICMP_SGT, val1, val2, "", - currentBlock); - BasicBlock* ifFalse = createBasicBlock("false IF_ICMPGT"); - branch(test, ifTrue, ifFalse, currentBlock); - currentBlock = ifFalse; - break; - } - - case IF_ICMPLE : { - Value *val2 = popAsInt(); - Value *val1 = popAsInt(); - uint32 tmp = i; - BasicBlock* ifTrue = opcodeInfos[tmp + readS2(bytecodes, i)].newBlock; - llvm::Value* test = new ICmpInst(ICmpInst::ICMP_SLE, val1, val2, "", - currentBlock); - BasicBlock* ifFalse = createBasicBlock("false IF_ICMPLE"); - branch(test, ifTrue, ifFalse, currentBlock); - currentBlock = ifFalse; - break; - } - - case IF_ACMPEQ : { - Value *val2 = pop(); - Value *val1 = pop(); - uint32 tmp = i; - BasicBlock* ifTrue = opcodeInfos[tmp + readS2(bytecodes, i)].newBlock; - llvm::Value* test = new ICmpInst(ICmpInst::ICMP_EQ, val1, val2, "", - currentBlock); - BasicBlock* ifFalse = createBasicBlock("false IF_ACMPEQ"); - branch(test, ifTrue, ifFalse, currentBlock); - currentBlock = ifFalse; - break; - } - - case IF_ACMPNE : { - Value *val2 = pop(); - Value *val1 = pop(); - uint32 tmp = i; - BasicBlock* ifTrue = opcodeInfos[tmp + readS2(bytecodes, i)].newBlock; - llvm::Value* test = new ICmpInst(ICmpInst::ICMP_NE, val1, val2, "", - currentBlock); - BasicBlock* ifFalse = createBasicBlock("false IF_ACMPNE"); - branch(test, ifTrue, ifFalse, currentBlock); - currentBlock = ifFalse; - break; - } - - case GOTO : { - uint32 tmp = i; - branch(opcodeInfos[tmp + readS2(bytecodes, i)].newBlock, - currentBlock); - break; - } - - case JSR : { - uint32 tmp = i; - Value* expr = ConstantExpr::getIntToPtr( - ConstantInt::get(Type::Int64Ty, - uint64_t (jsrIndex++)), - module->JavaObjectType); - push(expr, false); - branch(opcodeInfos[tmp + readS2(bytecodes, i)].newBlock, - currentBlock); - break; - } - - case RET : { - uint8 local = readU1(bytecodes, i); - Value* _val = new LoadInst(objectLocals[local], "", currentBlock); - Value* val = new PtrToIntInst(_val, Type::Int32Ty, "", currentBlock); - SwitchInst* inst = SwitchInst::Create(val, jsrs[0], jsrs.size(), - currentBlock); - - uint32 index = 0; - for (std::vector::iterator i = jsrs.begin(), - e = jsrs.end(); i!= e; ++i, ++index) { - inst->addCase(ConstantInt::get(Type::Int32Ty, index), *i); - } - - break; - } - - case TABLESWITCH : { - uint32 tmp = i; - uint32 reste = (i + 1) & 3; - uint32 filled = reste ? (4 - reste) : 0; - i += filled; - BasicBlock* def = opcodeInfos[tmp + readU4(bytecodes, i)].newBlock; - - sint32 low = readS4(bytecodes, i); - sint32 high = readS4(bytecodes, i) + 1; - - Value* index = pop(); - - const llvm::Type* type = index->getType(); - for (sint32 cur = low; cur < high; ++cur) { - Value* cmp = new ICmpInst(ICmpInst::ICMP_EQ, - ConstantInt::get(type, cur), index, - "", currentBlock); - BasicBlock* falseBlock = createBasicBlock("continue tableswitch"); - branch(cmp, opcodeInfos[tmp + readU4(bytecodes, i)].newBlock, - falseBlock, currentBlock); - currentBlock = falseBlock; - } - - - branch(def, currentBlock); - i = tmp + 12 + filled + ((high - low) << 2); - - break; - } - - case LOOKUPSWITCH : { - uint32 tmp = i; - uint32 filled = (3 - i) & 3; - i += filled; - BasicBlock* def = opcodeInfos[tmp + readU4(bytecodes, i)].newBlock; - uint32 nbs = readU4(bytecodes, i); - - bool unsign = topSign(); - Value* key = pop(); - const Type* type = key->getType(); - if (unsign) { - key = new ZExtInst(key, Type::Int32Ty, "", currentBlock); - } else if (type == Type::Int8Ty || type == Type::Int16Ty) { - key = new SExtInst(key, Type::Int32Ty, "", currentBlock); - } - for (uint32 cur = 0; cur < nbs; ++cur) { - Value* val = ConstantInt::get(Type::Int32Ty, readU4(bytecodes, i)); - Value* cmp = new ICmpInst(ICmpInst::ICMP_EQ, val, key, "", currentBlock); - BasicBlock* falseBlock = createBasicBlock("continue lookupswitch"); - branch(cmp, opcodeInfos[tmp + readU4(bytecodes, i)].newBlock, - falseBlock, currentBlock); - currentBlock = falseBlock; - } - branch(def, currentBlock); - i = tmp + 8 + filled + (nbs << 3); - break; - } - case IRETURN : { - bool unsign = topSign(); - Value* val = pop(); - assert(val->getType()->isInteger()); - convertValue(val, endNode->getType(), currentBlock, unsign); - endNode->addIncoming(val, currentBlock); - BranchInst::Create(endBlock, currentBlock); - break; - } - case LRETURN : - pop(); // remove the 0 on the stack - endNode->addIncoming(pop(), currentBlock); - BranchInst::Create(endBlock, currentBlock); - break; - - case FRETURN : - endNode->addIncoming(pop(), currentBlock); - BranchInst::Create(endBlock, currentBlock); - break; - - case DRETURN : - pop(); // remove the 0 on the stack - endNode->addIncoming(pop(), currentBlock); - BranchInst::Create(endBlock, currentBlock); - break; - - case ARETURN : - endNode->addIncoming(pop(), currentBlock); - BranchInst::Create(endBlock, currentBlock); - break; - - case RETURN : - BranchInst::Create(endBlock, currentBlock); - break; - - case GETSTATIC : { - uint16 index = readU2(bytecodes, i); - getStaticField(index); - break; - } - - case PUTSTATIC : { - uint16 index = readU2(bytecodes, i); - setStaticField(index); - break; - } - - case GETFIELD : { - uint16 index = readU2(bytecodes, i); - getVirtualField(index); - break; - } - - case PUTFIELD : { - uint16 index = readU2(bytecodes, i); - setVirtualField(index); - break; - } - - case INVOKEVIRTUAL : { - uint16 index = readU2(bytecodes, i); - invokeVirtual(index); - break; - } - - case INVOKESPECIAL : { - uint16 index = readU2(bytecodes, i); - invokeSpecial(index); - break; - } - - case INVOKESTATIC : { - uint16 index = readU2(bytecodes, i); - invokeStatic(index); - break; - } - - case INVOKEINTERFACE : { - uint16 index = readU2(bytecodes, i); - invokeInterface(index); - i += 2; - break; - } - - case NEW : { - uint16 index = readU2(bytecodes, i); - invokeNew(index); - break; - } - - case NEWARRAY : - case ANEWARRAY : { - - ConstantInt* sizeElement = 0; - Value* TheVT = 0; - Value* valCl = 0; - - if (bytecodes[i] == NEWARRAY) { - uint8 id = bytecodes[++i]; - uint8 charId = arrayType(id); -#ifndef ISOLATE_SHARING - JnjvmBootstrapLoader* loader = - compilingClass->classLoader->bootstrapLoader; - UserClassArray* dcl = loader->getArrayClass(id); - valCl = module->getNativeClass(dcl); - if (valCl->getType() != module->JavaCommonClassType) - valCl = new BitCastInst(valCl, module->JavaCommonClassType, "", - currentBlock); -#else - Value* args[2] = { isolateLocal, - ConstantInt::get(Type::Int32Ty, id - 4) }; - valCl = CallInst::Create(module->GetJnjvmArrayClassFunction, - args, args + 2, "", currentBlock); -#endif - - LLVMAssessorInfo& LAI = LLVMAssessorInfo::AssessorInfo[charId]; - sizeElement = LAI.sizeInBytesConstant; - TheVT = module->getPrimitiveArrayVT(); - } else { - uint16 index = readU2(bytecodes, i); - CommonClass* cl = 0; - valCl = getResolvedCommonClass(index, true, &cl); - - if (cl) { - JnjvmClassLoader* JCL = cl->classLoader; - const UTF8* arrayName = JCL->constructArrayName(1, cl->name); - - UserClassArray* dcl = JCL->constructArray(arrayName); - valCl = module->getNativeClass(dcl); - - // If we're static compiling and the class is not a class we - // are compiling, the result of getNativeClass is a pointer to - // the class. Load it. - if (module->isStaticCompiling() && - valCl->getType() != module->JavaClassArrayType) { - valCl = new LoadInst(valCl, "", currentBlock); - } - - if (valCl->getType() != module->JavaCommonClassType) { - valCl = new BitCastInst(valCl, module->JavaCommonClassType, "", - currentBlock); - } - - } else { - const llvm::Type* Ty = - PointerType::getUnqual(module->JavaCommonClassType); - Value* args[2]= { valCl, Constant::getNullValue(Ty) }; - valCl = CallInst::Create(module->GetArrayClassFunction, args, - args + 2, "", currentBlock); - } - - sizeElement = module->constantPtrSize; - TheVT = module->getReferenceArrayVT(); - } - Value* arg1 = popAsInt(); - - if (module->hasExceptionsEnabled()) { - Value* cmp = new ICmpInst(ICmpInst::ICMP_SLT, arg1, - module->constantZero, "", currentBlock); - - BasicBlock* BB1 = createBasicBlock(""); - BasicBlock* BB2 = createBasicBlock(""); - - BranchInst::Create(BB1, BB2, cmp, currentBlock); - currentBlock = BB1; - throwException(module->NegativeArraySizeExceptionFunction, arg1); - currentBlock = BB2; - - cmp = new ICmpInst(ICmpInst::ICMP_SGT, arg1, - module->MaxArraySizeConstant, - "", currentBlock); - - BB1 = createBasicBlock(""); - BB2 = createBasicBlock(""); - - BranchInst::Create(BB1, BB2, cmp, currentBlock); - currentBlock = BB1; - throwException(module->OutOfMemoryErrorFunction, arg1); - currentBlock = BB2; - } - - Value* mult = BinaryOperator::CreateMul(arg1, sizeElement, "", - currentBlock); - Value* size = - BinaryOperator::CreateAdd(module->JavaArraySizeConstant, mult, - "", currentBlock); - Value* res = invoke(module->JavaObjectAllocateFunction, size, TheVT, "", - currentBlock); - Value* cast = new BitCastInst(res, module->JavaArrayType, "", - currentBlock); - - // Set the size - Value* gep4[2] = { module->constantZero, - module->JavaArraySizeOffsetConstant }; - Value* GEP = GetElementPtrInst::Create(cast, gep4, gep4 + 2, - "", currentBlock); - - arg1 = new IntToPtrInst(arg1, module->ptrType, "", currentBlock); - new StoreInst(arg1, GEP, currentBlock); - - // Set the class - Value* gep[2] = { module->constantZero, - module->JavaObjectClassOffsetConstant }; - GEP = GetElementPtrInst::Create(res, gep, gep + 2, "", currentBlock); - new StoreInst(valCl, GEP, currentBlock); - - Value* gep1[2] = { module->constantZero, - module->JavaObjectLockOffsetConstant }; - Value* lockPtr = GetElementPtrInst::Create(res, gep1, gep1 + 2, - "", currentBlock); - Value* threadId = getCurrentThread(); - - threadId = new BitCastInst(threadId, module->ptrType, "", currentBlock); - - new StoreInst(threadId, lockPtr, currentBlock); - - push(res, false); - - break; - } - - case ARRAYLENGTH : { - Value* val = pop(); - JITVerifyNull(val); - push(arraySize(val), false); - break; - } - - case ATHROW : { - llvm::Value* arg = pop(); - throwException(arg); - break; - } - - case CHECKCAST : - if (!module->hasExceptionsEnabled()) { - i += 2; - break; - } - - case INSTANCEOF : { - - bool checkcast = (bytecodes[i] == CHECKCAST); - - BasicBlock* exceptionCheckcast = 0; - BasicBlock* endCheckcast = 0; - Value* result = 0; - - uint16 index = readU2(bytecodes, i); - UserCommonClass* cl = 0; - Value* clVar = getResolvedCommonClass(index, true, &cl); - Value* obj = top(); - Value* args[2] = { obj, clVar }; - Value* cmp = new ICmpInst(ICmpInst::ICMP_EQ, obj, - module->JavaObjectNullConstant, - "", currentBlock); - - if (checkcast) { - exceptionCheckcast = createBasicBlock("false checkcast"); - - - endCheckcast = createBasicBlock("null checkcast"); - BasicBlock* ifFalse = createBasicBlock("non null checkcast"); - - BranchInst::Create(endCheckcast, ifFalse, cmp, currentBlock); - currentBlock = exceptionCheckcast; - throwException(module->ClassCastExceptionFunction, args, 2); - currentBlock = ifFalse; - } - - if (cl) { - - BasicBlock* ifTrue = createBasicBlock("true type compare"); - BasicBlock* ifFalse = createBasicBlock("false type compare"); - BranchInst::Create(ifTrue, ifFalse, cmp, currentBlock); - PHINode* node = PHINode::Create(Type::Int1Ty, "", ifTrue); - node->addIncoming(ConstantInt::getFalse(), currentBlock); - Value* objCl = CallInst::Create(module->GetClassFunction, obj, "", - ifFalse); - Value* classArgs[2] = { objCl, clVar }; - - if (isInterface(cl->access)) { - Value* res = CallInst::Create(module->ImplementsFunction, - classArgs, classArgs + 2, "", - ifFalse); - node->addIncoming(res, ifFalse); - BranchInst::Create(ifTrue, ifFalse); - } else { - cmp = new ICmpInst(ICmpInst::ICMP_EQ, objCl, clVar, "", ifFalse); - BasicBlock* notEquals = createBasicBlock("false compare"); - BranchInst::Create(ifTrue, notEquals, cmp, ifFalse); - node->addIncoming(ConstantInt::getTrue(), ifFalse); - - if (cl->isPrimitive()) { - fprintf(stderr, "implement me"); - abort(); - } else if (cl->isArray()) { - Value* res = - CallInst::Create(module->InstantiationOfArrayFunction, - classArgs, classArgs + 2, "", notEquals); - node->addIncoming(res, notEquals); - BranchInst::Create(ifTrue, notEquals); - } else { - Value* depthCl; - if (cl->asClass()->isResolved()) { - depthCl = ConstantInt::get(Type::Int32Ty, cl->depth); - } else { - depthCl = CallInst::Create(module->GetDepthFunction, - clVar, "", notEquals); - } - - Value* depthClObj = CallInst::Create(module->GetDepthFunction, - objCl, "", notEquals); - Value* cmp = new ICmpInst(ICmpInst::ICMP_ULE, depthCl, depthClObj, - "", notEquals); - - BasicBlock* supDepth = createBasicBlock("superior depth"); - - BranchInst::Create(supDepth, ifTrue, cmp, notEquals); - node->addIncoming(ConstantInt::getFalse(), notEquals); - - Value* inDisplay = CallInst::Create(module->GetDisplayFunction, - objCl, "", supDepth); - - Value* displayArgs[2] = { inDisplay, depthCl }; - Value* clInDisplay = - CallInst::Create(module->GetClassInDisplayFunction, displayArgs, - displayArgs + 2, "", supDepth); - - cmp = new ICmpInst(ICmpInst::ICMP_EQ, clInDisplay, clVar, "", - supDepth); - BranchInst::Create(ifTrue, supDepth); - - node->addIncoming(cmp, supDepth); - } - } - - currentBlock = ifTrue; - result = node; - - } else { - result = CallInst::Create(module->InstanceOfFunction, args, - args + 2, "", currentBlock); - - } - - if (checkcast) { - BranchInst::Create(endCheckcast, exceptionCheckcast, result, - currentBlock); - currentBlock = endCheckcast; - } else { - pop(); - push(new ZExtInst(result, Type::Int32Ty, "", currentBlock), - false); - } - - break; - } - - case MONITORENTER : { - Value* obj = pop(); - JITVerifyNull(obj); - monitorEnter(obj); - break; - } - - case MONITOREXIT : { - Value* obj = pop(); - JITVerifyNull(obj); - monitorExit(obj); - break; - } - - case MULTIANEWARRAY : { - uint16 index = readU2(bytecodes, i); - uint8 dim = readU1(bytecodes, i); - - - Value* valCl = getResolvedCommonClass(index, true, 0); - Value** args = (Value**)alloca(sizeof(Value*) * (dim + 2)); - args[0] = valCl; - args[1] = ConstantInt::get(Type::Int32Ty, dim); - - for (int cur = dim + 1; cur >= 2; --cur) - args[cur] = pop(); - - std::vector Args; - for (sint32 v = 0; v < dim + 2; ++v) { - Args.push_back(args[v]); - } - push(invoke(module->MultiCallNewFunction, Args, "", currentBlock), - false); - break; - } - - case WIDE : - wide = true; - break; - - case IFNULL : { - uint32 tmp = i; - llvm::Value* val = pop(); - Constant* nil = Constant::getNullValue(val->getType()); - llvm::Value* test = new ICmpInst(ICmpInst::ICMP_EQ, val, nil, "", - currentBlock); - BasicBlock* ifFalse = createBasicBlock("true IFNULL"); - BasicBlock* ifTrue = opcodeInfos[readS2(bytecodes, i) + tmp].newBlock; - branch(test, ifTrue, ifFalse, currentBlock); - currentBlock = ifFalse; - break; - } - - case IFNONNULL : { - uint32 tmp = i; - llvm::Value* val = pop(); - Constant* nil = Constant::getNullValue(val->getType()); - llvm::Value* test = new ICmpInst(ICmpInst::ICMP_NE, val, nil, "", - currentBlock); - BasicBlock* ifFalse = createBasicBlock("false IFNONNULL"); - BasicBlock* ifTrue = opcodeInfos[readS2(bytecodes, i) + tmp].newBlock; - branch(test, ifTrue, ifFalse, currentBlock); - currentBlock = ifFalse; - break; - } - - default : - JavaThread::get()->getJVM()->unknownError("unknown bytecode"); - - } - } -} - -void JavaJIT::exploreOpcodes(uint8* bytecodes, uint32 codeLength) { - bool wide = false; - for(uint32 i = 0; i < codeLength; ++i) { - - PRINT_DEBUG(JNJVM_COMPILE, 1, COLOR_NORMAL, "\t[at %5d] %-5d ", i, - bytecodes[i]); - PRINT_DEBUG(JNJVM_COMPILE, 1, LIGHT_BLUE, "exploring "); - PRINT_DEBUG(JNJVM_COMPILE, 1, LIGHT_CYAN, OpcodeNames[bytecodes[i]]); - PRINT_DEBUG(JNJVM_COMPILE, 1, LIGHT_BLUE, "\n"); - - switch (bytecodes[i]) { - - case NOP : - case ACONST_NULL : - case ICONST_M1 : - case ICONST_0 : - case ICONST_1 : - case ICONST_2 : - case ICONST_3 : - case ICONST_4 : - case ICONST_5 : - case LCONST_0 : - case LCONST_1 : - case FCONST_0 : - case FCONST_1 : - case FCONST_2 : - case DCONST_0 : - case DCONST_1 : break; - - case BIPUSH : ++i; break; - - case SIPUSH : i += 2; break; - - case LDC : ++i; break; - - case LDC_W : - case LDC2_W : i += 2; break; - - case ILOAD : - case LLOAD : - case FLOAD : - case DLOAD : - case ALOAD : - i += WCALC(1, wide); - break; - - case ILOAD_0 : - case ILOAD_1 : - case ILOAD_2 : - case ILOAD_3 : - case LLOAD_0 : - case LLOAD_1 : - case LLOAD_2 : - case LLOAD_3 : - case FLOAD_0 : - case FLOAD_1 : - case FLOAD_2 : - case FLOAD_3 : - case DLOAD_0 : - case DLOAD_1 : - case DLOAD_2 : - case DLOAD_3 : - case ALOAD_0 : - case ALOAD_1 : - case ALOAD_2 : - case ALOAD_3 : - case IALOAD : - case LALOAD : - case FALOAD : - case DALOAD : - case AALOAD : - case BALOAD : - case CALOAD : - case SALOAD : break; - - case ISTORE : - case LSTORE : - case FSTORE : - case DSTORE : - case ASTORE : - i += WCALC(1, wide); - break; - - case ISTORE_0 : - case ISTORE_1 : - case ISTORE_2 : - case ISTORE_3 : - case LSTORE_0 : - case LSTORE_1 : - case LSTORE_2 : - case LSTORE_3 : - case FSTORE_0 : - case FSTORE_1 : - case FSTORE_2 : - case FSTORE_3 : - case DSTORE_0 : - case DSTORE_1 : - case DSTORE_2 : - case DSTORE_3 : - case ASTORE_0 : - case ASTORE_1 : - case ASTORE_2 : - case ASTORE_3 : - case IASTORE : - case LASTORE : - case FASTORE : - case DASTORE : - case AASTORE : - case BASTORE : - case CASTORE : - case SASTORE : - case POP : - case POP2 : - case DUP : - case DUP_X1 : - case DUP_X2 : - case DUP2 : - case DUP2_X1 : - case DUP2_X2 : - case SWAP : - case IADD : - case LADD : - case FADD : - case DADD : - case ISUB : - case LSUB : - case FSUB : - case DSUB : - case IMUL : - case LMUL : - case FMUL : - case DMUL : - case IDIV : - case LDIV : - case FDIV : - case DDIV : - case IREM : - case LREM : - case FREM : - case DREM : - case INEG : - case LNEG : - case FNEG : - case DNEG : - case ISHL : - case LSHL : - case ISHR : - case LSHR : - case IUSHR : - case LUSHR : - case IAND : - case LAND : - case IOR : - case LOR : - case IXOR : - case LXOR : break; - - case IINC : - i += WCALC(2, wide); - break; - - case I2L : - case I2F : - case I2D : - case L2I : - case L2F : - case L2D : - case F2I : - case F2L : - case F2D : - case D2I : - case D2L : - case D2F : - case I2B : - case I2C : - case I2S : - case LCMP : - case FCMPL : - case FCMPG : - case DCMPL : - case DCMPG : break; - - case IFEQ : - case IFNE : - case IFLT : - case IFGE : - case IFGT : - case IFLE : - case IF_ICMPEQ : - case IF_ICMPNE : - case IF_ICMPLT : - case IF_ICMPGE : - case IF_ICMPGT : - case IF_ICMPLE : - case IF_ACMPEQ : - case IF_ACMPNE : - case GOTO : { - uint32 tmp = i; - uint16 index = tmp + readU2(bytecodes, i); - if (!(opcodeInfos[index].newBlock)) - opcodeInfos[index].newBlock = createBasicBlock("GOTO or IF*"); - break; - } - - case JSR : { - uint32 tmp = i; - uint16 index = tmp + readU2(bytecodes, i); - if (!(opcodeInfos[index].newBlock)) { - BasicBlock* block = createBasicBlock("JSR"); - opcodeInfos[index].newBlock = block; - } - if (!(opcodeInfos[tmp + 3].newBlock)) { - BasicBlock* block = createBasicBlock("JSR2"); - jsrs.push_back(block); - opcodeInfos[tmp + 3].newBlock = block; - } else { - jsrs.push_back(opcodeInfos[tmp + 3].newBlock); - } - break; - } - - case RET : ++i; break; - - case TABLESWITCH : { - uint32 tmp = i; - uint32 reste = (i + 1) & 3; - uint32 filled = reste ? (4 - reste) : 0; - i += filled; - uint32 index = tmp + readU4(bytecodes, i); - if (!(opcodeInfos[index].newBlock)) { - BasicBlock* block = createBasicBlock("tableswitch"); - opcodeInfos[index].newBlock = block; - } - uint32 low = readU4(bytecodes, i); - uint32 high = readU4(bytecodes, i) + 1; - uint32 depl = high - low; - for (uint32 cur = 0; cur < depl; ++cur) { - uint32 index2 = tmp + readU4(bytecodes, i); - if (!(opcodeInfos[index2].newBlock)) { - BasicBlock* block = createBasicBlock("tableswitch"); - opcodeInfos[index2].newBlock = block; - } - } - i = tmp + 12 + filled + (depl << 2); - break; - } - - case LOOKUPSWITCH : { - uint32 tmp = i; - uint32 filled = (3 - i) & 3; - i += filled; - uint32 index = tmp + readU4(bytecodes, i); - if (!(opcodeInfos[index].newBlock)) { - BasicBlock* block = createBasicBlock("tableswitch"); - opcodeInfos[index].newBlock = block; - } - uint32 nbs = readU4(bytecodes, i); - for (uint32 cur = 0; cur < nbs; ++cur) { - i += 4; - uint32 index2 = tmp + readU4(bytecodes, i); - if (!(opcodeInfos[index2].newBlock)) { - BasicBlock* block = createBasicBlock("tableswitch"); - opcodeInfos[index2].newBlock = block; - } - } - - i = tmp + 8 + filled + (nbs << 3); - break; - } - - case IRETURN : - case LRETURN : - case FRETURN : - case DRETURN : - case ARETURN : - case RETURN : break; - - case GETSTATIC : - case PUTSTATIC : - case GETFIELD : - case PUTFIELD : - case INVOKEVIRTUAL : - case INVOKESPECIAL : - case INVOKESTATIC : - i += 2; - break; - - case INVOKEINTERFACE : - ++nbEnveloppes; - i += 4; - break; - - case NEW : - i += 2; - break; - - case NEWARRAY : - ++i; - break; - - case ANEWARRAY : - i += 2; - break; - - case ARRAYLENGTH : - case ATHROW : break; - - case CHECKCAST : - i += 2; - break; - - case INSTANCEOF : - i += 2; - break; - - case MONITORENTER : - break; - - case MONITOREXIT : - break; - - case MULTIANEWARRAY : - i += 3; - break; - - case WIDE : - wide = true; - break; - - case IFNULL : - case IFNONNULL : { - uint32 tmp = i; - uint16 index = tmp + readU2(bytecodes, i); - if (!(opcodeInfos[index].newBlock)) - opcodeInfos[index].newBlock = createBasicBlock("true IF*NULL"); - break; - } - - - default : - JavaThread::get()->getJVM()->unknownError("unknown bytecode"); - } - } -} Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaRuntimeJIT.cpp URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JavaRuntimeJIT.cpp?rev=65457&r1=65456&r2=65457&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/JavaRuntimeJIT.cpp (original) +++ vmkit/trunk/lib/JnJVM/VMCore/JavaRuntimeJIT.cpp Wed Feb 25 09:42:09 2009 @@ -13,12 +13,13 @@ #include "JavaCache.h" #include "JavaClass.h" #include "JavaConstantPool.h" -#include "JavaJIT.h" #include "JavaString.h" #include "JavaThread.h" #include "JavaTypes.h" #include "Jnjvm.h" +#include "jnjvm/OpcodeNames.def" + #include using namespace jnjvm; @@ -519,7 +520,7 @@ extern "C" void printExecution(uint32 opcode, uint32 index, JavaMethod* meth) { printf("[%p] executing %s %s at %d\n", (void*)mvm::Thread::get(), - meth->printString(), JavaJIT::OpcodeNames[opcode], index); + meth->printString(), OpcodeNames[opcode], index); fflush(stdout); } Removed: vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.cpp URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.cpp?rev=65456&view=auto ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.cpp (original) +++ vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.cpp (removed) @@ -1,2678 +0,0 @@ -//===--------- JnjvmModule.cpp - Definition of a Jnjvm module -------------===// -// -// JnJVM -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "llvm/BasicBlock.h" -#include "llvm/CallingConv.h" -#include "llvm/Constants.h" -#include "llvm/ExecutionEngine/ExecutionEngine.h" -#include "llvm/Instructions.h" -#include "llvm/Support/MutexGuard.h" -#include "llvm/Target/TargetData.h" - - -#include "mvm/JIT.h" - -#include "JavaCache.h" -#include "JavaConstantPool.h" -#include "JavaJIT.h" -#include "JavaString.h" -#include "JavaThread.h" -#include "JavaTypes.h" -#include "JavaUpcalls.h" -#include "Jnjvm.h" -#include "JnjvmModule.h" -#include "JnjvmModuleProvider.h" -#include "Reader.h" - -#include - -using namespace jnjvm; -using namespace llvm; - -llvm::Constant* JnjvmModule::PrimitiveArrayVT; -llvm::Constant* JnjvmModule::ReferenceArrayVT; -llvm::Function* JnjvmModule::StaticInitializer; -llvm::Function* JnjvmModule::ObjectPrinter; -llvm::Function* JnjvmModule::NativeLoader; - -extern void* JavaArrayVT[]; -extern void* ArrayObjectVT[]; -extern void* JavaObjectVT[]; - -extern ClassArray ArrayOfBool; -extern ClassArray ArrayOfByte; -extern ClassArray ArrayOfChar; -extern ClassArray ArrayOfShort; -extern ClassArray ArrayOfInt; -extern ClassArray ArrayOfFloat; -extern ClassArray ArrayOfDouble; -extern ClassArray ArrayOfLong; - -#ifdef WITH_TRACER -const llvm::FunctionType* JnjvmModule::MarkAndTraceType = 0; -#endif - -const llvm::Type* JnjvmModule::JavaObjectType = 0; -const llvm::Type* JnjvmModule::JavaArrayType = 0; -const llvm::Type* JnjvmModule::JavaArrayUInt8Type = 0; -const llvm::Type* JnjvmModule::JavaArraySInt8Type = 0; -const llvm::Type* JnjvmModule::JavaArrayUInt16Type = 0; -const llvm::Type* JnjvmModule::JavaArraySInt16Type = 0; -const llvm::Type* JnjvmModule::JavaArrayUInt32Type = 0; -const llvm::Type* JnjvmModule::JavaArraySInt32Type = 0; -const llvm::Type* JnjvmModule::JavaArrayFloatType = 0; -const llvm::Type* JnjvmModule::JavaArrayDoubleType = 0; -const llvm::Type* JnjvmModule::JavaArrayLongType = 0; -const llvm::Type* JnjvmModule::JavaArrayObjectType = 0; -const llvm::Type* JnjvmModule::CacheNodeType = 0; -const llvm::Type* JnjvmModule::EnveloppeType = 0; -const llvm::Type* JnjvmModule::ConstantPoolType = 0; -const llvm::Type* JnjvmModule::UTF8Type = 0; -const llvm::Type* JnjvmModule::JavaFieldType = 0; -const llvm::Type* JnjvmModule::JavaMethodType = 0; -const llvm::Type* JnjvmModule::AttributType = 0; -const llvm::Type* JnjvmModule::JavaThreadType = 0; - -#ifdef ISOLATE_SHARING -const llvm::Type* JnjvmModule::JnjvmType = 0; -#endif - -llvm::Constant* JnjvmModule::JavaObjectNullConstant; -llvm::Constant* JnjvmModule::MaxArraySizeConstant; -llvm::Constant* JnjvmModule::JavaArraySizeConstant; -llvm::ConstantInt* JnjvmModule::OffsetObjectSizeInClassConstant; -llvm::ConstantInt* JnjvmModule::OffsetVTInClassConstant; -llvm::ConstantInt* JnjvmModule::OffsetDepthInClassConstant; -llvm::ConstantInt* JnjvmModule::OffsetDisplayInClassConstant; -llvm::ConstantInt* JnjvmModule::OffsetTaskClassMirrorInClassConstant; -llvm::ConstantInt* JnjvmModule::OffsetStaticInstanceInTaskClassMirrorConstant; -llvm::ConstantInt* JnjvmModule::OffsetStatusInTaskClassMirrorConstant; -llvm::ConstantInt* JnjvmModule::OffsetInitializedInTaskClassMirrorConstant; -llvm::ConstantInt* JnjvmModule::OffsetJavaExceptionInThreadConstant; -llvm::ConstantInt* JnjvmModule::OffsetCXXExceptionInThreadConstant; -llvm::ConstantInt* JnjvmModule::ClassReadyConstant; -const llvm::Type* JnjvmModule::JavaClassType; -const llvm::Type* JnjvmModule::JavaClassPrimitiveType; -const llvm::Type* JnjvmModule::JavaClassArrayType; -const llvm::Type* JnjvmModule::JavaCommonClassType; -const llvm::Type* JnjvmModule::VTType; -llvm::ConstantInt* JnjvmModule::JavaArrayElementsOffsetConstant; -llvm::ConstantInt* JnjvmModule::JavaArraySizeOffsetConstant; -llvm::ConstantInt* JnjvmModule::JavaObjectLockOffsetConstant; -llvm::ConstantInt* JnjvmModule::JavaObjectClassOffsetConstant; - - -bool JnjvmModule::isCompiling(const CommonClass* cl) const { - if (cl->isClass()) { - // A class is being static compiled if owner class is not null. - return (((Class*)cl)->getOwnerClass() != 0); - } else if (cl->isArray()) { - return isCompiling(((ClassArray*)cl)->baseClass()); - } else { - return false; - } -} - -Constant* JnjvmModule::getNativeClass(CommonClass* classDef) { - - if (staticCompilation) { - - if (classDef->isClass() || - (classDef->isArray() && isCompiling(classDef)) || - (assumeCompiled && !(classDef->isArray() && - classDef->asArrayClass()->baseClass()->isPrimitive()))) { - native_class_iterator End = nativeClasses.end(); - native_class_iterator I = nativeClasses.find(classDef); - if (I == End) { - const llvm::Type* Ty = 0; - - if (classDef->isArray()) { - Ty = JavaClassArrayType->getContainedType(0); - } else { - Ty = JavaClassType->getContainedType(0); - } - - GlobalVariable* varGV = - new GlobalVariable(Ty, false, GlobalValue::ExternalLinkage, 0, - classDef->printString(), this); - - nativeClasses.insert(std::make_pair(classDef, varGV)); - - if (classDef->isClass() && isCompiling(classDef->asClass())) { - Constant* C = CreateConstantFromClass((Class*)classDef); - varGV->setInitializer(C); - } else if (classDef->isArray()) { - Constant* C = CreateConstantFromClassArray((ClassArray*)classDef); - varGV->setInitializer(C); - } - - return varGV; - - } else { - return I->second; - } - } else if (classDef->isArray()) { - array_class_iterator End = arrayClasses.end(); - array_class_iterator I = arrayClasses.find((ClassArray*)classDef); - if (I == End) { - const llvm::Type* Ty = JavaClassArrayType; - - GlobalVariable* varGV = - new GlobalVariable(Ty, false, GlobalValue::InternalLinkage, - Constant::getNullValue(Ty), - classDef->printString(), this); - - arrayClasses.insert(std::make_pair((ClassArray*)classDef, varGV)); - return varGV; - } else { - return I->second; - } - } else if (classDef->isPrimitive()) { - assert(0 && "implement me"); - } - return 0; - } else { - const llvm::Type* Ty = classDef->isClass() ? JavaClassType : - JavaCommonClassType; - - ConstantInt* CI = ConstantInt::get(Type::Int64Ty, uint64_t(classDef)); - return ConstantExpr::getIntToPtr(CI, Ty); - } -} - -Constant* JnjvmModule::getConstantPool(JavaConstantPool* ctp) { - if (staticCompilation) { - llvm::Constant* varGV = 0; - constant_pool_iterator End = constantPools.end(); - constant_pool_iterator I = constantPools.find(ctp); - if (I == End) { - const Type* Ty = ConstantPoolType->getContainedType(0); - varGV = new GlobalVariable(Ty, false, - GlobalValue::InternalLinkage, - Constant::getNullValue(Ty), "", this); - constantPools.insert(std::make_pair(ctp, varGV)); - return varGV; - } else { - return I->second; - } - - } else { - void* ptr = ctp->ctpRes; - assert(ptr && "No constant pool found"); - ConstantInt* CI = ConstantInt::get(Type::Int64Ty, uint64_t(ptr)); - return ConstantExpr::getIntToPtr(CI, ConstantPoolType); - } -} - -Constant* JnjvmModule::getMethodInClass(JavaMethod* meth) { - if (staticCompilation) { - Class* cl = meth->classDef; - Constant* MOffset = 0; - Constant* Array = 0; - method_iterator SI = virtualMethods.find(cl); - for (uint32 i = 0; i < cl->nbVirtualMethods + cl->nbStaticMethods; ++i) { - if (&cl->virtualMethods[i] == meth) { - MOffset = ConstantInt::get(Type::Int32Ty, i); - break; - } - } - Array = SI->second; - Constant* GEPs[2] = { constantZero, MOffset }; - return ConstantExpr::getGetElementPtr(Array, GEPs, 2); - - } else { - ConstantInt* CI = ConstantInt::get(Type::Int64Ty, (int64_t)meth); - return ConstantExpr::getIntToPtr(CI, JavaMethodType); - } -} - -Constant* JnjvmModule::getString(JavaString* str) { - if (staticCompilation) { - string_iterator SI = strings.find(str); - if (SI != strings.end()) { - return SI->second; - } else { - assert(str && "No string given"); - LLVMClassInfo* LCI = (LLVMClassInfo*)getClassInfo((Class*)str->getClass()); - const llvm::Type* Ty = LCI->getVirtualType(); - GlobalVariable* varGV = - new GlobalVariable(Ty->getContainedType(0), false, - GlobalValue::InternalLinkage, - 0, "", this); - Constant* res = ConstantExpr::getCast(Instruction::BitCast, varGV, - JavaObjectType); - strings.insert(std::make_pair(str, res)); - Constant* C = CreateConstantFromJavaString(str); - varGV->setInitializer(C); - return res; - } - - } else { - assert(str && "No string given"); - ConstantInt* CI = ConstantInt::get(Type::Int64Ty, uint64(str)); - return ConstantExpr::getIntToPtr(CI, JavaObjectType); - } -} - -Constant* JnjvmModule::getEnveloppe(Enveloppe* enveloppe) { - if (staticCompilation) { - enveloppe_iterator SI = enveloppes.find(enveloppe); - if (SI != enveloppes.end()) { - return SI->second; - } else { - GlobalVariable* varGV = - new GlobalVariable(EnveloppeType->getContainedType(0), false, - GlobalValue::InternalLinkage, 0, "", this); - enveloppes.insert(std::make_pair(enveloppe, varGV)); - - Constant* C = CreateConstantFromEnveloppe(enveloppe); - varGV->setInitializer(C); - return varGV; - } - - } else { - assert(enveloppe && "No enveloppe given"); - ConstantInt* CI = ConstantInt::get(Type::Int64Ty, uint64(enveloppe)); - return ConstantExpr::getIntToPtr(CI, EnveloppeType); - } -} - -Constant* JnjvmModule::getJavaClass(CommonClass* cl) { - if (staticCompilation) { - java_class_iterator End = javaClasses.end(); - java_class_iterator I = javaClasses.find(cl); - if (I == End) { - Class* javaClass = cl->classLoader->bootstrapLoader->upcalls->newClass; - LLVMClassInfo* LCI = (LLVMClassInfo*)getClassInfo(javaClass); - const llvm::Type* Ty = LCI->getVirtualType(); - - GlobalVariable* varGV = - new GlobalVariable(Ty->getContainedType(0), false, - GlobalValue::InternalLinkage, 0, "", this); - - Constant* res = ConstantExpr::getCast(Instruction::BitCast, varGV, - JavaObjectType); - - javaClasses.insert(std::make_pair(cl, res)); - varGV->setInitializer(CreateConstantFromJavaClass(cl)); - return res; - } else { - return I->second; - } - - } else { - JavaObject* obj = cl->getClassDelegatee(JavaThread::get()->getJVM()); - assert(obj && "Delegatee not created"); - Constant* CI = ConstantInt::get(Type::Int64Ty, uint64(obj)); - return ConstantExpr::getIntToPtr(CI, JavaObjectType); - } -} - -JavaObject* JnjvmModule::getFinalObject(llvm::Value* obj) { - if (staticCompilation) { - // TODO - } else { - if (ConstantExpr* CE = dyn_cast(obj)) { - if (ConstantInt* C = dyn_cast(CE->getOperand(0))) { - return (JavaObject*)C->getZExtValue(); - } - } - } - return 0; -} - - - -Constant* JnjvmModule::getFinalObject(JavaObject* obj) { - if (staticCompilation) { - final_object_iterator End = finalObjects.end(); - final_object_iterator I = finalObjects.find(obj); - if (I == End) { - abort(); - return 0; - } else { - return I->second; - } - - } else { - Constant* CI = ConstantInt::get(Type::Int64Ty, uint64(obj)); - return ConstantExpr::getIntToPtr(CI, JavaObjectType); - } -} - -Constant* JnjvmModule::CreateConstantFromStaticInstance(Class* cl) { - LLVMClassInfo* LCI = getClassInfo(cl); - const Type* Ty = LCI->getStaticType(); - const StructType* STy = dyn_cast(Ty->getContainedType(0)); - - std::vector Elts; - - for (uint32 i = 0; i < cl->nbStaticFields; ++i) { - JavaField& field = cl->staticFields[i]; - const Typedef* type = field.getSignature(); - LLVMAssessorInfo& LAI = getTypedefInfo(type); - const Type* Ty = LAI.llvmType; - - Attribut* attribut = field.lookupAttribut(Attribut::constantAttribut); - - if (!attribut) { - Elts.push_back(Constant::getNullValue(Ty)); - } else { - Reader reader(attribut, cl->bytes); - JavaConstantPool * ctpInfo = cl->ctpInfo; - uint16 idx = reader.readU2(); - if (type->isPrimitive()) { - if (Ty == Type::Int64Ty) { - Elts.push_back(ConstantInt::get(Ty, (uint64)ctpInfo->LongAt(idx))); - } else if (Ty == Type::DoubleTy) { - Elts.push_back(ConstantFP::get(Ty, ctpInfo->DoubleAt(idx))); - } else if (Ty == Type::FloatTy) { - Elts.push_back(ConstantFP::get(Ty, ctpInfo->FloatAt(idx))); - } else { - Elts.push_back(ConstantInt::get(Ty, (uint64)ctpInfo->IntegerAt(idx))); - } - } else if (type->isReference()){ - const UTF8* utf8 = ctpInfo->UTF8At(ctpInfo->ctpDef[idx]); - JavaString* obj = ctpInfo->resolveString(utf8, idx); - Constant* C = getString(obj); - C = ConstantExpr::getBitCast(C, JavaObjectType); - Elts.push_back(C); - } else { - fprintf(stderr, "Implement me"); - abort(); - } - } - } - - return ConstantStruct::get(STy, Elts); -} - -Constant* JnjvmModule::getStaticInstance(Class* classDef) { -#ifdef ISOLATE - assert(0 && "Should not be here"); - abort(); -#endif - if (staticCompilation) { - static_instance_iterator End = staticInstances.end(); - static_instance_iterator I = staticInstances.find(classDef); - if (I == End) { - - LLVMClassInfo* LCI = getClassInfo(classDef); - const Type* Ty = LCI->getStaticType(); - Ty = Ty->getContainedType(0); - GlobalVariable* varGV = - new GlobalVariable(Ty, false, GlobalValue::ExternalLinkage, - 0, classDef->printString(""), this); - - Constant* res = ConstantExpr::getCast(Instruction::BitCast, varGV, - ptrType); - staticInstances.insert(std::make_pair(classDef, res)); - - if (isCompiling(classDef)) { - Constant* C = CreateConstantFromStaticInstance(classDef); - varGV->setInitializer(C); - } - - return res; - } else { - return I->second; - } - - } else { - void* obj = ((Class*)classDef)->getStaticInstance(); - if (!obj) { - Class* cl = (Class*)classDef; - classDef->acquire(); - obj = cl->getStaticInstance(); - if (!obj) { - // Allocate now so that compiled code can reference it. - obj = cl->allocateStaticInstance(JavaThread::get()->getJVM()); - } - classDef->release(); - } - Constant* CI = ConstantInt::get(Type::Int64Ty, (uint64_t(obj))); - return ConstantExpr::getIntToPtr(CI, ptrType); - } -} - -Constant* JnjvmModule::getVirtualTable(Class* classDef) { - LLVMClassInfo* LCI = getClassInfo((Class*)classDef); - LCI->getVirtualType(); - if (staticCompilation) { - llvm::Constant* res = 0; - virtual_table_iterator End = virtualTables.end(); - virtual_table_iterator I = virtualTables.find(classDef); - if (I == End) { - - const ArrayType* ATy = dyn_cast(VTType->getContainedType(0)); - const PointerType* PTy = dyn_cast(ATy->getContainedType(0)); - ATy = ArrayType::get(PTy, classDef->virtualTableSize); - // Do not set a virtual table as a constant, because the runtime may - // modify it. - GlobalVariable* varGV = new GlobalVariable(ATy, false, - GlobalValue::ExternalLinkage, - 0, - classDef->printString(""), - this); - - res = ConstantExpr::getCast(Instruction::BitCast, varGV, VTType); - virtualTables.insert(std::make_pair(classDef, res)); - - if (isCompiling(classDef)) { - Constant* C = CreateConstantFromVT(classDef); - varGV->setInitializer(C); - } - - return res; - } else { - return I->second; - } - - } else { - assert(classDef->virtualVT && "Virtual VT not created"); - void* ptr = classDef->virtualVT; - ConstantInt* CI = ConstantInt::get(Type::Int64Ty, uint64_t(ptr)); - return ConstantExpr::getIntToPtr(CI, VTType); - } -} - -Constant* JnjvmModule::getNativeFunction(JavaMethod* meth, void* ptr) { - if (staticCompilation) { - llvm::Constant* varGV = 0; - native_function_iterator End = nativeFunctions.end(); - native_function_iterator I = nativeFunctions.find(meth); - if (I == End) { - - LLVMSignatureInfo* LSI = getSignatureInfo(meth->getSignature()); - const llvm::Type* valPtrType = LSI->getNativePtrType(); - - varGV = new GlobalVariable(valPtrType, true, - GlobalValue::InternalLinkage, - Constant::getNullValue(valPtrType), "", this); - - nativeFunctions.insert(std::make_pair(meth, varGV)); - return varGV; - } else { - return I->second; - } - - } else { - LLVMSignatureInfo* LSI = getSignatureInfo(meth->getSignature()); - const llvm::Type* valPtrType = LSI->getNativePtrType(); - - assert(ptr && "No native function given"); - - Constant* CI = ConstantInt::get(Type::Int64Ty, uint64_t(ptr)); - return ConstantExpr::getIntToPtr(CI, valPtrType); - } -} - -#ifndef WITHOUT_VTABLE -void JnjvmModule::allocateVT(Class* cl) { - for (uint32 i = 0; i < cl->nbVirtualMethods; ++i) { - JavaMethod& meth = cl->virtualMethods[i]; - if (meth.name->equals(cl->classLoader->bootstrapLoader->finalize)) { - meth.offset = 0; - } else { - JavaMethod* parent = cl->super? - cl->super->lookupMethodDontThrow(meth.name, meth.type, false, true, - 0) : - 0; - - uint64_t offset = 0; - if (!parent) { - offset = cl->virtualTableSize++; - meth.offset = offset; - } else { - offset = parent->offset; - meth.offset = parent->offset; - } - } - } - - VirtualTable* VT = 0; - if (cl->super) { - uint64 size = cl->virtualTableSize; - mvm::BumpPtrAllocator& allocator = cl->classLoader->allocator; - VT = (VirtualTable*)allocator.Allocate(size * sizeof(void*)); - Class* super = (Class*)cl->super; - assert(cl->virtualTableSize >= cl->super->virtualTableSize && - "Super VT bigger than own VT"); - assert(super->virtualVT && "Super does not have a VT!"); - memcpy(VT, super->virtualVT, cl->super->virtualTableSize * sizeof(void*)); - } else { - VT = JavaObjectVT; - } - - cl->virtualVT = VT; -} -#endif - - -#ifdef WITH_TRACER -llvm::Function* JnjvmModule::makeTracer(Class* cl, bool stat) { - - if (isStaticCompiling() && !generateTracers) { - return JavaObjectTracerFunction; - } - - LLVMClassInfo* LCI = (LLVMClassInfo*)getClassInfo(cl); - const Type* type = stat ? LCI->getStaticType() : LCI->getVirtualType(); - JavaField* fields = 0; - uint32 nbFields = 0; - if (stat) { - fields = cl->getStaticFields(); - nbFields = cl->nbStaticFields; - } else { - fields = cl->getVirtualFields(); - nbFields = cl->nbVirtualFields; - } - - Function* func = Function::Create(JnjvmModule::MarkAndTraceType, - GlobalValue::InternalLinkage, - "", - this); - - Constant* zero = mvm::MvmModule::constantZero; - Argument* arg = func->arg_begin(); - BasicBlock* block = BasicBlock::Create("", func); - llvm::Value* realArg = new BitCastInst(arg, type, "", block); - - std::vector Args; - Args.push_back(arg); -#ifdef MULTIPLE_GC - Value* GC = ++func->arg_begin(); - Args.push_back(GC); -#endif - if (!stat) { - if (cl->super == 0) { - CallInst::Create(JavaObjectTracerFunction, Args.begin(), Args.end(), - "", block); - - } else { - LLVMClassInfo* LCP = (LLVMClassInfo*)getClassInfo((Class*)(cl->super)); - Function* F = LCP->virtualTracerFunction; - if (!F) { - if (isStaticCompiling()) { - F = makeTracer(cl->super, false); - } else { - F = LCP->getVirtualTracer(); - } - assert(F && "Still no virtual tracer for super"); - } - CallInst::Create(F, Args.begin(), Args.end(), "", block); - } - } - - for (uint32 i = 0; i < nbFields; ++i) { - JavaField& cur = fields[i]; - if (cur.getSignature()->trace()) { - LLVMFieldInfo* LFI = getFieldInfo(&cur); - std::vector args; //size = 2 - args.push_back(zero); - args.push_back(LFI->getOffset()); - Value* ptr = GetElementPtrInst::Create(realArg, args.begin(), args.end(), - "",block); - Value* val = new LoadInst(ptr, "", block); - Value* valCast = new BitCastInst(val, JnjvmModule::JavaObjectType, "", - block); - std::vector Args; - Args.push_back(valCast); -#ifdef MULTIPLE_GC - Args.push_back(GC); -#endif - CallInst::Create(JnjvmModule::MarkAndTraceFunction, Args.begin(), - Args.end(), "", block); - } - } - - ReturnInst::Create(block); - - if (!stat) { - LCI->virtualTracerFunction = func; - } else { - LCI->staticTracerFunction = func; - } - - return func; -} -#endif - -Constant* JnjvmModule::CreateConstantForBaseObject(CommonClass* cl) { - const StructType* STy = - dyn_cast(JavaObjectType->getContainedType(0)); - - std::vector Elmts; - - // virtual table - if (cl->isClass()) { - Elmts.push_back(getVirtualTable(cl->asClass())); - } else { - ClassArray* clA = cl->asArrayClass(); - if (clA->baseClass()->isPrimitive()) { - Elmts.push_back(PrimitiveArrayVT); - } else { - Elmts.push_back(ReferenceArrayVT); - } - } - - // classof - Constant* Cl = getNativeClass(cl); - Constant* ClGEPs[2] = { constantZero, constantZero }; - Cl = ConstantExpr::getGetElementPtr(Cl, ClGEPs, 2); - - Elmts.push_back(Cl); - - // lock - Constant* L = ConstantInt::get(Type::Int64Ty, - JavaThread::get()->getThreadID()); - Elmts.push_back(ConstantExpr::getIntToPtr(L, ptrType)); - - return ConstantStruct::get(STy, Elmts); -} - -Constant* JnjvmModule::CreateConstantFromJavaClass(CommonClass* cl) { - Class* javaClass = cl->classLoader->bootstrapLoader->upcalls->newClass; - LLVMClassInfo* LCI = (LLVMClassInfo*)getClassInfo(javaClass); - const StructType* STy = - dyn_cast(LCI->getVirtualType()->getContainedType(0)); - - std::vector Elmts; - - // JavaObject - Elmts.push_back(CreateConstantForBaseObject(javaClass)); - - // signers - Elmts.push_back(Constant::getNullValue(JavaObjectType)); - - // pd - Elmts.push_back(Constant::getNullValue(JavaObjectType)); - - // vmdata - Constant* Cl = getNativeClass(cl); - Cl = ConstantExpr::getCast(Instruction::BitCast, Cl, JavaObjectType); - Elmts.push_back(Cl); - - // constructor - Elmts.push_back(Constant::getNullValue(JavaObjectType)); - - return ConstantStruct::get(STy, Elmts); -} - -Constant* JnjvmModule::CreateConstantFromJavaObject(JavaObject* obj) { - CommonClass* cl = obj->getClass(); - - if (cl->isArray()) { - Classpath* upcalls = cl->classLoader->bootstrapLoader->upcalls; - CommonClass* subClass = cl->asArrayClass()->baseClass(); - if (subClass->isPrimitive()) { - if (subClass == upcalls->OfBool) { - return CreateConstantFromArray((ArrayUInt8*)obj, - Type::Int8Ty); - } else if (subClass == upcalls->OfByte) { - return CreateConstantFromArray((ArraySInt8*)obj, - Type::Int8Ty); - } else if (subClass == upcalls->OfShort) { - return CreateConstantFromArray((ArraySInt16*)obj, - Type::Int16Ty); - } else if (subClass == upcalls->OfChar) { - return CreateConstantFromArray((ArrayUInt16*)obj, - Type::Int16Ty); - } else if (subClass == upcalls->OfInt) { - return CreateConstantFromArray((ArraySInt32*)obj, - Type::Int32Ty); - } else if (subClass == upcalls->OfFloat) { - return CreateConstantFromArray((ArrayFloat*)obj, - Type::FloatTy); - } else if (subClass == upcalls->OfLong) { - return CreateConstantFromArray((ArrayLong*)obj, - Type::Int64Ty); - } else if (subClass == upcalls->OfDouble) { - return CreateConstantFromArray((ArrayDouble*)obj, - Type::DoubleTy); - } else { - abort(); - } - } else { - return CreateConstantFromArray((ArrayObject*)obj, - JavaObjectType); - } - } else { - - std::vector Elmts; - - // JavaObject - Constant* CurConstant = CreateConstantForBaseObject(obj->getClass()); - - for (uint32 j = 0; j <= cl->depth; ++j) { - std::vector TempElts; - Elmts.push_back(CurConstant); - TempElts.push_back(CurConstant); - Class* curCl = cl->display[j]->asClass(); - LLVMClassInfo* LCI = getClassInfo(curCl); - const StructType* STy = - dyn_cast(LCI->getVirtualType()->getContainedType(0)); - - for (uint32 i = 0; i < curCl->nbVirtualFields; ++i) { - JavaField& field = curCl->virtualFields[i]; - const Typedef* type = field.getSignature(); - if (type->isPrimitive()) { - const PrimitiveTypedef* prim = (PrimitiveTypedef*)type; - if (prim->isBool() || prim->isByte()) { - ConstantInt* CI = ConstantInt::get(Type::Int8Ty, - field.getInt8Field(obj)); - TempElts.push_back(CI); - } else if (prim->isShort() || prim->isChar()) { - ConstantInt* CI = ConstantInt::get(Type::Int16Ty, - field.getInt16Field(obj)); - TempElts.push_back(CI); - } else if (prim->isInt()) { - ConstantInt* CI = ConstantInt::get(Type::Int32Ty, - field.getInt32Field(obj)); - TempElts.push_back(CI); - } else if (prim->isLong()) { - ConstantInt* CI = ConstantInt::get(Type::Int64Ty, - field.getLongField(obj)); - TempElts.push_back(CI); - } else if (prim->isFloat()) { - ConstantInt* CI = ConstantInt::get(Type::FloatTy, - field.getFloatField(obj)); - TempElts.push_back(CI); - } else if (prim->isDouble()) { - ConstantInt* CI = ConstantInt::get(Type::DoubleTy, - field.getDoubleField(obj)); - TempElts.push_back(CI); - } else { - abort(); - } - } else { - Constant* C = getFinalObject(field.getObjectField(obj)); - TempElts.push_back(C); - } - } - CurConstant = ConstantStruct::get(STy, TempElts); - } - - return CurConstant; - } -} - -Constant* JnjvmModule::CreateConstantFromJavaString(JavaString* str) { - Class* cl = (Class*)str->getClass(); - LLVMClassInfo* LCI = (LLVMClassInfo*)getClassInfo(cl); - const StructType* STy = - dyn_cast(LCI->getVirtualType()->getContainedType(0)); - - std::vector Elmts; - - Elmts.push_back(CreateConstantForBaseObject(cl)); - - Constant* Array = getUTF8(str->value); - Constant* ObjGEPs[2] = { constantZero, constantZero }; - Array = ConstantExpr::getGetElementPtr(Array, ObjGEPs, 2); - Elmts.push_back(Array); - - Elmts.push_back(ConstantInt::get(Type::Int32Ty, str->count)); - Elmts.push_back(ConstantInt::get(Type::Int32Ty, str->cachedHashCode)); - Elmts.push_back(ConstantInt::get(Type::Int32Ty, str->offset)); - - return ConstantStruct::get(STy, Elmts); -} - - -Constant* JnjvmModule::CreateConstantFromCacheNode(CacheNode* CN) { - const StructType* STy = - dyn_cast(CacheNodeType->getContainedType(0)); - - std::vector Elmts; - Elmts.push_back(Constant::getNullValue(STy->getContainedType(0))); - Elmts.push_back(Constant::getNullValue(STy->getContainedType(1))); - Elmts.push_back(Constant::getNullValue(STy->getContainedType(2))); - Elmts.push_back(getEnveloppe(CN->enveloppe)); - - return ConstantStruct::get(STy, Elmts); -} - -Constant* JnjvmModule::CreateConstantFromEnveloppe(Enveloppe* val) { - - const StructType* STy = - dyn_cast(EnveloppeType->getContainedType(0)); - const StructType* CNTy = - dyn_cast(CacheNodeType->getContainedType(0)); - - std::vector Elmts; - - Constant* firstCache = CreateConstantFromCacheNode(val->firstCache); - Elmts.push_back(new GlobalVariable(CNTy, false, - GlobalValue::InternalLinkage, - firstCache, "", this)); - Elmts.push_back(getUTF8(val->methodName)); - Elmts.push_back(getUTF8(val->methodSign)); - - Elmts.push_back(Constant::getNullValue(Type::Int8Ty)); - Elmts.push_back(getNativeClass(val->classDef)); - Elmts.push_back(firstCache); - - return ConstantStruct::get(STy, Elmts); - -} - -Constant* JnjvmModule::CreateConstantFromAttribut(Attribut& attribut) { - const StructType* STy = - dyn_cast(AttributType->getContainedType(0)); - - - std::vector Elmts; - - // name - Elmts.push_back(getUTF8(attribut.name)); - - // start - Elmts.push_back(ConstantInt::get(Type::Int32Ty, attribut.start)); - - // nbb - Elmts.push_back(ConstantInt::get(Type::Int32Ty, attribut.nbb)); - - return ConstantStruct::get(STy, Elmts); -} - -Constant* JnjvmModule::CreateConstantFromCommonClass(CommonClass* cl) { - const StructType* STy = - dyn_cast(JavaCommonClassType->getContainedType(0)); - - const ArrayType* ATy = ArrayType::get(JavaCommonClassType, cl->depth + 1); - - std::vector CommonClassElts; - std::vector TempElmts; - Constant* ClGEPs[2] = { constantZero, constantZero }; - - // display - for (uint32 i = 0; i <= cl->depth; ++i) { - Constant* Cl = getNativeClass(cl->display[i]); - if (Cl->getType() != JavaCommonClassType) - Cl = ConstantExpr::getGetElementPtr(Cl, ClGEPs, 2); - - TempElmts.push_back(Cl); - } - - Constant* display = ConstantArray::get(ATy, TempElmts); - TempElmts.clear(); - display = new GlobalVariable(ATy, true, GlobalValue::InternalLinkage, - display, "", this); - display = ConstantExpr::getCast(Instruction::BitCast, display, - PointerType::getUnqual(JavaCommonClassType)); - CommonClassElts.push_back(display); - - // depth - CommonClassElts.push_back(ConstantInt::get(Type::Int32Ty, cl->depth)); - - // delegatee - ATy = dyn_cast(STy->getContainedType(2)); - assert(ATy && "Malformed type"); - - Constant* TCM[1] = { getJavaClass(cl) }; - CommonClassElts.push_back(ConstantArray::get(ATy, TCM, 1)); - - // access - CommonClassElts.push_back(ConstantInt::get(Type::Int16Ty, cl->access)); - - // interfaces - if (cl->nbInterfaces) { - for (uint32 i = 0; i < cl->nbInterfaces; ++i) { - TempElmts.push_back(getNativeClass(cl->interfaces[i])); - } - - ATy = ArrayType::get(JavaClassType, cl->nbInterfaces); - Constant* interfaces = ConstantArray::get(ATy, TempElmts); - interfaces = new GlobalVariable(ATy, true, GlobalValue::InternalLinkage, - interfaces, "", this); - interfaces = ConstantExpr::getCast(Instruction::BitCast, interfaces, - PointerType::getUnqual(JavaClassType)); - - CommonClassElts.push_back(interfaces); - } else { - const Type* Ty = PointerType::getUnqual(JavaClassType); - CommonClassElts.push_back(Constant::getNullValue(Ty)); - } - - // nbInterfaces - CommonClassElts.push_back(ConstantInt::get(Type::Int16Ty, cl->nbInterfaces)); - - // name - CommonClassElts.push_back(getUTF8(cl->name)); - - // super - if (cl->super) { - CommonClassElts.push_back(getNativeClass(cl->super)); - } else { - CommonClassElts.push_back(Constant::getNullValue(JavaClassType)); - } - - // classLoader: store the static initializer, it will be overriden once - // the class is loaded. - Constant* loader = ConstantExpr::getBitCast(StaticInitializer, ptrType); - CommonClassElts.push_back(loader); - - return ConstantStruct::get(STy, CommonClassElts); -} - -Constant* JnjvmModule::CreateConstantFromJavaField(JavaField& field) { - const StructType* STy = - dyn_cast(JavaFieldType->getContainedType(0)); - - std::vector FieldElts; - std::vector TempElts; - - // signature - FieldElts.push_back(Constant::getNullValue(ptrType)); - - // access - FieldElts.push_back(ConstantInt::get(Type::Int16Ty, field.access)); - - // name - FieldElts.push_back(getUTF8(field.name)); - - // type - FieldElts.push_back(getUTF8(field.type)); - - // attributs - if (field.nbAttributs) { - const ArrayType* ATy = ArrayType::get(AttributType->getContainedType(0), - field.nbAttributs); - for (uint32 i = 0; i < field.nbAttributs; ++i) { - TempElts.push_back(CreateConstantFromAttribut(field.attributs[i])); - } - - Constant* attributs = ConstantArray::get(ATy, TempElts); - TempElts.clear(); - attributs = new GlobalVariable(ATy, true, GlobalValue::InternalLinkage, - attributs, "", this); - attributs = ConstantExpr::getCast(Instruction::BitCast, attributs, - AttributType); - - FieldElts.push_back(attributs); - } else { - FieldElts.push_back(Constant::getNullValue(AttributType)); - } - - // nbAttributs - FieldElts.push_back(ConstantInt::get(Type::Int16Ty, field.nbAttributs)); - - // classDef - FieldElts.push_back(getNativeClass(field.classDef)); - - // ptrOffset - FieldElts.push_back(ConstantInt::get(Type::Int32Ty, field.ptrOffset)); - - // num - FieldElts.push_back(ConstantInt::get(Type::Int16Ty, field.num)); - - //JInfo - FieldElts.push_back(Constant::getNullValue(ptrType)); - - return ConstantStruct::get(STy, FieldElts); -} - -Constant* JnjvmModule::CreateConstantFromJavaMethod(JavaMethod& method) { - const StructType* STy = - dyn_cast(JavaMethodType->getContainedType(0)); - - std::vector MethodElts; - std::vector TempElts; - - // signature - MethodElts.push_back(Constant::getNullValue(ptrType)); - - // access - MethodElts.push_back(ConstantInt::get(Type::Int16Ty, method.access)); - - // attributs - if (method.nbAttributs) { - const ArrayType* ATy = ArrayType::get(AttributType->getContainedType(0), - method.nbAttributs); - for (uint32 i = 0; i < method.nbAttributs; ++i) { - TempElts.push_back(CreateConstantFromAttribut(method.attributs[i])); - } - - Constant* attributs = ConstantArray::get(ATy, TempElts); - TempElts.clear(); - attributs = new GlobalVariable(ATy, true, GlobalValue::InternalLinkage, - attributs, "", this); - attributs = ConstantExpr::getCast(Instruction::BitCast, attributs, - AttributType); - - MethodElts.push_back(attributs); - } else { - MethodElts.push_back(Constant::getNullValue(AttributType)); - } - - // nbAttributs - MethodElts.push_back(ConstantInt::get(Type::Int16Ty, method.nbAttributs)); - - // enveloppes - // already allocated by the JIT, don't reallocate them. - MethodElts.push_back(Constant::getNullValue(EnveloppeType)); - - // nbEnveloppes - // 0 because we're not allocating here. - MethodElts.push_back(ConstantInt::get(Type::Int16Ty, 0)); - - // classDef - MethodElts.push_back(getNativeClass(method.classDef)); - - // name - MethodElts.push_back(getUTF8(method.name)); - - // type - MethodElts.push_back(getUTF8(method.type)); - - // canBeInlined - MethodElts.push_back(ConstantInt::get(Type::Int8Ty, method.canBeInlined)); - - // code - if (isAbstract(method.access)) { - MethodElts.push_back(Constant::getNullValue(ptrType)); - } else { - LLVMMethodInfo* LMI = getMethodInfo(&method); - Function* func = LMI->getMethod(); - MethodElts.push_back(ConstantExpr::getCast(Instruction::BitCast, func, - ptrType)); - } - - // offset - MethodElts.push_back(ConstantInt::get(Type::Int32Ty, method.offset)); - - //JInfo - MethodElts.push_back(Constant::getNullValue(ptrType)); - - return ConstantStruct::get(STy, MethodElts); -} - -Constant* JnjvmModule::CreateConstantFromClassPrimitive(ClassPrimitive* cl) { - const StructType* STy = - dyn_cast(JavaClassPrimitiveType->getContainedType(0)); - - std::vector ClassElts; - - // common class - ClassElts.push_back(CreateConstantFromCommonClass(cl)); - - // primSize - ClassElts.push_back(ConstantInt::get(Type::Int32Ty, cl->primSize)); - - return ConstantStruct::get(STy, ClassElts); -} - -Constant* JnjvmModule::CreateConstantFromClassArray(ClassArray* cl) { - const StructType* STy = - dyn_cast(JavaClassArrayType->getContainedType(0)); - - std::vector ClassElts; - Constant* ClGEPs[2] = { constantZero, constantZero }; - - // common class - ClassElts.push_back(CreateConstantFromCommonClass(cl)); - - // baseClass - Constant* Cl = getNativeClass(cl->baseClass()); - if (Cl->getType() != JavaCommonClassType) - Cl = ConstantExpr::getGetElementPtr(Cl, ClGEPs, 2); - - ClassElts.push_back(Cl); - - return ConstantStruct::get(STy, ClassElts); -} - -Constant* JnjvmModule::CreateConstantFromClass(Class* cl) { - const StructType* STy = - dyn_cast(JavaClassType->getContainedType(0)); - - std::vector ClassElts; - std::vector TempElts; - - // common class - ClassElts.push_back(CreateConstantFromCommonClass(cl)); - - // virtualSize - ClassElts.push_back(ConstantInt::get(Type::Int32Ty, cl->virtualSize)); - - // virtualTable - ClassElts.push_back(getVirtualTable(cl)); - - // IsolateInfo - const ArrayType* ATy = dyn_cast(STy->getContainedType(3)); - assert(ATy && "Malformed type"); - - const StructType* TCMTy = dyn_cast(ATy->getContainedType(0)); - assert(TCMTy && "Malformed type"); - - uint32 status = cl->needsInitialisationCheck() ? vmjc : ready; - TempElts.push_back(ConstantInt::get(Type::Int8Ty, status)); - TempElts.push_back(ConstantInt::get(Type::Int1Ty, status == ready ? 1 : 0)); - TempElts.push_back(getStaticInstance(cl)); - Constant* CStr[1] = { ConstantStruct::get(TCMTy, TempElts) }; - TempElts.clear(); - ClassElts.push_back(ConstantArray::get(ATy, CStr, 1)); - - // thinlock - ClassElts.push_back(Constant::getNullValue(ptrType)); - - if (cl->nbVirtualFields + cl->nbStaticFields) { - ATy = ArrayType::get(JavaFieldType->getContainedType(0), - cl->nbVirtualFields + cl->nbStaticFields); - } - - // virtualFields - if (cl->nbVirtualFields) { - - for (uint32 i = 0; i < cl->nbVirtualFields; ++i) { - TempElts.push_back(CreateConstantFromJavaField(cl->virtualFields[i])); - } - - } - - // staticFields - if (cl->nbStaticFields) { - - for (uint32 i = 0; i < cl->nbStaticFields; ++i) { - TempElts.push_back(CreateConstantFromJavaField(cl->staticFields[i])); - } - - } - - Constant* fields = 0; - if (cl->nbStaticFields + cl->nbVirtualFields) { - - fields = ConstantArray::get(ATy, TempElts); - TempElts.clear(); - fields = new GlobalVariable(ATy, false, GlobalValue::InternalLinkage, - fields, "", this); - fields = ConstantExpr::getCast(Instruction::BitCast, fields, JavaFieldType); - } else { - fields = Constant::getNullValue(JavaFieldType); - } - - // virtualFields - ClassElts.push_back(fields); - - ConstantInt* nbVirtualFields = - ConstantInt::get(Type::Int16Ty, cl->nbVirtualFields); - // nbVirtualFields - ClassElts.push_back(nbVirtualFields); - - // staticFields - // Output null, this will be set in the initializer. Otherwise, the - // assembly emitter of LLVM will try to align the data. - ClassElts.push_back(Constant::getNullValue(JavaFieldType)); - - // nbStaticFields - ClassElts.push_back(ConstantInt::get(Type::Int16Ty, cl->nbStaticFields)); - - // virtualMethods - if (cl->nbVirtualMethods + cl->nbStaticMethods) { - ATy = ArrayType::get(JavaMethodType->getContainedType(0), - cl->nbVirtualMethods + cl->nbStaticMethods); - } - - if (cl->nbVirtualMethods) { - for (uint32 i = 0; i < cl->nbVirtualMethods; ++i) { - TempElts.push_back(CreateConstantFromJavaMethod(cl->virtualMethods[i])); - } - } - - if (cl->nbStaticMethods) { - for (uint32 i = 0; i < cl->nbStaticMethods; ++i) { - TempElts.push_back(CreateConstantFromJavaMethod(cl->staticMethods[i])); - } - } - - Constant* methods = 0; - if (cl->nbVirtualMethods + cl->nbStaticMethods) { - methods = ConstantArray::get(ATy, TempElts); - TempElts.clear(); - GlobalVariable* GV = new GlobalVariable(ATy, false, - GlobalValue::InternalLinkage, - methods, "", this); - virtualMethods.insert(std::make_pair(cl, GV)); - methods = ConstantExpr::getCast(Instruction::BitCast, GV, - JavaMethodType); - } else { - methods = Constant::getNullValue(JavaMethodType); - } - - // virtualMethods - ClassElts.push_back(methods); - - ConstantInt* nbVirtualMethods = - ConstantInt::get(Type::Int16Ty, cl->nbVirtualMethods); - // nbVirtualMethods - ClassElts.push_back(nbVirtualMethods); - - // staticMethods - // Output null, this will be set in the initializer. - ClassElts.push_back(Constant::getNullValue(JavaMethodType)); - - // nbStaticMethods - ClassElts.push_back(ConstantInt::get(Type::Int16Ty, cl->nbStaticMethods)); - - // ownerClass - ClassElts.push_back(Constant::getNullValue(ptrType)); - - // bytes - ClassElts.push_back(Constant::getNullValue(JavaArrayUInt8Type)); - - // ctpInfo - ClassElts.push_back(Constant::getNullValue(ptrType)); - - // attributs - if (cl->nbAttributs) { - ATy = ArrayType::get(AttributType->getContainedType(0), - cl->nbAttributs); - - for (uint32 i = 0; i < cl->nbAttributs; ++i) { - TempElts.push_back(CreateConstantFromAttribut(cl->attributs[i])); - } - - Constant* attributs = ConstantArray::get(ATy, TempElts); - TempElts.clear(); - attributs = new GlobalVariable(ATy, true, GlobalValue::InternalLinkage, - attributs, "", this); - attributs = ConstantExpr::getCast(Instruction::BitCast, attributs, - AttributType); - ClassElts.push_back(attributs); - } else { - ClassElts.push_back(Constant::getNullValue(AttributType)); - } - - // nbAttributs - ClassElts.push_back(ConstantInt::get(Type::Int16Ty, cl->nbAttributs)); - - // innerClasses - if (cl->nbInnerClasses) { - for (uint32 i = 0; i < cl->nbInnerClasses; ++i) { - TempElts.push_back(getNativeClass(cl->innerClasses[i])); - } - - ATy = ArrayType::get(JavaClassType, cl->nbInnerClasses); - Constant* innerClasses = ConstantArray::get(ATy, TempElts); - innerClasses = new GlobalVariable(ATy, true, GlobalValue::InternalLinkage, - innerClasses, "", this); - innerClasses = ConstantExpr::getCast(Instruction::BitCast, innerClasses, - PointerType::getUnqual(JavaClassType)); - - ClassElts.push_back(innerClasses); - } else { - const Type* Ty = PointerType::getUnqual(JavaClassType); - ClassElts.push_back(Constant::getNullValue(Ty)); - } - - // nbInnerClasses - ClassElts.push_back(ConstantInt::get(Type::Int16Ty, cl->nbInnerClasses)); - - // outerClass - if (cl->outerClass) { - ClassElts.push_back(getNativeClass(cl->outerClass)); - } else { - ClassElts.push_back(Constant::getNullValue(JavaClassType)); - } - - // innerAccess - ClassElts.push_back(ConstantInt::get(Type::Int16Ty, cl->innerAccess)); - - // innerOuterResolved - ClassElts.push_back(ConstantInt::get(Type::Int8Ty, cl->innerOuterResolved)); - - // virtualTableSize - ClassElts.push_back(ConstantInt::get(Type::Int32Ty, cl->virtualTableSize)); - - // staticSize - ClassElts.push_back(ConstantInt::get(Type::Int32Ty, cl->staticSize)); - - // JInfo - ClassElts.push_back(Constant::getNullValue(ptrType)); - - // staticTracer - const Type* FTy = STy->getContainedType(STy->getNumContainedTypes() - 1); -#ifdef WITH_TRACER - Function* F = makeTracer(cl, true); - Constant* staticTracer = ConstantExpr::getCast(Instruction::BitCast, F, FTy); -#else - Constant* staticTracer = ConstantExpr::getNullValue(FTy); -#endif - ClassElts.push_back(staticTracer); - - - return ConstantStruct::get(STy, ClassElts); -} - -template -Constant* JnjvmModule::CreateConstantFromArray(T* val, const llvm::Type* Ty) { - std::vector Elemts; - const ArrayType* ATy = ArrayType::get(Ty, val->size); - Elemts.push_back(JavaObjectType->getContainedType(0)); - Elemts.push_back(pointerSizeType == Type::Int32Ty ? Type::Int32Ty : - Type::Int64Ty); - - Elemts.push_back(ATy); - - const StructType* STy = StructType::get(Elemts); - - std::vector Cts; - Cts.push_back(CreateConstantForBaseObject(val->getClass())); - Cts.push_back(ConstantInt::get(pointerSizeType, val->size)); - - std::vector Vals; - for (sint32 i = 0; i < val->size; ++i) { - if (Ty->isInteger()) { - Vals.push_back(ConstantInt::get(Ty, (uint64)val->elements[i])); - } else if (Ty->isFloatingPoint()) { - Vals.push_back(ConstantFP::get(Ty, (double)(size_t)val->elements[i])); - } else { - Vals.push_back(getFinalObject((JavaObject*)(size_t)val->elements[i])); - } - } - - Cts.push_back(ConstantArray::get(ATy, Vals)); - - return ConstantStruct::get(STy, Cts); -} - -Constant* JnjvmModule::CreateConstantFromUTF8(const UTF8* val) { - std::vector Elemts; - const ArrayType* ATy = ArrayType::get(Type::Int16Ty, val->size); - Elemts.push_back(JavaObjectType->getContainedType(0)); - Elemts.push_back(pointerSizeType == Type::Int32Ty ? Type::Int32Ty : - Type::Int64Ty); - - Elemts.push_back(ATy); - - const StructType* STy = StructType::get(Elemts); - - std::vector Cts; - Cts.push_back(CreateConstantForBaseObject(&ArrayOfChar)); - Cts.push_back(ConstantInt::get(pointerSizeType, val->size)); - - std::vector Vals; - for (sint32 i = 0; i < val->size; ++i) { - Vals.push_back(ConstantInt::get(Type::Int16Ty, val->elements[i])); - } - - Cts.push_back(ConstantArray::get(ATy, Vals)); - - return ConstantStruct::get(STy, Cts); - -} - -Constant* JnjvmModule::getUTF8(const UTF8* val) { - utf8_iterator End = utf8s.end(); - utf8_iterator I = utf8s.find(val); - if (I == End) { - Constant* C = CreateConstantFromUTF8(val); - GlobalVariable* varGV = new GlobalVariable(C->getType(), true, - GlobalValue::InternalLinkage, - C, "", this); - - Constant* res = ConstantExpr::getCast(Instruction::BitCast, varGV, - UTF8Type); - utf8s.insert(std::make_pair(val, res)); - - return res; - } else { - return I->second; - } -} - -Constant* JnjvmModule::CreateConstantFromVT(Class* classDef) { - uint32 size = classDef->virtualTableSize; - VirtualTable* VT = classDef->virtualVT; - const ArrayType* ATy = dyn_cast(VTType->getContainedType(0)); - const PointerType* PTy = dyn_cast(ATy->getContainedType(0)); - ATy = ArrayType::get(PTy, size); - - ConstantPointerNull* N = ConstantPointerNull::get(PTy); - std::vector Elemts; - - // Destructor - JavaMethod* meth = ((JavaMethod**)VT)[0]; - LLVMMethodInfo* LMI = getMethodInfo(meth); - Function* Finalizer = LMI->getMethod(); - Elemts.push_back(Finalizer ? - ConstantExpr::getCast(Instruction::BitCast, Finalizer, PTy) : N); - - // Delete - Elemts.push_back(N); - - // Tracer -#ifdef WITH_TRACER - Function* Tracer = makeTracer(classDef, false); - Elemts.push_back(Tracer ? - ConstantExpr::getCast(Instruction::BitCast, Tracer, PTy) : N); -#else - Elemts.push_back(N); -#endif - - // Printer - Elemts.push_back(ConstantExpr::getBitCast(ObjectPrinter, PTy)); - - // Hashcode - Elemts.push_back(N); - - for (uint32 i = VT_NB_FUNCS; i < size; ++i) { - JavaMethod* meth = ((JavaMethod**)VT)[i]; - LLVMMethodInfo* LMI = getMethodInfo(meth); - Function* F = LMI->getMethod(); - if (isAbstract(meth->access)) { - Elemts.push_back(Constant::getNullValue(PTy)); - } else { - Elemts.push_back(ConstantExpr::getCast(Instruction::BitCast, F, PTy)); - } - } - - Constant* Array = ConstantArray::get(ATy, Elemts); - - return Array; -} - -void JnjvmModule::makeVT(Class* cl) { - - VirtualTable* VT = 0; -#ifdef WITHOUT_VTABLE - mvm::BumpPtrAllocator& allocator = cl->classLoader->allocator; - VT = (VirtualTable*)allocator.Allocate(VT_SIZE); - memcpy(VT, JavaObjectVT, VT_SIZE); - cl->virtualVT = VT; -#else - if (cl->super) { - if (isStaticCompiling() && !cl->super->virtualVT) { - makeVT(cl->super); - } - - cl->virtualTableSize = cl->super->virtualTableSize; - } else { - cl->virtualTableSize = VT_NB_FUNCS; - } - - // Allocate the virtual table. - allocateVT(cl); - VT = cl->virtualVT; - - if (!staticCompilation) { - // Fill the virtual table with function pointers. - ExecutionEngine* EE = mvm::MvmModule::executionEngine; - for (uint32 i = 0; i < cl->nbVirtualMethods; ++i) { - JavaMethod& meth = cl->virtualMethods[i]; - LLVMMethodInfo* LMI = getMethodInfo(&meth); - Function* func = LMI->getMethod(); - - // Special handling for finalize method. Don't put a finalizer - // if there is none, or if it is empty. - if (meth.offset == 0) { -#if defined(ISOLATE_SHARING) || defined(USE_GC_BOEHM) - ((void**)VT)[0] = 0; -#else - JnjvmClassLoader* loader = cl->classLoader; - Function* func = loader->getModuleProvider()->parseFunction(&meth); - if (!cl->super) { - meth.canBeInlined = true; - ((void**)VT)[0] = 0; - } else { - Function::iterator BB = func->begin(); - BasicBlock::iterator I = BB->begin(); - if (isa(I)) { - ((void**)VT)[0] = 0; - } else { - // LLVM does not allow recursive compilation. Create the code now. - ((void**)VT)[0] = EE->getPointerToFunction(func); - } - } -#endif - } else { - ((void**)VT)[meth.offset] = EE->getPointerToFunctionOrStub(func); - } - } - -#ifdef WITH_TRACER - Function* func = makeTracer(cl, false); - - void* codePtr = mvm::MvmModule::executionEngine->getPointerToFunction(func); - ((void**)VT)[VT_TRACER_OFFSET] = codePtr; - func->deleteBody(); -#endif - - // If there is no super, then it's the first VT that we allocate. Assign - // this VT to native types. - if (!(cl->super)) { - ClassArray::initialiseVT(cl); - } - - } else { - for (uint32 i = 0; i < cl->nbVirtualMethods; ++i) { - JavaMethod& meth = cl->virtualMethods[i]; - ((void**)VT)[meth.offset] = &meth; - } - } - -#endif - -} - - -const Type* LLVMClassInfo::getVirtualType() { - if (!virtualType) { - std::vector fields; - - if (classDef->super && classDef->super->super) { - LLVMClassInfo* CLI = - JnjvmModule::getClassInfo((Class*)classDef->super); - fields.push_back(CLI->getVirtualType()->getContainedType(0)); - } else { - fields.push_back(JnjvmModule::JavaObjectType->getContainedType(0)); - } - - for (uint32 i = 0; i < classDef->nbVirtualFields; ++i) { - JavaField& field = classDef->virtualFields[i]; - field.num = i + 1; - Typedef* type = field.getSignature(); - LLVMAssessorInfo& LAI = JnjvmModule::getTypedefInfo(type); - fields.push_back(LAI.llvmType); - } - - - JnjvmModule* Mod = classDef->classLoader->getModule(); - StructType* structType = StructType::get(fields, false); - virtualType = PointerType::getUnqual(structType); - const TargetData* targetData = Mod->TheTargetData; - const StructLayout* sl = targetData->getStructLayout(structType); - - for (uint32 i = 0; i < classDef->nbVirtualFields; ++i) { - JavaField& field = classDef->virtualFields[i]; - field.ptrOffset = sl->getElementOffset(i + 1); - } - - uint64 size = Mod->getTypeSize(structType); - classDef->virtualSize = (uint32)size; - virtualSizeConstant = ConstantInt::get(Type::Int32Ty, size); - - if (!Mod->isStaticCompiling()) { - if (!classDef->virtualVT) { - Mod->makeVT((Class*)classDef); - } else { -#ifdef WITH_TRACER - // So the class is vmjc'ed. Create the virtual tracer. - Function* func = Function::Create(JnjvmModule::MarkAndTraceType, - GlobalValue::ExternalLinkage, - "markAndTraceObject", Mod); - - void* ptr = ((void**)classDef->virtualVT)[VT_TRACER_OFFSET]; - Mod->executionEngine->addGlobalMapping(func, ptr); - virtualTracerFunction = func; -#endif - } - } else { - Mod->makeVT(classDef); - } - - } - - return virtualType; -} - -const Type* LLVMClassInfo::getStaticType() { - - if (!staticType) { - Class* cl = (Class*)classDef; - std::vector fields; - - for (uint32 i = 0; i < classDef->nbStaticFields; ++i) { - JavaField& field = classDef->staticFields[i]; - field.num = i; - Typedef* type = field.getSignature(); - LLVMAssessorInfo& LAI = JnjvmModule::getTypedefInfo(type); - fields.push_back(LAI.llvmType); - } - - JnjvmModule* Mod = cl->classLoader->getModule(); - StructType* structType = StructType::get(fields, false); - staticType = PointerType::getUnqual(structType); - const TargetData* targetData = Mod->TheTargetData; - const StructLayout* sl = targetData->getStructLayout(structType); - - for (uint32 i = 0; i < classDef->nbStaticFields; ++i) { - JavaField& field = classDef->staticFields[i]; - field.ptrOffset = sl->getElementOffset(i); - } - - uint64 size = Mod->getTypeSize(structType); - cl->staticSize = size; -#ifdef WITH_TRACER - if (!Mod->isStaticCompiling()) { - Function* F = Mod->makeTracer(cl, true); - cl->staticTracer = (void (*)(void*)) (uintptr_t) - Mod->executionEngine->getPointerToFunction(F); - F->deleteBody(); - } -#endif - } - return staticType; -} - - -Value* LLVMClassInfo::getVirtualSize() { - if (!virtualSizeConstant) { - getVirtualType(); - assert(classDef->virtualSize && "Zero size for a class?"); - virtualSizeConstant = - ConstantInt::get(Type::Int32Ty, classDef->virtualSize); - } - return virtualSizeConstant; -} - -Function* LLVMClassInfo::getStaticTracer() { - if (!staticTracerFunction) { - getStaticType(); - } - return staticTracerFunction; -} - -Function* LLVMClassInfo::getVirtualTracer() { - if (!virtualTracerFunction) { - getVirtualType(); - } - return virtualTracerFunction; -} - -Function* LLVMMethodInfo::getMethod() { - if (!methodFunction) { - JnjvmClassLoader* JCL = methodDef->classDef->classLoader; - JnjvmModule* Mod = JCL->getModule(); - if (Mod->isStaticCompiling()) { - - const UTF8* jniConsClName = methodDef->classDef->name; - const UTF8* jniConsName = methodDef->name; - const UTF8* jniConsType = methodDef->type; - sint32 clen = jniConsClName->size; - sint32 mnlen = jniConsName->size; - sint32 mtlen = jniConsType->size; - - char* buf = (char*)alloca(3 + JNI_NAME_PRE_LEN + 1 + - ((mnlen + clen + mtlen) << 1)); - - bool jnjvm = false; - if (isNative(methodDef->access)) { - // Verify if it's defined by JnJVM - JCL->nativeLookup(methodDef, jnjvm, buf); - } - - if (!jnjvm) { - methodDef->jniConsFromMethOverloaded(buf + 1); - memcpy(buf, "JnJVM", 5); - } - - methodFunction = Function::Create(getFunctionType(), - GlobalValue::GhostLinkage, buf, Mod); - - } else { - - methodFunction = Function::Create(getFunctionType(), - GlobalValue::GhostLinkage, - "", Mod); - - } - methodFunction->addAnnotation(this); - } - return methodFunction; -} - -const FunctionType* LLVMMethodInfo::getFunctionType() { - if (!functionType) { - Signdef* sign = methodDef->getSignature(); - LLVMSignatureInfo* LSI = JnjvmModule::getSignatureInfo(sign); - assert(LSI); - if (isStatic(methodDef->access)) { - functionType = LSI->getStaticType(); - } else { - functionType = LSI->getVirtualType(); - } - } - return functionType; -} - -ConstantInt* LLVMMethodInfo::getOffset() { - if (!offsetConstant) { - JnjvmModule::resolveVirtualClass(methodDef->classDef); - offsetConstant = ConstantInt::get(Type::Int32Ty, methodDef->offset); - } - return offsetConstant; -} - -ConstantInt* LLVMFieldInfo::getOffset() { - if (!offsetConstant) { - if (isStatic(fieldDef->access)) { - JnjvmModule::resolveStaticClass(fieldDef->classDef); - } else { - JnjvmModule::resolveVirtualClass(fieldDef->classDef); - } - - offsetConstant = ConstantInt::get(Type::Int32Ty, fieldDef->num); - } - return offsetConstant; -} - -const llvm::FunctionType* LLVMSignatureInfo::getVirtualType() { - if (!virtualType) { - // Lock here because we are called by arbitrary code - mvm::MvmModule::protectIR(); - std::vector llvmArgs; - uint32 size = signature->nbArguments; - Typedef* const* arguments = signature->getArgumentsType(); - - llvmArgs.push_back(JnjvmModule::JavaObjectType); - - for (uint32 i = 0; i < size; ++i) { - Typedef* type = arguments[i]; - LLVMAssessorInfo& LAI = JnjvmModule::getTypedefInfo(type); - llvmArgs.push_back(LAI.llvmType); - } - -#if defined(ISOLATE_SHARING) - llvmArgs.push_back(JnjvmModule::ConstantPoolType); // cached constant pool -#endif - - LLVMAssessorInfo& LAI = - JnjvmModule::getTypedefInfo(signature->getReturnType()); - virtualType = FunctionType::get(LAI.llvmType, llvmArgs, false); - mvm::MvmModule::unprotectIR(); - } - return virtualType; -} - -const llvm::FunctionType* LLVMSignatureInfo::getStaticType() { - if (!staticType) { - // Lock here because we are called by arbitrary code - mvm::MvmModule::protectIR(); - std::vector llvmArgs; - uint32 size = signature->nbArguments; - Typedef* const* arguments = signature->getArgumentsType(); - - for (uint32 i = 0; i < size; ++i) { - Typedef* type = arguments[i]; - LLVMAssessorInfo& LAI = JnjvmModule::getTypedefInfo(type); - llvmArgs.push_back(LAI.llvmType); - } - -#if defined(ISOLATE_SHARING) - llvmArgs.push_back(JnjvmModule::ConstantPoolType); // cached constant pool -#endif - - LLVMAssessorInfo& LAI = - JnjvmModule::getTypedefInfo(signature->getReturnType()); - staticType = FunctionType::get(LAI.llvmType, llvmArgs, false); - mvm::MvmModule::unprotectIR(); - } - return staticType; -} - -const llvm::FunctionType* LLVMSignatureInfo::getNativeType() { - if (!nativeType) { - // Lock here because we are called by arbitrary code - mvm::MvmModule::protectIR(); - std::vector llvmArgs; - uint32 size = signature->nbArguments; - Typedef* const* arguments = signature->getArgumentsType(); - - llvmArgs.push_back(mvm::MvmModule::ptrType); // JNIEnv - llvmArgs.push_back(JnjvmModule::JavaObjectType); // Class - - for (uint32 i = 0; i < size; ++i) { - Typedef* type = arguments[i]; - LLVMAssessorInfo& LAI = JnjvmModule::getTypedefInfo(type); - llvmArgs.push_back(LAI.llvmType); - } - -#if defined(ISOLATE_SHARING) - llvmArgs.push_back(JnjvmModule::ConstantPoolType); // cached constant pool -#endif - - LLVMAssessorInfo& LAI = - JnjvmModule::getTypedefInfo(signature->getReturnType()); - nativeType = FunctionType::get(LAI.llvmType, llvmArgs, false); - mvm::MvmModule::unprotectIR(); - } - return nativeType; -} - - -Function* LLVMSignatureInfo::createFunctionCallBuf(bool virt) { - - std::vector Args; - - JnjvmModule* Mod = signature->initialLoader->getModule(); - const char* name = 0; - if (Mod->isStaticCompiling()) { - name = virt ? signature->printString("virtual_buf") : - signature->printString("static_buf"); - } else { - name = ""; - } - - Function* res = Function::Create(virt ? getVirtualBufType() : - getStaticBufType(), - GlobalValue::InternalLinkage, name, Mod); - - BasicBlock* currentBlock = BasicBlock::Create("enter", res); - Function::arg_iterator i = res->arg_begin(); - Value *obj, *ptr, *func; -#if defined(ISOLATE_SHARING) - Value* ctp = i; -#endif - ++i; - func = i; - ++i; - if (virt) { - obj = i; - ++i; - Args.push_back(obj); - } - ptr = i; - - Typedef* const* arguments = signature->getArgumentsType(); - for (uint32 i = 0; i < signature->nbArguments; ++i) { - - LLVMAssessorInfo& LAI = JnjvmModule::getTypedefInfo(arguments[i]); - Value* val = new BitCastInst(ptr, LAI.llvmTypePtr, "", currentBlock); - Value* arg = new LoadInst(val, "", currentBlock); - Args.push_back(arg); - ptr = GetElementPtrInst::Create(ptr, JnjvmModule::constantEight, "", - currentBlock); - } - -#if defined(ISOLATE_SHARING) - Args.push_back(ctp); -#endif - - Value* val = CallInst::Create(func, Args.begin(), Args.end(), "", - currentBlock); - if (res->getFunctionType()->getReturnType() != Type::VoidTy) - ReturnInst::Create(val, currentBlock); - else - ReturnInst::Create(currentBlock); - - return res; -} - -Function* LLVMSignatureInfo::createFunctionCallAP(bool virt) { - - std::vector Args; - - JnjvmModule* Mod = signature->initialLoader->getModule(); - const char* name = 0; - if (Mod->isStaticCompiling()) { - name = virt ? signature->printString("virtual_ap") : - signature->printString("static_ap"); - } else { - name = ""; - } - - Function* res = Function::Create(virt ? getVirtualBufType() : - getStaticBufType(), - GlobalValue::InternalLinkage, name, Mod); - - BasicBlock* currentBlock = BasicBlock::Create("enter", res); - Function::arg_iterator i = res->arg_begin(); - Value *obj, *ap, *func; -#if defined(ISOLATE_SHARING) - Value* ctp = i; -#endif - ++i; - func = i; - ++i; - if (virt) { - obj = i; - Args.push_back(obj); - ++i; - } - ap = i; - - Typedef* const* arguments = signature->getArgumentsType(); - for (uint32 i = 0; i < signature->nbArguments; ++i) { - LLVMAssessorInfo& LAI = JnjvmModule::getTypedefInfo(arguments[i]); - Args.push_back(new VAArgInst(ap, LAI.llvmType, "", currentBlock)); - } - -#if defined(ISOLATE_SHARING) - Args.push_back(ctp); -#endif - - Value* val = CallInst::Create(func, Args.begin(), Args.end(), "", - currentBlock); - if (res->getFunctionType()->getReturnType() != Type::VoidTy) - ReturnInst::Create(val, currentBlock); - else - ReturnInst::Create(currentBlock); - - return res; -} - -const PointerType* LLVMSignatureInfo::getStaticPtrType() { - if (!staticPtrType) { - staticPtrType = PointerType::getUnqual(getStaticType()); - } - return staticPtrType; -} - -const PointerType* LLVMSignatureInfo::getVirtualPtrType() { - if (!virtualPtrType) { - virtualPtrType = PointerType::getUnqual(getVirtualType()); - } - return virtualPtrType; -} - -const PointerType* LLVMSignatureInfo::getNativePtrType() { - if (!nativePtrType) { - nativePtrType = PointerType::getUnqual(getNativeType()); - } - return nativePtrType; -} - - -const FunctionType* LLVMSignatureInfo::getVirtualBufType() { - if (!virtualBufType) { - // Lock here because we are called by arbitrary code - mvm::MvmModule::protectIR(); - std::vector Args2; - Args2.push_back(JnjvmModule::ConstantPoolType); // ctp - Args2.push_back(getVirtualPtrType()); - Args2.push_back(JnjvmModule::JavaObjectType); - Args2.push_back(JnjvmModule::ptrType); - LLVMAssessorInfo& LAI = - JnjvmModule::getTypedefInfo(signature->getReturnType()); - virtualBufType = FunctionType::get(LAI.llvmType, Args2, false); - mvm::MvmModule::unprotectIR(); - } - return virtualBufType; -} - -const FunctionType* LLVMSignatureInfo::getStaticBufType() { - if (!staticBufType) { - // Lock here because we are called by arbitrary code - mvm::MvmModule::protectIR(); - std::vector Args; - Args.push_back(JnjvmModule::ConstantPoolType); // ctp - Args.push_back(getStaticPtrType()); - Args.push_back(JnjvmModule::ptrType); - LLVMAssessorInfo& LAI = - JnjvmModule::getTypedefInfo(signature->getReturnType()); - staticBufType = FunctionType::get(LAI.llvmType, Args, false); - mvm::MvmModule::unprotectIR(); - } - return staticBufType; -} - -Function* LLVMSignatureInfo::getVirtualBuf() { - if (!virtualBufFunction) { - // Lock here because we are called by arbitrary code - mvm::MvmModule::protectIR(); - virtualBufFunction = createFunctionCallBuf(true); - if (!signature->initialLoader->getModule()->isStaticCompiling()) { - signature->setVirtualCallBuf((intptr_t) - mvm::MvmModule::executionEngine->getPointerToGlobal(virtualBufFunction)); - // Now that it's compiled, we don't need the IR anymore - virtualBufFunction->deleteBody(); - } - mvm::MvmModule::unprotectIR(); - } - return virtualBufFunction; -} - -Function* LLVMSignatureInfo::getVirtualAP() { - if (!virtualAPFunction) { - // Lock here because we are called by arbitrary code - mvm::MvmModule::protectIR(); - virtualAPFunction = createFunctionCallAP(true); - if (!signature->initialLoader->getModule()->isStaticCompiling()) { - signature->setVirtualCallAP((intptr_t) - mvm::MvmModule::executionEngine->getPointerToGlobal(virtualAPFunction)); - // Now that it's compiled, we don't need the IR anymore - virtualAPFunction->deleteBody(); - } - mvm::MvmModule::unprotectIR(); - } - return virtualAPFunction; -} - -Function* LLVMSignatureInfo::getStaticBuf() { - if (!staticBufFunction) { - // Lock here because we are called by arbitrary code - mvm::MvmModule::protectIR(); - staticBufFunction = createFunctionCallBuf(false); - if (!signature->initialLoader->getModule()->isStaticCompiling()) { - signature->setStaticCallBuf((intptr_t) - mvm::MvmModule::executionEngine->getPointerToGlobal(staticBufFunction)); - // Now that it's compiled, we don't need the IR anymore - staticBufFunction->deleteBody(); - } - mvm::MvmModule::unprotectIR(); - } - return staticBufFunction; -} - -Function* LLVMSignatureInfo::getStaticAP() { - if (!staticAPFunction) { - // Lock here because we are called by arbitrary code - mvm::MvmModule::protectIR(); - staticAPFunction = createFunctionCallAP(false); - if (!signature->initialLoader->getModule()->isStaticCompiling()) { - signature->setStaticCallAP((intptr_t) - mvm::MvmModule::executionEngine->getPointerToGlobal(staticAPFunction)); - // Now that it's compiled, we don't need the IR anymore - staticAPFunction->deleteBody(); - } - mvm::MvmModule::unprotectIR(); - } - return staticAPFunction; -} - -void JnjvmModule::resolveVirtualClass(Class* cl) { - // Lock here because we may be called by a class resolver - mvm::MvmModule::protectIR(); - LLVMClassInfo* LCI = (LLVMClassInfo*)getClassInfo(cl); - LCI->getVirtualType(); - mvm::MvmModule::unprotectIR(); -} - -void JnjvmModule::resolveStaticClass(Class* cl) { - // Lock here because we may be called by a class initializer - mvm::MvmModule::protectIR(); - LLVMClassInfo* LCI = (LLVMClassInfo*)getClassInfo(cl); - LCI->getStaticType(); - mvm::MvmModule::unprotectIR(); -} - - -namespace jnjvm { - namespace llvm_runtime { - #include "LLVMRuntime.inc" - } -} - -Module* JnjvmModule::initialModule; - -void JnjvmModule::initialise() { - jnjvm::llvm_runtime::makeLLVMModuleContents(this); - Module* module = this; - initialModule = this; - - VTType = PointerType::getUnqual(module->getTypeByName("VT")); - -#ifdef ISOLATE_SHARING - JnjvmType = - PointerType::getUnqual(module->getTypeByName("Jnjvm")); -#endif - ConstantPoolType = ptrPtrType; - - JavaObjectType = - PointerType::getUnqual(module->getTypeByName("JavaObject")); - - JavaArrayType = - PointerType::getUnqual(module->getTypeByName("JavaArray")); - - JavaCommonClassType = - PointerType::getUnqual(module->getTypeByName("JavaCommonClass")); - JavaClassPrimitiveType = - PointerType::getUnqual(module->getTypeByName("JavaClassPrimitive")); - JavaClassArrayType = - PointerType::getUnqual(module->getTypeByName("JavaClassArray")); - JavaClassType = - PointerType::getUnqual(module->getTypeByName("JavaClass")); - - JavaArrayUInt8Type = - PointerType::getUnqual(module->getTypeByName("ArrayUInt8")); - JavaArraySInt8Type = - PointerType::getUnqual(module->getTypeByName("ArraySInt8")); - JavaArrayUInt16Type = - PointerType::getUnqual(module->getTypeByName("ArrayUInt16")); - JavaArraySInt16Type = - PointerType::getUnqual(module->getTypeByName("ArraySInt16")); - JavaArrayUInt32Type = - PointerType::getUnqual(module->getTypeByName("ArrayUInt32")); - JavaArraySInt32Type = - PointerType::getUnqual(module->getTypeByName("ArraySInt32")); - JavaArrayLongType = - PointerType::getUnqual(module->getTypeByName("ArrayLong")); - JavaArrayFloatType = - PointerType::getUnqual(module->getTypeByName("ArrayFloat")); - JavaArrayDoubleType = - PointerType::getUnqual(module->getTypeByName("ArrayDouble")); - JavaArrayObjectType = - PointerType::getUnqual(module->getTypeByName("ArrayObject")); - - CacheNodeType = - PointerType::getUnqual(module->getTypeByName("CacheNode")); - - EnveloppeType = - PointerType::getUnqual(module->getTypeByName("Enveloppe")); - - JavaFieldType = - PointerType::getUnqual(module->getTypeByName("JavaField")); - JavaMethodType = - PointerType::getUnqual(module->getTypeByName("JavaMethod")); - UTF8Type = - PointerType::getUnqual(module->getTypeByName("UTF8")); - AttributType = - PointerType::getUnqual(module->getTypeByName("Attribut")); - JavaThreadType = - PointerType::getUnqual(module->getTypeByName("JavaThread")); - -#ifdef WITH_TRACER - MarkAndTraceType = module->getFunction("MarkAndTrace")->getFunctionType(); -#endif - - JavaObjectNullConstant = Constant::getNullValue(JnjvmModule::JavaObjectType); - MaxArraySizeConstant = ConstantInt::get(Type::Int32Ty, - JavaArray::MaxArraySize); - JavaArraySizeConstant = - ConstantInt::get(Type::Int32Ty, sizeof(JavaObject) + sizeof(ssize_t)); - - - JavaArrayElementsOffsetConstant = mvm::MvmModule::constantTwo; - JavaArraySizeOffsetConstant = mvm::MvmModule::constantOne; - JavaObjectLockOffsetConstant = mvm::MvmModule::constantTwo; - JavaObjectClassOffsetConstant = mvm::MvmModule::constantOne; - - OffsetDisplayInClassConstant = mvm::MvmModule::constantZero; - OffsetDepthInClassConstant = mvm::MvmModule::constantOne; - - OffsetObjectSizeInClassConstant = mvm::MvmModule::constantOne; - OffsetVTInClassConstant = mvm::MvmModule::constantTwo; - OffsetTaskClassMirrorInClassConstant = mvm::MvmModule::constantThree; - OffsetStaticInstanceInTaskClassMirrorConstant = mvm::MvmModule::constantTwo; - OffsetStatusInTaskClassMirrorConstant = mvm::MvmModule::constantZero; - OffsetInitializedInTaskClassMirrorConstant = mvm::MvmModule::constantOne; - - OffsetJavaExceptionInThreadConstant = ConstantInt::get(Type::Int32Ty, 9); - OffsetCXXExceptionInThreadConstant = ConstantInt::get(Type::Int32Ty, 10); - - ClassReadyConstant = ConstantInt::get(Type::Int8Ty, ready); - - - if (staticCompilation) { - const Type* ATy = VTType->getContainedType(0); - PrimitiveArrayVT = new GlobalVariable(ATy, true, - GlobalValue::ExternalLinkage, - 0, "JavaArrayVT", this); - - ReferenceArrayVT = new GlobalVariable(ATy, true, - GlobalValue::ExternalLinkage, - 0, "ArrayObjectVT", this); - - - - ATy = JavaClassArrayType->getContainedType(0); - GlobalVariable* varGV = 0; - -#define PRIMITIVE_ARRAY(name) \ - varGV = new GlobalVariable(ATy, true, GlobalValue::ExternalLinkage, \ - 0, #name, this); \ - arrayClasses.insert(std::make_pair(&name, varGV)); - - PRIMITIVE_ARRAY(ArrayOfBool) - PRIMITIVE_ARRAY(ArrayOfByte) - PRIMITIVE_ARRAY(ArrayOfChar) - PRIMITIVE_ARRAY(ArrayOfShort) - PRIMITIVE_ARRAY(ArrayOfInt) - PRIMITIVE_ARRAY(ArrayOfFloat) - PRIMITIVE_ARRAY(ArrayOfDouble) - PRIMITIVE_ARRAY(ArrayOfLong) - -#undef PRIMITIVE_ARRAY - - std::vector llvmArgs; - llvmArgs.push_back(ptrType); // class loader. - const FunctionType* FTy = FunctionType::get(Type::VoidTy, llvmArgs, false); - - StaticInitializer = Function::Create(FTy, GlobalValue::InternalLinkage, - "Init", this); - - llvmArgs.clear(); - llvmArgs.push_back(JavaMethodType); - - FTy = FunctionType::get(ptrType, llvmArgs, false); - - NativeLoader = Function::Create(FTy, GlobalValue::ExternalLinkage, - "vmjcNativeLoader", this); - - llvmArgs.clear(); - FTy = FunctionType::get(Type::VoidTy, llvmArgs, false); - ObjectPrinter = Function::Create(FTy, GlobalValue::ExternalLinkage, - "printJavaObject", this); - - } else { - PrimitiveArrayVT = ConstantExpr::getIntToPtr(ConstantInt::get(Type::Int64Ty, - uint64(JavaArrayVT)), - VTType); - - ReferenceArrayVT = ConstantExpr::getIntToPtr(ConstantInt::get(Type::Int64Ty, - uint64(ArrayObjectVT)), - VTType); - } - - LLVMAssessorInfo::initialise(); -} - -Constant* JnjvmModule::getReferenceArrayVT() { - return ReferenceArrayVT; -} - -Constant* JnjvmModule::getPrimitiveArrayVT() { - return PrimitiveArrayVT; -} - -void JnjvmModule::setMethod(JavaMethod* meth, void* ptr, const char* name) { - Function* func = getMethodInfo(meth)->getMethod(); - func->setName(name); - assert(ptr && "No value given"); - if (executionEngine) executionEngine->addGlobalMapping(func, ptr); - func->setLinkage(GlobalValue::ExternalLinkage); -} - -void JnjvmModule::printStats() { - fprintf(stderr, "----------------- Info from the module -----------------\n"); - fprintf(stderr, "Number of native classes : %llu\n", - (unsigned long long int) nativeClasses.size()); - fprintf(stderr, "Number of Java classes : %llu\n", - (unsigned long long int) javaClasses.size()); - fprintf(stderr, "Number of external array classes : %llu\n", - (unsigned long long int) arrayClasses.size()); - fprintf(stderr, "Number of virtual tables : %llu\n", - (unsigned long long int) virtualTables.size()); - fprintf(stderr, "Number of static instances : %llu\n", - (unsigned long long int) staticInstances.size()); - fprintf(stderr, "Number of constant pools : %llu\n", - (unsigned long long int) constantPools.size()); - fprintf(stderr, "Number of strings : %llu\n", - (unsigned long long int) strings.size()); - fprintf(stderr, "Number of enveloppes : %llu\n", - (unsigned long long int) enveloppes.size()); - fprintf(stderr, "Number of native functions : %llu\n", - (unsigned long long int) nativeFunctions.size()); - fprintf(stderr, "----------------- Total size in .data ------------------\n"); - uint64 size = 0; - for (Module::const_global_iterator i = global_begin(), e = global_end(); - i != e; ++i) { - size += getTypeSize(i->getType()); - } - fprintf(stderr, "%lluB\n", (unsigned long long int)size); -} - - -Function* JnjvmModule::getMethod(JavaMethod* meth) { - return getMethodInfo(meth)->getMethod(); -} - -JnjvmModule::JnjvmModule(const std::string &ModuleID, bool sc) : - MvmModule(ModuleID) { - - staticCompilation = sc; - generateTracers = true; - generateStubs = true; - enabledException = true; - assumeCompiled = false; - if (!VTType) initialise(); - - Module* module = initialModule; - - InterfaceLookupFunction = module->getFunction("jnjvmVirtualLookup"); - MultiCallNewFunction = module->getFunction("multiCallNew"); - ForceLoadedCheckFunction = module->getFunction("forceLoadedCheck"); - InitialisationCheckFunction = module->getFunction("initialisationCheck"); - ForceInitialisationCheckFunction = - module->getFunction("forceInitialisationCheck"); - InitialiseClassFunction = module->getFunction("jnjvmRuntimeInitialiseClass"); - - GetConstantPoolAtFunction = module->getFunction("getConstantPoolAt"); - ArrayLengthFunction = module->getFunction("arrayLength"); - GetVTFunction = module->getFunction("getVT"); - GetClassFunction = module->getFunction("getClass"); - ClassLookupFunction = module->getFunction("classLookup"); - GetVTFromClassFunction = module->getFunction("getVTFromClass"); - GetObjectSizeFromClassFunction = - module->getFunction("getObjectSizeFromClass"); - - GetClassDelegateeFunction = module->getFunction("getClassDelegatee"); - RuntimeDelegateeFunction = module->getFunction("jnjvmRuntimeDelegatee"); - InstanceOfFunction = module->getFunction("instanceOf"); - IsAssignableFromFunction = module->getFunction("isAssignableFrom"); - ImplementsFunction = module->getFunction("implements"); - InstantiationOfArrayFunction = module->getFunction("instantiationOfArray"); - GetDepthFunction = module->getFunction("getDepth"); - GetStaticInstanceFunction = module->getFunction("getStaticInstance"); - GetDisplayFunction = module->getFunction("getDisplay"); - GetClassInDisplayFunction = module->getFunction("getClassInDisplay"); - AquireObjectFunction = module->getFunction("JavaObjectAquire"); - ReleaseObjectFunction = module->getFunction("JavaObjectRelease"); - OverflowThinLockFunction = module->getFunction("overflowThinLock"); - - VirtualFieldLookupFunction = module->getFunction("virtualFieldLookup"); - StaticFieldLookupFunction = module->getFunction("staticFieldLookup"); - - JniProceedPendingExceptionFunction = - module->getFunction("jniProceedPendingException"); - GetSJLJBufferFunction = module->getFunction("getSJLJBuffer"); - - NullPointerExceptionFunction = - module->getFunction("jnjvmNullPointerException"); - ClassCastExceptionFunction = module->getFunction("jnjvmClassCastException"); - IndexOutOfBoundsExceptionFunction = - module->getFunction("indexOutOfBoundsException"); - NegativeArraySizeExceptionFunction = - module->getFunction("negativeArraySizeException"); - OutOfMemoryErrorFunction = module->getFunction("outOfMemoryError"); - - JavaObjectAllocateFunction = module->getFunction("gcmalloc"); - - PrintExecutionFunction = module->getFunction("printExecution"); - PrintMethodStartFunction = module->getFunction("printMethodStart"); - PrintMethodEndFunction = module->getFunction("printMethodEnd"); - - ThrowExceptionFunction = module->getFunction("JavaThreadThrowException"); - - GetArrayClassFunction = module->getFunction("getArrayClass"); - - GetFinalInt8FieldFunction = module->getFunction("getFinalInt8Field"); - GetFinalInt16FieldFunction = module->getFunction("getFinalInt16Field"); - GetFinalInt32FieldFunction = module->getFunction("getFinalInt32Field"); - GetFinalLongFieldFunction = module->getFunction("getFinalLongField"); - GetFinalFloatFieldFunction = module->getFunction("getFinalFloatField"); - GetFinalDoubleFieldFunction = module->getFunction("getFinalDoubleField"); - GetFinalObjectFieldFunction = module->getFunction("getFinalObjectField"); - -#ifdef ISOLATE - StringLookupFunction = module->getFunction("stringLookup"); -#ifdef ISOLATE_SHARING - EnveloppeLookupFunction = module->getFunction("enveloppeLookup"); - GetCtpCacheNodeFunction = module->getFunction("getCtpCacheNode"); - GetCtpClassFunction = module->getFunction("getCtpClass"); - GetJnjvmExceptionClassFunction = - module->getFunction("getJnjvmExceptionClass"); - GetJnjvmArrayClassFunction = module->getFunction("getJnjvmArrayClass"); - StaticCtpLookupFunction = module->getFunction("staticCtpLookup"); - SpecialCtpLookupFunction = module->getFunction("specialCtpLookup"); -#endif -#endif - -#ifdef SERVICE - ServiceCallStartFunction = module->getFunction("serviceCallStart"); - ServiceCallStopFunction = module->getFunction("serviceCallStop"); -#endif - -#ifdef WITH_TRACER - MarkAndTraceFunction = module->getFunction("MarkAndTrace"); - JavaObjectTracerFunction = module->getFunction("JavaObjectTracer"); - JavaArrayTracerFunction = module->getFunction("JavaArrayTracer"); - ArrayObjectTracerFunction = module->getFunction("ArrayObjectTracer"); -#endif - -#ifndef WITHOUT_VTABLE - VirtualLookupFunction = module->getFunction("vtableLookup"); -#endif - - GetLockFunction = module->getFunction("getLock"); - - addTypeName("JavaObject", JavaObjectType); - addTypeName("JavaArray", JavaArrayType); - addTypeName("JavaCommonClass", JavaCommonClassType); - addTypeName("JavaClass", JavaClassType); - addTypeName("JavaClassPrimitive", JavaClassPrimitiveType); - addTypeName("JavaClassArray", JavaClassArrayType); - addTypeName("ArrayUInt8", JavaArrayUInt8Type); - addTypeName("ArraySInt8", JavaArraySInt8Type); - addTypeName("ArrayUInt16", JavaArrayUInt16Type); - addTypeName("ArraySInt16", JavaArraySInt16Type); - addTypeName("ArraySInt32", JavaArraySInt32Type); - addTypeName("ArrayLong", JavaArrayLongType); - addTypeName("ArrayFloat", JavaArrayFloatType); - addTypeName("ArrayDouble", JavaArrayDoubleType); - addTypeName("ArrayObject", JavaArrayObjectType); - addTypeName("CacheNode", CacheNodeType); - addTypeName("Enveloppe", EnveloppeType); -} - -void LLVMAssessorInfo::initialise() { - AssessorInfo[I_VOID].llvmType = Type::VoidTy; - AssessorInfo[I_VOID].llvmTypePtr = 0; - AssessorInfo[I_VOID].llvmNullConstant = 0; - AssessorInfo[I_VOID].sizeInBytesConstant = 0; - - AssessorInfo[I_BOOL].llvmType = Type::Int8Ty; - AssessorInfo[I_BOOL].llvmTypePtr = PointerType::getUnqual(Type::Int8Ty); - AssessorInfo[I_BOOL].llvmNullConstant = - Constant::getNullValue(Type::Int8Ty); - AssessorInfo[I_BOOL].sizeInBytesConstant = mvm::MvmModule::constantOne; - - AssessorInfo[I_BYTE].llvmType = Type::Int8Ty; - AssessorInfo[I_BYTE].llvmTypePtr = PointerType::getUnqual(Type::Int8Ty); - AssessorInfo[I_BYTE].llvmNullConstant = - Constant::getNullValue(Type::Int8Ty); - AssessorInfo[I_BYTE].sizeInBytesConstant = mvm::MvmModule::constantOne; - - AssessorInfo[I_SHORT].llvmType = Type::Int16Ty; - AssessorInfo[I_SHORT].llvmTypePtr = PointerType::getUnqual(Type::Int16Ty); - AssessorInfo[I_SHORT].llvmNullConstant = - Constant::getNullValue(Type::Int16Ty); - AssessorInfo[I_SHORT].sizeInBytesConstant = mvm::MvmModule::constantTwo; - - AssessorInfo[I_CHAR].llvmType = Type::Int16Ty; - AssessorInfo[I_CHAR].llvmTypePtr = PointerType::getUnqual(Type::Int16Ty); - AssessorInfo[I_CHAR].llvmNullConstant = - Constant::getNullValue(Type::Int16Ty); - AssessorInfo[I_CHAR].sizeInBytesConstant = mvm::MvmModule::constantTwo; - - AssessorInfo[I_INT].llvmType = Type::Int32Ty; - AssessorInfo[I_INT].llvmTypePtr = PointerType::getUnqual(Type::Int32Ty); - AssessorInfo[I_INT].llvmNullConstant = - Constant::getNullValue(Type::Int32Ty); - AssessorInfo[I_INT].sizeInBytesConstant = mvm::MvmModule::constantFour; - - AssessorInfo[I_FLOAT].llvmType = Type::FloatTy; - AssessorInfo[I_FLOAT].llvmTypePtr = PointerType::getUnqual(Type::FloatTy); - AssessorInfo[I_FLOAT].llvmNullConstant = - Constant::getNullValue(Type::FloatTy); - AssessorInfo[I_FLOAT].sizeInBytesConstant = mvm::MvmModule::constantFour; - - AssessorInfo[I_LONG].llvmType = Type::Int64Ty; - AssessorInfo[I_LONG].llvmTypePtr = PointerType::getUnqual(Type::Int64Ty); - AssessorInfo[I_LONG].llvmNullConstant = - Constant::getNullValue(Type::Int64Ty); - AssessorInfo[I_LONG].sizeInBytesConstant = mvm::MvmModule::constantEight; - - AssessorInfo[I_DOUBLE].llvmType = Type::DoubleTy; - AssessorInfo[I_DOUBLE].llvmTypePtr = PointerType::getUnqual(Type::DoubleTy); - AssessorInfo[I_DOUBLE].llvmNullConstant = - Constant::getNullValue(Type::DoubleTy); - AssessorInfo[I_DOUBLE].sizeInBytesConstant = mvm::MvmModule::constantEight; - - AssessorInfo[I_TAB].llvmType = JnjvmModule::JavaObjectType; - AssessorInfo[I_TAB].llvmTypePtr = - PointerType::getUnqual(JnjvmModule::JavaObjectType); - AssessorInfo[I_TAB].llvmNullConstant = - JnjvmModule::JavaObjectNullConstant; - AssessorInfo[I_TAB].sizeInBytesConstant = mvm::MvmModule::constantPtrSize; - - AssessorInfo[I_REF].llvmType = JnjvmModule::JavaObjectType; - AssessorInfo[I_REF].llvmTypePtr = - PointerType::getUnqual(JnjvmModule::JavaObjectType); - AssessorInfo[I_REF].llvmNullConstant = - JnjvmModule::JavaObjectNullConstant; - AssessorInfo[I_REF].sizeInBytesConstant = mvm::MvmModule::constantPtrSize; -} - -std::map LLVMAssessorInfo::AssessorInfo; - -LLVMAssessorInfo& JnjvmModule::getTypedefInfo(const Typedef* type) { - return LLVMAssessorInfo::AssessorInfo[type->getKey()->elements[0]]; -} - -static AnnotationID JavaMethod_ID( - AnnotationManager::getID("Java::JavaMethod")); - - -LLVMMethodInfo::LLVMMethodInfo(JavaMethod* M) : - llvm::Annotation(JavaMethod_ID), methodDef(M), methodFunction(0), - offsetConstant(0), functionType(0) {} - -JavaMethod* LLVMMethodInfo::get(const llvm::Function* F) { - LLVMMethodInfo *MI = (LLVMMethodInfo*)F->getAnnotation(JavaMethod_ID); - if (MI) return MI->methodDef; - return 0; -} - -#ifdef SERVICE -Value* JnjvmModule::getIsolate(Jnjvm* isolate, Value* Where) { - if (staticCompilation) { - llvm::Constant* varGV = 0; - isolate_iterator End = isolates.end(); - isolate_iterator I = isolates.find(isolate); - if (I == End) { - - - Constant* cons = - ConstantExpr::getIntToPtr(ConstantInt::get(Type::Int64Ty, - uint64_t(isolate)), - ptrType); - - varGV = new GlobalVariable(ptrType, !staticCompilation, - GlobalValue::ExternalLinkage, - cons, "", this); - - isolates.insert(std::make_pair(isolate, varGV)); - } else { - varGV = I->second; - } - if (BasicBlock* BB = dyn_cast(Where)) { - return new LoadInst(varGV, "", BB); - } else { - assert(dyn_cast(Where) && "Wrong use of module"); - return new LoadInst(varGV, "", dyn_cast(Where)); - } - } else { - ConstantInt* CI = ConstantInt::get(Type::Int64Ty, uint64_t(isolate)); - return ConstantExpr::getIntToPtr(CI, ptrType); - } -} -#endif - -void JnjvmModule::CreateStaticInitializer() { - - std::vector llvmArgs; - llvmArgs.push_back(ptrType); // class loader - llvmArgs.push_back(JavaCommonClassType); // cl - const FunctionType* FTy = FunctionType::get(Type::VoidTy, llvmArgs, false); - - Function* AddClass = Function::Create(FTy, GlobalValue::ExternalLinkage, - "vmjcAddPreCompiledClass", this); - - llvmArgs.clear(); - llvmArgs.push_back(ptrType); // class loader - llvmArgs.push_back(PointerType::getUnqual(JavaClassArrayType)); // array ptr - llvmArgs.push_back(UTF8Type); // name - FTy = FunctionType::get(Type::VoidTy, llvmArgs, false); - - Function* GetClassArray = Function::Create(FTy, GlobalValue::ExternalLinkage, - "vmjcGetClassArray", this); - - if (!StaticInitializer) { - std::vector llvmArgs; - llvmArgs.push_back(ptrType); // class loader. - const FunctionType* FTy = FunctionType::get(Type::VoidTy, llvmArgs, false); - - StaticInitializer = Function::Create(FTy, GlobalValue::InternalLinkage, - "Init", this); - } - - BasicBlock* currentBlock = BasicBlock::Create("enter", StaticInitializer); - Function::arg_iterator loader = StaticInitializer->arg_begin(); - - Value* Args[3]; - // If we have defined some strings. - if (strings.begin() != strings.end()) { - llvmArgs.clear(); - llvmArgs.push_back(ptrType); // class loader - llvmArgs.push_back(strings.begin()->second->getType()); // val - FTy = FunctionType::get(Type::VoidTy, llvmArgs, false); - - Function* AddString = Function::Create(FTy, GlobalValue::ExternalLinkage, - "vmjcAddString", this); - - - - for (string_iterator i = strings.begin(), e = strings.end(); i != e; ++i) { - Args[0] = loader; - Args[1] = i->second; - CallInst::Create(AddString, Args, Args + 2, "", currentBlock); - } - } - - for (native_class_iterator i = nativeClasses.begin(), - e = nativeClasses.end(); i != e; ++i) { - if (isCompiling(i->first)) { - Args[0] = loader; - Args[1] = ConstantExpr::getBitCast(i->second, JavaCommonClassType); - CallInst::Create(AddClass, Args, Args + 2, "", currentBlock); - } - } - - for (array_class_iterator i = arrayClasses.begin(), - e = arrayClasses.end(); i != e; ++i) { - if (!(i->first->baseClass()->isPrimitive())) { - Args[0] = loader; - Args[1] = i->second; - Args[2] = getUTF8(i->first->name); - CallInst::Create(GetClassArray, Args, Args + 3, "", currentBlock); - } - } - - - ReturnInst::Create(currentBlock); -} - -void JnjvmModule::setNoInline(Class* cl) { - for (uint32 i = 0; i < cl->nbVirtualMethods; ++i) { - JavaMethod& meth = cl->virtualMethods[i]; - if (!isAbstract(meth.access)) { - LLVMMethodInfo* LMI = getMethodInfo(&meth); - Function* func = LMI->getMethod(); - func->addFnAttr(Attribute::NoInline); - } - } - - for (uint32 i = 0; i < cl->nbStaticMethods; ++i) { - JavaMethod& meth = cl->staticMethods[i]; - if (!isAbstract(meth.access)) { - LLVMMethodInfo* LMI = getMethodInfo(&meth); - Function* func = LMI->getMethod(); - func->addFnAttr(Attribute::NoInline); - } - } -} - -LLVMSignatureInfo* JnjvmModule::getSignatureInfo(Signdef* sign) { - return sign->getInfo(); -} - -LLVMClassInfo* JnjvmModule::getClassInfo(Class* cl) { - return cl->getInfo(); -} - -LLVMFieldInfo* JnjvmModule::getFieldInfo(JavaField* field) { - return field->getInfo(); -} - -LLVMMethodInfo* JnjvmModule::getMethodInfo(JavaMethod* method) { - return method->getInfo(); -} Removed: vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.h URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.h?rev=65456&view=auto ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.h (original) +++ vmkit/trunk/lib/JnJVM/VMCore/JnjvmModule.h (removed) @@ -1,492 +0,0 @@ -//===------- JnjvmModule.h - Definition of a Jnjvm module -----------------===// -// -// JnJVM -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef JNJVM_MODULE_H -#define JNJVM_MODULE_H - -#include - -#include "mvm/Allocator.h" -#include "mvm/JIT.h" - -#include "llvm/Module.h" - -namespace llvm { - class Constant; - class ConstantInt; - class Function; - class GlobalVariable; - class Type; - class Value; -} - -namespace jnjvm { - -class Attribut; -class CacheNode; -class CommonClass; -class Class; -class ClassArray; -class ClassPrimitive; -class Enveloppe; -class JavaConstantPool; -class JavaField; -class JavaMethod; -class JavaObject; -class JavaString; -class JnjvmModule; -class Typedef; -class Signdef; -class UTF8; - -class LLVMAssessorInfo { -public: - const llvm::Type* llvmType; - const llvm::Type* llvmTypePtr; - llvm::Constant* llvmNullConstant; - llvm::ConstantInt* sizeInBytesConstant; - - static void initialise(); - static std::map AssessorInfo; - -}; - - -class LLVMClassInfo : public mvm::JITInfo { - friend class JnjvmModule; -private: - Class* classDef; - /// virtualSizeLLVM - The LLVM constant size of instances of this class. - /// - llvm::ConstantInt* virtualSizeConstant; - llvm::Function* virtualTracerFunction; - llvm::Function* staticTracerFunction; - /// virtualType - The LLVM type of instance of this class. - /// - const llvm::Type * virtualType; - - /// staticType - The LLVM type of the static instance of this class. - /// - const llvm::Type * staticType; -public: - - llvm::Value* getVirtualSize(); - llvm::Function* getStaticTracer(); - llvm::Function* getVirtualTracer(); - const llvm::Type* getVirtualType(); - const llvm::Type* getStaticType(); - - LLVMClassInfo(Class* cl) : - classDef(cl), - virtualSizeConstant(0), - virtualTracerFunction(0), - staticTracerFunction(0), - virtualType(0), - staticType(0) {} -}; - -class LLVMMethodInfo : public mvm::JITInfo, private llvm::Annotation { -private: - JavaMethod* methodDef; - - llvm::Function* methodFunction; - llvm::ConstantInt* offsetConstant; - const llvm::FunctionType* functionType; - -public: - llvm::Function* getMethod(); - llvm::ConstantInt* getOffset(); - const llvm::FunctionType* getFunctionType(); - - LLVMMethodInfo(JavaMethod* M); - - static JavaMethod* get(const llvm::Function* F); -}; - -class LLVMFieldInfo : public mvm::JITInfo { -private: - JavaField* fieldDef; - - llvm::ConstantInt* offsetConstant; - -public: - llvm::ConstantInt* getOffset(); - - LLVMFieldInfo(JavaField* F) : - fieldDef(F), - offsetConstant(0) {} -}; - -class LLVMSignatureInfo : public mvm::JITInfo { -private: - const llvm::FunctionType* staticType; - const llvm::FunctionType* virtualType; - const llvm::FunctionType* nativeType; - - const llvm::FunctionType* virtualBufType; - const llvm::FunctionType* staticBufType; - - const llvm::PointerType* staticPtrType; - const llvm::PointerType* virtualPtrType; - const llvm::PointerType* nativePtrType; - - llvm::Function* virtualBufFunction; - llvm::Function* virtualAPFunction; - llvm::Function* staticBufFunction; - llvm::Function* staticAPFunction; - - Signdef* signature; - - llvm::Function* createFunctionCallBuf(bool virt); - llvm::Function* createFunctionCallAP(bool virt); - - - -public: - const llvm::FunctionType* getVirtualType(); - const llvm::FunctionType* getStaticType(); - const llvm::FunctionType* getNativeType(); - - const llvm::FunctionType* getVirtualBufType(); - const llvm::FunctionType* getStaticBufType(); - - const llvm::PointerType* getStaticPtrType(); - const llvm::PointerType* getNativePtrType(); - const llvm::PointerType* getVirtualPtrType(); - - llvm::Function* getVirtualBuf(); - llvm::Function* getVirtualAP(); - llvm::Function* getStaticBuf(); - llvm::Function* getStaticAP(); - - LLVMSignatureInfo(Signdef* sign) : - staticType(0), - virtualType(0), - nativeType(0), - virtualBufType(0), - staticBufType(0), - staticPtrType(0), - virtualPtrType(0), - nativePtrType(0), - virtualBufFunction(0), - virtualAPFunction(0), - staticBufFunction(0), - staticAPFunction(0), - signature(sign) {} - -}; - -class JnjvmModule : public mvm::MvmModule { - friend class LLVMClassInfo; -private: - std::map nativeClasses; - std::map arrayClasses; - std::map javaClasses; - std::map virtualTables; - std::map staticInstances; - std::map constantPools; - std::map strings; - std::map enveloppes; - std::map nativeFunctions; - std::map utf8s; - std::map virtualMethods; - std::map finalObjects; - - typedef std::map::iterator - final_object_iterator; - - typedef std::map::iterator - method_iterator; - - typedef std::map::iterator - native_class_iterator; - - typedef std::map::iterator - array_class_iterator; - - typedef std::map::iterator - java_class_iterator; - - typedef std::map::iterator - virtual_table_iterator; - - typedef std::map::iterator - static_instance_iterator; - - typedef std::map::iterator - constant_pool_iterator; - - typedef std::map::iterator - string_iterator; - - typedef std::map::iterator - enveloppe_iterator; - - typedef std::map::iterator - native_function_iterator; - - typedef std::map::iterator - utf8_iterator; - - - bool staticCompilation; - bool enabledException; - -#ifdef WITH_TRACER - llvm::Function* makeTracer(Class* cl, bool stat); -#endif - - void makeVT(Class* cl); - void allocateVT(Class* cl); - - static llvm::Constant* PrimitiveArrayVT; - static llvm::Constant* ReferenceArrayVT; - - static llvm::Function* StaticInitializer; - static llvm::Function* ObjectPrinter; - -public: - - static llvm::Function* NativeLoader; - - bool generateTracers; - bool generateStubs; - bool assumeCompiled; - - bool isStaticCompiling() { - return staticCompilation; - } - - bool hasExceptionsEnabled() { - return enabledException; - } - - void disableExceptions() { - enabledException = false; - } - - void setIsStaticCompiling(bool sc) { - staticCompilation = sc; - } - - static llvm::ConstantInt* JavaArraySizeOffsetConstant; - static llvm::ConstantInt* JavaArrayElementsOffsetConstant; - static llvm::ConstantInt* JavaObjectLockOffsetConstant; - static llvm::ConstantInt* JavaObjectClassOffsetConstant; - - static const llvm::Type* JavaArrayUInt8Type; - static const llvm::Type* JavaArraySInt8Type; - static const llvm::Type* JavaArrayUInt16Type; - static const llvm::Type* JavaArraySInt16Type; - static const llvm::Type* JavaArrayUInt32Type; - static const llvm::Type* JavaArraySInt32Type; - static const llvm::Type* JavaArrayLongType; - static const llvm::Type* JavaArrayFloatType; - static const llvm::Type* JavaArrayDoubleType; - static const llvm::Type* JavaArrayObjectType; - - static const llvm::Type* VTType; - static const llvm::Type* JavaObjectType; - static const llvm::Type* JavaArrayType; - static const llvm::Type* JavaCommonClassType; - static const llvm::Type* JavaClassType; - static const llvm::Type* JavaClassArrayType; - static const llvm::Type* JavaClassPrimitiveType; - static const llvm::Type* JavaCacheType; - static const llvm::Type* EnveloppeType; - static const llvm::Type* CacheNodeType; - static const llvm::Type* ConstantPoolType; - static const llvm::Type* UTF8Type; - static const llvm::Type* JavaMethodType; - static const llvm::Type* JavaFieldType; - static const llvm::Type* AttributType; - static const llvm::Type* JavaThreadType; - -#ifdef ISOLATE_SHARING - static const llvm::Type* JnjvmType; -#endif - -#ifdef WITH_TRACER - llvm::Function* MarkAndTraceFunction; - static const llvm::FunctionType* MarkAndTraceType; - llvm::Function* JavaObjectTracerFunction; - llvm::Function* JavaArrayTracerFunction; - llvm::Function* ArrayObjectTracerFunction; -#endif - - llvm::Function* GetSJLJBufferFunction; - llvm::Function* InterfaceLookupFunction; - llvm::Function* VirtualFieldLookupFunction; - llvm::Function* StaticFieldLookupFunction; - llvm::Function* PrintExecutionFunction; - llvm::Function* PrintMethodStartFunction; - llvm::Function* PrintMethodEndFunction; - llvm::Function* JniProceedPendingExceptionFunction; - llvm::Function* InitialiseClassFunction; - llvm::Function* InitialisationCheckFunction; - llvm::Function* ForceInitialisationCheckFunction; - llvm::Function* ForceLoadedCheckFunction; - llvm::Function* ClassLookupFunction; -#ifndef WITHOUT_VTABLE - llvm::Function* VirtualLookupFunction; -#endif - llvm::Function* InstanceOfFunction; - llvm::Function* IsAssignableFromFunction; - llvm::Function* ImplementsFunction; - llvm::Function* InstantiationOfArrayFunction; - llvm::Function* GetDepthFunction; - llvm::Function* GetClassInDisplayFunction; - llvm::Function* GetStaticInstanceFunction; - llvm::Function* GetDisplayFunction; - llvm::Function* AquireObjectFunction; - llvm::Function* ReleaseObjectFunction; - llvm::Function* GetConstantPoolAtFunction; - llvm::Function* MultiCallNewFunction; - llvm::Function* GetArrayClassFunction; - -#ifdef ISOLATE - llvm::Function* StringLookupFunction; -#ifdef ISOLATE_SHARING - llvm::Function* GetCtpCacheNodeFunction; - llvm::Function* GetCtpClassFunction; - llvm::Function* EnveloppeLookupFunction; - llvm::Function* GetJnjvmExceptionClassFunction; - llvm::Function* GetJnjvmArrayClassFunction; - llvm::Function* StaticCtpLookupFunction; - llvm::Function* SpecialCtpLookupFunction; -#endif -#endif - -#ifdef SERVICE - llvm::Function* ServiceCallStartFunction; - llvm::Function* ServiceCallStopFunction; -#endif - - llvm::Function* GetClassDelegateeFunction; - llvm::Function* RuntimeDelegateeFunction; - llvm::Function* ArrayLengthFunction; - llvm::Function* GetVTFunction; - llvm::Function* GetClassFunction; - llvm::Function* JavaObjectAllocateFunction; - llvm::Function* GetVTFromClassFunction; - llvm::Function* GetObjectSizeFromClassFunction; - - llvm::Function* GetLockFunction; - llvm::Function* OverflowThinLockFunction; - - llvm::Function* GetFinalInt8FieldFunction; - llvm::Function* GetFinalInt16FieldFunction; - llvm::Function* GetFinalInt32FieldFunction; - llvm::Function* GetFinalLongFieldFunction; - llvm::Function* GetFinalFloatFieldFunction; - llvm::Function* GetFinalDoubleFieldFunction; - llvm::Function* GetFinalObjectFieldFunction; - - static llvm::ConstantInt* OffsetObjectSizeInClassConstant; - static llvm::ConstantInt* OffsetVTInClassConstant; - static llvm::ConstantInt* OffsetDepthInClassConstant; - static llvm::ConstantInt* OffsetDisplayInClassConstant; - static llvm::ConstantInt* OffsetTaskClassMirrorInClassConstant; - static llvm::ConstantInt* OffsetStaticInstanceInTaskClassMirrorConstant; - static llvm::ConstantInt* OffsetInitializedInTaskClassMirrorConstant; - static llvm::ConstantInt* OffsetStatusInTaskClassMirrorConstant; - - static llvm::ConstantInt* OffsetJavaExceptionInThreadConstant; - static llvm::ConstantInt* OffsetCXXExceptionInThreadConstant; - - static llvm::ConstantInt* ClassReadyConstant; - - static llvm::Constant* JavaObjectNullConstant; - static llvm::Constant* MaxArraySizeConstant; - static llvm::Constant* JavaArraySizeConstant; - - llvm::Function* ThrowExceptionFunction; - llvm::Function* NullPointerExceptionFunction; - llvm::Function* IndexOutOfBoundsExceptionFunction; - llvm::Function* ClassCastExceptionFunction; - llvm::Function* OutOfMemoryErrorFunction; - llvm::Function* NegativeArraySizeExceptionFunction; - - static void resolveVirtualClass(Class* cl); - static void resolveStaticClass(Class* cl); - static void setMethod(JavaMethod* meth, void* ptr, const char* name); - static llvm::Function* getMethod(JavaMethod* meth); - - static LLVMSignatureInfo* getSignatureInfo(Signdef* sign); - static LLVMClassInfo* getClassInfo(Class* cl); - static LLVMFieldInfo* getFieldInfo(JavaField* field); - static LLVMMethodInfo* getMethodInfo(JavaMethod* method); - static LLVMAssessorInfo& getTypedefInfo(const Typedef* type); - - explicit JnjvmModule(const std::string &ModuleID, bool sc = false); - void initialise(); - void printStats(); - - llvm::Constant* getFinalObject(JavaObject* obj); - JavaObject* getFinalObject(llvm::Value* C); - llvm::Constant* getNativeClass(CommonClass* cl); - llvm::Constant* getJavaClass(CommonClass* cl); - llvm::Constant* getStaticInstance(Class* cl); - llvm::Constant* getVirtualTable(Class* cl); - llvm::Constant* getMethodInClass(JavaMethod* meth); - - llvm::Constant* getEnveloppe(Enveloppe* enveloppe); - llvm::Constant* getString(JavaString* str); - llvm::Constant* getConstantPool(JavaConstantPool* ctp); - llvm::Constant* getNativeFunction(JavaMethod* meth, void* natPtr); - - llvm::Constant* getReferenceArrayVT(); - llvm::Constant* getPrimitiveArrayVT(); - -#ifdef SERVICE - std::map isolates; - typedef std::map::iterator - isolate_iterator; - - llvm::Value* getIsolate(Jnjvm* vm, llvm::Value* Where); -#endif - - - bool isCompiling(const CommonClass* cl) const; - - void CreateStaticInitializer(); - - static void setNoInline(Class* cl); - -private: - static llvm::Module* initialModule; - - //--------------- Static compiler specific functions -----------------------// - llvm::Constant* CreateConstantFromVT(Class* classDef); - llvm::Constant* CreateConstantFromUTF8(const UTF8* val); - llvm::Constant* CreateConstantFromEnveloppe(Enveloppe* val); - llvm::Constant* CreateConstantFromCacheNode(CacheNode* CN); - llvm::Constant* CreateConstantFromCommonClass(CommonClass* cl); - llvm::Constant* CreateConstantFromClass(Class* cl); - llvm::Constant* CreateConstantFromClassPrimitive(ClassPrimitive* cl); - llvm::Constant* CreateConstantFromClassArray(ClassArray* cl); - llvm::Constant* CreateConstantFromAttribut(Attribut& attribut); - llvm::Constant* CreateConstantFromJavaField(JavaField& field); - llvm::Constant* CreateConstantFromJavaMethod(JavaMethod& method); - llvm::Constant* CreateConstantFromStaticInstance(Class* cl); - llvm::Constant* CreateConstantFromJavaString(JavaString* str); - llvm::Constant* CreateConstantFromJavaClass(CommonClass* cl); - llvm::Constant* CreateConstantForBaseObject(CommonClass* cl); - llvm::Constant* CreateConstantFromJavaObject(JavaObject* obj); - llvm::Constant* getUTF8(const UTF8* val); - - template - llvm::Constant* CreateConstantFromArray(T* val, const llvm::Type* Ty); - - -}; - -} - -#endif Removed: vmkit/trunk/lib/JnJVM/VMCore/JnjvmModuleProvider.cpp URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JnjvmModuleProvider.cpp?rev=65456&view=auto ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/JnjvmModuleProvider.cpp (original) +++ vmkit/trunk/lib/JnJVM/VMCore/JnjvmModuleProvider.cpp (removed) @@ -1,219 +0,0 @@ -//===--- JnjvmModuleProvider.cpp - LLVM Module Provider for Jnjvm ---------===// -// -// Jnjvm -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "llvm/LinkAllPasses.h" -#include "llvm/PassManager.h" -#include "llvm/ExecutionEngine/ExecutionEngine.h" -#include "llvm/Support/MutexGuard.h" -#include "llvm/Target/TargetData.h" - -#include "mvm/JIT.h" - -#include "JavaAccess.h" -#include "JavaClass.h" -#include "JavaConstantPool.h" -#include "JavaJIT.h" -#include "JavaThread.h" -#include "JavaTypes.h" -#include "Jnjvm.h" -#include "JnjvmModule.h" -#include "JnjvmModuleProvider.h" - -using namespace llvm; -using namespace jnjvm; - - -static AnnotationID JavaCallback_ID( - AnnotationManager::getID("Java::Callback")); - - -class CallbackInfo: public Annotation { -public: - Class* cl; - uint32 index; - - CallbackInfo(Class* c, uint32 i) : Annotation(JavaCallback_ID), - cl(c), index(i) {} -}; - -JavaMethod* JnjvmModuleProvider::staticLookup(Class* caller, uint32 index) { - JavaConstantPool* ctpInfo = caller->getConstantPool(); - - - bool isStatic = ctpInfo->isAStaticCall(index); - - CommonClass* cl = 0; - const UTF8* utf8 = 0; - Signdef* sign = 0; - - ctpInfo->resolveMethod(index, cl, utf8, sign); - UserClass* lookup = cl->isArray() ? cl->super : cl->asClass(); - JavaMethod* meth = lookup->lookupMethod(utf8, sign->keyName, isStatic, true, - 0); - - assert(lookup->isInitializing() && "Class not ready"); - - - return meth; -} - -bool JnjvmModuleProvider::materializeFunction(Function *F, - std::string *ErrInfo) { - - if (!(F->hasNotBeenReadFromBitcode())) - return false; - - assert(mvm::MvmModule::executionEngine && "No execution engine"); - if (mvm::MvmModule::executionEngine->getPointerToGlobalIfAvailable(F)) - return false; - - JavaMethod* meth = LLVMMethodInfo::get(F); - - if (!meth) { - // It's a callback - CallbackInfo* CI = (CallbackInfo*)F->getAnnotation(JavaCallback_ID); - assert(CI && "No callback where there should be one"); - meth = staticLookup(CI->cl, CI->index); - } - - void* val = meth->compiledPtr(); - - - if (F->isDeclaration()) - mvm::MvmModule::executionEngine->updateGlobalMapping(F, val); - - if (isVirtual(meth->access)) { - LLVMMethodInfo* LMI = ((JnjvmModule*)TheModule)->getMethodInfo(meth); - uint64_t offset = LMI->getOffset()->getZExtValue(); - assert(meth->classDef->isResolved() && "Class not resolved"); -#if !defined(ISOLATE_SHARING) && !defined(SERVICE) - assert(meth->classDef->isInitializing() && "Class not ready"); -#endif - assert(meth->classDef->virtualVT && "Class has no VT"); - assert(meth->classDef->virtualTableSize > offset && - "The method's offset is greater than the virtual table size"); - ((void**)meth->classDef->virtualVT)[offset] = val; - } else { -#ifndef ISOLATE_SHARING - meth->classDef->initialiseClass(JavaThread::get()->getJVM()); -#endif - } - - return false; -} - -void* JnjvmModuleProvider::materializeFunction(JavaMethod* meth) { - Function* func = parseFunction(meth); - - void* res = mvm::MvmModule::executionEngine->getPointerToGlobal(func); - func->deleteBody(); - - return res; -} - -Function* JnjvmModuleProvider::parseFunction(JavaMethod* meth) { - JnjvmModule* M = (JnjvmModule*)TheModule; - LLVMMethodInfo* LMI = M->getMethodInfo(meth); - Function* func = LMI->getMethod(); - if (func->hasNotBeenReadFromBitcode()) { - // We are jitting. Take the lock. - M->protectIR(); - JavaJIT jit(meth, func); - if (isNative(meth->access)) { - jit.nativeCompile(); - mvm::MvmModule::runPasses(func, JavaNativeFunctionPasses); - } else { - jit.javaCompile(); - mvm::MvmModule::runPasses(func, M->globalFunctionPasses); - mvm::MvmModule::runPasses(func, JavaFunctionPasses); - } - M->unprotectIR(); - } - return func; -} - -llvm::Function* JnjvmModuleProvider::addCallback(Class* cl, uint32 index, - Signdef* sign, bool stat) { - - JnjvmModule* M = cl->classLoader->getModule(); - Function* func = 0; - LLVMSignatureInfo* LSI = M->getSignatureInfo(sign); - if (!stat) { - const char* name = cl->printString(); - char* key = (char*)alloca(strlen(name) + 2); - sprintf(key, "%s%d", name, index); - Function* F = TheModule->getFunction(key); - if (F) return F; - - const FunctionType* type = LSI->getVirtualType(); - - func = Function::Create(type, GlobalValue::GhostLinkage, key, TheModule); - } else { - const llvm::FunctionType* type = LSI->getStaticType(); - if (M->isStaticCompiling()) { - func = Function::Create(type, GlobalValue::ExternalLinkage, "staticCallback", - TheModule); - } else { - func = Function::Create(type, GlobalValue::GhostLinkage, "staticCallback", - TheModule); - } - } - - ++nbCallbacks; - CallbackInfo* A = new CallbackInfo(cl, index); - func->addAnnotation(A); - - return func; -} - -namespace mvm { - llvm::FunctionPass* createEscapeAnalysisPass(llvm::Function*); -} - -namespace jnjvm { - llvm::FunctionPass* createLowerConstantCallsPass(); -} - -JnjvmModuleProvider::JnjvmModuleProvider(JnjvmModule *m) { - TheModule = (Module*)m; - if (m->executionEngine) { - m->protectEngine.lock(); - m->executionEngine->addModuleProvider(this); - m->protectEngine.unlock(); - } - - JavaNativeFunctionPasses = new llvm::FunctionPassManager(this); - JavaNativeFunctionPasses->add(new llvm::TargetData(m)); - // Lower constant calls to lower things like getClass used - // on synchronized methods. - JavaNativeFunctionPasses->add(createLowerConstantCallsPass()); - - JavaFunctionPasses = new llvm::FunctionPassManager(this); - JavaFunctionPasses->add(new llvm::TargetData(m)); - Function* func = m->JavaObjectAllocateFunction; - JavaFunctionPasses->add(mvm::createEscapeAnalysisPass(func)); - JavaFunctionPasses->add(createLowerConstantCallsPass()); - nbCallbacks = 0; -} - -JnjvmModuleProvider::~JnjvmModuleProvider() { - if (mvm::MvmModule::executionEngine) { - mvm::MvmModule::protectEngine.lock(); - mvm::MvmModule::executionEngine->removeModuleProvider(this); - mvm::MvmModule::protectEngine.unlock(); - } - delete TheModule; - delete JavaNativeFunctionPasses; - delete JavaFunctionPasses; -} - -void JnjvmModuleProvider::printStats() { - fprintf(stderr, "------------ Info from the module provider -------------\n"); - fprintf(stderr, "Number of callbacks : %d\n", nbCallbacks); -} Removed: vmkit/trunk/lib/JnJVM/VMCore/JnjvmModuleProvider.h URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JnjvmModuleProvider.h?rev=65456&view=auto ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/JnjvmModuleProvider.h (original) +++ vmkit/trunk/lib/JnJVM/VMCore/JnjvmModuleProvider.h (removed) @@ -1,53 +0,0 @@ -//===----- JnjvmModuleProvider.h - LLVM Module Provider for Jnjvm ---------===// -// -// Jnjvm -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef JNJVM_MODULE_PROVIDER_H -#define JNJVM_MODULE_PROVIDER_H - -#include - -using namespace llvm; - -namespace llvm { -class FunctionPassManager; -} - -namespace jnjvm { - -class JnjvmModule; - -class JnjvmModuleProvider : public ModuleProvider { -private: - JavaMethod* staticLookup(Class* caller, uint32 index); - - llvm::FunctionPassManager* JavaFunctionPasses; - llvm::FunctionPassManager* JavaNativeFunctionPasses; - - uint32 nbCallbacks; - -public: - - JnjvmModuleProvider(JnjvmModule *m); - ~JnjvmModuleProvider(); - - llvm::Function* addCallback(Class* cl, uint32 index, Signdef* sign, - bool stat); - - bool materializeFunction(Function *F, std::string *ErrInfo = 0); - void* materializeFunction(JavaMethod* meth); - llvm::Function* parseFunction(JavaMethod* meth); - - Module* materializeModule(std::string *ErrInfo = 0) { return TheModule; } - - void printStats(); -}; - -} // End jnjvm namespace - -#endif Removed: vmkit/trunk/lib/JnJVM/VMCore/LowerConstantCalls.cpp URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/LowerConstantCalls.cpp?rev=65456&view=auto ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/LowerConstantCalls.cpp (original) +++ vmkit/trunk/lib/JnJVM/VMCore/LowerConstantCalls.cpp (removed) @@ -1,532 +0,0 @@ -//===----- LowerConstantCalls.cpp - Changes arrayLength calls --------------===// -// -// JnJVM -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "llvm/Constants.h" -#include "llvm/Pass.h" -#include "llvm/Function.h" -#include "llvm/Instructions.h" -#include "llvm/Support/CallSite.h" -#include "llvm/Support/Compiler.h" -#include "llvm/Support/Debug.h" - -#include "JavaClass.h" -#include "JnjvmModule.h" - -using namespace llvm; - -namespace jnjvm { - - class VISIBILITY_HIDDEN LowerConstantCalls : public FunctionPass { - public: - static char ID; - LowerConstantCalls() : FunctionPass((intptr_t)&ID) { } - - virtual bool runOnFunction(Function &F); - private: - }; - char LowerConstantCalls::ID = 0; - static RegisterPass X("LowerConstantCalls", - "Lower Constant calls"); - - -#ifdef ISOLATE -static Value* getTCM(JnjvmModule* module, Value* Arg, Instruction* CI) { - Value* GEP[2] = { module->constantZero, - module->OffsetTaskClassMirrorInClassConstant }; - Value* TCMArray = GetElementPtrInst::Create(Arg, GEP, GEP + 2, "", CI); - - Value* threadId = CallInst::Create(module->llvm_frameaddress, - module->constantZero, "", CI); - threadId = new PtrToIntInst(threadId, module->pointerSizeType, "", CI); - threadId = BinaryOperator::CreateAnd(threadId, module->constantThreadIDMask, - "", CI); - - threadId = new IntToPtrInst(threadId, module->ptr32Type, "", CI); - - Value* IsolateID = GetElementPtrInst::Create(threadId, module->constantThree, - "", CI); - IsolateID = new LoadInst(IsolateID, "", CI); - - Value* GEP2[2] = { module->constantZero, IsolateID }; - - Value* TCM = GetElementPtrInst::Create(TCMArray, GEP2, GEP2 + 2, "", - CI); - return TCM; -} - -static Value* getDelegatee(JnjvmModule* module, Value* Arg, Instruction* CI) { - Value* GEP[2] = { module->constantZero, - module->constantTwo }; - Value* TCMArray = GetElementPtrInst::Create(Arg, GEP, GEP + 2, "", CI); - - Value* threadId = CallInst::Create(module->llvm_frameaddress, - module->constantZero, "", CI); - threadId = new PtrToIntInst(threadId, module->pointerSizeType, "", CI); - threadId = BinaryOperator::CreateAnd(threadId, module->constantThreadIDMask, - "", CI); - - threadId = new IntToPtrInst(threadId, module->ptr32Type, "", CI); - - Value* IsolateID = GetElementPtrInst::Create(threadId, module->constantThree, - "", CI); - IsolateID = new LoadInst(IsolateID, "", CI); - - Value* GEP2[2] = { module->constantZero, IsolateID }; - - Value* TCM = GetElementPtrInst::Create(TCMArray, GEP2, GEP2 + 2, "", - CI); - return new LoadInst(TCM, "", CI); -} - -#else - -static Value* getTCM(JnjvmModule* module, Value* Arg, Instruction* CI) { - Value* GEP[2] = { module->constantZero, - module->OffsetTaskClassMirrorInClassConstant }; - Value* TCMArray = GetElementPtrInst::Create(Arg, GEP, GEP + 2, "", CI); - - Value* GEP2[2] = { module->constantZero, module->constantZero }; - - Value* TCM = GetElementPtrInst::Create(TCMArray, GEP2, GEP2 + 2, "", - CI); - return TCM; - -} - -static Value* getDelegatee(JnjvmModule* module, Value* Arg, Instruction* CI) { - Value* GEP[2] = { module->constantZero, - module->constantTwo }; - Value* TCMArray = GetElementPtrInst::Create(Arg, GEP, GEP + 2, "", CI); - - Value* GEP2[2] = { module->constantZero, module->constantZero }; - - Value* TCM = GetElementPtrInst::Create(TCMArray, GEP2, GEP2 + 2, "", - CI); - return new LoadInst(TCM, "", CI); - -} -#endif - -bool LowerConstantCalls::runOnFunction(Function& F) { - JnjvmModule* module = (JnjvmModule*)F.getParent(); - JavaMethod* meth = LLVMMethodInfo::get(&F); - bool Changed = false; - for (Function::iterator BI = F.begin(), BE = F.end(); BI != BE; BI++) { - BasicBlock *Cur = BI; - for (BasicBlock::iterator II = Cur->begin(), IE = Cur->end(); II != IE;) { - Instruction *I = II; - II++; - - if (ICmpInst* Cmp = dyn_cast(I)) { - if (Cmp->getOperand(1) == module->JavaObjectNullConstant) { - Value* Arg = Cmp->getOperand(0); - if (isVirtual(meth->access) && Arg == F.arg_begin()) { - Changed = true; - Cmp->replaceAllUsesWith(ConstantInt::getFalse()); - Cmp->eraseFromParent(); - break; - } - - CallSite Ca = CallSite::get(Arg); - Instruction* CI = Ca.getInstruction(); - if (CI && Ca.getCalledValue() == module->JavaObjectAllocateFunction) { - Changed = true; - Cmp->replaceAllUsesWith(ConstantInt::getFalse()); - Cmp->eraseFromParent(); - break; - } - } - } - - CallSite Call = CallSite::get(I); - Instruction* CI = Call.getInstruction(); - if (CI) { - Value* V = Call.getCalledValue(); - if (V == module->ArrayLengthFunction) { - Changed = true; - Value* val = Call.getArgument(0); // get the array - Value* array = new BitCastInst(val, module->JavaArrayType, - "", CI); - Value* args[2] = { module->constantZero, - module->JavaArraySizeOffsetConstant }; - Value* ptr = GetElementPtrInst::Create(array, args, args + 2, - "", CI); - Value* load = new LoadInst(ptr, "", CI); - load = new PtrToIntInst(load, Type::Int32Ty, "", CI); - CI->replaceAllUsesWith(load); - CI->eraseFromParent(); - } else if (V == module->GetVTFunction) { - Changed = true; - Value* val = Call.getArgument(0); // get the object - Value* indexes[2] = { module->constantZero, module->constantZero }; - Value* VTPtr = GetElementPtrInst::Create(val, indexes, indexes + 2, - "", CI); - Value* VT = new LoadInst(VTPtr, "", CI); - CI->replaceAllUsesWith(VT); - CI->eraseFromParent(); - } else if (V == module->GetClassFunction) { - Changed = true; - Value* val = Call.getArgument(0); // get the object - Value* args2[2] = { module->constantZero, - module->JavaObjectClassOffsetConstant }; - Value* classPtr = GetElementPtrInst::Create(val, args2, args2 + 2, - "", CI); - Value* cl = new LoadInst(classPtr, "", CI); - CI->replaceAllUsesWith(cl); - CI->eraseFromParent(); - } else if (V == module->GetVTFromClassFunction) { - Changed = true; - - Value* val = Call.getArgument(0); - Value* indexes[2] = { module->constantZero, - module->OffsetVTInClassConstant }; - Value* VTPtr = GetElementPtrInst::Create(val, indexes, indexes + 2, - "", CI); - Value* VT = new LoadInst(VTPtr, "", CI); - CI->replaceAllUsesWith(VT); - CI->eraseFromParent(); - } else if (V == module->GetObjectSizeFromClassFunction) { - Changed = true; - - Value* val = Call.getArgument(0); - Value* indexes[2] = { module->constantZero, - module->OffsetObjectSizeInClassConstant }; - Value* SizePtr = GetElementPtrInst::Create(val, indexes, indexes + 2, - "", CI); - Value* Size = new LoadInst(SizePtr, "", CI); - CI->replaceAllUsesWith(Size); - CI->eraseFromParent(); - } else if (V == module->GetDepthFunction) { - Changed = true; - Value* val = Call.getArgument(0); - Value* indexes[2] = { module->constantZero, - module->OffsetDepthInClassConstant }; - Value* DepthPtr = GetElementPtrInst::Create(val, indexes, - indexes + 2, "", CI); - Value* Depth = new LoadInst(DepthPtr, "", CI); - CI->replaceAllUsesWith(Depth); - CI->eraseFromParent(); - } else if (V == module->GetDisplayFunction) { - Changed = true; - Value* val = Call.getArgument(0); - Value* indexes[2] = { module->constantZero, - module->OffsetDisplayInClassConstant }; - Value* DisplayPtr = GetElementPtrInst::Create(val, indexes, - indexes + 2, "", CI); - Value* Display = new LoadInst(DisplayPtr, "", CI); - CI->replaceAllUsesWith(Display); - CI->eraseFromParent(); - } else if (V == module->GetClassInDisplayFunction) { - Changed = true; - Value* val = Call.getArgument(0); - Value* depth = Call.getArgument(1); - Value* ClassPtr = GetElementPtrInst::Create(val, depth, "", CI); - Value* Class = new LoadInst(ClassPtr, "", CI); - CI->replaceAllUsesWith(Class); - CI->eraseFromParent(); -#if defined(ISOLATE) - } else if (V == module->GetStaticInstanceFunction) { - Changed = true; - - Value* TCM = getTCM(module, Call.getArgument(0), CI); - Constant* C = module->OffsetStaticInstanceInTaskClassMirrorConstant; - Value* GEP[2] = { module->constantZero, C }; - Value* Replace = GetElementPtrInst::Create(TCM, GEP, GEP + 2, "", CI); - Replace = new LoadInst(Replace, "", CI); - CI->replaceAllUsesWith(Replace); - CI->eraseFromParent(); -#endif - } else if (V == module->GetClassDelegateeFunction) { - Changed = true; - BasicBlock* NBB = II->getParent()->splitBasicBlock(II); - I->getParent()->getTerminator()->eraseFromParent(); - Value* Del = getDelegatee(module, Call.getArgument(0), CI); - Value* cmp = new ICmpInst(ICmpInst::ICMP_EQ, Del, - module->JavaObjectNullConstant, "", CI); - - BasicBlock* NoDelegatee = BasicBlock::Create("No delegatee", &F); - BasicBlock* DelegateeOK = BasicBlock::Create("Delegatee OK", &F); - BranchInst::Create(NoDelegatee, DelegateeOK, cmp, CI); - PHINode* phi = PHINode::Create(module->JavaObjectType, "", DelegateeOK); - phi->addIncoming(Del, CI->getParent()); - - Value* Res = CallInst::Create(module->RuntimeDelegateeFunction, - Call.getArgument(0), "", NoDelegatee); - BranchInst::Create(DelegateeOK, NoDelegatee); - phi->addIncoming(Res, NoDelegatee); - - CI->replaceAllUsesWith(phi); - CI->eraseFromParent(); - BranchInst::Create(NBB, DelegateeOK); - break; - - } else if (V == module->InitialisationCheckFunction) { - Changed = true; - - BasicBlock* NBB = 0; - if (CI->getParent()->getTerminator() != CI) { - NBB = II->getParent()->splitBasicBlock(II); - CI->getParent()->getTerminator()->eraseFromParent(); - } else { - InvokeInst* Invoke = dyn_cast(CI); - assert(Invoke && "Last instruction is not an invoke"); - NBB = Invoke->getNormalDest(); - } - - Value* Cl = Call.getArgument(0); - Value* TCM = getTCM(module, Call.getArgument(0), CI); - Value* GEP[2] = - { module->constantZero, - module->OffsetInitializedInTaskClassMirrorConstant }; - Value* StatusPtr = GetElementPtrInst::Create(TCM, GEP, GEP + 2, "", - CI); - - Value* test = new LoadInst(StatusPtr, "", CI); - - BasicBlock* trueCl = BasicBlock::Create("Initialized", &F); - BasicBlock* falseCl = BasicBlock::Create("Uninitialized", &F); - PHINode* node = llvm::PHINode::Create(JnjvmModule::JavaClassType, "", trueCl); - node->addIncoming(Cl, CI->getParent()); - BranchInst::Create(trueCl, falseCl, test, CI); - - - Value* res = 0; - if (InvokeInst* Invoke = dyn_cast(CI)) { - Value* Args[1] = { Cl }; - BasicBlock* UI = Invoke->getUnwindDest(); - - res = InvokeInst::Create(module->InitialiseClassFunction, - trueCl, UI, Args, Args + 1, - "", falseCl); - - // For some reason, an LLVM pass may add PHI nodes to the - // exception destination. - BasicBlock::iterator Temp = UI->getInstList().begin(); - while (PHINode* PHI = dyn_cast(Temp)) { - Value* Val = PHI->getIncomingValueForBlock(CI->getParent()); - PHI->removeIncomingValue(CI->getParent(), false); - PHI->addIncoming(Val, falseCl); - Temp++; - } - - // And here we set the phi nodes of the normal dest of the Invoke - // instruction. The phi nodes have now the trueCl as basic block. - Temp = NBB->getInstList().begin(); - while (PHINode* PHI = dyn_cast(Temp)) { - Value* Val = PHI->getIncomingValueForBlock(CI->getParent()); - PHI->removeIncomingValue(CI->getParent(), false); - PHI->addIncoming(Val, trueCl); - Temp++; - } - - } else { - res = CallInst::Create(module->InitialiseClassFunction, - Cl, "", falseCl); - BranchInst::Create(trueCl, falseCl); - } - - node->addIncoming(res, falseCl); - - - CI->replaceAllUsesWith(node); - CI->eraseFromParent(); - BranchInst::Create(NBB, trueCl); - break; - } else if (V == module->GetConstantPoolAtFunction) { - Function* resolver = dyn_cast(Call.getArgument(0)); - assert(resolver && "Wrong use of GetConstantPoolAt"); - const Type* returnType = resolver->getReturnType(); - Value* CTP = Call.getArgument(1); - Value* Index = Call.getArgument(3); - Changed = true; - BasicBlock* NBB = 0; - if (CI->getParent()->getTerminator() != CI) { - NBB = II->getParent()->splitBasicBlock(II); - CI->getParent()->getTerminator()->eraseFromParent(); - } else { - InvokeInst* Invoke = dyn_cast(CI); - assert(Invoke && "Last instruction is not an invoke"); - NBB = Invoke->getNormalDest(); - } - -#ifdef ISOLATE_SHARING - ConstantInt* Cons = dyn_cast(Index); - assert(CI && "Wrong use of GetConstantPoolAt"); - uint64 val = Cons->getZExtValue(); - Value* indexes = ConstantInt::get(Type::Int32Ty, val + 1); -#else - Value* indexes = Index; -#endif - Value* arg1 = GetElementPtrInst::Create(CTP, indexes, "", CI); - arg1 = new LoadInst(arg1, "", false, CI); - Value* test = new ICmpInst(ICmpInst::ICMP_EQ, arg1, - mvm::MvmModule::constantPtrNull, "", CI); - - BasicBlock* trueCl = BasicBlock::Create("Ctp OK", &F); - BasicBlock* falseCl = BasicBlock::Create("Ctp Not OK", &F); - PHINode* node = llvm::PHINode::Create(returnType, "", trueCl); - node->addIncoming(arg1, CI->getParent()); - BranchInst::Create(falseCl, trueCl, test, CI); - - std::vector Args; - unsigned ArgSize = Call.arg_size(), i = 1; - while (++i < ArgSize) { - Args.push_back(Call.getArgument(i)); - } - - Value* res = 0; - if (InvokeInst* Invoke = dyn_cast(CI)) { - BasicBlock* UI = Invoke->getUnwindDest(); - res = InvokeInst::Create(resolver, trueCl, UI, Args.begin(), - Args.end(), "", falseCl); - - // For some reason, an LLVM pass may add PHI nodes to the - // exception destination. - BasicBlock::iterator Temp = UI->getInstList().begin(); - while (PHINode* PHI = dyn_cast(Temp)) { - Value* Val = PHI->getIncomingValueForBlock(CI->getParent()); - PHI->removeIncomingValue(CI->getParent(), false); - PHI->addIncoming(Val, falseCl); - Temp++; - } - - // And here we set the phi nodes of the normal dest of the Invoke - // instruction. The phi nodes have now the trueCl as basic block. - Temp = NBB->getInstList().begin(); - while (PHINode* PHI = dyn_cast(Temp)) { - Value* Val = PHI->getIncomingValueForBlock(CI->getParent()); - PHI->removeIncomingValue(CI->getParent(), false); - PHI->addIncoming(Val, trueCl); - Temp++; - } - - } else { - res = CallInst::Create(resolver, Args.begin(), Args.end(), "", - falseCl); - BranchInst::Create(trueCl, falseCl); - } - - node->addIncoming(res, falseCl); - - - CI->replaceAllUsesWith(node); - CI->eraseFromParent(); - BranchInst::Create(NBB, trueCl); - break; - } else if (V == module->GetArrayClassFunction) { - const llvm::Type* Ty = - PointerType::getUnqual(module->JavaCommonClassType); - Constant* nullValue = Constant::getNullValue(Ty); - // Check if we have already proceed this call. - if (Call.getArgument(1) == nullValue) { - BasicBlock* NBB = II->getParent()->splitBasicBlock(II); - I->getParent()->getTerminator()->eraseFromParent(); - - Constant* init = - Constant::getNullValue(module->JavaCommonClassType); - GlobalVariable* GV = - new GlobalVariable(module->JavaCommonClassType, false, - GlobalValue::ExternalLinkage, - init, "", module); - - Value* LoadedGV = new LoadInst(GV, "", CI); - Value* cmp = new ICmpInst(ICmpInst::ICMP_EQ, LoadedGV, init, - "", CI); - - BasicBlock* OKBlock = BasicBlock::Create("", &F); - BasicBlock* NotOKBlock = BasicBlock::Create("", &F); - PHINode* node = PHINode::Create(module->JavaCommonClassType, "", - OKBlock); - node->addIncoming(LoadedGV, CI->getParent()); - - BranchInst::Create(NotOKBlock, OKBlock, cmp, CI); - - Value* args[2] = { Call.getArgument(0), GV }; - Value* res = CallInst::Create(module->GetArrayClassFunction, args, - args + 2, "", NotOKBlock); - BranchInst::Create(OKBlock, NotOKBlock); - node->addIncoming(res, NotOKBlock); - - CI->replaceAllUsesWith(node); - CI->eraseFromParent(); - BranchInst::Create(NBB, OKBlock); - break; - } - } else if (V == module->ForceInitialisationCheckFunction || - V == module->ForceLoadedCheckFunction ) { - Changed = true; - CI->eraseFromParent(); - } else if (V == module->GetFinalInt8FieldFunction || - V == module->GetFinalInt16FieldFunction || - V == module->GetFinalInt32FieldFunction || - V == module->GetFinalLongFieldFunction || - V == module->GetFinalFloatFieldFunction || - V == module->GetFinalDoubleFieldFunction || - V == module->GetFinalObjectFieldFunction) { - Changed = true; - Value* val = Call.getArgument(0); - Value* res = new LoadInst(val, "", CI); - CI->replaceAllUsesWith(res); - CI->eraseFromParent(); - } -#ifdef ISOLATE_SHARING - else if (V == module->GetCtpClassFunction) { - Changed = true; - Value* val = Call.getArgument(0); - Value* indexes[2] = { module->constantZero, - module->OffsetCtpInClassConstant }; - Value* VTPtr = GetElementPtrInst::Create(val, indexes, - indexes + 2, "", CI); - Value* VT = new LoadInst(VTPtr, "", CI); - CI->replaceAllUsesWith(VT); - CI->eraseFromParent(); - } else if (V == module->GetCtpCacheNodeFunction) { - Changed = true; - Value* val = Call.getArgument(0); - Value* indexes[2] = { module->constantZero, module->constantFour }; - Value* VTPtr = GetElementPtrInst::Create(val, indexes, - indexes + 2, "", CI); - Value* VT = new LoadInst(VTPtr, "", CI); - CI->replaceAllUsesWith(VT); - CI->eraseFromParent(); - } else if (V == module->GetJnjvmArrayClassFunction) { - Changed = true; - Value* val = Call.getArgument(0); - Value* index = Call.getArgument(1); - Value* indexes[3] = { module->constantZero, module->constantTwo, - index }; - Value* VTPtr = GetElementPtrInst::Create(val, indexes, indexes + 3, - "", CI); - Value* VT = new LoadInst(VTPtr, "", CI); - CI->replaceAllUsesWith(VT); - CI->eraseFromParent(); - } else if (V == module->GetJnjvmExceptionClassFunction) { - Changed = true; - Value* val = Call.getArgument(0); - Value* indexes[2] = { module->constantZero, module->constantOne }; - Value* VTPtr = GetElementPtrInst::Create(val, indexes, indexes + 2, - "", CI); - Value* VT = new LoadInst(VTPtr, "", CI); - CI->replaceAllUsesWith(VT); - CI->eraseFromParent(); - } -#endif - - } - } - } - return Changed; -} - - -FunctionPass* createLowerConstantCallsPass() { - return new LowerConstantCalls(); -} - -} Modified: vmkit/trunk/lib/JnJVM/VMCore/Makefile URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/Makefile?rev=65457&r1=65456&r2=65457&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/Makefile (original) +++ vmkit/trunk/lib/JnJVM/VMCore/Makefile Wed Feb 25 09:42:09 2009 @@ -14,7 +14,7 @@ include $(LEVEL)/Makefile.common -CXX.Flags += -I$(PROJ_OBJ_DIR)/../LLVMRuntime -I$(PROJ_SRC_DIR)/../Classpath $(CLASSPATH_FLAGS) +CXX.Flags += -I$(PROJ_OBJ_DIR)/../LLVMRuntime -I$(PROJ_SRC_DIR)/../Classpath $(CLASSPATH_FLAGS) -I$(PROJ_SRC_DIR)/../../../include/jnjvm ifeq ($(ISOLATE_BUILD), 1) CXX.Flags += -I$(PROJ_SRC_DIR)/../Isolate Removed: vmkit/trunk/lib/JnJVM/VMCore/OpcodeNames.def URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/OpcodeNames.def?rev=65456&view=auto ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/OpcodeNames.def (original) +++ vmkit/trunk/lib/JnJVM/VMCore/OpcodeNames.def (removed) @@ -1,221 +0,0 @@ -//===-------------- OpcodeNames.def - Name of opcodes ---------------------===// -// -// JnJVM -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef OPCODE_NAMES_DEF -#define OPCODE_NAMES_DEF - -const char* jnjvm::JavaJIT::OpcodeNames[256] = { - "NOP", - "ACONST_NULL", - "ICONST_M1", - "ICONST_0", - "ICONST_1", - "ICONST_2", - "ICONST_3", - "ICONST_4", - "ICONST_5", - "LCONST_0", - "LCONST_1", - "FCONST_0", - "FCONST_1", - "FCONST_2", - "DCONST_0", - "DCONST_1", - "BIPUSH", - "SIPUSH", - "LDC", - "LDC_W", - "LDC2_W", - "ILOAD", - "LLOAD", - "FLOAD", - "DLOAD", - "ALOAD", - "ILOAD_0", - "ILOAD_1", - "ILOAD_2", - "ILOAD_3", - "LLOAD_0", - "LLOAD_1", - "LLOAD_2", - "LLOAD_3", - "FLOAD_0", - "FLOAD_1", - "FLOAD_2", - "FLOAD_3", - "DLOAD_0", - "DLOAD_1", - "DLOAD_2", - "DLOAD_3", - "ALOAD_0", - "ALOAD_1", - "ALOAD_2", - "ALOAD_3", - "IALOAD", - "LALOAD", - "FALOAD", - "DALOAD", - "AALOAD", - "BALOAD", - "CALOAD", - "SALOAD", - "ISTORE", - "LSTORE", - "FSTORE", - "DSTORE", - "ASTORE", - "ISTORE_0", - "ISTORE_1", - "ISTORE_2", - "ISTORE_3", - "LSTORE_0", - "LSTORE_1", - "LSTORE_2", - "LSTORE_3", - "FSTORE_0", - "FSTORE_1", - "FSTORE_2", - "FSTORE_3", - "DSTORE_0", - "DSTORE_1", - "DSTORE_2", - "DSTORE_3", - "ASTORE_0", - "ASTORE_1", - "ASTORE_2", - "ASTORE_3", - "IASTORE", - "LASTORE", - "FASTORE", - "DASTORE", - "AASTORE", - "BASTORE", - "CASTORE", - "SASTORE", - "POP", - "POP2", - "DUP", - "DUP_X1", - "DUP_X2", - "DUP2", - "DUP2_X1", - "DUP2_X2", - "SWAP", - "IADD", - "LADD", - "FADD", - "DADD", - "ISUB", - "LSUB", - "FSUB", - "DSUB", - "IMUL", - "LMUL", - "FMUL", - "DMUL", - "IDIV", - "LDIV", - "FDIV", - "DDIV", - "IREM", - "LREM", - "FREM", - "DREM", - "INEG", - "LNEG", - "FNEG", - "DNEG", - "ISHL", - "LSHL", - "ISHR", - "LSHR", - "IUSHR", - "LUSHR", - "IAND", - "LAND", - "IOR", - "LOR", - "IXOR", - "LXOR", - "IINC", - "I2L", - "I2F", - "I2D", - "L2I", - "L2F", - "L2D", - "F2I", - "F2L", - "F2D", - "D2I", - "D2L", - "D2F", - "I2B", - "I2C", - "I2S", - "LCMP", - "FCMPL", - "FCMPG", - "DCMPL", - "DCMPG", - "IFEQ", - "IFNE", - "IFLT", - "IFGE", - "IFGT", - "IFLE", - "IF_ICMPEQ", - "IF_ICMPNE", - "IF_ICMPLT", - "IF_ICMPGE", - "IF_ICMPGT", - "IF_ICMPLE", - "IF_ACMPEQ", - "IF_ACMPNE", - "GOTO", - "JSR", - "RET", - "TABLESWITCH", - "LOOKUPSWITCH", - "IRETURN", - "LRETURN", - "FRETURN", - "DRETURN", - "ARETURN", - "RETURN", - "GETSTATIC", - "PUTSTATIC", - "GETFIELD", - "PUTFIELD", - "INVOKEVIRTUAL", - "INVOKESPECIAL", - "INVOKESTATIC", - "INVOKEINTERFACE", - "UNUSED", - "NEW", - "NEWARRAY", - "ANEWARRAY", - "ARRAYLENGTH", - "ATHROW", - "CHECKCAST", - "INSTANCEOF", - "MONITORENTER", - "MONITOREXIT", - "WIDE", - "MULTIANEWARRAY", - "IFNULL", - "IFNONNULL", - "GOTO_W", - "JSR_W", - "BREAKPOINT", - "IMPDEP1", - "IMPDEP2" -}; - -#endif Modified: vmkit/trunk/tools/jnjvm/Makefile URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/tools/jnjvm/Makefile?rev=65457&r1=65456&r2=65457&view=diff ============================================================================== --- vmkit/trunk/tools/jnjvm/Makefile (original) +++ vmkit/trunk/tools/jnjvm/Makefile Wed Feb 25 09:42:09 2009 @@ -11,7 +11,7 @@ include $(LEVEL)/Makefile.config TOOLNAME = jnjvm -USEDLIBS = Allocator CommonThread Mvm JnJVM Classpath $(GCLIB) +USEDLIBS = Allocator CommonThread Mvm JnJVM Classpath JnjvmCompiler $(GCLIB) LINK_COMPONENTS = jit nativecodegen scalaropts instrumentation ipa ipo ifeq ($(ISOLATE_SHARING_BUILD), 1) Modified: vmkit/trunk/tools/vmjc/Makefile URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/tools/vmjc/Makefile?rev=65457&r1=65456&r2=65457&view=diff ============================================================================== --- vmkit/trunk/tools/vmjc/Makefile (original) +++ vmkit/trunk/tools/vmjc/Makefile Wed Feb 25 09:42:09 2009 @@ -11,7 +11,7 @@ include $(LEVEL)/Makefile.config TOOLNAME = vmjc -USEDLIBS = Allocator CommonThread Mvm JnJVM Classpath $(GCLIB) +USEDLIBS = Allocator CommonThread Mvm JnJVM Classpath JnjvmCompiler $(GCLIB) LINK_COMPONENTS = jit nativecodegen scalaropts instrumentation ipa ipo bitwriter include $(LEVEL)/Makefile.common Modified: vmkit/trunk/tools/vmkit/Makefile URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/tools/vmkit/Makefile?rev=65457&r1=65456&r2=65457&view=diff ============================================================================== --- vmkit/trunk/tools/vmkit/Makefile (original) +++ vmkit/trunk/tools/vmkit/Makefile Wed Feb 25 09:42:09 2009 @@ -14,7 +14,7 @@ USEDLIBS = Allocator CommonThread Mvm $(GCLIB) ifeq ($(WITH_JNJVM), 1) -USEDLIBS += JnJVM Classpath +USEDLIBS += JnJVM Classpath JnjvmCompiler endif ifeq ($(ISOLATE_SHARING_BUILD), 1) From nicolas.geoffray at lip6.fr Wed Feb 25 07:43:56 2009 From: nicolas.geoffray at lip6.fr (Nicolas Geoffray) Date: Wed, 25 Feb 2009 15:43:56 -0000 Subject: [vmkit-commits] [vmkit] r65458 - /vmkit/trunk/lib/JnJVM/Makefile Message-ID: <200902251543.n1PFhvmE024393@zion.cs.uiuc.edu> Author: geoffray Date: Wed Feb 25 09:43:56 2009 New Revision: 65458 URL: http://llvm.org/viewvc/llvm-project?rev=65458&view=rev Log: Forgot that file in the previous commit. Modified: vmkit/trunk/lib/JnJVM/Makefile Modified: vmkit/trunk/lib/JnJVM/Makefile URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/Makefile?rev=65458&r1=65457&r2=65458&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/Makefile (original) +++ vmkit/trunk/lib/JnJVM/Makefile Wed Feb 25 09:43:56 2009 @@ -8,7 +8,7 @@ ##===----------------------------------------------------------------------===## LEVEL = ../.. -DIRS = LLVMRuntime VMCore Classpath +DIRS = LLVMRuntime VMCore Classpath Compiler include $(LEVEL)/Makefile.config From nicolas.geoffray at lip6.fr Wed Feb 25 07:45:25 2009 From: nicolas.geoffray at lip6.fr (Nicolas Geoffray) Date: Wed, 25 Feb 2009 15:45:25 -0000 Subject: [vmkit-commits] [vmkit] r65459 - /vmkit/trunk/lib/JnJVM/Compiler/Makefile Message-ID: <200902251545.n1PFjQWG024458@zion.cs.uiuc.edu> Author: geoffray Date: Wed Feb 25 09:45:25 2009 New Revision: 65459 URL: http://llvm.org/viewvc/llvm-project?rev=65459&view=rev Log: Also forgot that file. Added: vmkit/trunk/lib/JnJVM/Compiler/Makefile Added: vmkit/trunk/lib/JnJVM/Compiler/Makefile URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/Compiler/Makefile?rev=65459&view=auto ============================================================================== --- vmkit/trunk/lib/JnJVM/Compiler/Makefile (added) +++ vmkit/trunk/lib/JnJVM/Compiler/Makefile Wed Feb 25 09:45:25 2009 @@ -0,0 +1,21 @@ +##===- lib/JnJVM/Compiler/Makefile -------------------------*- Makefile -*-===## +# +# The VMKit project +# +# This file is distributed under the University of Illinois Open Source +# License. See LICENSE.TXT for details. +# +##===----------------------------------------------------------------------===## +LEVEL = ../../.. + +LIBRARYNAME = JnjvmCompiler + +include $(LEVEL)/Makefile.config + +include $(LEVEL)/Makefile.common + +CXX.Flags += -I$(PROJ_OBJ_DIR)/../LLVMRuntime -I$(PROJ_SRC_DIR)/../Classpath $(CLASSPATH_FLAGS) -I$(PROJ_SRC_DIR)/../VMCore + +ifeq ($(ISOLATE_BUILD), 1) + CXX.Flags += -I$(PROJ_SRC_DIR)/../Isolate +endif From nicolas.geoffray at lip6.fr Wed Feb 25 16:49:44 2009 From: nicolas.geoffray at lip6.fr (Nicolas Geoffray) Date: Thu, 26 Feb 2009 00:49:44 -0000 Subject: [vmkit-commits] [vmkit] r65495 - /vmkit/trunk/include/mvm/Threads/Thread.h Message-ID: <200902260049.n1Q0ni8Y011028@zion.cs.uiuc.edu> Author: geoffray Date: Wed Feb 25 18:49:43 2009 New Revision: 65495 URL: http://llvm.org/viewvc/llvm-project?rev=65495&view=rev Log: The comment was wrong: GCC is doing the right thing. Modified: vmkit/trunk/include/mvm/Threads/Thread.h Modified: vmkit/trunk/include/mvm/Threads/Thread.h URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/include/mvm/Threads/Thread.h?rev=65495&r1=65494&r2=65495&view=diff ============================================================================== --- vmkit/trunk/include/mvm/Threads/Thread.h (original) +++ vmkit/trunk/include/mvm/Threads/Thread.h Wed Feb 25 18:49:43 2009 @@ -85,14 +85,7 @@ #define FRAME_IP(fp) (fp[1]) #endif -// Apparently gcc for i386 and family considers __builtin_frame_address(0) to -// return the caller, not the current function. -#if defined(__i386__) || defined(i386) || defined(_M_IX86) || \ - defined(__x86_64__) || defined(_M_AMD64) -#define FRAME_PTR() __builtin_frame_address(0) -#else #define FRAME_PTR() (((void**)__builtin_frame_address(0))[0]) -#endif /// Thread - This class is the base of custom virtual machines' Thread classes. /// It provides static functions to manage threads. An instance of this class From nicolas.geoffray at lip6.fr Thu Feb 26 04:44:45 2009 From: nicolas.geoffray at lip6.fr (Nicolas Geoffray) Date: Thu, 26 Feb 2009 12:44:45 -0000 Subject: [vmkit-commits] [vmkit] r65528 - in /vmkit/trunk/lib/N3: LLVMRuntime/runtime.ll VMCore/CLIJit.cpp VMCore/Opcodes.cpp Message-ID: <200902261244.n1QCijnQ015748@zion.cs.uiuc.edu> Author: geoffray Date: Thu Feb 26 06:44:43 2009 New Revision: 65528 URL: http://llvm.org/viewvc/llvm-project?rev=65528&view=rev Log: Fix N3 debugging. Modified: vmkit/trunk/lib/N3/LLVMRuntime/runtime.ll vmkit/trunk/lib/N3/VMCore/CLIJit.cpp vmkit/trunk/lib/N3/VMCore/Opcodes.cpp Modified: vmkit/trunk/lib/N3/LLVMRuntime/runtime.ll URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/N3/LLVMRuntime/runtime.ll?rev=65528&r1=65527&r2=65528&view=diff ============================================================================== --- vmkit/trunk/lib/N3/LLVMRuntime/runtime.ll (original) +++ vmkit/trunk/lib/N3/LLVMRuntime/runtime.ll Thu Feb 26 06:44:43 2009 @@ -49,5 +49,5 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Debugging methods ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -declare void @printExecution(i32, i32) +declare void @n3PrintExecution(i32, i32) Modified: vmkit/trunk/lib/N3/VMCore/CLIJit.cpp URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/N3/VMCore/CLIJit.cpp?rev=65528&r1=65527&r2=65528&view=diff ============================================================================== --- vmkit/trunk/lib/N3/VMCore/CLIJit.cpp (original) +++ vmkit/trunk/lib/N3/VMCore/CLIJit.cpp Thu Feb 26 06:44:43 2009 @@ -1599,7 +1599,7 @@ getCLIExceptionLLVM = module->getFunction("GetCLIException"); - printExecutionLLVM = module->getFunction("printExecution"); + printExecutionLLVM = module->getFunction("n3PrintExecution"); Modified: vmkit/trunk/lib/N3/VMCore/Opcodes.cpp URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/N3/VMCore/Opcodes.cpp?rev=65528&r1=65527&r2=65528&view=diff ============================================================================== --- vmkit/trunk/lib/N3/VMCore/Opcodes.cpp (original) +++ vmkit/trunk/lib/N3/VMCore/Opcodes.cpp Thu Feb 26 06:44:43 2009 @@ -105,8 +105,8 @@ } -void CLIJit::printExecution(char* opcode, VMMethod* meth) { - printf("executing %s %s\n", meth->printString(), opcode); +extern "C" void n3PrintExecution(char* opcode, VMMethod* meth) { + fprintf(stderr, "executing %s %s\n", meth->printString(), opcode); } From nicolas.geoffray at lip6.fr Thu Feb 26 10:44:00 2009 From: nicolas.geoffray at lip6.fr (Nicolas Geoffray) Date: Thu, 26 Feb 2009 18:44:00 -0000 Subject: [vmkit-commits] [vmkit] r65555 - in /vmkit/trunk: include/jnjvm/ include/mvm/ include/mvm/Threads/ lib/JnJVM/Classpath/ lib/JnJVM/Compiler/ lib/JnJVM/VMCore/ lib/Mvm/Runtime/ lib/N3/Mono/ lib/N3/PNetLib/ lib/N3/VMCore/ tools/jnjvm/ tools/vmjc/ tools/vmkit/ Message-ID: <200902261844.n1QIi1X6029359@zion.cs.uiuc.edu> Author: geoffray Date: Thu Feb 26 12:44:00 2009 New Revision: 65555 URL: http://llvm.org/viewvc/llvm-project?rev=65555&view=rev Log: Completely rewrite the JnjvmModule abstraction in the JVM. We now have two separate kinds of modules: AOT and JIT. The JVM lets the tool decide which JIT it wants. Because I had to use virtual functions, JnjvmModule could not extend llvm::Module anymore. And since there was no real reason for it to extend the llvm::Module class, I moved the llvm::Module object to a field. Also as a side-effect, I had to fix stack unwinding problems. Functions that are involved in Java/native cross-calls and functions that get the frame pointer now have a noinline attribute. This fixes the Debug build on x86. Added: vmkit/trunk/lib/JnJVM/Compiler/JnjvmModuleAOT.cpp vmkit/trunk/lib/JnJVM/Compiler/JnjvmModuleJIT.cpp Modified: vmkit/trunk/include/jnjvm/JnjvmModule.h vmkit/trunk/include/mvm/JIT.h vmkit/trunk/include/mvm/Threads/Thread.h vmkit/trunk/include/mvm/VirtualMachine.h vmkit/trunk/lib/JnJVM/Classpath/ClasspathConstructor.cpp vmkit/trunk/lib/JnJVM/Classpath/ClasspathMethod.cpp vmkit/trunk/lib/JnJVM/Compiler/JavaJIT.cpp vmkit/trunk/lib/JnJVM/Compiler/JnjvmModule.cpp vmkit/trunk/lib/JnJVM/Compiler/JnjvmModuleProvider.cpp vmkit/trunk/lib/JnJVM/Compiler/LowerConstantCalls.cpp vmkit/trunk/lib/JnJVM/VMCore/JavaClass.h vmkit/trunk/lib/JnJVM/VMCore/JavaInitialise.cpp vmkit/trunk/lib/JnJVM/VMCore/JavaRuntimeJIT.cpp vmkit/trunk/lib/JnJVM/VMCore/JavaThread.cpp vmkit/trunk/lib/JnJVM/VMCore/JavaThread.h vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.cpp vmkit/trunk/lib/JnJVM/VMCore/JnjvmClassLoader.cpp vmkit/trunk/lib/JnJVM/VMCore/JnjvmClassLoader.h vmkit/trunk/lib/Mvm/Runtime/JIT.cpp vmkit/trunk/lib/N3/Mono/MonoString.cpp vmkit/trunk/lib/N3/PNetLib/PNetString.cpp vmkit/trunk/lib/N3/VMCore/CLIJit.cpp vmkit/trunk/lib/N3/VMCore/CLIJitMeta.cpp vmkit/trunk/lib/N3/VMCore/CLIRuntimeJIT.cpp vmkit/trunk/lib/N3/VMCore/N3.cpp vmkit/trunk/lib/N3/VMCore/VMThread.cpp vmkit/trunk/tools/jnjvm/Main.cpp vmkit/trunk/tools/vmjc/vmjc.cpp vmkit/trunk/tools/vmkit/Launcher.cpp Modified: vmkit/trunk/include/jnjvm/JnjvmModule.h URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/include/jnjvm/JnjvmModule.h?rev=65555&r1=65554&r2=65555&view=diff ============================================================================== --- vmkit/trunk/include/jnjvm/JnjvmModule.h (original) +++ vmkit/trunk/include/jnjvm/JnjvmModule.h Thu Feb 26 12:44:00 2009 @@ -184,97 +184,8 @@ class JnjvmModule : public mvm::MvmModule { friend class LLVMClassInfo; -private: - std::map nativeClasses; - std::map arrayClasses; - std::map javaClasses; - std::map virtualTables; - std::map staticInstances; - std::map constantPools; - std::map strings; - std::map enveloppes; - std::map nativeFunctions; - std::map utf8s; - std::map virtualMethods; - std::map finalObjects; - - typedef std::map::iterator - final_object_iterator; - - typedef std::map::iterator - method_iterator; - - typedef std::map::iterator - native_class_iterator; - - typedef std::map::iterator - array_class_iterator; - - typedef std::map::iterator - java_class_iterator; - - typedef std::map::iterator - virtual_table_iterator; - - typedef std::map::iterator - static_instance_iterator; - - typedef std::map::iterator - constant_pool_iterator; - - typedef std::map::iterator - string_iterator; - - typedef std::map::iterator - enveloppe_iterator; - - typedef std::map::iterator - native_function_iterator; - - typedef std::map::iterator - utf8_iterator; - - - bool staticCompilation; - bool enabledException; - -#ifdef WITH_TRACER - llvm::Function* makeTracer(Class* cl, bool stat); -#endif - void makeVT(Class* cl); - void allocateVT(Class* cl); - - static llvm::Constant* PrimitiveArrayVT; - static llvm::Constant* ReferenceArrayVT; - - static llvm::Function* StaticInitializer; - static llvm::Function* ObjectPrinter; - public: - - static llvm::Function* NativeLoader; - - bool generateTracers; - bool generateStubs; - bool assumeCompiled; - - bool isStaticCompiling() { - return staticCompilation; - } - - bool hasExceptionsEnabled() { - return enabledException; - } - - void disableExceptions() { - enabledException = false; - } - - void setIsStaticCompiling(bool sc) { - staticCompilation = sc; - } - static llvm::ConstantInt* JavaArraySizeOffsetConstant; static llvm::ConstantInt* JavaArrayElementsOffsetConstant; static llvm::ConstantInt* JavaObjectLockOffsetConstant; @@ -412,10 +323,59 @@ llvm::Function* ClassCastExceptionFunction; llvm::Function* OutOfMemoryErrorFunction; llvm::Function* NegativeArraySizeExceptionFunction; + + static llvm::Function* NativeLoader; + +protected: +#ifdef WITH_TRACER + llvm::Function* internalMakeTracer(Class* cl, bool stat); + virtual llvm::Function* makeTracer(Class* cl, bool stat) { + return internalMakeTracer(cl, stat); + } +#endif + + llvm::Constant* PrimitiveArrayVT; + llvm::Constant* ReferenceArrayVT; + + void internalMakeVT(Class* cl); + +private: + + void initialise(); + + bool enabledException; + + /// allocateVT - Allocate a VT for the class. The VT will be the VT of + /// instances of the class. + void allocateVT(Class* cl); + + + virtual void makeVT(Class* cl) = 0; + + + +public: + + JnjvmModule(const std::string &ModuleID, JnjvmModule* Father = 0); + + + virtual bool isStaticCompiling() = 0; + + bool hasExceptionsEnabled() { + return enabledException; + } + + void disableExceptions() { + enabledException = false; + } + + virtual ~JnjvmModule() {} + + llvm::Constant* getReferenceArrayVT(); + llvm::Constant* getPrimitiveArrayVT(); static void resolveVirtualClass(Class* cl); static void resolveStaticClass(Class* cl); - static void setMethod(JavaMethod* meth, void* ptr, const char* name); static llvm::Function* getMethod(JavaMethod* meth); static LLVMSignatureInfo* getSignatureInfo(Signdef* sign); @@ -424,43 +384,99 @@ static LLVMMethodInfo* getMethodInfo(JavaMethod* method); static LLVMAssessorInfo& getTypedefInfo(const Typedef* type); - explicit JnjvmModule(const std::string &ModuleID, bool sc = false); - void initialise(); - void printStats(); - llvm::Constant* getFinalObject(JavaObject* obj); - JavaObject* getFinalObject(llvm::Value* C); - llvm::Constant* getNativeClass(CommonClass* cl); - llvm::Constant* getJavaClass(CommonClass* cl); - llvm::Constant* getStaticInstance(Class* cl); - llvm::Constant* getVirtualTable(Class* cl); - llvm::Constant* getMethodInClass(JavaMethod* meth); - - llvm::Constant* getEnveloppe(Enveloppe* enveloppe); - llvm::Constant* getString(JavaString* str); - llvm::Constant* getConstantPool(JavaConstantPool* ctp); - llvm::Constant* getNativeFunction(JavaMethod* meth, void* natPtr); + virtual llvm::Constant* getFinalObject(JavaObject* obj) = 0; + virtual JavaObject* getFinalObject(llvm::Value* C) = 0; + virtual llvm::Constant* getNativeClass(CommonClass* cl) = 0; + virtual llvm::Constant* getJavaClass(CommonClass* cl) = 0; + virtual llvm::Constant* getStaticInstance(Class* cl) = 0; + virtual llvm::Constant* getVirtualTable(Class* cl) = 0; + virtual llvm::Constant* getMethodInClass(JavaMethod* meth) = 0; + + virtual llvm::Constant* getEnveloppe(Enveloppe* enveloppe) = 0; + virtual llvm::Constant* getString(JavaString* str) = 0; + virtual llvm::Constant* getConstantPool(JavaConstantPool* ctp) = 0; + virtual llvm::Constant* getNativeFunction(JavaMethod* meth, void* natPtr) = 0; + + virtual void setMethod(JavaMethod* meth, void* ptr, const char* name) = 0; - llvm::Constant* getReferenceArrayVT(); - llvm::Constant* getPrimitiveArrayVT(); #ifdef SERVICE - std::map isolates; - typedef std::map::iterator - isolate_iterator; + virtual llvm::Value* getIsolate(Jnjvm* vm, llvm::Value* Where) = 0; +#endif + +}; + +class JnjvmModuleJIT : public JnjvmModule { +public: + JnjvmModuleJIT(const std::string &ModuleID, JnjvmModule* Father = 0); + + virtual bool isStaticCompiling() { + return false; + } + + virtual void makeVT(Class* cl); + + virtual llvm::Constant* getFinalObject(JavaObject* obj); + virtual JavaObject* getFinalObject(llvm::Value* C); + virtual llvm::Constant* getNativeClass(CommonClass* cl); + virtual llvm::Constant* getJavaClass(CommonClass* cl); + virtual llvm::Constant* getStaticInstance(Class* cl); + virtual llvm::Constant* getVirtualTable(Class* cl); + virtual llvm::Constant* getMethodInClass(JavaMethod* meth); + + virtual llvm::Constant* getEnveloppe(Enveloppe* enveloppe); + virtual llvm::Constant* getString(JavaString* str); + virtual llvm::Constant* getConstantPool(JavaConstantPool* ctp); + virtual llvm::Constant* getNativeFunction(JavaMethod* meth, void* natPtr); - llvm::Value* getIsolate(Jnjvm* vm, llvm::Value* Where); + virtual void setMethod(JavaMethod* meth, void* ptr, const char* name); + + +#ifdef SERVICE + virtual llvm::Value* getIsolate(Jnjvm* vm, llvm::Value* Where); #endif + virtual ~JnjvmModuleJIT() {} - bool isCompiling(const CommonClass* cl) const; +}; + +class JnjvmModuleAOT : public JnjvmModule { + +public: + JnjvmModuleAOT(const std::string &ModuleID, JnjvmModule* Father = 0); - void CreateStaticInitializer(); + virtual bool isStaticCompiling() { + return true; + } + + virtual void makeVT(Class* cl); + + virtual llvm::Constant* getFinalObject(JavaObject* obj); + virtual JavaObject* getFinalObject(llvm::Value* C); + virtual llvm::Constant* getNativeClass(CommonClass* cl); + virtual llvm::Constant* getJavaClass(CommonClass* cl); + virtual llvm::Constant* getStaticInstance(Class* cl); + virtual llvm::Constant* getVirtualTable(Class* cl); + virtual llvm::Constant* getMethodInClass(JavaMethod* meth); + + virtual llvm::Constant* getEnveloppe(Enveloppe* enveloppe); + virtual llvm::Constant* getString(JavaString* str); + virtual llvm::Constant* getConstantPool(JavaConstantPool* ctp); + virtual llvm::Constant* getNativeFunction(JavaMethod* meth, void* natPtr); + + virtual void setMethod(JavaMethod* meth, void* ptr, const char* name); - static void setNoInline(Class* cl); + +#ifdef SERVICE + virtual llvm::Value* getIsolate(Jnjvm* vm, llvm::Value* Where); +#endif + + virtual ~JnjvmModuleAOT() {} private: - static llvm::Module* initialModule; + + virtual llvm::Function* makeTracer(Class* cl, bool stat); //--------------- Static compiler specific functions -----------------------// llvm::Constant* CreateConstantFromVT(Class* classDef); @@ -483,6 +499,79 @@ template llvm::Constant* CreateConstantFromArray(T* val, const llvm::Type* Ty); + + std::map nativeClasses; + std::map arrayClasses; + std::map javaClasses; + std::map virtualTables; + std::map staticInstances; + std::map constantPools; + std::map strings; + std::map enveloppes; + std::map nativeFunctions; + std::map utf8s; + std::map virtualMethods; + std::map finalObjects; + + typedef std::map::iterator + final_object_iterator; + + typedef std::map::iterator + method_iterator; + + typedef std::map::iterator + native_class_iterator; + + typedef std::map::iterator + array_class_iterator; + + typedef std::map::iterator + java_class_iterator; + + typedef std::map::iterator + virtual_table_iterator; + + typedef std::map::iterator + static_instance_iterator; + + typedef std::map::iterator + constant_pool_iterator; + + typedef std::map::iterator + string_iterator; + + typedef std::map::iterator + enveloppe_iterator; + + typedef std::map::iterator + native_function_iterator; + + typedef std::map::iterator + utf8_iterator; + +#ifdef SERVICE + virtual llvm::Value* getIsolate(Jnjvm* vm, llvm::Value* Where); + std::map isolates; + typedef std::map::iterator + isolate_iterator; +#endif + + bool isCompiling(const CommonClass* cl) const; + +public: + llvm::Function* StaticInitializer; + llvm::Function* ObjectPrinter; + + bool generateTracers; + bool generateStubs; + bool assumeCompiled; + + + void CreateStaticInitializer(); + + static void setNoInline(Class* cl); + + void printStats(); }; Modified: vmkit/trunk/include/mvm/JIT.h URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/include/mvm/JIT.h?rev=65555&r1=65554&r2=65555&view=diff ============================================================================== --- vmkit/trunk/include/mvm/JIT.h (original) +++ vmkit/trunk/include/mvm/JIT.h Thu Feb 26 12:44:00 2009 @@ -12,8 +12,7 @@ #include #include - -#include "llvm/Module.h" +#include #include "types.h" @@ -25,6 +24,7 @@ class ExistingModuleProvider; class Function; class FunctionPassManager; + class Module; class PointerType; class TargetData; class TargetMachine; @@ -55,10 +55,19 @@ const float NaNFloat = NAN; //(float)(((float)0.0) / (float)0.0); const double NaNDouble = NAN; //0.0 / 0.0; -class MvmModule : public llvm::Module { +class MvmModule { +protected: + llvm::Module* TheModule; + public: - MvmModule(const std::string& ModuleID); + explicit MvmModule(const std::string& ModuleID); + + virtual ~MvmModule() {} + + llvm::Module* getLLVMModule() { + return TheModule; + } llvm::Function* exceptionEndCatch; llvm::Function* exceptionBeginCatch; Modified: vmkit/trunk/include/mvm/Threads/Thread.h URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/include/mvm/Threads/Thread.h?rev=65555&r1=65554&r2=65555&view=diff ============================================================================== --- vmkit/trunk/include/mvm/Threads/Thread.h (original) +++ vmkit/trunk/include/mvm/Threads/Thread.h Thu Feb 26 12:44:00 2009 @@ -79,13 +79,22 @@ }; + #if defined(__MACH__) && defined(__PPC__) #define FRAME_IP(fp) (fp[2]) #else #define FRAME_IP(fp) (fp[1]) #endif +// Apparently gcc for i386 and family considers __builtin_frame_address(0) to +// return the caller, not the current function. +#if defined(__i386__) || defined(i386) || defined(_M_IX86) || \ + defined(__x86_64__) || defined(_M_AMD64) +#define FRAME_PTR() __builtin_frame_address(0) +#else #define FRAME_PTR() (((void**)__builtin_frame_address(0))[0]) +#endif + /// Thread - This class is the base of custom virtual machines' Thread classes. /// It provides static functions to manage threads. An instance of this class Modified: vmkit/trunk/include/mvm/VirtualMachine.h URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/include/mvm/VirtualMachine.h?rev=65555&r1=65554&r2=65555&view=diff ============================================================================== --- vmkit/trunk/include/mvm/VirtualMachine.h (original) +++ vmkit/trunk/include/mvm/VirtualMachine.h Thu Feb 26 12:44:00 2009 @@ -54,7 +54,7 @@ /// waitForExit - Wait until the virtual machine stops its execution. virtual void waitForExit() = 0; - static CompilationUnit* initialiseJVM(bool staticCompilation = false); + static CompilationUnit* initialiseJVM(); static VirtualMachine* createJVM(CompilationUnit* C = 0); static CompilationUnit* initialiseCLIVM(); Modified: vmkit/trunk/lib/JnJVM/Classpath/ClasspathConstructor.cpp URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/Classpath/ClasspathConstructor.cpp?rev=65555&r1=65554&r2=65555&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/Classpath/ClasspathConstructor.cpp (original) +++ vmkit/trunk/lib/JnJVM/Classpath/ClasspathConstructor.cpp Thu Feb 26 12:44:00 2009 @@ -65,15 +65,12 @@ return res; } -JNIEXPORT jobject JNICALL Java_java_lang_reflect_Constructor_constructNative( -#ifdef NATIVE_JNI -JNIEnv *env, -#endif -JavaObjectConstructor* cons, jobject _args, jclass Clazz, jint index) { - +static jobject proceed(JavaObjectConstructor* cons, jobject _args, jclass Clazz, + jint index) __attribute__ ((noinline)); + +static jobject proceed(JavaObjectConstructor* cons, jobject _args, jclass Clazz, + jint index) { jobject res = 0; - - Jnjvm* vm = JavaThread::get()->getJVM(); JavaMethod* meth = cons->getInternalMethod(); JavaArray* args = (JavaArray*)_args; @@ -87,7 +84,6 @@ void* startBuf = (void*)buf; // Do it after alloca - BEGIN_NATIVE_EXCEPTION(0) if (nbArgs == size) { UserCommonClass* _cl = @@ -128,6 +124,22 @@ } else { vm->illegalArgumentExceptionForMethod(meth, 0, 0); } + + return res; +} + +JNIEXPORT jobject JNICALL Java_java_lang_reflect_Constructor_constructNative( +#ifdef NATIVE_JNI +JNIEnv *env, +#endif +JavaObjectConstructor* cons, jobject _args, jclass Clazz, jint index) { + + jobject res = 0; + + BEGIN_NATIVE_EXCEPTION(0) + + // Proceed in another function because we are using alloca. + res = proceed(cons, _args, Clazz, index); END_NATIVE_EXCEPTION Modified: vmkit/trunk/lib/JnJVM/Classpath/ClasspathMethod.cpp URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/Classpath/ClasspathMethod.cpp?rev=65555&r1=65554&r2=65555&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/Classpath/ClasspathMethod.cpp (original) +++ vmkit/trunk/lib/JnJVM/Classpath/ClasspathMethod.cpp Thu Feb 26 12:44:00 2009 @@ -85,15 +85,13 @@ return res; } -JNIEXPORT jobject JNICALL Java_java_lang_reflect_Method_invokeNative( -#ifdef NATIVE_JNI -JNIEnv *env, -#endif -JavaObjectMethod* Meth, jobject _obj, jobject _args, jclass Cl, jint index) { - - JavaObject* res = 0; +static jobject proceed(JavaObjectMethod* Meth, jobject _obj, jobject _args, + jclass Cl, jint index) __attribute__((noinline)); +static jobject proceed(JavaObjectMethod* Meth, jobject _obj, jobject _args, + jclass Cl, jint index) { + JavaObject* res = 0; Jnjvm* vm = JavaThread::get()->getJVM(); JavaMethod* meth = Meth->getInternalMethod(); @@ -106,7 +104,6 @@ uintptr_t buf = size ? (uintptr_t)alloca(size * sizeof(uint64)) : 0; - BEGIN_NATIVE_EXCEPTION(0) void* _buf = (void*)buf; if (nbArgs == size) { @@ -219,13 +216,29 @@ vm->illegalArgumentExceptionForMethod(meth, 0, 0); } + return (jobject)res; +} + +#undef RUN_METH + +JNIEXPORT jobject JNICALL Java_java_lang_reflect_Method_invokeNative( +#ifdef NATIVE_JNI +JNIEnv *env, +#endif +JavaObjectMethod* Meth, jobject _obj, jobject _args, jclass Cl, jint index) { + + jobject res = 0; + + BEGIN_NATIVE_EXCEPTION(0) + + // Create a new function because we use alloca. + res = proceed(Meth, _obj, _args, Cl, index); + END_NATIVE_EXCEPTION return (jobject) res; } -#undef RUN_METH - JNIEXPORT jobjectArray JNICALL Java_java_lang_reflect_Method_getExceptionTypes( #ifdef NATIVE_JNI JNIEnv *env, Modified: vmkit/trunk/lib/JnJVM/Compiler/JavaJIT.cpp URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/Compiler/JavaJIT.cpp?rev=65555&r1=65554&r2=65555&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/Compiler/JavaJIT.cpp (original) +++ vmkit/trunk/lib/JnJVM/Compiler/JavaJIT.cpp Thu Feb 26 12:44:00 2009 @@ -957,8 +957,7 @@ Value* res = getResolvedCommonClass(index, false, &cl); #ifndef ISOLATE - if (cl || (module->isStaticCompiling() && module->isCompiling(cl))) - res = module->getJavaClass(cl); + if (cl) res = module->getJavaClass(cl); else #endif Modified: vmkit/trunk/lib/JnJVM/Compiler/JnjvmModule.cpp URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/Compiler/JnjvmModule.cpp?rev=65555&r1=65554&r2=65555&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/Compiler/JnjvmModule.cpp (original) +++ vmkit/trunk/lib/JnJVM/Compiler/JnjvmModule.cpp Thu Feb 26 12:44:00 2009 @@ -10,50 +10,24 @@ #include "llvm/BasicBlock.h" #include "llvm/CallingConv.h" #include "llvm/Constants.h" -#include "llvm/ExecutionEngine/ExecutionEngine.h" #include "llvm/Instructions.h" -#include "llvm/Support/MutexGuard.h" -#include "llvm/Target/TargetData.h" - #include "mvm/JIT.h" -#include "JavaCache.h" -#include "JavaConstantPool.h" -#include "JavaJIT.h" -#include "JavaString.h" -#include "JavaThread.h" +#include "JavaArray.h" +#include "JavaClass.h" #include "JavaTypes.h" -#include "JavaUpcalls.h" -#include "Jnjvm.h" -#include "Reader.h" #include "jnjvm/JnjvmModule.h" #include "jnjvm/JnjvmModuleProvider.h" -#include - using namespace jnjvm; using namespace llvm; -llvm::Constant* JnjvmModule::PrimitiveArrayVT; -llvm::Constant* JnjvmModule::ReferenceArrayVT; -llvm::Function* JnjvmModule::StaticInitializer; -llvm::Function* JnjvmModule::ObjectPrinter; -llvm::Function* JnjvmModule::NativeLoader; -extern void* JavaArrayVT[]; -extern void* ArrayObjectVT[]; extern void* JavaObjectVT[]; -extern ClassArray ArrayOfBool; -extern ClassArray ArrayOfByte; -extern ClassArray ArrayOfChar; -extern ClassArray ArrayOfShort; -extern ClassArray ArrayOfInt; -extern ClassArray ArrayOfFloat; -extern ClassArray ArrayOfDouble; -extern ClassArray ArrayOfLong; +llvm::Function* JnjvmModule::NativeLoader; #ifdef WITH_TRACER const llvm::FunctionType* JnjvmModule::MarkAndTraceType = 0; @@ -105,1978 +79,160 @@ const llvm::Type* JnjvmModule::VTType; llvm::ConstantInt* JnjvmModule::JavaArrayElementsOffsetConstant; llvm::ConstantInt* JnjvmModule::JavaArraySizeOffsetConstant; -llvm::ConstantInt* JnjvmModule::JavaObjectLockOffsetConstant; -llvm::ConstantInt* JnjvmModule::JavaObjectClassOffsetConstant; - - -bool JnjvmModule::isCompiling(const CommonClass* cl) const { - if (cl->isClass()) { - // A class is being static compiled if owner class is not null. - return (((Class*)cl)->getOwnerClass() != 0); - } else if (cl->isArray()) { - return isCompiling(((ClassArray*)cl)->baseClass()); - } else { - return false; - } -} - -Constant* JnjvmModule::getNativeClass(CommonClass* classDef) { - - if (staticCompilation) { - - if (classDef->isClass() || - (classDef->isArray() && isCompiling(classDef)) || - (assumeCompiled && !(classDef->isArray() && - classDef->asArrayClass()->baseClass()->isPrimitive()))) { - native_class_iterator End = nativeClasses.end(); - native_class_iterator I = nativeClasses.find(classDef); - if (I == End) { - const llvm::Type* Ty = 0; - - if (classDef->isArray()) { - Ty = JavaClassArrayType->getContainedType(0); - } else { - Ty = JavaClassType->getContainedType(0); - } - - GlobalVariable* varGV = - new GlobalVariable(Ty, false, GlobalValue::ExternalLinkage, 0, - classDef->printString(), this); - - nativeClasses.insert(std::make_pair(classDef, varGV)); - - if (classDef->isClass() && isCompiling(classDef->asClass())) { - Constant* C = CreateConstantFromClass((Class*)classDef); - varGV->setInitializer(C); - } else if (classDef->isArray()) { - Constant* C = CreateConstantFromClassArray((ClassArray*)classDef); - varGV->setInitializer(C); - } - - return varGV; - - } else { - return I->second; - } - } else if (classDef->isArray()) { - array_class_iterator End = arrayClasses.end(); - array_class_iterator I = arrayClasses.find((ClassArray*)classDef); - if (I == End) { - const llvm::Type* Ty = JavaClassArrayType; - - GlobalVariable* varGV = - new GlobalVariable(Ty, false, GlobalValue::InternalLinkage, - Constant::getNullValue(Ty), - classDef->printString(), this); - - arrayClasses.insert(std::make_pair((ClassArray*)classDef, varGV)); - return varGV; - } else { - return I->second; - } - } else if (classDef->isPrimitive()) { - assert(0 && "implement me"); - } - return 0; - } else { - const llvm::Type* Ty = classDef->isClass() ? JavaClassType : - JavaCommonClassType; - - ConstantInt* CI = ConstantInt::get(Type::Int64Ty, uint64_t(classDef)); - return ConstantExpr::getIntToPtr(CI, Ty); - } -} - -Constant* JnjvmModule::getConstantPool(JavaConstantPool* ctp) { - if (staticCompilation) { - llvm::Constant* varGV = 0; - constant_pool_iterator End = constantPools.end(); - constant_pool_iterator I = constantPools.find(ctp); - if (I == End) { - const Type* Ty = ConstantPoolType->getContainedType(0); - varGV = new GlobalVariable(Ty, false, - GlobalValue::InternalLinkage, - Constant::getNullValue(Ty), "", this); - constantPools.insert(std::make_pair(ctp, varGV)); - return varGV; - } else { - return I->second; - } - - } else { - void* ptr = ctp->ctpRes; - assert(ptr && "No constant pool found"); - ConstantInt* CI = ConstantInt::get(Type::Int64Ty, uint64_t(ptr)); - return ConstantExpr::getIntToPtr(CI, ConstantPoolType); - } -} - -Constant* JnjvmModule::getMethodInClass(JavaMethod* meth) { - if (staticCompilation) { - Class* cl = meth->classDef; - Constant* MOffset = 0; - Constant* Array = 0; - method_iterator SI = virtualMethods.find(cl); - for (uint32 i = 0; i < cl->nbVirtualMethods + cl->nbStaticMethods; ++i) { - if (&cl->virtualMethods[i] == meth) { - MOffset = ConstantInt::get(Type::Int32Ty, i); - break; - } - } - Array = SI->second; - Constant* GEPs[2] = { constantZero, MOffset }; - return ConstantExpr::getGetElementPtr(Array, GEPs, 2); - - } else { - ConstantInt* CI = ConstantInt::get(Type::Int64Ty, (int64_t)meth); - return ConstantExpr::getIntToPtr(CI, JavaMethodType); - } -} - -Constant* JnjvmModule::getString(JavaString* str) { - if (staticCompilation) { - string_iterator SI = strings.find(str); - if (SI != strings.end()) { - return SI->second; - } else { - assert(str && "No string given"); - LLVMClassInfo* LCI = (LLVMClassInfo*)getClassInfo((Class*)str->getClass()); - const llvm::Type* Ty = LCI->getVirtualType(); - GlobalVariable* varGV = - new GlobalVariable(Ty->getContainedType(0), false, - GlobalValue::InternalLinkage, - 0, "", this); - Constant* res = ConstantExpr::getCast(Instruction::BitCast, varGV, - JavaObjectType); - strings.insert(std::make_pair(str, res)); - Constant* C = CreateConstantFromJavaString(str); - varGV->setInitializer(C); - return res; - } - - } else { - assert(str && "No string given"); - ConstantInt* CI = ConstantInt::get(Type::Int64Ty, uint64(str)); - return ConstantExpr::getIntToPtr(CI, JavaObjectType); - } -} - -Constant* JnjvmModule::getEnveloppe(Enveloppe* enveloppe) { - if (staticCompilation) { - enveloppe_iterator SI = enveloppes.find(enveloppe); - if (SI != enveloppes.end()) { - return SI->second; - } else { - GlobalVariable* varGV = - new GlobalVariable(EnveloppeType->getContainedType(0), false, - GlobalValue::InternalLinkage, 0, "", this); - enveloppes.insert(std::make_pair(enveloppe, varGV)); - - Constant* C = CreateConstantFromEnveloppe(enveloppe); - varGV->setInitializer(C); - return varGV; - } - - } else { - assert(enveloppe && "No enveloppe given"); - ConstantInt* CI = ConstantInt::get(Type::Int64Ty, uint64(enveloppe)); - return ConstantExpr::getIntToPtr(CI, EnveloppeType); - } -} - -Constant* JnjvmModule::getJavaClass(CommonClass* cl) { - if (staticCompilation) { - java_class_iterator End = javaClasses.end(); - java_class_iterator I = javaClasses.find(cl); - if (I == End) { - Class* javaClass = cl->classLoader->bootstrapLoader->upcalls->newClass; - LLVMClassInfo* LCI = (LLVMClassInfo*)getClassInfo(javaClass); - const llvm::Type* Ty = LCI->getVirtualType(); - - GlobalVariable* varGV = - new GlobalVariable(Ty->getContainedType(0), false, - GlobalValue::InternalLinkage, 0, "", this); - - Constant* res = ConstantExpr::getCast(Instruction::BitCast, varGV, - JavaObjectType); - - javaClasses.insert(std::make_pair(cl, res)); - varGV->setInitializer(CreateConstantFromJavaClass(cl)); - return res; - } else { - return I->second; - } - - } else { - JavaObject* obj = cl->getClassDelegatee(JavaThread::get()->getJVM()); - assert(obj && "Delegatee not created"); - Constant* CI = ConstantInt::get(Type::Int64Ty, uint64(obj)); - return ConstantExpr::getIntToPtr(CI, JavaObjectType); - } -} - -JavaObject* JnjvmModule::getFinalObject(llvm::Value* obj) { - if (staticCompilation) { - // TODO - } else { - if (ConstantExpr* CE = dyn_cast(obj)) { - if (ConstantInt* C = dyn_cast(CE->getOperand(0))) { - return (JavaObject*)C->getZExtValue(); - } - } - } - return 0; -} - - - -Constant* JnjvmModule::getFinalObject(JavaObject* obj) { - if (staticCompilation) { - final_object_iterator End = finalObjects.end(); - final_object_iterator I = finalObjects.find(obj); - if (I == End) { - abort(); - return 0; - } else { - return I->second; - } - - } else { - Constant* CI = ConstantInt::get(Type::Int64Ty, uint64(obj)); - return ConstantExpr::getIntToPtr(CI, JavaObjectType); - } -} - -Constant* JnjvmModule::CreateConstantFromStaticInstance(Class* cl) { - LLVMClassInfo* LCI = getClassInfo(cl); - const Type* Ty = LCI->getStaticType(); - const StructType* STy = dyn_cast(Ty->getContainedType(0)); - - std::vector Elts; - - for (uint32 i = 0; i < cl->nbStaticFields; ++i) { - JavaField& field = cl->staticFields[i]; - const Typedef* type = field.getSignature(); - LLVMAssessorInfo& LAI = getTypedefInfo(type); - const Type* Ty = LAI.llvmType; - - Attribut* attribut = field.lookupAttribut(Attribut::constantAttribut); - - if (!attribut) { - Elts.push_back(Constant::getNullValue(Ty)); - } else { - Reader reader(attribut, cl->bytes); - JavaConstantPool * ctpInfo = cl->ctpInfo; - uint16 idx = reader.readU2(); - if (type->isPrimitive()) { - if (Ty == Type::Int64Ty) { - Elts.push_back(ConstantInt::get(Ty, (uint64)ctpInfo->LongAt(idx))); - } else if (Ty == Type::DoubleTy) { - Elts.push_back(ConstantFP::get(Ty, ctpInfo->DoubleAt(idx))); - } else if (Ty == Type::FloatTy) { - Elts.push_back(ConstantFP::get(Ty, ctpInfo->FloatAt(idx))); - } else { - Elts.push_back(ConstantInt::get(Ty, (uint64)ctpInfo->IntegerAt(idx))); - } - } else if (type->isReference()){ - const UTF8* utf8 = ctpInfo->UTF8At(ctpInfo->ctpDef[idx]); - JavaString* obj = ctpInfo->resolveString(utf8, idx); - Constant* C = getString(obj); - C = ConstantExpr::getBitCast(C, JavaObjectType); - Elts.push_back(C); - } else { - fprintf(stderr, "Implement me"); - abort(); - } - } - } - - return ConstantStruct::get(STy, Elts); -} - -Constant* JnjvmModule::getStaticInstance(Class* classDef) { -#ifdef ISOLATE - assert(0 && "Should not be here"); - abort(); -#endif - if (staticCompilation) { - static_instance_iterator End = staticInstances.end(); - static_instance_iterator I = staticInstances.find(classDef); - if (I == End) { - - LLVMClassInfo* LCI = getClassInfo(classDef); - const Type* Ty = LCI->getStaticType(); - Ty = Ty->getContainedType(0); - GlobalVariable* varGV = - new GlobalVariable(Ty, false, GlobalValue::ExternalLinkage, - 0, classDef->printString(""), this); - - Constant* res = ConstantExpr::getCast(Instruction::BitCast, varGV, - ptrType); - staticInstances.insert(std::make_pair(classDef, res)); - - if (isCompiling(classDef)) { - Constant* C = CreateConstantFromStaticInstance(classDef); - varGV->setInitializer(C); - } - - return res; - } else { - return I->second; - } - - } else { - void* obj = ((Class*)classDef)->getStaticInstance(); - if (!obj) { - Class* cl = (Class*)classDef; - classDef->acquire(); - obj = cl->getStaticInstance(); - if (!obj) { - // Allocate now so that compiled code can reference it. - obj = cl->allocateStaticInstance(JavaThread::get()->getJVM()); - } - classDef->release(); - } - Constant* CI = ConstantInt::get(Type::Int64Ty, (uint64_t(obj))); - return ConstantExpr::getIntToPtr(CI, ptrType); - } -} - -Constant* JnjvmModule::getVirtualTable(Class* classDef) { - LLVMClassInfo* LCI = getClassInfo((Class*)classDef); - LCI->getVirtualType(); - if (staticCompilation) { - llvm::Constant* res = 0; - virtual_table_iterator End = virtualTables.end(); - virtual_table_iterator I = virtualTables.find(classDef); - if (I == End) { - - const ArrayType* ATy = dyn_cast(VTType->getContainedType(0)); - const PointerType* PTy = dyn_cast(ATy->getContainedType(0)); - ATy = ArrayType::get(PTy, classDef->virtualTableSize); - // Do not set a virtual table as a constant, because the runtime may - // modify it. - GlobalVariable* varGV = new GlobalVariable(ATy, false, - GlobalValue::ExternalLinkage, - 0, - classDef->printString(""), - this); - - res = ConstantExpr::getCast(Instruction::BitCast, varGV, VTType); - virtualTables.insert(std::make_pair(classDef, res)); - - if (isCompiling(classDef)) { - Constant* C = CreateConstantFromVT(classDef); - varGV->setInitializer(C); - } - - return res; - } else { - return I->second; - } - - } else { - assert(classDef->virtualVT && "Virtual VT not created"); - void* ptr = classDef->virtualVT; - ConstantInt* CI = ConstantInt::get(Type::Int64Ty, uint64_t(ptr)); - return ConstantExpr::getIntToPtr(CI, VTType); - } -} - -Constant* JnjvmModule::getNativeFunction(JavaMethod* meth, void* ptr) { - if (staticCompilation) { - llvm::Constant* varGV = 0; - native_function_iterator End = nativeFunctions.end(); - native_function_iterator I = nativeFunctions.find(meth); - if (I == End) { - - LLVMSignatureInfo* LSI = getSignatureInfo(meth->getSignature()); - const llvm::Type* valPtrType = LSI->getNativePtrType(); - - varGV = new GlobalVariable(valPtrType, true, - GlobalValue::InternalLinkage, - Constant::getNullValue(valPtrType), "", this); - - nativeFunctions.insert(std::make_pair(meth, varGV)); - return varGV; - } else { - return I->second; - } - - } else { - LLVMSignatureInfo* LSI = getSignatureInfo(meth->getSignature()); - const llvm::Type* valPtrType = LSI->getNativePtrType(); - - assert(ptr && "No native function given"); - - Constant* CI = ConstantInt::get(Type::Int64Ty, uint64_t(ptr)); - return ConstantExpr::getIntToPtr(CI, valPtrType); - } -} - -#ifndef WITHOUT_VTABLE -void JnjvmModule::allocateVT(Class* cl) { - for (uint32 i = 0; i < cl->nbVirtualMethods; ++i) { - JavaMethod& meth = cl->virtualMethods[i]; - if (meth.name->equals(cl->classLoader->bootstrapLoader->finalize)) { - meth.offset = 0; - } else { - JavaMethod* parent = cl->super? - cl->super->lookupMethodDontThrow(meth.name, meth.type, false, true, - 0) : - 0; - - uint64_t offset = 0; - if (!parent) { - offset = cl->virtualTableSize++; - meth.offset = offset; - } else { - offset = parent->offset; - meth.offset = parent->offset; - } - } - } - - VirtualTable* VT = 0; - if (cl->super) { - uint64 size = cl->virtualTableSize; - mvm::BumpPtrAllocator& allocator = cl->classLoader->allocator; - VT = (VirtualTable*)allocator.Allocate(size * sizeof(void*)); - Class* super = (Class*)cl->super; - assert(cl->virtualTableSize >= cl->super->virtualTableSize && - "Super VT bigger than own VT"); - assert(super->virtualVT && "Super does not have a VT!"); - memcpy(VT, super->virtualVT, cl->super->virtualTableSize * sizeof(void*)); - } else { - VT = JavaObjectVT; - } - - cl->virtualVT = VT; -} -#endif - - -#ifdef WITH_TRACER -llvm::Function* JnjvmModule::makeTracer(Class* cl, bool stat) { - - if (isStaticCompiling() && !generateTracers) { - return JavaObjectTracerFunction; - } - - LLVMClassInfo* LCI = (LLVMClassInfo*)getClassInfo(cl); - const Type* type = stat ? LCI->getStaticType() : LCI->getVirtualType(); - JavaField* fields = 0; - uint32 nbFields = 0; - if (stat) { - fields = cl->getStaticFields(); - nbFields = cl->nbStaticFields; - } else { - fields = cl->getVirtualFields(); - nbFields = cl->nbVirtualFields; - } - - Function* func = Function::Create(JnjvmModule::MarkAndTraceType, - GlobalValue::InternalLinkage, - "", - this); - - Constant* zero = mvm::MvmModule::constantZero; - Argument* arg = func->arg_begin(); - BasicBlock* block = BasicBlock::Create("", func); - llvm::Value* realArg = new BitCastInst(arg, type, "", block); - - std::vector Args; - Args.push_back(arg); -#ifdef MULTIPLE_GC - Value* GC = ++func->arg_begin(); - Args.push_back(GC); -#endif - if (!stat) { - if (cl->super == 0) { - CallInst::Create(JavaObjectTracerFunction, Args.begin(), Args.end(), - "", block); - - } else { - LLVMClassInfo* LCP = (LLVMClassInfo*)getClassInfo((Class*)(cl->super)); - Function* F = LCP->virtualTracerFunction; - if (!F) { - if (isStaticCompiling()) { - F = makeTracer(cl->super, false); - } else { - F = LCP->getVirtualTracer(); - } - assert(F && "Still no virtual tracer for super"); - } - CallInst::Create(F, Args.begin(), Args.end(), "", block); - } - } - - for (uint32 i = 0; i < nbFields; ++i) { - JavaField& cur = fields[i]; - if (cur.getSignature()->trace()) { - LLVMFieldInfo* LFI = getFieldInfo(&cur); - std::vector args; //size = 2 - args.push_back(zero); - args.push_back(LFI->getOffset()); - Value* ptr = GetElementPtrInst::Create(realArg, args.begin(), args.end(), - "",block); - Value* val = new LoadInst(ptr, "", block); - Value* valCast = new BitCastInst(val, JnjvmModule::JavaObjectType, "", - block); - std::vector Args; - Args.push_back(valCast); -#ifdef MULTIPLE_GC - Args.push_back(GC); -#endif - CallInst::Create(JnjvmModule::MarkAndTraceFunction, Args.begin(), - Args.end(), "", block); - } - } - - ReturnInst::Create(block); - - if (!stat) { - LCI->virtualTracerFunction = func; - } else { - LCI->staticTracerFunction = func; - } - - return func; -} -#endif - -Constant* JnjvmModule::CreateConstantForBaseObject(CommonClass* cl) { - const StructType* STy = - dyn_cast(JavaObjectType->getContainedType(0)); - - std::vector Elmts; - - // virtual table - if (cl->isClass()) { - Elmts.push_back(getVirtualTable(cl->asClass())); - } else { - ClassArray* clA = cl->asArrayClass(); - if (clA->baseClass()->isPrimitive()) { - Elmts.push_back(PrimitiveArrayVT); - } else { - Elmts.push_back(ReferenceArrayVT); - } - } - - // classof - Constant* Cl = getNativeClass(cl); - Constant* ClGEPs[2] = { constantZero, constantZero }; - Cl = ConstantExpr::getGetElementPtr(Cl, ClGEPs, 2); - - Elmts.push_back(Cl); - - // lock - Constant* L = ConstantInt::get(Type::Int64Ty, - JavaThread::get()->getThreadID()); - Elmts.push_back(ConstantExpr::getIntToPtr(L, ptrType)); - - return ConstantStruct::get(STy, Elmts); -} - -Constant* JnjvmModule::CreateConstantFromJavaClass(CommonClass* cl) { - Class* javaClass = cl->classLoader->bootstrapLoader->upcalls->newClass; - LLVMClassInfo* LCI = (LLVMClassInfo*)getClassInfo(javaClass); - const StructType* STy = - dyn_cast(LCI->getVirtualType()->getContainedType(0)); - - std::vector Elmts; - - // JavaObject - Elmts.push_back(CreateConstantForBaseObject(javaClass)); - - // signers - Elmts.push_back(Constant::getNullValue(JavaObjectType)); - - // pd - Elmts.push_back(Constant::getNullValue(JavaObjectType)); - - // vmdata - Constant* Cl = getNativeClass(cl); - Cl = ConstantExpr::getCast(Instruction::BitCast, Cl, JavaObjectType); - Elmts.push_back(Cl); - - // constructor - Elmts.push_back(Constant::getNullValue(JavaObjectType)); - - return ConstantStruct::get(STy, Elmts); -} - -Constant* JnjvmModule::CreateConstantFromJavaObject(JavaObject* obj) { - CommonClass* cl = obj->getClass(); - - if (cl->isArray()) { - Classpath* upcalls = cl->classLoader->bootstrapLoader->upcalls; - CommonClass* subClass = cl->asArrayClass()->baseClass(); - if (subClass->isPrimitive()) { - if (subClass == upcalls->OfBool) { - return CreateConstantFromArray((ArrayUInt8*)obj, - Type::Int8Ty); - } else if (subClass == upcalls->OfByte) { - return CreateConstantFromArray((ArraySInt8*)obj, - Type::Int8Ty); - } else if (subClass == upcalls->OfShort) { - return CreateConstantFromArray((ArraySInt16*)obj, - Type::Int16Ty); - } else if (subClass == upcalls->OfChar) { - return CreateConstantFromArray((ArrayUInt16*)obj, - Type::Int16Ty); - } else if (subClass == upcalls->OfInt) { - return CreateConstantFromArray((ArraySInt32*)obj, - Type::Int32Ty); - } else if (subClass == upcalls->OfFloat) { - return CreateConstantFromArray((ArrayFloat*)obj, - Type::FloatTy); - } else if (subClass == upcalls->OfLong) { - return CreateConstantFromArray((ArrayLong*)obj, - Type::Int64Ty); - } else if (subClass == upcalls->OfDouble) { - return CreateConstantFromArray((ArrayDouble*)obj, - Type::DoubleTy); - } else { - abort(); - } - } else { - return CreateConstantFromArray((ArrayObject*)obj, - JavaObjectType); - } - } else { - - std::vector Elmts; - - // JavaObject - Constant* CurConstant = CreateConstantForBaseObject(obj->getClass()); - - for (uint32 j = 0; j <= cl->depth; ++j) { - std::vector TempElts; - Elmts.push_back(CurConstant); - TempElts.push_back(CurConstant); - Class* curCl = cl->display[j]->asClass(); - LLVMClassInfo* LCI = getClassInfo(curCl); - const StructType* STy = - dyn_cast(LCI->getVirtualType()->getContainedType(0)); - - for (uint32 i = 0; i < curCl->nbVirtualFields; ++i) { - JavaField& field = curCl->virtualFields[i]; - const Typedef* type = field.getSignature(); - if (type->isPrimitive()) { - const PrimitiveTypedef* prim = (PrimitiveTypedef*)type; - if (prim->isBool() || prim->isByte()) { - ConstantInt* CI = ConstantInt::get(Type::Int8Ty, - field.getInt8Field(obj)); - TempElts.push_back(CI); - } else if (prim->isShort() || prim->isChar()) { - ConstantInt* CI = ConstantInt::get(Type::Int16Ty, - field.getInt16Field(obj)); - TempElts.push_back(CI); - } else if (prim->isInt()) { - ConstantInt* CI = ConstantInt::get(Type::Int32Ty, - field.getInt32Field(obj)); - TempElts.push_back(CI); - } else if (prim->isLong()) { - ConstantInt* CI = ConstantInt::get(Type::Int64Ty, - field.getLongField(obj)); - TempElts.push_back(CI); - } else if (prim->isFloat()) { - ConstantInt* CI = ConstantInt::get(Type::FloatTy, - field.getFloatField(obj)); - TempElts.push_back(CI); - } else if (prim->isDouble()) { - ConstantInt* CI = ConstantInt::get(Type::DoubleTy, - field.getDoubleField(obj)); - TempElts.push_back(CI); - } else { - abort(); - } - } else { - Constant* C = getFinalObject(field.getObjectField(obj)); - TempElts.push_back(C); - } - } - CurConstant = ConstantStruct::get(STy, TempElts); - } - - return CurConstant; - } -} - -Constant* JnjvmModule::CreateConstantFromJavaString(JavaString* str) { - Class* cl = (Class*)str->getClass(); - LLVMClassInfo* LCI = (LLVMClassInfo*)getClassInfo(cl); - const StructType* STy = - dyn_cast(LCI->getVirtualType()->getContainedType(0)); - - std::vector Elmts; - - Elmts.push_back(CreateConstantForBaseObject(cl)); - - Constant* Array = getUTF8(str->value); - Constant* ObjGEPs[2] = { constantZero, constantZero }; - Array = ConstantExpr::getGetElementPtr(Array, ObjGEPs, 2); - Elmts.push_back(Array); - - Elmts.push_back(ConstantInt::get(Type::Int32Ty, str->count)); - Elmts.push_back(ConstantInt::get(Type::Int32Ty, str->cachedHashCode)); - Elmts.push_back(ConstantInt::get(Type::Int32Ty, str->offset)); - - return ConstantStruct::get(STy, Elmts); -} - - -Constant* JnjvmModule::CreateConstantFromCacheNode(CacheNode* CN) { - const StructType* STy = - dyn_cast(CacheNodeType->getContainedType(0)); - - std::vector Elmts; - Elmts.push_back(Constant::getNullValue(STy->getContainedType(0))); - Elmts.push_back(Constant::getNullValue(STy->getContainedType(1))); - Elmts.push_back(Constant::getNullValue(STy->getContainedType(2))); - Elmts.push_back(getEnveloppe(CN->enveloppe)); - - return ConstantStruct::get(STy, Elmts); -} - -Constant* JnjvmModule::CreateConstantFromEnveloppe(Enveloppe* val) { - - const StructType* STy = - dyn_cast(EnveloppeType->getContainedType(0)); - const StructType* CNTy = - dyn_cast(CacheNodeType->getContainedType(0)); - - std::vector Elmts; - - Constant* firstCache = CreateConstantFromCacheNode(val->firstCache); - Elmts.push_back(new GlobalVariable(CNTy, false, - GlobalValue::InternalLinkage, - firstCache, "", this)); - Elmts.push_back(getUTF8(val->methodName)); - Elmts.push_back(getUTF8(val->methodSign)); - - Elmts.push_back(Constant::getNullValue(Type::Int8Ty)); - Elmts.push_back(getNativeClass(val->classDef)); - Elmts.push_back(firstCache); - - return ConstantStruct::get(STy, Elmts); - -} - -Constant* JnjvmModule::CreateConstantFromAttribut(Attribut& attribut) { - const StructType* STy = - dyn_cast(AttributType->getContainedType(0)); - - - std::vector Elmts; - - // name - Elmts.push_back(getUTF8(attribut.name)); - - // start - Elmts.push_back(ConstantInt::get(Type::Int32Ty, attribut.start)); - - // nbb - Elmts.push_back(ConstantInt::get(Type::Int32Ty, attribut.nbb)); - - return ConstantStruct::get(STy, Elmts); -} - -Constant* JnjvmModule::CreateConstantFromCommonClass(CommonClass* cl) { - const StructType* STy = - dyn_cast(JavaCommonClassType->getContainedType(0)); - - const ArrayType* ATy = ArrayType::get(JavaCommonClassType, cl->depth + 1); - - std::vector CommonClassElts; - std::vector TempElmts; - Constant* ClGEPs[2] = { constantZero, constantZero }; - - // display - for (uint32 i = 0; i <= cl->depth; ++i) { - Constant* Cl = getNativeClass(cl->display[i]); - if (Cl->getType() != JavaCommonClassType) - Cl = ConstantExpr::getGetElementPtr(Cl, ClGEPs, 2); - - TempElmts.push_back(Cl); - } - - Constant* display = ConstantArray::get(ATy, TempElmts); - TempElmts.clear(); - display = new GlobalVariable(ATy, true, GlobalValue::InternalLinkage, - display, "", this); - display = ConstantExpr::getCast(Instruction::BitCast, display, - PointerType::getUnqual(JavaCommonClassType)); - CommonClassElts.push_back(display); - - // depth - CommonClassElts.push_back(ConstantInt::get(Type::Int32Ty, cl->depth)); - - // delegatee - ATy = dyn_cast(STy->getContainedType(2)); - assert(ATy && "Malformed type"); - - Constant* TCM[1] = { getJavaClass(cl) }; - CommonClassElts.push_back(ConstantArray::get(ATy, TCM, 1)); - - // access - CommonClassElts.push_back(ConstantInt::get(Type::Int16Ty, cl->access)); - - // interfaces - if (cl->nbInterfaces) { - for (uint32 i = 0; i < cl->nbInterfaces; ++i) { - TempElmts.push_back(getNativeClass(cl->interfaces[i])); - } - - ATy = ArrayType::get(JavaClassType, cl->nbInterfaces); - Constant* interfaces = ConstantArray::get(ATy, TempElmts); - interfaces = new GlobalVariable(ATy, true, GlobalValue::InternalLinkage, - interfaces, "", this); - interfaces = ConstantExpr::getCast(Instruction::BitCast, interfaces, - PointerType::getUnqual(JavaClassType)); - - CommonClassElts.push_back(interfaces); - } else { - const Type* Ty = PointerType::getUnqual(JavaClassType); - CommonClassElts.push_back(Constant::getNullValue(Ty)); - } - - // nbInterfaces - CommonClassElts.push_back(ConstantInt::get(Type::Int16Ty, cl->nbInterfaces)); - - // name - CommonClassElts.push_back(getUTF8(cl->name)); - - // super - if (cl->super) { - CommonClassElts.push_back(getNativeClass(cl->super)); - } else { - CommonClassElts.push_back(Constant::getNullValue(JavaClassType)); - } - - // classLoader: store the static initializer, it will be overriden once - // the class is loaded. - Constant* loader = ConstantExpr::getBitCast(StaticInitializer, ptrType); - CommonClassElts.push_back(loader); - - return ConstantStruct::get(STy, CommonClassElts); -} - -Constant* JnjvmModule::CreateConstantFromJavaField(JavaField& field) { - const StructType* STy = - dyn_cast(JavaFieldType->getContainedType(0)); - - std::vector FieldElts; - std::vector TempElts; - - // signature - FieldElts.push_back(Constant::getNullValue(ptrType)); - - // access - FieldElts.push_back(ConstantInt::get(Type::Int16Ty, field.access)); - - // name - FieldElts.push_back(getUTF8(field.name)); - - // type - FieldElts.push_back(getUTF8(field.type)); - - // attributs - if (field.nbAttributs) { - const ArrayType* ATy = ArrayType::get(AttributType->getContainedType(0), - field.nbAttributs); - for (uint32 i = 0; i < field.nbAttributs; ++i) { - TempElts.push_back(CreateConstantFromAttribut(field.attributs[i])); - } - - Constant* attributs = ConstantArray::get(ATy, TempElts); - TempElts.clear(); - attributs = new GlobalVariable(ATy, true, GlobalValue::InternalLinkage, - attributs, "", this); - attributs = ConstantExpr::getCast(Instruction::BitCast, attributs, - AttributType); - - FieldElts.push_back(attributs); - } else { - FieldElts.push_back(Constant::getNullValue(AttributType)); - } - - // nbAttributs - FieldElts.push_back(ConstantInt::get(Type::Int16Ty, field.nbAttributs)); - - // classDef - FieldElts.push_back(getNativeClass(field.classDef)); - - // ptrOffset - FieldElts.push_back(ConstantInt::get(Type::Int32Ty, field.ptrOffset)); - - // num - FieldElts.push_back(ConstantInt::get(Type::Int16Ty, field.num)); - - //JInfo - FieldElts.push_back(Constant::getNullValue(ptrType)); - - return ConstantStruct::get(STy, FieldElts); -} - -Constant* JnjvmModule::CreateConstantFromJavaMethod(JavaMethod& method) { - const StructType* STy = - dyn_cast(JavaMethodType->getContainedType(0)); - - std::vector MethodElts; - std::vector TempElts; - - // signature - MethodElts.push_back(Constant::getNullValue(ptrType)); - - // access - MethodElts.push_back(ConstantInt::get(Type::Int16Ty, method.access)); - - // attributs - if (method.nbAttributs) { - const ArrayType* ATy = ArrayType::get(AttributType->getContainedType(0), - method.nbAttributs); - for (uint32 i = 0; i < method.nbAttributs; ++i) { - TempElts.push_back(CreateConstantFromAttribut(method.attributs[i])); - } - - Constant* attributs = ConstantArray::get(ATy, TempElts); - TempElts.clear(); - attributs = new GlobalVariable(ATy, true, GlobalValue::InternalLinkage, - attributs, "", this); - attributs = ConstantExpr::getCast(Instruction::BitCast, attributs, - AttributType); - - MethodElts.push_back(attributs); - } else { - MethodElts.push_back(Constant::getNullValue(AttributType)); - } - - // nbAttributs - MethodElts.push_back(ConstantInt::get(Type::Int16Ty, method.nbAttributs)); - - // enveloppes - // already allocated by the JIT, don't reallocate them. - MethodElts.push_back(Constant::getNullValue(EnveloppeType)); - - // nbEnveloppes - // 0 because we're not allocating here. - MethodElts.push_back(ConstantInt::get(Type::Int16Ty, 0)); - - // classDef - MethodElts.push_back(getNativeClass(method.classDef)); - - // name - MethodElts.push_back(getUTF8(method.name)); - - // type - MethodElts.push_back(getUTF8(method.type)); - - // canBeInlined - MethodElts.push_back(ConstantInt::get(Type::Int8Ty, method.canBeInlined)); - - // code - if (isAbstract(method.access)) { - MethodElts.push_back(Constant::getNullValue(ptrType)); - } else { - LLVMMethodInfo* LMI = getMethodInfo(&method); - Function* func = LMI->getMethod(); - MethodElts.push_back(ConstantExpr::getCast(Instruction::BitCast, func, - ptrType)); - } - - // offset - MethodElts.push_back(ConstantInt::get(Type::Int32Ty, method.offset)); - - //JInfo - MethodElts.push_back(Constant::getNullValue(ptrType)); - - return ConstantStruct::get(STy, MethodElts); -} - -Constant* JnjvmModule::CreateConstantFromClassPrimitive(ClassPrimitive* cl) { - const StructType* STy = - dyn_cast(JavaClassPrimitiveType->getContainedType(0)); - - std::vector ClassElts; - - // common class - ClassElts.push_back(CreateConstantFromCommonClass(cl)); - - // primSize - ClassElts.push_back(ConstantInt::get(Type::Int32Ty, cl->primSize)); - - return ConstantStruct::get(STy, ClassElts); -} - -Constant* JnjvmModule::CreateConstantFromClassArray(ClassArray* cl) { - const StructType* STy = - dyn_cast(JavaClassArrayType->getContainedType(0)); - - std::vector ClassElts; - Constant* ClGEPs[2] = { constantZero, constantZero }; - - // common class - ClassElts.push_back(CreateConstantFromCommonClass(cl)); - - // baseClass - Constant* Cl = getNativeClass(cl->baseClass()); - if (Cl->getType() != JavaCommonClassType) - Cl = ConstantExpr::getGetElementPtr(Cl, ClGEPs, 2); - - ClassElts.push_back(Cl); - - return ConstantStruct::get(STy, ClassElts); -} - -Constant* JnjvmModule::CreateConstantFromClass(Class* cl) { - const StructType* STy = - dyn_cast(JavaClassType->getContainedType(0)); - - std::vector ClassElts; - std::vector TempElts; - - // common class - ClassElts.push_back(CreateConstantFromCommonClass(cl)); - - // virtualSize - ClassElts.push_back(ConstantInt::get(Type::Int32Ty, cl->virtualSize)); - - // virtualTable - ClassElts.push_back(getVirtualTable(cl)); - - // IsolateInfo - const ArrayType* ATy = dyn_cast(STy->getContainedType(3)); - assert(ATy && "Malformed type"); - - const StructType* TCMTy = dyn_cast(ATy->getContainedType(0)); - assert(TCMTy && "Malformed type"); - - uint32 status = cl->needsInitialisationCheck() ? vmjc : ready; - TempElts.push_back(ConstantInt::get(Type::Int8Ty, status)); - TempElts.push_back(ConstantInt::get(Type::Int1Ty, status == ready ? 1 : 0)); - TempElts.push_back(getStaticInstance(cl)); - Constant* CStr[1] = { ConstantStruct::get(TCMTy, TempElts) }; - TempElts.clear(); - ClassElts.push_back(ConstantArray::get(ATy, CStr, 1)); - - // thinlock - ClassElts.push_back(Constant::getNullValue(ptrType)); - - if (cl->nbVirtualFields + cl->nbStaticFields) { - ATy = ArrayType::get(JavaFieldType->getContainedType(0), - cl->nbVirtualFields + cl->nbStaticFields); - } - - // virtualFields - if (cl->nbVirtualFields) { - - for (uint32 i = 0; i < cl->nbVirtualFields; ++i) { - TempElts.push_back(CreateConstantFromJavaField(cl->virtualFields[i])); - } - - } - - // staticFields - if (cl->nbStaticFields) { - - for (uint32 i = 0; i < cl->nbStaticFields; ++i) { - TempElts.push_back(CreateConstantFromJavaField(cl->staticFields[i])); - } - - } - - Constant* fields = 0; - if (cl->nbStaticFields + cl->nbVirtualFields) { - - fields = ConstantArray::get(ATy, TempElts); - TempElts.clear(); - fields = new GlobalVariable(ATy, false, GlobalValue::InternalLinkage, - fields, "", this); - fields = ConstantExpr::getCast(Instruction::BitCast, fields, JavaFieldType); - } else { - fields = Constant::getNullValue(JavaFieldType); - } - - // virtualFields - ClassElts.push_back(fields); - - ConstantInt* nbVirtualFields = - ConstantInt::get(Type::Int16Ty, cl->nbVirtualFields); - // nbVirtualFields - ClassElts.push_back(nbVirtualFields); - - // staticFields - // Output null, this will be set in the initializer. Otherwise, the - // assembly emitter of LLVM will try to align the data. - ClassElts.push_back(Constant::getNullValue(JavaFieldType)); - - // nbStaticFields - ClassElts.push_back(ConstantInt::get(Type::Int16Ty, cl->nbStaticFields)); - - // virtualMethods - if (cl->nbVirtualMethods + cl->nbStaticMethods) { - ATy = ArrayType::get(JavaMethodType->getContainedType(0), - cl->nbVirtualMethods + cl->nbStaticMethods); - } - - if (cl->nbVirtualMethods) { - for (uint32 i = 0; i < cl->nbVirtualMethods; ++i) { - TempElts.push_back(CreateConstantFromJavaMethod(cl->virtualMethods[i])); - } - } - - if (cl->nbStaticMethods) { - for (uint32 i = 0; i < cl->nbStaticMethods; ++i) { - TempElts.push_back(CreateConstantFromJavaMethod(cl->staticMethods[i])); - } - } - - Constant* methods = 0; - if (cl->nbVirtualMethods + cl->nbStaticMethods) { - methods = ConstantArray::get(ATy, TempElts); - TempElts.clear(); - GlobalVariable* GV = new GlobalVariable(ATy, false, - GlobalValue::InternalLinkage, - methods, "", this); - virtualMethods.insert(std::make_pair(cl, GV)); - methods = ConstantExpr::getCast(Instruction::BitCast, GV, - JavaMethodType); - } else { - methods = Constant::getNullValue(JavaMethodType); - } - - // virtualMethods - ClassElts.push_back(methods); - - ConstantInt* nbVirtualMethods = - ConstantInt::get(Type::Int16Ty, cl->nbVirtualMethods); - // nbVirtualMethods - ClassElts.push_back(nbVirtualMethods); - - // staticMethods - // Output null, this will be set in the initializer. - ClassElts.push_back(Constant::getNullValue(JavaMethodType)); - - // nbStaticMethods - ClassElts.push_back(ConstantInt::get(Type::Int16Ty, cl->nbStaticMethods)); - - // ownerClass - ClassElts.push_back(Constant::getNullValue(ptrType)); - - // bytes - ClassElts.push_back(Constant::getNullValue(JavaArrayUInt8Type)); - - // ctpInfo - ClassElts.push_back(Constant::getNullValue(ptrType)); - - // attributs - if (cl->nbAttributs) { - ATy = ArrayType::get(AttributType->getContainedType(0), - cl->nbAttributs); - - for (uint32 i = 0; i < cl->nbAttributs; ++i) { - TempElts.push_back(CreateConstantFromAttribut(cl->attributs[i])); - } - - Constant* attributs = ConstantArray::get(ATy, TempElts); - TempElts.clear(); - attributs = new GlobalVariable(ATy, true, GlobalValue::InternalLinkage, - attributs, "", this); - attributs = ConstantExpr::getCast(Instruction::BitCast, attributs, - AttributType); - ClassElts.push_back(attributs); - } else { - ClassElts.push_back(Constant::getNullValue(AttributType)); - } - - // nbAttributs - ClassElts.push_back(ConstantInt::get(Type::Int16Ty, cl->nbAttributs)); - - // innerClasses - if (cl->nbInnerClasses) { - for (uint32 i = 0; i < cl->nbInnerClasses; ++i) { - TempElts.push_back(getNativeClass(cl->innerClasses[i])); - } - - ATy = ArrayType::get(JavaClassType, cl->nbInnerClasses); - Constant* innerClasses = ConstantArray::get(ATy, TempElts); - innerClasses = new GlobalVariable(ATy, true, GlobalValue::InternalLinkage, - innerClasses, "", this); - innerClasses = ConstantExpr::getCast(Instruction::BitCast, innerClasses, - PointerType::getUnqual(JavaClassType)); - - ClassElts.push_back(innerClasses); - } else { - const Type* Ty = PointerType::getUnqual(JavaClassType); - ClassElts.push_back(Constant::getNullValue(Ty)); - } - - // nbInnerClasses - ClassElts.push_back(ConstantInt::get(Type::Int16Ty, cl->nbInnerClasses)); - - // outerClass - if (cl->outerClass) { - ClassElts.push_back(getNativeClass(cl->outerClass)); - } else { - ClassElts.push_back(Constant::getNullValue(JavaClassType)); - } - - // innerAccess - ClassElts.push_back(ConstantInt::get(Type::Int16Ty, cl->innerAccess)); - - // innerOuterResolved - ClassElts.push_back(ConstantInt::get(Type::Int8Ty, cl->innerOuterResolved)); - - // virtualTableSize - ClassElts.push_back(ConstantInt::get(Type::Int32Ty, cl->virtualTableSize)); - - // staticSize - ClassElts.push_back(ConstantInt::get(Type::Int32Ty, cl->staticSize)); - - // JInfo - ClassElts.push_back(Constant::getNullValue(ptrType)); - - // staticTracer - const Type* FTy = STy->getContainedType(STy->getNumContainedTypes() - 1); -#ifdef WITH_TRACER - Function* F = makeTracer(cl, true); - Constant* staticTracer = ConstantExpr::getCast(Instruction::BitCast, F, FTy); -#else - Constant* staticTracer = ConstantExpr::getNullValue(FTy); -#endif - ClassElts.push_back(staticTracer); - - - return ConstantStruct::get(STy, ClassElts); -} - -template -Constant* JnjvmModule::CreateConstantFromArray(T* val, const llvm::Type* Ty) { - std::vector Elemts; - const ArrayType* ATy = ArrayType::get(Ty, val->size); - Elemts.push_back(JavaObjectType->getContainedType(0)); - Elemts.push_back(pointerSizeType == Type::Int32Ty ? Type::Int32Ty : - Type::Int64Ty); - - Elemts.push_back(ATy); - - const StructType* STy = StructType::get(Elemts); - - std::vector Cts; - Cts.push_back(CreateConstantForBaseObject(val->getClass())); - Cts.push_back(ConstantInt::get(pointerSizeType, val->size)); - - std::vector Vals; - for (sint32 i = 0; i < val->size; ++i) { - if (Ty->isInteger()) { - Vals.push_back(ConstantInt::get(Ty, (uint64)val->elements[i])); - } else if (Ty->isFloatingPoint()) { - Vals.push_back(ConstantFP::get(Ty, (double)(size_t)val->elements[i])); - } else { - Vals.push_back(getFinalObject((JavaObject*)(size_t)val->elements[i])); - } - } - - Cts.push_back(ConstantArray::get(ATy, Vals)); - - return ConstantStruct::get(STy, Cts); -} - -Constant* JnjvmModule::CreateConstantFromUTF8(const UTF8* val) { - std::vector Elemts; - const ArrayType* ATy = ArrayType::get(Type::Int16Ty, val->size); - Elemts.push_back(JavaObjectType->getContainedType(0)); - Elemts.push_back(pointerSizeType == Type::Int32Ty ? Type::Int32Ty : - Type::Int64Ty); - - Elemts.push_back(ATy); - - const StructType* STy = StructType::get(Elemts); - - std::vector Cts; - Cts.push_back(CreateConstantForBaseObject(&ArrayOfChar)); - Cts.push_back(ConstantInt::get(pointerSizeType, val->size)); - - std::vector Vals; - for (sint32 i = 0; i < val->size; ++i) { - Vals.push_back(ConstantInt::get(Type::Int16Ty, val->elements[i])); - } - - Cts.push_back(ConstantArray::get(ATy, Vals)); - - return ConstantStruct::get(STy, Cts); - -} - -Constant* JnjvmModule::getUTF8(const UTF8* val) { - utf8_iterator End = utf8s.end(); - utf8_iterator I = utf8s.find(val); - if (I == End) { - Constant* C = CreateConstantFromUTF8(val); - GlobalVariable* varGV = new GlobalVariable(C->getType(), true, - GlobalValue::InternalLinkage, - C, "", this); - - Constant* res = ConstantExpr::getCast(Instruction::BitCast, varGV, - UTF8Type); - utf8s.insert(std::make_pair(val, res)); - - return res; - } else { - return I->second; - } -} - -Constant* JnjvmModule::CreateConstantFromVT(Class* classDef) { - uint32 size = classDef->virtualTableSize; - VirtualTable* VT = classDef->virtualVT; - const ArrayType* ATy = dyn_cast(VTType->getContainedType(0)); - const PointerType* PTy = dyn_cast(ATy->getContainedType(0)); - ATy = ArrayType::get(PTy, size); - - ConstantPointerNull* N = ConstantPointerNull::get(PTy); - std::vector Elemts; - - // Destructor - JavaMethod* meth = ((JavaMethod**)VT)[0]; - LLVMMethodInfo* LMI = getMethodInfo(meth); - Function* Finalizer = LMI->getMethod(); - Elemts.push_back(Finalizer ? - ConstantExpr::getCast(Instruction::BitCast, Finalizer, PTy) : N); - - // Delete - Elemts.push_back(N); - - // Tracer -#ifdef WITH_TRACER - Function* Tracer = makeTracer(classDef, false); - Elemts.push_back(Tracer ? - ConstantExpr::getCast(Instruction::BitCast, Tracer, PTy) : N); -#else - Elemts.push_back(N); -#endif - - // Printer - Elemts.push_back(ConstantExpr::getBitCast(ObjectPrinter, PTy)); - - // Hashcode - Elemts.push_back(N); - - for (uint32 i = VT_NB_FUNCS; i < size; ++i) { - JavaMethod* meth = ((JavaMethod**)VT)[i]; - LLVMMethodInfo* LMI = getMethodInfo(meth); - Function* F = LMI->getMethod(); - if (isAbstract(meth->access)) { - Elemts.push_back(Constant::getNullValue(PTy)); - } else { - Elemts.push_back(ConstantExpr::getCast(Instruction::BitCast, F, PTy)); - } - } - - Constant* Array = ConstantArray::get(ATy, Elemts); - - return Array; -} - -void JnjvmModule::makeVT(Class* cl) { - - VirtualTable* VT = 0; -#ifdef WITHOUT_VTABLE - mvm::BumpPtrAllocator& allocator = cl->classLoader->allocator; - VT = (VirtualTable*)allocator.Allocate(VT_SIZE); - memcpy(VT, JavaObjectVT, VT_SIZE); - cl->virtualVT = VT; -#else - if (cl->super) { - if (isStaticCompiling() && !cl->super->virtualVT) { - makeVT(cl->super); - } - - cl->virtualTableSize = cl->super->virtualTableSize; - } else { - cl->virtualTableSize = VT_NB_FUNCS; - } - - // Allocate the virtual table. - allocateVT(cl); - VT = cl->virtualVT; - - if (!staticCompilation) { - // Fill the virtual table with function pointers. - ExecutionEngine* EE = mvm::MvmModule::executionEngine; - for (uint32 i = 0; i < cl->nbVirtualMethods; ++i) { - JavaMethod& meth = cl->virtualMethods[i]; - LLVMMethodInfo* LMI = getMethodInfo(&meth); - Function* func = LMI->getMethod(); - - // Special handling for finalize method. Don't put a finalizer - // if there is none, or if it is empty. - if (meth.offset == 0) { -#if defined(ISOLATE_SHARING) || defined(USE_GC_BOEHM) - ((void**)VT)[0] = 0; -#else - JnjvmClassLoader* loader = cl->classLoader; - Function* func = loader->getModuleProvider()->parseFunction(&meth); - if (!cl->super) { - meth.canBeInlined = true; - ((void**)VT)[0] = 0; - } else { - Function::iterator BB = func->begin(); - BasicBlock::iterator I = BB->begin(); - if (isa(I)) { - ((void**)VT)[0] = 0; - } else { - // LLVM does not allow recursive compilation. Create the code now. - ((void**)VT)[0] = EE->getPointerToFunction(func); - } - } -#endif - } else { - ((void**)VT)[meth.offset] = EE->getPointerToFunctionOrStub(func); - } - } - -#ifdef WITH_TRACER - Function* func = makeTracer(cl, false); - - void* codePtr = mvm::MvmModule::executionEngine->getPointerToFunction(func); - ((void**)VT)[VT_TRACER_OFFSET] = codePtr; - func->deleteBody(); -#endif - - // If there is no super, then it's the first VT that we allocate. Assign - // this VT to native types. - if (!(cl->super)) { - ClassArray::initialiseVT(cl); - } - - } else { - for (uint32 i = 0; i < cl->nbVirtualMethods; ++i) { - JavaMethod& meth = cl->virtualMethods[i]; - ((void**)VT)[meth.offset] = &meth; - } - } - -#endif - -} - - -const Type* LLVMClassInfo::getVirtualType() { - if (!virtualType) { - std::vector fields; - - if (classDef->super && classDef->super->super) { - LLVMClassInfo* CLI = - JnjvmModule::getClassInfo((Class*)classDef->super); - fields.push_back(CLI->getVirtualType()->getContainedType(0)); - } else { - fields.push_back(JnjvmModule::JavaObjectType->getContainedType(0)); - } - - for (uint32 i = 0; i < classDef->nbVirtualFields; ++i) { - JavaField& field = classDef->virtualFields[i]; - field.num = i + 1; - Typedef* type = field.getSignature(); - LLVMAssessorInfo& LAI = JnjvmModule::getTypedefInfo(type); - fields.push_back(LAI.llvmType); - } - - - JnjvmModule* Mod = classDef->classLoader->getModule(); - StructType* structType = StructType::get(fields, false); - virtualType = PointerType::getUnqual(structType); - const TargetData* targetData = Mod->TheTargetData; - const StructLayout* sl = targetData->getStructLayout(structType); - - for (uint32 i = 0; i < classDef->nbVirtualFields; ++i) { - JavaField& field = classDef->virtualFields[i]; - field.ptrOffset = sl->getElementOffset(i + 1); - } - - uint64 size = Mod->getTypeSize(structType); - classDef->virtualSize = (uint32)size; - virtualSizeConstant = ConstantInt::get(Type::Int32Ty, size); - - if (!Mod->isStaticCompiling()) { - if (!classDef->virtualVT) { - Mod->makeVT((Class*)classDef); - } else { -#ifdef WITH_TRACER - // So the class is vmjc'ed. Create the virtual tracer. - Function* func = Function::Create(JnjvmModule::MarkAndTraceType, - GlobalValue::ExternalLinkage, - "markAndTraceObject", Mod); - - void* ptr = ((void**)classDef->virtualVT)[VT_TRACER_OFFSET]; - Mod->executionEngine->addGlobalMapping(func, ptr); - virtualTracerFunction = func; -#endif - } - } else { - Mod->makeVT(classDef); - } - - } - - return virtualType; -} - -const Type* LLVMClassInfo::getStaticType() { - - if (!staticType) { - Class* cl = (Class*)classDef; - std::vector fields; - - for (uint32 i = 0; i < classDef->nbStaticFields; ++i) { - JavaField& field = classDef->staticFields[i]; - field.num = i; - Typedef* type = field.getSignature(); - LLVMAssessorInfo& LAI = JnjvmModule::getTypedefInfo(type); - fields.push_back(LAI.llvmType); - } - - JnjvmModule* Mod = cl->classLoader->getModule(); - StructType* structType = StructType::get(fields, false); - staticType = PointerType::getUnqual(structType); - const TargetData* targetData = Mod->TheTargetData; - const StructLayout* sl = targetData->getStructLayout(structType); - - for (uint32 i = 0; i < classDef->nbStaticFields; ++i) { - JavaField& field = classDef->staticFields[i]; - field.ptrOffset = sl->getElementOffset(i); - } - - uint64 size = Mod->getTypeSize(structType); - cl->staticSize = size; -#ifdef WITH_TRACER - if (!Mod->isStaticCompiling()) { - Function* F = Mod->makeTracer(cl, true); - cl->staticTracer = (void (*)(void*)) (uintptr_t) - Mod->executionEngine->getPointerToFunction(F); - F->deleteBody(); - } -#endif - } - return staticType; -} - - -Value* LLVMClassInfo::getVirtualSize() { - if (!virtualSizeConstant) { - getVirtualType(); - assert(classDef->virtualSize && "Zero size for a class?"); - virtualSizeConstant = - ConstantInt::get(Type::Int32Ty, classDef->virtualSize); - } - return virtualSizeConstant; -} - -Function* LLVMClassInfo::getStaticTracer() { - if (!staticTracerFunction) { - getStaticType(); - } - return staticTracerFunction; -} - -Function* LLVMClassInfo::getVirtualTracer() { - if (!virtualTracerFunction) { - getVirtualType(); - } - return virtualTracerFunction; -} - -Function* LLVMMethodInfo::getMethod() { - if (!methodFunction) { - JnjvmClassLoader* JCL = methodDef->classDef->classLoader; - JnjvmModule* Mod = JCL->getModule(); - if (Mod->isStaticCompiling()) { - - const UTF8* jniConsClName = methodDef->classDef->name; - const UTF8* jniConsName = methodDef->name; - const UTF8* jniConsType = methodDef->type; - sint32 clen = jniConsClName->size; - sint32 mnlen = jniConsName->size; - sint32 mtlen = jniConsType->size; - - char* buf = (char*)alloca(3 + JNI_NAME_PRE_LEN + 1 + - ((mnlen + clen + mtlen) << 1)); - - bool jnjvm = false; - if (isNative(methodDef->access)) { - // Verify if it's defined by JnJVM - JCL->nativeLookup(methodDef, jnjvm, buf); - } - - if (!jnjvm) { - methodDef->jniConsFromMethOverloaded(buf + 1); - memcpy(buf, "JnJVM", 5); - } - - methodFunction = Function::Create(getFunctionType(), - GlobalValue::GhostLinkage, buf, Mod); - - } else { - - methodFunction = Function::Create(getFunctionType(), - GlobalValue::GhostLinkage, - "", Mod); - - } - methodFunction->addAnnotation(this); - } - return methodFunction; -} - -const FunctionType* LLVMMethodInfo::getFunctionType() { - if (!functionType) { - Signdef* sign = methodDef->getSignature(); - LLVMSignatureInfo* LSI = JnjvmModule::getSignatureInfo(sign); - assert(LSI); - if (isStatic(methodDef->access)) { - functionType = LSI->getStaticType(); - } else { - functionType = LSI->getVirtualType(); - } - } - return functionType; -} - -ConstantInt* LLVMMethodInfo::getOffset() { - if (!offsetConstant) { - JnjvmModule::resolveVirtualClass(methodDef->classDef); - offsetConstant = ConstantInt::get(Type::Int32Ty, methodDef->offset); - } - return offsetConstant; -} - -ConstantInt* LLVMFieldInfo::getOffset() { - if (!offsetConstant) { - if (isStatic(fieldDef->access)) { - JnjvmModule::resolveStaticClass(fieldDef->classDef); - } else { - JnjvmModule::resolveVirtualClass(fieldDef->classDef); - } - - offsetConstant = ConstantInt::get(Type::Int32Ty, fieldDef->num); - } - return offsetConstant; -} - -const llvm::FunctionType* LLVMSignatureInfo::getVirtualType() { - if (!virtualType) { - // Lock here because we are called by arbitrary code - mvm::MvmModule::protectIR(); - std::vector llvmArgs; - uint32 size = signature->nbArguments; - Typedef* const* arguments = signature->getArgumentsType(); - - llvmArgs.push_back(JnjvmModule::JavaObjectType); - - for (uint32 i = 0; i < size; ++i) { - Typedef* type = arguments[i]; - LLVMAssessorInfo& LAI = JnjvmModule::getTypedefInfo(type); - llvmArgs.push_back(LAI.llvmType); - } - -#if defined(ISOLATE_SHARING) - llvmArgs.push_back(JnjvmModule::ConstantPoolType); // cached constant pool -#endif - - LLVMAssessorInfo& LAI = - JnjvmModule::getTypedefInfo(signature->getReturnType()); - virtualType = FunctionType::get(LAI.llvmType, llvmArgs, false); - mvm::MvmModule::unprotectIR(); - } - return virtualType; -} - -const llvm::FunctionType* LLVMSignatureInfo::getStaticType() { - if (!staticType) { - // Lock here because we are called by arbitrary code - mvm::MvmModule::protectIR(); - std::vector llvmArgs; - uint32 size = signature->nbArguments; - Typedef* const* arguments = signature->getArgumentsType(); - - for (uint32 i = 0; i < size; ++i) { - Typedef* type = arguments[i]; - LLVMAssessorInfo& LAI = JnjvmModule::getTypedefInfo(type); - llvmArgs.push_back(LAI.llvmType); - } +llvm::ConstantInt* JnjvmModule::JavaObjectLockOffsetConstant; +llvm::ConstantInt* JnjvmModule::JavaObjectClassOffsetConstant; -#if defined(ISOLATE_SHARING) - llvmArgs.push_back(JnjvmModule::ConstantPoolType); // cached constant pool -#endif - LLVMAssessorInfo& LAI = - JnjvmModule::getTypedefInfo(signature->getReturnType()); - staticType = FunctionType::get(LAI.llvmType, llvmArgs, false); - mvm::MvmModule::unprotectIR(); - } - return staticType; -} +#ifndef WITHOUT_VTABLE +void JnjvmModule::allocateVT(Class* cl) { + for (uint32 i = 0; i < cl->nbVirtualMethods; ++i) { + JavaMethod& meth = cl->virtualMethods[i]; + if (meth.name->equals(cl->classLoader->bootstrapLoader->finalize)) { + meth.offset = 0; + } else { + JavaMethod* parent = cl->super? + cl->super->lookupMethodDontThrow(meth.name, meth.type, false, true, + 0) : + 0; -const llvm::FunctionType* LLVMSignatureInfo::getNativeType() { - if (!nativeType) { - // Lock here because we are called by arbitrary code - mvm::MvmModule::protectIR(); - std::vector llvmArgs; - uint32 size = signature->nbArguments; - Typedef* const* arguments = signature->getArgumentsType(); - - llvmArgs.push_back(mvm::MvmModule::ptrType); // JNIEnv - llvmArgs.push_back(JnjvmModule::JavaObjectType); // Class - - for (uint32 i = 0; i < size; ++i) { - Typedef* type = arguments[i]; - LLVMAssessorInfo& LAI = JnjvmModule::getTypedefInfo(type); - llvmArgs.push_back(LAI.llvmType); + uint64_t offset = 0; + if (!parent) { + offset = cl->virtualTableSize++; + meth.offset = offset; + } else { + offset = parent->offset; + meth.offset = parent->offset; + } } - -#if defined(ISOLATE_SHARING) - llvmArgs.push_back(JnjvmModule::ConstantPoolType); // cached constant pool -#endif - - LLVMAssessorInfo& LAI = - JnjvmModule::getTypedefInfo(signature->getReturnType()); - nativeType = FunctionType::get(LAI.llvmType, llvmArgs, false); - mvm::MvmModule::unprotectIR(); } - return nativeType; -} - - -Function* LLVMSignatureInfo::createFunctionCallBuf(bool virt) { - - std::vector Args; - JnjvmModule* Mod = signature->initialLoader->getModule(); - const char* name = 0; - if (Mod->isStaticCompiling()) { - name = virt ? signature->printString("virtual_buf") : - signature->printString("static_buf"); + VirtualTable* VT = 0; + if (cl->super) { + uint64 size = cl->virtualTableSize; + mvm::BumpPtrAllocator& allocator = cl->classLoader->allocator; + VT = (VirtualTable*)allocator.Allocate(size * sizeof(void*)); + Class* super = (Class*)cl->super; + assert(cl->virtualTableSize >= cl->super->virtualTableSize && + "Super VT bigger than own VT"); + assert(super->virtualVT && "Super does not have a VT!"); + memcpy(VT, super->virtualVT, cl->super->virtualTableSize * sizeof(void*)); } else { - name = ""; - } - - Function* res = Function::Create(virt ? getVirtualBufType() : - getStaticBufType(), - GlobalValue::InternalLinkage, name, Mod); - - BasicBlock* currentBlock = BasicBlock::Create("enter", res); - Function::arg_iterator i = res->arg_begin(); - Value *obj, *ptr, *func; -#if defined(ISOLATE_SHARING) - Value* ctp = i; -#endif - ++i; - func = i; - ++i; - if (virt) { - obj = i; - ++i; - Args.push_back(obj); - } - ptr = i; - - Typedef* const* arguments = signature->getArgumentsType(); - for (uint32 i = 0; i < signature->nbArguments; ++i) { - - LLVMAssessorInfo& LAI = JnjvmModule::getTypedefInfo(arguments[i]); - Value* val = new BitCastInst(ptr, LAI.llvmTypePtr, "", currentBlock); - Value* arg = new LoadInst(val, "", currentBlock); - Args.push_back(arg); - ptr = GetElementPtrInst::Create(ptr, JnjvmModule::constantEight, "", - currentBlock); + VT = JavaObjectVT; } -#if defined(ISOLATE_SHARING) - Args.push_back(ctp); + cl->virtualVT = VT; +} #endif - Value* val = CallInst::Create(func, Args.begin(), Args.end(), "", - currentBlock); - if (res->getFunctionType()->getReturnType() != Type::VoidTy) - ReturnInst::Create(val, currentBlock); - else - ReturnInst::Create(currentBlock); - - return res; -} -Function* LLVMSignatureInfo::createFunctionCallAP(bool virt) { - - std::vector Args; +#ifdef WITH_TRACER +llvm::Function* JnjvmModule::internalMakeTracer(Class* cl, bool stat) { - JnjvmModule* Mod = signature->initialLoader->getModule(); - const char* name = 0; - if (Mod->isStaticCompiling()) { - name = virt ? signature->printString("virtual_ap") : - signature->printString("static_ap"); + LLVMClassInfo* LCI = (LLVMClassInfo*)getClassInfo(cl); + const Type* type = stat ? LCI->getStaticType() : LCI->getVirtualType(); + JavaField* fields = 0; + uint32 nbFields = 0; + if (stat) { + fields = cl->getStaticFields(); + nbFields = cl->nbStaticFields; } else { - name = ""; + fields = cl->getVirtualFields(); + nbFields = cl->nbVirtualFields; } - - Function* res = Function::Create(virt ? getVirtualBufType() : - getStaticBufType(), - GlobalValue::InternalLinkage, name, Mod); - BasicBlock* currentBlock = BasicBlock::Create("enter", res); - Function::arg_iterator i = res->arg_begin(); - Value *obj, *ap, *func; -#if defined(ISOLATE_SHARING) - Value* ctp = i; -#endif - ++i; - func = i; - ++i; - if (virt) { - obj = i; - Args.push_back(obj); - ++i; - } - ap = i; + Function* func = Function::Create(JnjvmModule::MarkAndTraceType, + GlobalValue::InternalLinkage, + "", getLLVMModule()); - Typedef* const* arguments = signature->getArgumentsType(); - for (uint32 i = 0; i < signature->nbArguments; ++i) { - LLVMAssessorInfo& LAI = JnjvmModule::getTypedefInfo(arguments[i]); - Args.push_back(new VAArgInst(ap, LAI.llvmType, "", currentBlock)); - } + Constant* zero = mvm::MvmModule::constantZero; + Argument* arg = func->arg_begin(); + BasicBlock* block = BasicBlock::Create("", func); + llvm::Value* realArg = new BitCastInst(arg, type, "", block); -#if defined(ISOLATE_SHARING) - Args.push_back(ctp); + std::vector Args; + Args.push_back(arg); +#ifdef MULTIPLE_GC + Value* GC = ++func->arg_begin(); + Args.push_back(GC); #endif + if (!stat) { + if (cl->super == 0) { + CallInst::Create(JavaObjectTracerFunction, Args.begin(), Args.end(), + "", block); - Value* val = CallInst::Create(func, Args.begin(), Args.end(), "", - currentBlock); - if (res->getFunctionType()->getReturnType() != Type::VoidTy) - ReturnInst::Create(val, currentBlock); - else - ReturnInst::Create(currentBlock); - - return res; -} - -const PointerType* LLVMSignatureInfo::getStaticPtrType() { - if (!staticPtrType) { - staticPtrType = PointerType::getUnqual(getStaticType()); - } - return staticPtrType; -} - -const PointerType* LLVMSignatureInfo::getVirtualPtrType() { - if (!virtualPtrType) { - virtualPtrType = PointerType::getUnqual(getVirtualType()); + } else { + LLVMClassInfo* LCP = (LLVMClassInfo*)getClassInfo((Class*)(cl->super)); + Function* F = LCP->virtualTracerFunction; + if (!F) { + if (isStaticCompiling()) { + F = internalMakeTracer(cl->super, false); + } else { + F = LCP->getVirtualTracer(); + } + assert(F && "Still no virtual tracer for super"); + } + CallInst::Create(F, Args.begin(), Args.end(), "", block); + } } - return virtualPtrType; -} - -const PointerType* LLVMSignatureInfo::getNativePtrType() { - if (!nativePtrType) { - nativePtrType = PointerType::getUnqual(getNativeType()); + + for (uint32 i = 0; i < nbFields; ++i) { + JavaField& cur = fields[i]; + if (cur.getSignature()->trace()) { + LLVMFieldInfo* LFI = getFieldInfo(&cur); + std::vector args; //size = 2 + args.push_back(zero); + args.push_back(LFI->getOffset()); + Value* ptr = GetElementPtrInst::Create(realArg, args.begin(), args.end(), + "",block); + Value* val = new LoadInst(ptr, "", block); + Value* valCast = new BitCastInst(val, JnjvmModule::JavaObjectType, "", + block); + std::vector Args; + Args.push_back(valCast); +#ifdef MULTIPLE_GC + Args.push_back(GC); +#endif + CallInst::Create(JnjvmModule::MarkAndTraceFunction, Args.begin(), + Args.end(), "", block); + } } - return nativePtrType; -} - -const FunctionType* LLVMSignatureInfo::getVirtualBufType() { - if (!virtualBufType) { - // Lock here because we are called by arbitrary code - mvm::MvmModule::protectIR(); - std::vector Args2; - Args2.push_back(JnjvmModule::ConstantPoolType); // ctp - Args2.push_back(getVirtualPtrType()); - Args2.push_back(JnjvmModule::JavaObjectType); - Args2.push_back(JnjvmModule::ptrType); - LLVMAssessorInfo& LAI = - JnjvmModule::getTypedefInfo(signature->getReturnType()); - virtualBufType = FunctionType::get(LAI.llvmType, Args2, false); - mvm::MvmModule::unprotectIR(); + ReturnInst::Create(block); + + if (!stat) { + LCI->virtualTracerFunction = func; + } else { + LCI->staticTracerFunction = func; } - return virtualBufType; -} -const FunctionType* LLVMSignatureInfo::getStaticBufType() { - if (!staticBufType) { - // Lock here because we are called by arbitrary code - mvm::MvmModule::protectIR(); - std::vector Args; - Args.push_back(JnjvmModule::ConstantPoolType); // ctp - Args.push_back(getStaticPtrType()); - Args.push_back(JnjvmModule::ptrType); - LLVMAssessorInfo& LAI = - JnjvmModule::getTypedefInfo(signature->getReturnType()); - staticBufType = FunctionType::get(LAI.llvmType, Args, false); - mvm::MvmModule::unprotectIR(); - } - return staticBufType; + return func; } +#endif -Function* LLVMSignatureInfo::getVirtualBuf() { - if (!virtualBufFunction) { - // Lock here because we are called by arbitrary code - mvm::MvmModule::protectIR(); - virtualBufFunction = createFunctionCallBuf(true); - if (!signature->initialLoader->getModule()->isStaticCompiling()) { - signature->setVirtualCallBuf((intptr_t) - mvm::MvmModule::executionEngine->getPointerToGlobal(virtualBufFunction)); - // Now that it's compiled, we don't need the IR anymore - virtualBufFunction->deleteBody(); - } - mvm::MvmModule::unprotectIR(); - } - return virtualBufFunction; -} -Function* LLVMSignatureInfo::getVirtualAP() { - if (!virtualAPFunction) { - // Lock here because we are called by arbitrary code - mvm::MvmModule::protectIR(); - virtualAPFunction = createFunctionCallAP(true); - if (!signature->initialLoader->getModule()->isStaticCompiling()) { - signature->setVirtualCallAP((intptr_t) - mvm::MvmModule::executionEngine->getPointerToGlobal(virtualAPFunction)); - // Now that it's compiled, we don't need the IR anymore - virtualAPFunction->deleteBody(); +void JnjvmModule::internalMakeVT(Class* cl) { + + VirtualTable* VT = 0; +#ifdef WITHOUT_VTABLE + mvm::BumpPtrAllocator& allocator = cl->classLoader->allocator; + VT = (VirtualTable*)allocator.Allocate(VT_SIZE); + memcpy(VT, JavaObjectVT, VT_SIZE); + cl->virtualVT = VT; +#else + if (cl->super) { + if (isStaticCompiling() && !cl->super->virtualVT) { + makeVT(cl->super); } - mvm::MvmModule::unprotectIR(); - } - return virtualAPFunction; -} -Function* LLVMSignatureInfo::getStaticBuf() { - if (!staticBufFunction) { - // Lock here because we are called by arbitrary code - mvm::MvmModule::protectIR(); - staticBufFunction = createFunctionCallBuf(false); - if (!signature->initialLoader->getModule()->isStaticCompiling()) { - signature->setStaticCallBuf((intptr_t) - mvm::MvmModule::executionEngine->getPointerToGlobal(staticBufFunction)); - // Now that it's compiled, we don't need the IR anymore - staticBufFunction->deleteBody(); - } - mvm::MvmModule::unprotectIR(); + cl->virtualTableSize = cl->super->virtualTableSize; + } else { + cl->virtualTableSize = VT_NB_FUNCS; } - return staticBufFunction; -} -Function* LLVMSignatureInfo::getStaticAP() { - if (!staticAPFunction) { - // Lock here because we are called by arbitrary code - mvm::MvmModule::protectIR(); - staticAPFunction = createFunctionCallAP(false); - if (!signature->initialLoader->getModule()->isStaticCompiling()) { - signature->setStaticCallAP((intptr_t) - mvm::MvmModule::executionEngine->getPointerToGlobal(staticAPFunction)); - // Now that it's compiled, we don't need the IR anymore - staticAPFunction->deleteBody(); - } - mvm::MvmModule::unprotectIR(); - } - return staticAPFunction; + // Allocate the virtual table. + allocateVT(cl); + VT = cl->virtualVT; +#endif } void JnjvmModule::resolveVirtualClass(Class* cl) { @@ -2102,12 +258,9 @@ } } -Module* JnjvmModule::initialModule; - void JnjvmModule::initialise() { - jnjvm::llvm_runtime::makeLLVMModuleContents(this); - Module* module = this; - initialModule = this; + jnjvm::llvm_runtime::makeLLVMModuleContents(getLLVMModule()); + Module* module = getLLVMModule(); VTType = PointerType::getUnqual(module->getTypeByName("VT")); @@ -2201,68 +354,6 @@ ClassReadyConstant = ConstantInt::get(Type::Int8Ty, ready); - - if (staticCompilation) { - const Type* ATy = VTType->getContainedType(0); - PrimitiveArrayVT = new GlobalVariable(ATy, true, - GlobalValue::ExternalLinkage, - 0, "JavaArrayVT", this); - - ReferenceArrayVT = new GlobalVariable(ATy, true, - GlobalValue::ExternalLinkage, - 0, "ArrayObjectVT", this); - - - - ATy = JavaClassArrayType->getContainedType(0); - GlobalVariable* varGV = 0; - -#define PRIMITIVE_ARRAY(name) \ - varGV = new GlobalVariable(ATy, true, GlobalValue::ExternalLinkage, \ - 0, #name, this); \ - arrayClasses.insert(std::make_pair(&name, varGV)); - - PRIMITIVE_ARRAY(ArrayOfBool) - PRIMITIVE_ARRAY(ArrayOfByte) - PRIMITIVE_ARRAY(ArrayOfChar) - PRIMITIVE_ARRAY(ArrayOfShort) - PRIMITIVE_ARRAY(ArrayOfInt) - PRIMITIVE_ARRAY(ArrayOfFloat) - PRIMITIVE_ARRAY(ArrayOfDouble) - PRIMITIVE_ARRAY(ArrayOfLong) - -#undef PRIMITIVE_ARRAY - - std::vector llvmArgs; - llvmArgs.push_back(ptrType); // class loader. - const FunctionType* FTy = FunctionType::get(Type::VoidTy, llvmArgs, false); - - StaticInitializer = Function::Create(FTy, GlobalValue::InternalLinkage, - "Init", this); - - llvmArgs.clear(); - llvmArgs.push_back(JavaMethodType); - - FTy = FunctionType::get(ptrType, llvmArgs, false); - - NativeLoader = Function::Create(FTy, GlobalValue::ExternalLinkage, - "vmjcNativeLoader", this); - - llvmArgs.clear(); - FTy = FunctionType::get(Type::VoidTy, llvmArgs, false); - ObjectPrinter = Function::Create(FTy, GlobalValue::ExternalLinkage, - "printJavaObject", this); - - } else { - PrimitiveArrayVT = ConstantExpr::getIntToPtr(ConstantInt::get(Type::Int64Ty, - uint64(JavaArrayVT)), - VTType); - - ReferenceArrayVT = ConstantExpr::getIntToPtr(ConstantInt::get(Type::Int64Ty, - uint64(ArrayObjectVT)), - VTType); - } - LLVMAssessorInfo::initialise(); } @@ -2274,59 +365,41 @@ return PrimitiveArrayVT; } -void JnjvmModule::setMethod(JavaMethod* meth, void* ptr, const char* name) { - Function* func = getMethodInfo(meth)->getMethod(); - func->setName(name); - assert(ptr && "No value given"); - if (executionEngine) executionEngine->addGlobalMapping(func, ptr); - func->setLinkage(GlobalValue::ExternalLinkage); -} - -void JnjvmModule::printStats() { - fprintf(stderr, "----------------- Info from the module -----------------\n"); - fprintf(stderr, "Number of native classes : %llu\n", - (unsigned long long int) nativeClasses.size()); - fprintf(stderr, "Number of Java classes : %llu\n", - (unsigned long long int) javaClasses.size()); - fprintf(stderr, "Number of external array classes : %llu\n", - (unsigned long long int) arrayClasses.size()); - fprintf(stderr, "Number of virtual tables : %llu\n", - (unsigned long long int) virtualTables.size()); - fprintf(stderr, "Number of static instances : %llu\n", - (unsigned long long int) staticInstances.size()); - fprintf(stderr, "Number of constant pools : %llu\n", - (unsigned long long int) constantPools.size()); - fprintf(stderr, "Number of strings : %llu\n", - (unsigned long long int) strings.size()); - fprintf(stderr, "Number of enveloppes : %llu\n", - (unsigned long long int) enveloppes.size()); - fprintf(stderr, "Number of native functions : %llu\n", - (unsigned long long int) nativeFunctions.size()); - fprintf(stderr, "----------------- Total size in .data ------------------\n"); - uint64 size = 0; - for (Module::const_global_iterator i = global_begin(), e = global_end(); - i != e; ++i) { - size += getTypeSize(i->getType()); - } - fprintf(stderr, "%lluB\n", (unsigned long long int)size); -} - - Function* JnjvmModule::getMethod(JavaMethod* meth) { return getMethodInfo(meth)->getMethod(); } -JnjvmModule::JnjvmModule(const std::string &ModuleID, bool sc) : +JnjvmModule::JnjvmModule(const std::string &ModuleID, JnjvmModule* Father) : MvmModule(ModuleID) { - staticCompilation = sc; - generateTracers = true; - generateStubs = true; - enabledException = true; - assumeCompiled = false; - if (!VTType) initialise(); - - Module* module = initialModule; + Module* module = 0; + if (!Father) { + assert(!VTType && "Attempting to create a new initial JnjvmModule"); + enabledException = true; + initialise(); + module = getLLVMModule(); + } else { + enabledException = Father->enabledException; + module = getLLVMModule(); + module->addTypeName("JavaObject", JavaObjectType); + module->addTypeName("JavaArray", JavaArrayType); + module->addTypeName("JavaCommonClass", JavaCommonClassType); + module->addTypeName("JavaClass", JavaClassType); + module->addTypeName("JavaClassPrimitive", JavaClassPrimitiveType); + module->addTypeName("JavaClassArray", JavaClassArrayType); + module->addTypeName("ArrayUInt8", JavaArrayUInt8Type); + module->addTypeName("ArraySInt8", JavaArraySInt8Type); + module->addTypeName("ArrayUInt16", JavaArrayUInt16Type); + module->addTypeName("ArraySInt16", JavaArraySInt16Type); + module->addTypeName("ArraySInt32", JavaArraySInt32Type); + module->addTypeName("ArrayLong", JavaArrayLongType); + module->addTypeName("ArrayFloat", JavaArrayFloatType); + module->addTypeName("ArrayDouble", JavaArrayDoubleType); + module->addTypeName("ArrayObject", JavaArrayObjectType); + module->addTypeName("CacheNode", CacheNodeType); + module->addTypeName("Enveloppe", EnveloppeType); + module = Father->getLLVMModule(); + } InterfaceLookupFunction = module->getFunction("jnjvmVirtualLookup"); MultiCallNewFunction = module->getFunction("multiCallNew"); @@ -2424,256 +497,5 @@ #endif GetLockFunction = module->getFunction("getLock"); - - addTypeName("JavaObject", JavaObjectType); - addTypeName("JavaArray", JavaArrayType); - addTypeName("JavaCommonClass", JavaCommonClassType); - addTypeName("JavaClass", JavaClassType); - addTypeName("JavaClassPrimitive", JavaClassPrimitiveType); - addTypeName("JavaClassArray", JavaClassArrayType); - addTypeName("ArrayUInt8", JavaArrayUInt8Type); - addTypeName("ArraySInt8", JavaArraySInt8Type); - addTypeName("ArrayUInt16", JavaArrayUInt16Type); - addTypeName("ArraySInt16", JavaArraySInt16Type); - addTypeName("ArraySInt32", JavaArraySInt32Type); - addTypeName("ArrayLong", JavaArrayLongType); - addTypeName("ArrayFloat", JavaArrayFloatType); - addTypeName("ArrayDouble", JavaArrayDoubleType); - addTypeName("ArrayObject", JavaArrayObjectType); - addTypeName("CacheNode", CacheNodeType); - addTypeName("Enveloppe", EnveloppeType); -} - -void LLVMAssessorInfo::initialise() { - AssessorInfo[I_VOID].llvmType = Type::VoidTy; - AssessorInfo[I_VOID].llvmTypePtr = 0; - AssessorInfo[I_VOID].llvmNullConstant = 0; - AssessorInfo[I_VOID].sizeInBytesConstant = 0; - - AssessorInfo[I_BOOL].llvmType = Type::Int8Ty; - AssessorInfo[I_BOOL].llvmTypePtr = PointerType::getUnqual(Type::Int8Ty); - AssessorInfo[I_BOOL].llvmNullConstant = - Constant::getNullValue(Type::Int8Ty); - AssessorInfo[I_BOOL].sizeInBytesConstant = mvm::MvmModule::constantOne; - - AssessorInfo[I_BYTE].llvmType = Type::Int8Ty; - AssessorInfo[I_BYTE].llvmTypePtr = PointerType::getUnqual(Type::Int8Ty); - AssessorInfo[I_BYTE].llvmNullConstant = - Constant::getNullValue(Type::Int8Ty); - AssessorInfo[I_BYTE].sizeInBytesConstant = mvm::MvmModule::constantOne; - - AssessorInfo[I_SHORT].llvmType = Type::Int16Ty; - AssessorInfo[I_SHORT].llvmTypePtr = PointerType::getUnqual(Type::Int16Ty); - AssessorInfo[I_SHORT].llvmNullConstant = - Constant::getNullValue(Type::Int16Ty); - AssessorInfo[I_SHORT].sizeInBytesConstant = mvm::MvmModule::constantTwo; - - AssessorInfo[I_CHAR].llvmType = Type::Int16Ty; - AssessorInfo[I_CHAR].llvmTypePtr = PointerType::getUnqual(Type::Int16Ty); - AssessorInfo[I_CHAR].llvmNullConstant = - Constant::getNullValue(Type::Int16Ty); - AssessorInfo[I_CHAR].sizeInBytesConstant = mvm::MvmModule::constantTwo; - - AssessorInfo[I_INT].llvmType = Type::Int32Ty; - AssessorInfo[I_INT].llvmTypePtr = PointerType::getUnqual(Type::Int32Ty); - AssessorInfo[I_INT].llvmNullConstant = - Constant::getNullValue(Type::Int32Ty); - AssessorInfo[I_INT].sizeInBytesConstant = mvm::MvmModule::constantFour; - - AssessorInfo[I_FLOAT].llvmType = Type::FloatTy; - AssessorInfo[I_FLOAT].llvmTypePtr = PointerType::getUnqual(Type::FloatTy); - AssessorInfo[I_FLOAT].llvmNullConstant = - Constant::getNullValue(Type::FloatTy); - AssessorInfo[I_FLOAT].sizeInBytesConstant = mvm::MvmModule::constantFour; - - AssessorInfo[I_LONG].llvmType = Type::Int64Ty; - AssessorInfo[I_LONG].llvmTypePtr = PointerType::getUnqual(Type::Int64Ty); - AssessorInfo[I_LONG].llvmNullConstant = - Constant::getNullValue(Type::Int64Ty); - AssessorInfo[I_LONG].sizeInBytesConstant = mvm::MvmModule::constantEight; - - AssessorInfo[I_DOUBLE].llvmType = Type::DoubleTy; - AssessorInfo[I_DOUBLE].llvmTypePtr = PointerType::getUnqual(Type::DoubleTy); - AssessorInfo[I_DOUBLE].llvmNullConstant = - Constant::getNullValue(Type::DoubleTy); - AssessorInfo[I_DOUBLE].sizeInBytesConstant = mvm::MvmModule::constantEight; - - AssessorInfo[I_TAB].llvmType = JnjvmModule::JavaObjectType; - AssessorInfo[I_TAB].llvmTypePtr = - PointerType::getUnqual(JnjvmModule::JavaObjectType); - AssessorInfo[I_TAB].llvmNullConstant = - JnjvmModule::JavaObjectNullConstant; - AssessorInfo[I_TAB].sizeInBytesConstant = mvm::MvmModule::constantPtrSize; - - AssessorInfo[I_REF].llvmType = JnjvmModule::JavaObjectType; - AssessorInfo[I_REF].llvmTypePtr = - PointerType::getUnqual(JnjvmModule::JavaObjectType); - AssessorInfo[I_REF].llvmNullConstant = - JnjvmModule::JavaObjectNullConstant; - AssessorInfo[I_REF].sizeInBytesConstant = mvm::MvmModule::constantPtrSize; -} - -std::map LLVMAssessorInfo::AssessorInfo; - -LLVMAssessorInfo& JnjvmModule::getTypedefInfo(const Typedef* type) { - return LLVMAssessorInfo::AssessorInfo[type->getKey()->elements[0]]; -} - -static AnnotationID JavaMethod_ID( - AnnotationManager::getID("Java::JavaMethod")); - - -LLVMMethodInfo::LLVMMethodInfo(JavaMethod* M) : - llvm::Annotation(JavaMethod_ID), methodDef(M), methodFunction(0), - offsetConstant(0), functionType(0) {} - -JavaMethod* LLVMMethodInfo::get(const llvm::Function* F) { - LLVMMethodInfo *MI = (LLVMMethodInfo*)F->getAnnotation(JavaMethod_ID); - if (MI) return MI->methodDef; - return 0; -} - -#ifdef SERVICE -Value* JnjvmModule::getIsolate(Jnjvm* isolate, Value* Where) { - if (staticCompilation) { - llvm::Constant* varGV = 0; - isolate_iterator End = isolates.end(); - isolate_iterator I = isolates.find(isolate); - if (I == End) { - - - Constant* cons = - ConstantExpr::getIntToPtr(ConstantInt::get(Type::Int64Ty, - uint64_t(isolate)), - ptrType); - - varGV = new GlobalVariable(ptrType, !staticCompilation, - GlobalValue::ExternalLinkage, - cons, "", this); - - isolates.insert(std::make_pair(isolate, varGV)); - } else { - varGV = I->second; - } - if (BasicBlock* BB = dyn_cast(Where)) { - return new LoadInst(varGV, "", BB); - } else { - assert(dyn_cast(Where) && "Wrong use of module"); - return new LoadInst(varGV, "", dyn_cast(Where)); - } - } else { - ConstantInt* CI = ConstantInt::get(Type::Int64Ty, uint64_t(isolate)); - return ConstantExpr::getIntToPtr(CI, ptrType); - } -} -#endif - -void JnjvmModule::CreateStaticInitializer() { - - std::vector llvmArgs; - llvmArgs.push_back(ptrType); // class loader - llvmArgs.push_back(JavaCommonClassType); // cl - const FunctionType* FTy = FunctionType::get(Type::VoidTy, llvmArgs, false); - - Function* AddClass = Function::Create(FTy, GlobalValue::ExternalLinkage, - "vmjcAddPreCompiledClass", this); - llvmArgs.clear(); - llvmArgs.push_back(ptrType); // class loader - llvmArgs.push_back(PointerType::getUnqual(JavaClassArrayType)); // array ptr - llvmArgs.push_back(UTF8Type); // name - FTy = FunctionType::get(Type::VoidTy, llvmArgs, false); - - Function* GetClassArray = Function::Create(FTy, GlobalValue::ExternalLinkage, - "vmjcGetClassArray", this); - - if (!StaticInitializer) { - std::vector llvmArgs; - llvmArgs.push_back(ptrType); // class loader. - const FunctionType* FTy = FunctionType::get(Type::VoidTy, llvmArgs, false); - - StaticInitializer = Function::Create(FTy, GlobalValue::InternalLinkage, - "Init", this); - } - - BasicBlock* currentBlock = BasicBlock::Create("enter", StaticInitializer); - Function::arg_iterator loader = StaticInitializer->arg_begin(); - - Value* Args[3]; - // If we have defined some strings. - if (strings.begin() != strings.end()) { - llvmArgs.clear(); - llvmArgs.push_back(ptrType); // class loader - llvmArgs.push_back(strings.begin()->second->getType()); // val - FTy = FunctionType::get(Type::VoidTy, llvmArgs, false); - - Function* AddString = Function::Create(FTy, GlobalValue::ExternalLinkage, - "vmjcAddString", this); - - - - for (string_iterator i = strings.begin(), e = strings.end(); i != e; ++i) { - Args[0] = loader; - Args[1] = i->second; - CallInst::Create(AddString, Args, Args + 2, "", currentBlock); - } - } - - for (native_class_iterator i = nativeClasses.begin(), - e = nativeClasses.end(); i != e; ++i) { - if (isCompiling(i->first)) { - Args[0] = loader; - Args[1] = ConstantExpr::getBitCast(i->second, JavaCommonClassType); - CallInst::Create(AddClass, Args, Args + 2, "", currentBlock); - } - } - - for (array_class_iterator i = arrayClasses.begin(), - e = arrayClasses.end(); i != e; ++i) { - if (!(i->first->baseClass()->isPrimitive())) { - Args[0] = loader; - Args[1] = i->second; - Args[2] = getUTF8(i->first->name); - CallInst::Create(GetClassArray, Args, Args + 3, "", currentBlock); - } - } - - - ReturnInst::Create(currentBlock); -} - -void JnjvmModule::setNoInline(Class* cl) { - for (uint32 i = 0; i < cl->nbVirtualMethods; ++i) { - JavaMethod& meth = cl->virtualMethods[i]; - if (!isAbstract(meth.access)) { - LLVMMethodInfo* LMI = getMethodInfo(&meth); - Function* func = LMI->getMethod(); - func->addFnAttr(Attribute::NoInline); - } - } - - for (uint32 i = 0; i < cl->nbStaticMethods; ++i) { - JavaMethod& meth = cl->staticMethods[i]; - if (!isAbstract(meth.access)) { - LLVMMethodInfo* LMI = getMethodInfo(&meth); - Function* func = LMI->getMethod(); - func->addFnAttr(Attribute::NoInline); - } - } -} - -LLVMSignatureInfo* JnjvmModule::getSignatureInfo(Signdef* sign) { - return sign->getInfo(); -} - -LLVMClassInfo* JnjvmModule::getClassInfo(Class* cl) { - return cl->getInfo(); -} - -LLVMFieldInfo* JnjvmModule::getFieldInfo(JavaField* field) { - return field->getInfo(); -} - -LLVMMethodInfo* JnjvmModule::getMethodInfo(JavaMethod* method) { - return method->getInfo(); } Added: vmkit/trunk/lib/JnJVM/Compiler/JnjvmModuleAOT.cpp URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/Compiler/JnjvmModuleAOT.cpp?rev=65555&view=auto ============================================================================== --- vmkit/trunk/lib/JnJVM/Compiler/JnjvmModuleAOT.cpp (added) +++ vmkit/trunk/lib/JnJVM/Compiler/JnjvmModuleAOT.cpp Thu Feb 26 12:44:00 2009 @@ -0,0 +1,1417 @@ +//===--------- JnjvmModule.cpp - Definition of a Jnjvm module -------------===// +// +// JnJVM +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/BasicBlock.h" +#include "llvm/Constants.h" +#include "llvm/Instructions.h" + +#include "mvm/Threads/Thread.h" + +#include "jnjvm/JnjvmModule.h" + +#include "JavaCache.h" +#include "JavaConstantPool.h" +#include "JavaString.h" +#include "JavaTypes.h" +#include "JavaUpcalls.h" +#include "Reader.h" + +#include + +using namespace jnjvm; +using namespace llvm; + +extern void* JavaArrayVT[]; +extern void* ArrayObjectVT[]; +extern void* JavaObjectVT[]; + +extern ClassArray ArrayOfBool; +extern ClassArray ArrayOfByte; +extern ClassArray ArrayOfChar; +extern ClassArray ArrayOfShort; +extern ClassArray ArrayOfInt; +extern ClassArray ArrayOfFloat; +extern ClassArray ArrayOfDouble; +extern ClassArray ArrayOfLong; + +bool JnjvmModuleAOT::isCompiling(const CommonClass* cl) const { + if (cl->isClass()) { + // A class is being static compiled if owner class is not null. + return (((Class*)cl)->getOwnerClass() != 0); + } else if (cl->isArray()) { + return isCompiling(((ClassArray*)cl)->baseClass()); + } else { + return false; + } +} + +Constant* JnjvmModuleAOT::getNativeClass(CommonClass* classDef) { + + if (classDef->isClass() || + (classDef->isArray() && isCompiling(classDef)) || + (assumeCompiled && !(classDef->isArray() && + classDef->asArrayClass()->baseClass()->isPrimitive()))) { + native_class_iterator End = nativeClasses.end(); + native_class_iterator I = nativeClasses.find(classDef); + if (I == End) { + const llvm::Type* Ty = 0; + + if (classDef->isArray()) { + Ty = JavaClassArrayType->getContainedType(0); + } else { + Ty = JavaClassType->getContainedType(0); + } + + GlobalVariable* varGV = + new GlobalVariable(Ty, false, GlobalValue::ExternalLinkage, 0, + classDef->printString(), getLLVMModule()); + + nativeClasses.insert(std::make_pair(classDef, varGV)); + + if (classDef->isClass() && isCompiling(classDef->asClass())) { + Constant* C = CreateConstantFromClass((Class*)classDef); + varGV->setInitializer(C); + } else if (classDef->isArray()) { + Constant* C = CreateConstantFromClassArray((ClassArray*)classDef); + varGV->setInitializer(C); + } + + return varGV; + + } else { + return I->second; + } + } else if (classDef->isArray()) { + array_class_iterator End = arrayClasses.end(); + array_class_iterator I = arrayClasses.find((ClassArray*)classDef); + if (I == End) { + const llvm::Type* Ty = JavaClassArrayType; + + GlobalVariable* varGV = + new GlobalVariable(Ty, false, GlobalValue::InternalLinkage, + Constant::getNullValue(Ty), + classDef->printString(), getLLVMModule()); + + arrayClasses.insert(std::make_pair((ClassArray*)classDef, varGV)); + return varGV; + } else { + return I->second; + } + } else if (classDef->isPrimitive()) { + assert(0 && "implement me"); + } + return 0; +} + +Constant* JnjvmModuleAOT::getConstantPool(JavaConstantPool* ctp) { + llvm::Constant* varGV = 0; + constant_pool_iterator End = constantPools.end(); + constant_pool_iterator I = constantPools.find(ctp); + if (I == End) { + const Type* Ty = ConstantPoolType->getContainedType(0); + varGV = new GlobalVariable(Ty, false, + GlobalValue::InternalLinkage, + Constant::getNullValue(Ty), "", getLLVMModule()); + constantPools.insert(std::make_pair(ctp, varGV)); + return varGV; + } else { + return I->second; + } +} + +Constant* JnjvmModuleAOT::getMethodInClass(JavaMethod* meth) { + Class* cl = meth->classDef; + Constant* MOffset = 0; + Constant* Array = 0; + method_iterator SI = virtualMethods.find(cl); + for (uint32 i = 0; i < cl->nbVirtualMethods + cl->nbStaticMethods; ++i) { + if (&cl->virtualMethods[i] == meth) { + MOffset = ConstantInt::get(Type::Int32Ty, i); + break; + } + } + Array = SI->second; + Constant* GEPs[2] = { constantZero, MOffset }; + return ConstantExpr::getGetElementPtr(Array, GEPs, 2); +} + +Constant* JnjvmModuleAOT::getString(JavaString* str) { + string_iterator SI = strings.find(str); + if (SI != strings.end()) { + return SI->second; + } else { + assert(str && "No string given"); + LLVMClassInfo* LCI = (LLVMClassInfo*)getClassInfo((Class*)str->getClass()); + const llvm::Type* Ty = LCI->getVirtualType(); + GlobalVariable* varGV = + new GlobalVariable(Ty->getContainedType(0), false, + GlobalValue::InternalLinkage, + 0, "", getLLVMModule()); + Constant* res = ConstantExpr::getCast(Instruction::BitCast, varGV, + JavaObjectType); + strings.insert(std::make_pair(str, res)); + Constant* C = CreateConstantFromJavaString(str); + varGV->setInitializer(C); + return res; + } +} + +Constant* JnjvmModuleAOT::getEnveloppe(Enveloppe* enveloppe) { + enveloppe_iterator SI = enveloppes.find(enveloppe); + if (SI != enveloppes.end()) { + return SI->second; + } else { + GlobalVariable* varGV = + new GlobalVariable(EnveloppeType->getContainedType(0), false, + GlobalValue::InternalLinkage, 0, "", getLLVMModule()); + enveloppes.insert(std::make_pair(enveloppe, varGV)); + + Constant* C = CreateConstantFromEnveloppe(enveloppe); + varGV->setInitializer(C); + return varGV; + } +} + +Constant* JnjvmModuleAOT::getJavaClass(CommonClass* cl) { + java_class_iterator End = javaClasses.end(); + java_class_iterator I = javaClasses.find(cl); + if (I == End) { + Class* javaClass = cl->classLoader->bootstrapLoader->upcalls->newClass; + LLVMClassInfo* LCI = (LLVMClassInfo*)getClassInfo(javaClass); + const llvm::Type* Ty = LCI->getVirtualType(); + + GlobalVariable* varGV = + new GlobalVariable(Ty->getContainedType(0), false, + GlobalValue::InternalLinkage, 0, "", getLLVMModule()); + + Constant* res = ConstantExpr::getCast(Instruction::BitCast, varGV, + JavaObjectType); + + javaClasses.insert(std::make_pair(cl, res)); + varGV->setInitializer(CreateConstantFromJavaClass(cl)); + return res; + } else { + return I->second; + } +} + +JavaObject* JnjvmModuleAOT::getFinalObject(llvm::Value* obj) { + return 0; +} + + + +Constant* JnjvmModuleAOT::getFinalObject(JavaObject* obj) { + final_object_iterator End = finalObjects.end(); + final_object_iterator I = finalObjects.find(obj); + if (I == End) { + abort(); + return 0; + } else { + return I->second; + } +} + +Constant* JnjvmModuleAOT::CreateConstantFromStaticInstance(Class* cl) { + LLVMClassInfo* LCI = getClassInfo(cl); + const Type* Ty = LCI->getStaticType(); + const StructType* STy = dyn_cast(Ty->getContainedType(0)); + + std::vector Elts; + + for (uint32 i = 0; i < cl->nbStaticFields; ++i) { + JavaField& field = cl->staticFields[i]; + const Typedef* type = field.getSignature(); + LLVMAssessorInfo& LAI = getTypedefInfo(type); + const Type* Ty = LAI.llvmType; + + Attribut* attribut = field.lookupAttribut(Attribut::constantAttribut); + + if (!attribut) { + Elts.push_back(Constant::getNullValue(Ty)); + } else { + Reader reader(attribut, cl->bytes); + JavaConstantPool * ctpInfo = cl->ctpInfo; + uint16 idx = reader.readU2(); + if (type->isPrimitive()) { + if (Ty == Type::Int64Ty) { + Elts.push_back(ConstantInt::get(Ty, (uint64)ctpInfo->LongAt(idx))); + } else if (Ty == Type::DoubleTy) { + Elts.push_back(ConstantFP::get(Ty, ctpInfo->DoubleAt(idx))); + } else if (Ty == Type::FloatTy) { + Elts.push_back(ConstantFP::get(Ty, ctpInfo->FloatAt(idx))); + } else { + Elts.push_back(ConstantInt::get(Ty, (uint64)ctpInfo->IntegerAt(idx))); + } + } else if (type->isReference()){ + const UTF8* utf8 = ctpInfo->UTF8At(ctpInfo->ctpDef[idx]); + JavaString* obj = ctpInfo->resolveString(utf8, idx); + Constant* C = getString(obj); + C = ConstantExpr::getBitCast(C, JavaObjectType); + Elts.push_back(C); + } else { + fprintf(stderr, "Implement me"); + abort(); + } + } + } + + return ConstantStruct::get(STy, Elts); +} + +Constant* JnjvmModuleAOT::getStaticInstance(Class* classDef) { +#ifdef ISOLATE + assert(0 && "Should not be here"); + abort(); +#endif + static_instance_iterator End = staticInstances.end(); + static_instance_iterator I = staticInstances.find(classDef); + if (I == End) { + + LLVMClassInfo* LCI = getClassInfo(classDef); + const Type* Ty = LCI->getStaticType(); + Ty = Ty->getContainedType(0); + GlobalVariable* varGV = + new GlobalVariable(Ty, false, GlobalValue::ExternalLinkage, + 0, classDef->printString(""), getLLVMModule()); + + Constant* res = ConstantExpr::getCast(Instruction::BitCast, varGV, + ptrType); + staticInstances.insert(std::make_pair(classDef, res)); + + if (isCompiling(classDef)) { + Constant* C = CreateConstantFromStaticInstance(classDef); + varGV->setInitializer(C); + } + + return res; + } else { + return I->second; + } +} + +Constant* JnjvmModuleAOT::getVirtualTable(Class* classDef) { + LLVMClassInfo* LCI = getClassInfo((Class*)classDef); + LCI->getVirtualType(); + llvm::Constant* res = 0; + virtual_table_iterator End = virtualTables.end(); + virtual_table_iterator I = virtualTables.find(classDef); + if (I == End) { + + const ArrayType* ATy = dyn_cast(VTType->getContainedType(0)); + const PointerType* PTy = dyn_cast(ATy->getContainedType(0)); + ATy = ArrayType::get(PTy, classDef->virtualTableSize); + // Do not set a virtual table as a constant, because the runtime may + // modify it. + GlobalVariable* varGV = new GlobalVariable(ATy, false, + GlobalValue::ExternalLinkage, + 0, + classDef->printString(""), + getLLVMModule()); + + res = ConstantExpr::getCast(Instruction::BitCast, varGV, VTType); + virtualTables.insert(std::make_pair(classDef, res)); + + if (isCompiling(classDef)) { + Constant* C = CreateConstantFromVT(classDef); + varGV->setInitializer(C); + } + + return res; + } else { + return I->second; + } +} + +Constant* JnjvmModuleAOT::getNativeFunction(JavaMethod* meth, void* ptr) { + llvm::Constant* varGV = 0; + native_function_iterator End = nativeFunctions.end(); + native_function_iterator I = nativeFunctions.find(meth); + if (I == End) { + + LLVMSignatureInfo* LSI = getSignatureInfo(meth->getSignature()); + const llvm::Type* valPtrType = LSI->getNativePtrType(); + + varGV = new GlobalVariable(valPtrType, true, + GlobalValue::InternalLinkage, + Constant::getNullValue(valPtrType), "", getLLVMModule()); + + nativeFunctions.insert(std::make_pair(meth, varGV)); + return varGV; + } else { + return I->second; + } +} + +Constant* JnjvmModuleAOT::CreateConstantForBaseObject(CommonClass* cl) { + const StructType* STy = + dyn_cast(JavaObjectType->getContainedType(0)); + + std::vector Elmts; + + // virtual table + if (cl->isClass()) { + Elmts.push_back(getVirtualTable(cl->asClass())); + } else { + ClassArray* clA = cl->asArrayClass(); + if (clA->baseClass()->isPrimitive()) { + Elmts.push_back(PrimitiveArrayVT); + } else { + Elmts.push_back(ReferenceArrayVT); + } + } + + // classof + Constant* Cl = getNativeClass(cl); + Constant* ClGEPs[2] = { constantZero, constantZero }; + Cl = ConstantExpr::getGetElementPtr(Cl, ClGEPs, 2); + + Elmts.push_back(Cl); + + // lock + Constant* L = ConstantInt::get(Type::Int64Ty, + mvm::Thread::get()->getThreadID()); + Elmts.push_back(ConstantExpr::getIntToPtr(L, ptrType)); + + return ConstantStruct::get(STy, Elmts); +} + +Constant* JnjvmModuleAOT::CreateConstantFromJavaClass(CommonClass* cl) { + Class* javaClass = cl->classLoader->bootstrapLoader->upcalls->newClass; + LLVMClassInfo* LCI = (LLVMClassInfo*)getClassInfo(javaClass); + const StructType* STy = + dyn_cast(LCI->getVirtualType()->getContainedType(0)); + + std::vector Elmts; + + // JavaObject + Elmts.push_back(CreateConstantForBaseObject(javaClass)); + + // signers + Elmts.push_back(Constant::getNullValue(JavaObjectType)); + + // pd + Elmts.push_back(Constant::getNullValue(JavaObjectType)); + + // vmdata + Constant* Cl = getNativeClass(cl); + Cl = ConstantExpr::getCast(Instruction::BitCast, Cl, JavaObjectType); + Elmts.push_back(Cl); + + // constructor + Elmts.push_back(Constant::getNullValue(JavaObjectType)); + + return ConstantStruct::get(STy, Elmts); +} + +Constant* JnjvmModuleAOT::CreateConstantFromJavaObject(JavaObject* obj) { + CommonClass* cl = obj->getClass(); + + if (cl->isArray()) { + Classpath* upcalls = cl->classLoader->bootstrapLoader->upcalls; + CommonClass* subClass = cl->asArrayClass()->baseClass(); + if (subClass->isPrimitive()) { + if (subClass == upcalls->OfBool) { + return CreateConstantFromArray((ArrayUInt8*)obj, + Type::Int8Ty); + } else if (subClass == upcalls->OfByte) { + return CreateConstantFromArray((ArraySInt8*)obj, + Type::Int8Ty); + } else if (subClass == upcalls->OfShort) { + return CreateConstantFromArray((ArraySInt16*)obj, + Type::Int16Ty); + } else if (subClass == upcalls->OfChar) { + return CreateConstantFromArray((ArrayUInt16*)obj, + Type::Int16Ty); + } else if (subClass == upcalls->OfInt) { + return CreateConstantFromArray((ArraySInt32*)obj, + Type::Int32Ty); + } else if (subClass == upcalls->OfFloat) { + return CreateConstantFromArray((ArrayFloat*)obj, + Type::FloatTy); + } else if (subClass == upcalls->OfLong) { + return CreateConstantFromArray((ArrayLong*)obj, + Type::Int64Ty); + } else if (subClass == upcalls->OfDouble) { + return CreateConstantFromArray((ArrayDouble*)obj, + Type::DoubleTy); + } else { + abort(); + } + } else { + return CreateConstantFromArray((ArrayObject*)obj, + JavaObjectType); + } + } else { + + std::vector Elmts; + + // JavaObject + Constant* CurConstant = CreateConstantForBaseObject(obj->getClass()); + + for (uint32 j = 0; j <= cl->depth; ++j) { + std::vector TempElts; + Elmts.push_back(CurConstant); + TempElts.push_back(CurConstant); + Class* curCl = cl->display[j]->asClass(); + LLVMClassInfo* LCI = getClassInfo(curCl); + const StructType* STy = + dyn_cast(LCI->getVirtualType()->getContainedType(0)); + + for (uint32 i = 0; i < curCl->nbVirtualFields; ++i) { + JavaField& field = curCl->virtualFields[i]; + const Typedef* type = field.getSignature(); + if (type->isPrimitive()) { + const PrimitiveTypedef* prim = (PrimitiveTypedef*)type; + if (prim->isBool() || prim->isByte()) { + ConstantInt* CI = ConstantInt::get(Type::Int8Ty, + field.getInt8Field(obj)); + TempElts.push_back(CI); + } else if (prim->isShort() || prim->isChar()) { + ConstantInt* CI = ConstantInt::get(Type::Int16Ty, + field.getInt16Field(obj)); + TempElts.push_back(CI); + } else if (prim->isInt()) { + ConstantInt* CI = ConstantInt::get(Type::Int32Ty, + field.getInt32Field(obj)); + TempElts.push_back(CI); + } else if (prim->isLong()) { + ConstantInt* CI = ConstantInt::get(Type::Int64Ty, + field.getLongField(obj)); + TempElts.push_back(CI); + } else if (prim->isFloat()) { + ConstantFP* CF = ConstantFP::get(Type::FloatTy, + field.getFloatField(obj)); + TempElts.push_back(CF); + } else if (prim->isDouble()) { + ConstantFP* CF = ConstantFP::get(Type::DoubleTy, + field.getDoubleField(obj)); + TempElts.push_back(CF); + } else { + abort(); + } + } else { + Constant* C = getFinalObject(field.getObjectField(obj)); + TempElts.push_back(C); + } + } + CurConstant = ConstantStruct::get(STy, TempElts); + } + + return CurConstant; + } +} + +Constant* JnjvmModuleAOT::CreateConstantFromJavaString(JavaString* str) { + Class* cl = (Class*)str->getClass(); + LLVMClassInfo* LCI = (LLVMClassInfo*)getClassInfo(cl); + const StructType* STy = + dyn_cast(LCI->getVirtualType()->getContainedType(0)); + + std::vector Elmts; + + Elmts.push_back(CreateConstantForBaseObject(cl)); + + Constant* Array = getUTF8(str->value); + Constant* ObjGEPs[2] = { constantZero, constantZero }; + Array = ConstantExpr::getGetElementPtr(Array, ObjGEPs, 2); + Elmts.push_back(Array); + + Elmts.push_back(ConstantInt::get(Type::Int32Ty, str->count)); + Elmts.push_back(ConstantInt::get(Type::Int32Ty, str->cachedHashCode)); + Elmts.push_back(ConstantInt::get(Type::Int32Ty, str->offset)); + + return ConstantStruct::get(STy, Elmts); +} + + +Constant* JnjvmModuleAOT::CreateConstantFromCacheNode(CacheNode* CN) { + const StructType* STy = + dyn_cast(CacheNodeType->getContainedType(0)); + + std::vector Elmts; + Elmts.push_back(Constant::getNullValue(STy->getContainedType(0))); + Elmts.push_back(Constant::getNullValue(STy->getContainedType(1))); + Elmts.push_back(Constant::getNullValue(STy->getContainedType(2))); + Elmts.push_back(getEnveloppe(CN->enveloppe)); + + return ConstantStruct::get(STy, Elmts); +} + +Constant* JnjvmModuleAOT::CreateConstantFromEnveloppe(Enveloppe* val) { + + const StructType* STy = + dyn_cast(EnveloppeType->getContainedType(0)); + const StructType* CNTy = + dyn_cast(CacheNodeType->getContainedType(0)); + + std::vector Elmts; + + Constant* firstCache = CreateConstantFromCacheNode(val->firstCache); + Elmts.push_back(new GlobalVariable(CNTy, false, + GlobalValue::InternalLinkage, + firstCache, "", getLLVMModule())); + Elmts.push_back(getUTF8(val->methodName)); + Elmts.push_back(getUTF8(val->methodSign)); + + Elmts.push_back(Constant::getNullValue(Type::Int8Ty)); + Elmts.push_back(getNativeClass(val->classDef)); + Elmts.push_back(firstCache); + + return ConstantStruct::get(STy, Elmts); + +} + +Constant* JnjvmModuleAOT::CreateConstantFromAttribut(Attribut& attribut) { + const StructType* STy = + dyn_cast(AttributType->getContainedType(0)); + + + std::vector Elmts; + + // name + Elmts.push_back(getUTF8(attribut.name)); + + // start + Elmts.push_back(ConstantInt::get(Type::Int32Ty, attribut.start)); + + // nbb + Elmts.push_back(ConstantInt::get(Type::Int32Ty, attribut.nbb)); + + return ConstantStruct::get(STy, Elmts); +} + +Constant* JnjvmModuleAOT::CreateConstantFromCommonClass(CommonClass* cl) { + const StructType* STy = + dyn_cast(JavaCommonClassType->getContainedType(0)); + + const ArrayType* ATy = ArrayType::get(JavaCommonClassType, cl->depth + 1); + + std::vector CommonClassElts; + std::vector TempElmts; + Constant* ClGEPs[2] = { constantZero, constantZero }; + + // display + for (uint32 i = 0; i <= cl->depth; ++i) { + Constant* Cl = getNativeClass(cl->display[i]); + if (Cl->getType() != JavaCommonClassType) + Cl = ConstantExpr::getGetElementPtr(Cl, ClGEPs, 2); + + TempElmts.push_back(Cl); + } + + Constant* display = ConstantArray::get(ATy, TempElmts); + TempElmts.clear(); + display = new GlobalVariable(ATy, true, GlobalValue::InternalLinkage, + display, "", getLLVMModule()); + display = ConstantExpr::getCast(Instruction::BitCast, display, + PointerType::getUnqual(JavaCommonClassType)); + CommonClassElts.push_back(display); + + // depth + CommonClassElts.push_back(ConstantInt::get(Type::Int32Ty, cl->depth)); + + // delegatee + ATy = dyn_cast(STy->getContainedType(2)); + assert(ATy && "Malformed type"); + + Constant* TCM[1] = { getJavaClass(cl) }; + CommonClassElts.push_back(ConstantArray::get(ATy, TCM, 1)); + + // access + CommonClassElts.push_back(ConstantInt::get(Type::Int16Ty, cl->access)); + + // interfaces + if (cl->nbInterfaces) { + for (uint32 i = 0; i < cl->nbInterfaces; ++i) { + TempElmts.push_back(getNativeClass(cl->interfaces[i])); + } + + ATy = ArrayType::get(JavaClassType, cl->nbInterfaces); + Constant* interfaces = ConstantArray::get(ATy, TempElmts); + interfaces = new GlobalVariable(ATy, true, GlobalValue::InternalLinkage, + interfaces, "", getLLVMModule()); + interfaces = ConstantExpr::getCast(Instruction::BitCast, interfaces, + PointerType::getUnqual(JavaClassType)); + + CommonClassElts.push_back(interfaces); + } else { + const Type* Ty = PointerType::getUnqual(JavaClassType); + CommonClassElts.push_back(Constant::getNullValue(Ty)); + } + + // nbInterfaces + CommonClassElts.push_back(ConstantInt::get(Type::Int16Ty, cl->nbInterfaces)); + + // name + CommonClassElts.push_back(getUTF8(cl->name)); + + // super + if (cl->super) { + CommonClassElts.push_back(getNativeClass(cl->super)); + } else { + CommonClassElts.push_back(Constant::getNullValue(JavaClassType)); + } + + // classLoader: store the static initializer, it will be overriden once + // the class is loaded. + Constant* loader = ConstantExpr::getBitCast(StaticInitializer, ptrType); + CommonClassElts.push_back(loader); + + return ConstantStruct::get(STy, CommonClassElts); +} + +Constant* JnjvmModuleAOT::CreateConstantFromJavaField(JavaField& field) { + const StructType* STy = + dyn_cast(JavaFieldType->getContainedType(0)); + + std::vector FieldElts; + std::vector TempElts; + + // signature + FieldElts.push_back(Constant::getNullValue(ptrType)); + + // access + FieldElts.push_back(ConstantInt::get(Type::Int16Ty, field.access)); + + // name + FieldElts.push_back(getUTF8(field.name)); + + // type + FieldElts.push_back(getUTF8(field.type)); + + // attributs + if (field.nbAttributs) { + const ArrayType* ATy = ArrayType::get(AttributType->getContainedType(0), + field.nbAttributs); + for (uint32 i = 0; i < field.nbAttributs; ++i) { + TempElts.push_back(CreateConstantFromAttribut(field.attributs[i])); + } + + Constant* attributs = ConstantArray::get(ATy, TempElts); + TempElts.clear(); + attributs = new GlobalVariable(ATy, true, GlobalValue::InternalLinkage, + attributs, "", getLLVMModule()); + attributs = ConstantExpr::getCast(Instruction::BitCast, attributs, + AttributType); + + FieldElts.push_back(attributs); + } else { + FieldElts.push_back(Constant::getNullValue(AttributType)); + } + + // nbAttributs + FieldElts.push_back(ConstantInt::get(Type::Int16Ty, field.nbAttributs)); + + // classDef + FieldElts.push_back(getNativeClass(field.classDef)); + + // ptrOffset + FieldElts.push_back(ConstantInt::get(Type::Int32Ty, field.ptrOffset)); + + // num + FieldElts.push_back(ConstantInt::get(Type::Int16Ty, field.num)); + + //JInfo + FieldElts.push_back(Constant::getNullValue(ptrType)); + + return ConstantStruct::get(STy, FieldElts); +} + +Constant* JnjvmModuleAOT::CreateConstantFromJavaMethod(JavaMethod& method) { + const StructType* STy = + dyn_cast(JavaMethodType->getContainedType(0)); + + std::vector MethodElts; + std::vector TempElts; + + // signature + MethodElts.push_back(Constant::getNullValue(ptrType)); + + // access + MethodElts.push_back(ConstantInt::get(Type::Int16Ty, method.access)); + + // attributs + if (method.nbAttributs) { + const ArrayType* ATy = ArrayType::get(AttributType->getContainedType(0), + method.nbAttributs); + for (uint32 i = 0; i < method.nbAttributs; ++i) { + TempElts.push_back(CreateConstantFromAttribut(method.attributs[i])); + } + + Constant* attributs = ConstantArray::get(ATy, TempElts); + TempElts.clear(); + attributs = new GlobalVariable(ATy, true, GlobalValue::InternalLinkage, + attributs, "", getLLVMModule()); + attributs = ConstantExpr::getCast(Instruction::BitCast, attributs, + AttributType); + + MethodElts.push_back(attributs); + } else { + MethodElts.push_back(Constant::getNullValue(AttributType)); + } + + // nbAttributs + MethodElts.push_back(ConstantInt::get(Type::Int16Ty, method.nbAttributs)); + + // enveloppes + // already allocated by the JIT, don't reallocate them. + MethodElts.push_back(Constant::getNullValue(EnveloppeType)); + + // nbEnveloppes + // 0 because we're not allocating here. + MethodElts.push_back(ConstantInt::get(Type::Int16Ty, 0)); + + // classDef + MethodElts.push_back(getNativeClass(method.classDef)); + + // name + MethodElts.push_back(getUTF8(method.name)); + + // type + MethodElts.push_back(getUTF8(method.type)); + + // canBeInlined + MethodElts.push_back(ConstantInt::get(Type::Int8Ty, method.canBeInlined)); + + // code + if (isAbstract(method.access)) { + MethodElts.push_back(Constant::getNullValue(ptrType)); + } else { + LLVMMethodInfo* LMI = getMethodInfo(&method); + Function* func = LMI->getMethod(); + MethodElts.push_back(ConstantExpr::getCast(Instruction::BitCast, func, + ptrType)); + } + + // offset + MethodElts.push_back(ConstantInt::get(Type::Int32Ty, method.offset)); + + //JInfo + MethodElts.push_back(Constant::getNullValue(ptrType)); + + return ConstantStruct::get(STy, MethodElts); +} + +Constant* JnjvmModuleAOT::CreateConstantFromClassPrimitive(ClassPrimitive* cl) { + const StructType* STy = + dyn_cast(JavaClassPrimitiveType->getContainedType(0)); + + std::vector ClassElts; + + // common class + ClassElts.push_back(CreateConstantFromCommonClass(cl)); + + // primSize + ClassElts.push_back(ConstantInt::get(Type::Int32Ty, cl->primSize)); + + return ConstantStruct::get(STy, ClassElts); +} + +Constant* JnjvmModuleAOT::CreateConstantFromClassArray(ClassArray* cl) { + const StructType* STy = + dyn_cast(JavaClassArrayType->getContainedType(0)); + + std::vector ClassElts; + Constant* ClGEPs[2] = { constantZero, constantZero }; + + // common class + ClassElts.push_back(CreateConstantFromCommonClass(cl)); + + // baseClass + Constant* Cl = getNativeClass(cl->baseClass()); + if (Cl->getType() != JavaCommonClassType) + Cl = ConstantExpr::getGetElementPtr(Cl, ClGEPs, 2); + + ClassElts.push_back(Cl); + + return ConstantStruct::get(STy, ClassElts); +} + +Constant* JnjvmModuleAOT::CreateConstantFromClass(Class* cl) { + const StructType* STy = + dyn_cast(JavaClassType->getContainedType(0)); + + std::vector ClassElts; + std::vector TempElts; + + // common class + ClassElts.push_back(CreateConstantFromCommonClass(cl)); + + // virtualSize + ClassElts.push_back(ConstantInt::get(Type::Int32Ty, cl->virtualSize)); + + // virtualTable + ClassElts.push_back(getVirtualTable(cl)); + + // IsolateInfo + const ArrayType* ATy = dyn_cast(STy->getContainedType(3)); + assert(ATy && "Malformed type"); + + const StructType* TCMTy = dyn_cast(ATy->getContainedType(0)); + assert(TCMTy && "Malformed type"); + + uint32 status = cl->needsInitialisationCheck() ? vmjc : ready; + TempElts.push_back(ConstantInt::get(Type::Int8Ty, status)); + TempElts.push_back(ConstantInt::get(Type::Int1Ty, status == ready ? 1 : 0)); + TempElts.push_back(getStaticInstance(cl)); + Constant* CStr[1] = { ConstantStruct::get(TCMTy, TempElts) }; + TempElts.clear(); + ClassElts.push_back(ConstantArray::get(ATy, CStr, 1)); + + // thinlock + ClassElts.push_back(Constant::getNullValue(ptrType)); + + if (cl->nbVirtualFields + cl->nbStaticFields) { + ATy = ArrayType::get(JavaFieldType->getContainedType(0), + cl->nbVirtualFields + cl->nbStaticFields); + } + + // virtualFields + if (cl->nbVirtualFields) { + + for (uint32 i = 0; i < cl->nbVirtualFields; ++i) { + TempElts.push_back(CreateConstantFromJavaField(cl->virtualFields[i])); + } + + } + + // staticFields + if (cl->nbStaticFields) { + + for (uint32 i = 0; i < cl->nbStaticFields; ++i) { + TempElts.push_back(CreateConstantFromJavaField(cl->staticFields[i])); + } + + } + + Constant* fields = 0; + if (cl->nbStaticFields + cl->nbVirtualFields) { + + fields = ConstantArray::get(ATy, TempElts); + TempElts.clear(); + fields = new GlobalVariable(ATy, false, GlobalValue::InternalLinkage, + fields, "", getLLVMModule()); + fields = ConstantExpr::getCast(Instruction::BitCast, fields, JavaFieldType); + } else { + fields = Constant::getNullValue(JavaFieldType); + } + + // virtualFields + ClassElts.push_back(fields); + + ConstantInt* nbVirtualFields = + ConstantInt::get(Type::Int16Ty, cl->nbVirtualFields); + // nbVirtualFields + ClassElts.push_back(nbVirtualFields); + + // staticFields + // Output null, getLLVMModule() will be set in the initializer. Otherwise, the + // assembly emitter of LLVM will try to align the data. + ClassElts.push_back(Constant::getNullValue(JavaFieldType)); + + // nbStaticFields + ClassElts.push_back(ConstantInt::get(Type::Int16Ty, cl->nbStaticFields)); + + // virtualMethods + if (cl->nbVirtualMethods + cl->nbStaticMethods) { + ATy = ArrayType::get(JavaMethodType->getContainedType(0), + cl->nbVirtualMethods + cl->nbStaticMethods); + } + + if (cl->nbVirtualMethods) { + for (uint32 i = 0; i < cl->nbVirtualMethods; ++i) { + TempElts.push_back(CreateConstantFromJavaMethod(cl->virtualMethods[i])); + } + } + + if (cl->nbStaticMethods) { + for (uint32 i = 0; i < cl->nbStaticMethods; ++i) { + TempElts.push_back(CreateConstantFromJavaMethod(cl->staticMethods[i])); + } + } + + Constant* methods = 0; + if (cl->nbVirtualMethods + cl->nbStaticMethods) { + methods = ConstantArray::get(ATy, TempElts); + TempElts.clear(); + GlobalVariable* GV = new GlobalVariable(ATy, false, + GlobalValue::InternalLinkage, + methods, "", getLLVMModule()); + virtualMethods.insert(std::make_pair(cl, GV)); + methods = ConstantExpr::getCast(Instruction::BitCast, GV, + JavaMethodType); + } else { + methods = Constant::getNullValue(JavaMethodType); + } + + // virtualMethods + ClassElts.push_back(methods); + + ConstantInt* nbVirtualMethods = + ConstantInt::get(Type::Int16Ty, cl->nbVirtualMethods); + // nbVirtualMethods + ClassElts.push_back(nbVirtualMethods); + + // staticMethods + // Output null, getLLVMModule() will be set in the initializer. + ClassElts.push_back(Constant::getNullValue(JavaMethodType)); + + // nbStaticMethods + ClassElts.push_back(ConstantInt::get(Type::Int16Ty, cl->nbStaticMethods)); + + // ownerClass + ClassElts.push_back(Constant::getNullValue(ptrType)); + + // bytes + ClassElts.push_back(Constant::getNullValue(JavaArrayUInt8Type)); + + // ctpInfo + ClassElts.push_back(Constant::getNullValue(ptrType)); + + // attributs + if (cl->nbAttributs) { + ATy = ArrayType::get(AttributType->getContainedType(0), + cl->nbAttributs); + + for (uint32 i = 0; i < cl->nbAttributs; ++i) { + TempElts.push_back(CreateConstantFromAttribut(cl->attributs[i])); + } + + Constant* attributs = ConstantArray::get(ATy, TempElts); + TempElts.clear(); + attributs = new GlobalVariable(ATy, true, GlobalValue::InternalLinkage, + attributs, "", getLLVMModule()); + attributs = ConstantExpr::getCast(Instruction::BitCast, attributs, + AttributType); + ClassElts.push_back(attributs); + } else { + ClassElts.push_back(Constant::getNullValue(AttributType)); + } + + // nbAttributs + ClassElts.push_back(ConstantInt::get(Type::Int16Ty, cl->nbAttributs)); + + // innerClasses + if (cl->nbInnerClasses) { + for (uint32 i = 0; i < cl->nbInnerClasses; ++i) { + TempElts.push_back(getNativeClass(cl->innerClasses[i])); + } + + ATy = ArrayType::get(JavaClassType, cl->nbInnerClasses); + Constant* innerClasses = ConstantArray::get(ATy, TempElts); + innerClasses = new GlobalVariable(ATy, true, GlobalValue::InternalLinkage, + innerClasses, "", getLLVMModule()); + innerClasses = ConstantExpr::getCast(Instruction::BitCast, innerClasses, + PointerType::getUnqual(JavaClassType)); + + ClassElts.push_back(innerClasses); + } else { + const Type* Ty = PointerType::getUnqual(JavaClassType); + ClassElts.push_back(Constant::getNullValue(Ty)); + } + + // nbInnerClasses + ClassElts.push_back(ConstantInt::get(Type::Int16Ty, cl->nbInnerClasses)); + + // outerClass + if (cl->outerClass) { + ClassElts.push_back(getNativeClass(cl->outerClass)); + } else { + ClassElts.push_back(Constant::getNullValue(JavaClassType)); + } + + // innerAccess + ClassElts.push_back(ConstantInt::get(Type::Int16Ty, cl->innerAccess)); + + // innerOuterResolved + ClassElts.push_back(ConstantInt::get(Type::Int8Ty, cl->innerOuterResolved)); + + // virtualTableSize + ClassElts.push_back(ConstantInt::get(Type::Int32Ty, cl->virtualTableSize)); + + // staticSize + ClassElts.push_back(ConstantInt::get(Type::Int32Ty, cl->staticSize)); + + // JInfo + ClassElts.push_back(Constant::getNullValue(ptrType)); + + // staticTracer + const Type* FTy = STy->getContainedType(STy->getNumContainedTypes() - 1); +#ifdef WITH_TRACER + Function* F = makeTracer(cl, true); + Constant* staticTracer = ConstantExpr::getCast(Instruction::BitCast, F, FTy); +#else + Constant* staticTracer = ConstantExpr::getNullValue(FTy); +#endif + ClassElts.push_back(staticTracer); + + + return ConstantStruct::get(STy, ClassElts); +} + +template +Constant* JnjvmModuleAOT::CreateConstantFromArray(T* val, const Type* Ty) { + std::vector Elemts; + const ArrayType* ATy = ArrayType::get(Ty, val->size); + Elemts.push_back(JavaObjectType->getContainedType(0)); + Elemts.push_back(pointerSizeType == Type::Int32Ty ? Type::Int32Ty : + Type::Int64Ty); + + Elemts.push_back(ATy); + + const StructType* STy = StructType::get(Elemts); + + std::vector Cts; + Cts.push_back(CreateConstantForBaseObject(val->getClass())); + Cts.push_back(ConstantInt::get(pointerSizeType, val->size)); + + std::vector Vals; + for (sint32 i = 0; i < val->size; ++i) { + if (Ty->isInteger()) { + Vals.push_back(ConstantInt::get(Ty, (uint64)val->elements[i])); + } else if (Ty->isFloatingPoint()) { + Vals.push_back(ConstantFP::get(Ty, (double)(size_t)val->elements[i])); + } else { + Vals.push_back(getFinalObject((JavaObject*)(size_t)val->elements[i])); + } + } + + Cts.push_back(ConstantArray::get(ATy, Vals)); + + return ConstantStruct::get(STy, Cts); +} + +Constant* JnjvmModuleAOT::CreateConstantFromUTF8(const UTF8* val) { + std::vector Elemts; + const ArrayType* ATy = ArrayType::get(Type::Int16Ty, val->size); + Elemts.push_back(JavaObjectType->getContainedType(0)); + Elemts.push_back(pointerSizeType == Type::Int32Ty ? Type::Int32Ty : + Type::Int64Ty); + + Elemts.push_back(ATy); + + const StructType* STy = StructType::get(Elemts); + + std::vector Cts; + Cts.push_back(CreateConstantForBaseObject(&ArrayOfChar)); + Cts.push_back(ConstantInt::get(pointerSizeType, val->size)); + + std::vector Vals; + for (sint32 i = 0; i < val->size; ++i) { + Vals.push_back(ConstantInt::get(Type::Int16Ty, val->elements[i])); + } + + Cts.push_back(ConstantArray::get(ATy, Vals)); + + return ConstantStruct::get(STy, Cts); + +} + +Constant* JnjvmModuleAOT::getUTF8(const UTF8* val) { + utf8_iterator End = utf8s.end(); + utf8_iterator I = utf8s.find(val); + if (I == End) { + Constant* C = CreateConstantFromUTF8(val); + GlobalVariable* varGV = new GlobalVariable(C->getType(), true, + GlobalValue::InternalLinkage, + C, "", getLLVMModule()); + + Constant* res = ConstantExpr::getCast(Instruction::BitCast, varGV, + UTF8Type); + utf8s.insert(std::make_pair(val, res)); + + return res; + } else { + return I->second; + } +} + +Constant* JnjvmModuleAOT::CreateConstantFromVT(Class* classDef) { + uint32 size = classDef->virtualTableSize; + VirtualTable* VT = classDef->virtualVT; + const ArrayType* ATy = dyn_cast(VTType->getContainedType(0)); + const PointerType* PTy = dyn_cast(ATy->getContainedType(0)); + ATy = ArrayType::get(PTy, size); + + ConstantPointerNull* N = ConstantPointerNull::get(PTy); + std::vector Elemts; + + // Destructor + JavaMethod* meth = ((JavaMethod**)VT)[0]; + LLVMMethodInfo* LMI = getMethodInfo(meth); + Function* Finalizer = LMI->getMethod(); + Elemts.push_back(Finalizer ? + ConstantExpr::getCast(Instruction::BitCast, Finalizer, PTy) : N); + + // Delete + Elemts.push_back(N); + + // Tracer +#ifdef WITH_TRACER + Function* Tracer = makeTracer(classDef, false); + Elemts.push_back(Tracer ? + ConstantExpr::getCast(Instruction::BitCast, Tracer, PTy) : N); +#else + Elemts.push_back(N); +#endif + + // Printer + Elemts.push_back(ConstantExpr::getBitCast(ObjectPrinter, PTy)); + + // Hashcode + Elemts.push_back(N); + + for (uint32 i = VT_NB_FUNCS; i < size; ++i) { + JavaMethod* meth = ((JavaMethod**)VT)[i]; + LLVMMethodInfo* LMI = getMethodInfo(meth); + Function* F = LMI->getMethod(); + if (isAbstract(meth->access)) { + Elemts.push_back(Constant::getNullValue(PTy)); + } else { + Elemts.push_back(ConstantExpr::getCast(Instruction::BitCast, F, PTy)); + } + } + + Constant* Array = ConstantArray::get(ATy, Elemts); + + return Array; +} + +#ifdef WITH_TRACER +llvm::Function* JnjvmModuleAOT::makeTracer(Class* cl, bool stat) { + if (!generateTracers) { + return JavaObjectTracerFunction; + } else { + return internalMakeTracer(cl, stat); + } +} +#endif + +JnjvmModuleAOT::JnjvmModuleAOT(const std::string& ModuleID, + JnjvmModule* Father) : + JnjvmModule(ModuleID, Father) { + + generateTracers = true; + generateStubs = true; + assumeCompiled = false; + + const Type* ATy = VTType->getContainedType(0); + PrimitiveArrayVT = new GlobalVariable(ATy, true, + GlobalValue::ExternalLinkage, + 0, "JavaArrayVT", getLLVMModule()); + + ReferenceArrayVT = new GlobalVariable(ATy, true, + GlobalValue::ExternalLinkage, + 0, "ArrayObjectVT", getLLVMModule()); + + + + ATy = JavaClassArrayType->getContainedType(0); + GlobalVariable* varGV = 0; + +#define PRIMITIVE_ARRAY(name) \ + varGV = new GlobalVariable(ATy, true, GlobalValue::ExternalLinkage, \ + 0, #name, getLLVMModule()); \ + arrayClasses.insert(std::make_pair(&name, varGV)); + + PRIMITIVE_ARRAY(ArrayOfBool) + PRIMITIVE_ARRAY(ArrayOfByte) + PRIMITIVE_ARRAY(ArrayOfChar) + PRIMITIVE_ARRAY(ArrayOfShort) + PRIMITIVE_ARRAY(ArrayOfInt) + PRIMITIVE_ARRAY(ArrayOfFloat) + PRIMITIVE_ARRAY(ArrayOfDouble) + PRIMITIVE_ARRAY(ArrayOfLong) + +#undef PRIMITIVE_ARRAY + + std::vector llvmArgs; + llvmArgs.push_back(ptrType); // class loader. + const FunctionType* FTy = FunctionType::get(Type::VoidTy, llvmArgs, false); + + StaticInitializer = Function::Create(FTy, GlobalValue::InternalLinkage, + "Init", getLLVMModule()); + + llvmArgs.clear(); + llvmArgs.push_back(JavaMethodType); + + FTy = FunctionType::get(ptrType, llvmArgs, false); + + NativeLoader = Function::Create(FTy, GlobalValue::ExternalLinkage, + "vmjcNativeLoader", getLLVMModule()); + + llvmArgs.clear(); + FTy = FunctionType::get(Type::VoidTy, llvmArgs, false); + ObjectPrinter = Function::Create(FTy, GlobalValue::ExternalLinkage, + "printJavaObject", getLLVMModule()); +} + +void JnjvmModuleAOT::printStats() { + fprintf(stderr, "----------------- Info from the module -----------------\n"); + fprintf(stderr, "Number of native classes : %llu\n", + (unsigned long long int) nativeClasses.size()); + fprintf(stderr, "Number of Java classes : %llu\n", + (unsigned long long int) javaClasses.size()); + fprintf(stderr, "Number of external array classes : %llu\n", + (unsigned long long int) arrayClasses.size()); + fprintf(stderr, "Number of virtual tables : %llu\n", + (unsigned long long int) virtualTables.size()); + fprintf(stderr, "Number of static instances : %llu\n", + (unsigned long long int) staticInstances.size()); + fprintf(stderr, "Number of constant pools : %llu\n", + (unsigned long long int) constantPools.size()); + fprintf(stderr, "Number of strings : %llu\n", + (unsigned long long int) strings.size()); + fprintf(stderr, "Number of enveloppes : %llu\n", + (unsigned long long int) enveloppes.size()); + fprintf(stderr, "Number of native functions : %llu\n", + (unsigned long long int) nativeFunctions.size()); + fprintf(stderr, "----------------- Total size in .data ------------------\n"); + uint64 size = 0; + Module* Mod = getLLVMModule(); + for (Module::const_global_iterator i = Mod->global_begin(), + e = Mod->global_end(); i != e; ++i) { + size += getTypeSize(i->getType()); + } + fprintf(stderr, "%lluB\n", (unsigned long long int)size); +} + + +#ifdef SERVICE +Value* JnjvmModuleAOT::getIsolate(Jnjvm* isolate, Value* Where) { + llvm::Constant* varGV = 0; + isolate_iterator End = isolates.end(); + isolate_iterator I = isolates.find(isolate); + if (I == End) { + + + Constant* cons = + ConstantExpr::getIntToPtr(ConstantInt::get(Type::Int64Ty, + uint64_t(isolate)), + ptrType); + + varGV = new GlobalVariable(ptrType, !staticCompilation, + GlobalValue::ExternalLinkage, + cons, "", getLLVMModule()); + + isolates.insert(std::make_pair(isolate, varGV)); + } else { + varGV = I->second; + } + if (BasicBlock* BB = dyn_cast(Where)) { + return new LoadInst(varGV, "", BB); + } else { + assert(dyn_cast(Where) && "Wrong use of module"); + return new LoadInst(varGV, "", dyn_cast(Where)); + } +} +#endif + +void JnjvmModuleAOT::CreateStaticInitializer() { + + std::vector llvmArgs; + llvmArgs.push_back(ptrType); // class loader + llvmArgs.push_back(JavaCommonClassType); // cl + const FunctionType* FTy = FunctionType::get(Type::VoidTy, llvmArgs, false); + + Function* AddClass = Function::Create(FTy, GlobalValue::ExternalLinkage, + "vmjcAddPreCompiledClass", getLLVMModule()); + + llvmArgs.clear(); + llvmArgs.push_back(ptrType); // class loader + llvmArgs.push_back(PointerType::getUnqual(JavaClassArrayType)); // array ptr + llvmArgs.push_back(UTF8Type); // name + FTy = FunctionType::get(Type::VoidTy, llvmArgs, false); + + Function* GetClassArray = Function::Create(FTy, GlobalValue::ExternalLinkage, + "vmjcGetClassArray", getLLVMModule()); + + BasicBlock* currentBlock = BasicBlock::Create("enter", StaticInitializer); + Function::arg_iterator loader = StaticInitializer->arg_begin(); + + Value* Args[3]; + // If we have defined some strings. + if (strings.begin() != strings.end()) { + llvmArgs.clear(); + llvmArgs.push_back(ptrType); // class loader + llvmArgs.push_back(strings.begin()->second->getType()); // val + FTy = FunctionType::get(Type::VoidTy, llvmArgs, false); + + Function* AddString = Function::Create(FTy, GlobalValue::ExternalLinkage, + "vmjcAddString", getLLVMModule()); + + + + for (string_iterator i = strings.begin(), e = strings.end(); i != e; ++i) { + Args[0] = loader; + Args[1] = i->second; + CallInst::Create(AddString, Args, Args + 2, "", currentBlock); + } + } + + for (native_class_iterator i = nativeClasses.begin(), + e = nativeClasses.end(); i != e; ++i) { + if (isCompiling(i->first)) { + Args[0] = loader; + Args[1] = ConstantExpr::getBitCast(i->second, JavaCommonClassType); + CallInst::Create(AddClass, Args, Args + 2, "", currentBlock); + } + } + + for (array_class_iterator i = arrayClasses.begin(), + e = arrayClasses.end(); i != e; ++i) { + if (!(i->first->baseClass()->isPrimitive())) { + Args[0] = loader; + Args[1] = i->second; + Args[2] = getUTF8(i->first->name); + CallInst::Create(GetClassArray, Args, Args + 3, "", currentBlock); + } + } + + + ReturnInst::Create(currentBlock); +} + +void JnjvmModuleAOT::setNoInline(Class* cl) { + for (uint32 i = 0; i < cl->nbVirtualMethods; ++i) { + JavaMethod& meth = cl->virtualMethods[i]; + if (!isAbstract(meth.access)) { + LLVMMethodInfo* LMI = getMethodInfo(&meth); + Function* func = LMI->getMethod(); + func->addFnAttr(Attribute::NoInline); + } + } + + for (uint32 i = 0; i < cl->nbStaticMethods; ++i) { + JavaMethod& meth = cl->staticMethods[i]; + if (!isAbstract(meth.access)) { + LLVMMethodInfo* LMI = getMethodInfo(&meth); + Function* func = LMI->getMethod(); + func->addFnAttr(Attribute::NoInline); + } + } +} + +void JnjvmModuleAOT::makeVT(Class* cl) { + internalMakeVT(cl); +#ifndef WITHOUT_VTABLE + VirtualTable* VT = cl->virtualVT; + for (uint32 i = 0; i < cl->nbVirtualMethods; ++i) { + JavaMethod& meth = cl->virtualMethods[i]; + ((void**)VT)[meth.offset] = &meth; + } +#endif +} + +void JnjvmModuleAOT::setMethod(JavaMethod* meth, void* ptr, const char* name) { + Function* func = getMethodInfo(meth)->getMethod(); + func->setName(name); + func->setLinkage(GlobalValue::ExternalLinkage); +} Added: vmkit/trunk/lib/JnJVM/Compiler/JnjvmModuleJIT.cpp URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/Compiler/JnjvmModuleJIT.cpp?rev=65555&view=auto ============================================================================== --- vmkit/trunk/lib/JnJVM/Compiler/JnjvmModuleJIT.cpp (added) +++ vmkit/trunk/lib/JnJVM/Compiler/JnjvmModuleJIT.cpp Thu Feb 26 12:44:00 2009 @@ -0,0 +1,201 @@ +//===--------- JnjvmModule.cpp - Definition of a Jnjvm module -------------===// +// +// JnJVM +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Constants.h" +#include "llvm/DerivedTypes.h" +#include "llvm/Instructions.h" +#include "llvm/ExecutionEngine/ExecutionEngine.h" + +#include "JavaConstantPool.h" +#include "JavaThread.h" +#include "Jnjvm.h" + +#include "jnjvm/JnjvmModule.h" +#include "jnjvm/JnjvmModuleProvider.h" + +using namespace jnjvm; +using namespace llvm; + +extern void* JavaArrayVT[]; +extern void* ArrayObjectVT[]; + +Constant* JnjvmModuleJIT::getNativeClass(CommonClass* classDef) { + const llvm::Type* Ty = classDef->isClass() ? JavaClassType : + JavaCommonClassType; + + ConstantInt* CI = ConstantInt::get(Type::Int64Ty, uint64_t(classDef)); + return ConstantExpr::getIntToPtr(CI, Ty); +} + +Constant* JnjvmModuleJIT::getConstantPool(JavaConstantPool* ctp) { + void* ptr = ctp->ctpRes; + assert(ptr && "No constant pool found"); + ConstantInt* CI = ConstantInt::get(Type::Int64Ty, uint64_t(ptr)); + return ConstantExpr::getIntToPtr(CI, ConstantPoolType); +} + +Constant* JnjvmModuleJIT::getMethodInClass(JavaMethod* meth) { + ConstantInt* CI = ConstantInt::get(Type::Int64Ty, (int64_t)meth); + return ConstantExpr::getIntToPtr(CI, JavaMethodType); +} + +Constant* JnjvmModuleJIT::getString(JavaString* str) { + assert(str && "No string given"); + ConstantInt* CI = ConstantInt::get(Type::Int64Ty, uint64(str)); + return ConstantExpr::getIntToPtr(CI, JavaObjectType); +} + +Constant* JnjvmModuleJIT::getEnveloppe(Enveloppe* enveloppe) { + assert(enveloppe && "No enveloppe given"); + ConstantInt* CI = ConstantInt::get(Type::Int64Ty, uint64(enveloppe)); + return ConstantExpr::getIntToPtr(CI, EnveloppeType); +} + +Constant* JnjvmModuleJIT::getJavaClass(CommonClass* cl) { + JavaObject* obj = cl->getClassDelegatee(JavaThread::get()->getJVM()); + assert(obj && "Delegatee not created"); + Constant* CI = ConstantInt::get(Type::Int64Ty, uint64(obj)); + return ConstantExpr::getIntToPtr(CI, JavaObjectType); +} + +JavaObject* JnjvmModuleJIT::getFinalObject(llvm::Value* obj) { + if (ConstantExpr* CE = dyn_cast(obj)) { + if (ConstantInt* C = dyn_cast(CE->getOperand(0))) { + return (JavaObject*)C->getZExtValue(); + } + } + return 0; +} + +Constant* JnjvmModuleJIT::getFinalObject(JavaObject* obj) { + Constant* CI = ConstantInt::get(Type::Int64Ty, uint64(obj)); + return ConstantExpr::getIntToPtr(CI, JavaObjectType); +} + +Constant* JnjvmModuleJIT::getStaticInstance(Class* classDef) { +#ifdef ISOLATE + assert(0 && "Should not be here"); + abort(); +#endif + void* obj = ((Class*)classDef)->getStaticInstance(); + if (!obj) { + Class* cl = (Class*)classDef; + classDef->acquire(); + obj = cl->getStaticInstance(); + if (!obj) { + // Allocate now so that compiled code can reference it. + obj = cl->allocateStaticInstance(JavaThread::get()->getJVM()); + } + classDef->release(); + } + Constant* CI = ConstantInt::get(Type::Int64Ty, (uint64_t(obj))); + return ConstantExpr::getIntToPtr(CI, ptrType); +} + +Constant* JnjvmModuleJIT::getVirtualTable(Class* classDef) { + LLVMClassInfo* LCI = getClassInfo((Class*)classDef); + LCI->getVirtualType(); + + assert(classDef->virtualVT && "Virtual VT not created"); + void* ptr = classDef->virtualVT; + ConstantInt* CI = ConstantInt::get(Type::Int64Ty, uint64_t(ptr)); + return ConstantExpr::getIntToPtr(CI, VTType); +} + +Constant* JnjvmModuleJIT::getNativeFunction(JavaMethod* meth, void* ptr) { + LLVMSignatureInfo* LSI = getSignatureInfo(meth->getSignature()); + const llvm::Type* valPtrType = LSI->getNativePtrType(); + + assert(ptr && "No native function given"); + + Constant* CI = ConstantInt::get(Type::Int64Ty, uint64_t(ptr)); + return ConstantExpr::getIntToPtr(CI, valPtrType); +} + +JnjvmModuleJIT::JnjvmModuleJIT(const std::string &ModuleID, + JnjvmModule* Father) : + JnjvmModule(ModuleID, Father) { + + ConstantInt* CI = ConstantInt::get(Type::Int64Ty, uint64(JavaArrayVT)); + PrimitiveArrayVT = ConstantExpr::getIntToPtr(CI, VTType); + + CI = ConstantInt::get(Type::Int64Ty, uint64(ArrayObjectVT)); + ReferenceArrayVT = ConstantExpr::getIntToPtr(CI, VTType); +} + +#ifdef SERVICE +Value* JnjvmModuleJIT::getIsolate(Jnjvm* isolate, Value* Where) { + ConstantInt* CI = ConstantInt::get(Type::Int64Ty, uint64_t(isolate)); + return ConstantExpr::getIntToPtr(CI, ptrType); +} +#endif + +void JnjvmModuleJIT::makeVT(Class* cl) { + internalMakeVT(cl); + +#ifndef WITHOUT_VTABLE + VirtualTable* VT = cl->virtualVT; + + // Fill the virtual table with function pointers. + ExecutionEngine* EE = mvm::MvmModule::executionEngine; + for (uint32 i = 0; i < cl->nbVirtualMethods; ++i) { + JavaMethod& meth = cl->virtualMethods[i]; + LLVMMethodInfo* LMI = getMethodInfo(&meth); + Function* func = LMI->getMethod(); + + // Special handling for finalize method. Don't put a finalizer + // if there is none, or if it is empty. + if (meth.offset == 0) { +#if defined(ISOLATE_SHARING) || defined(USE_GC_BOEHM) + ((void**)VT)[0] = 0; +#else + JnjvmClassLoader* loader = cl->classLoader; + Function* func = loader->getModuleProvider()->parseFunction(&meth); + if (!cl->super) { + meth.canBeInlined = true; + ((void**)VT)[0] = 0; + } else { + Function::iterator BB = func->begin(); + BasicBlock::iterator I = BB->begin(); + if (isa(I)) { + ((void**)VT)[0] = 0; + } else { + // LLVM does not allow recursive compilation. Create the code now. + ((void**)VT)[0] = EE->getPointerToFunction(func); + } + } +#endif + } else { + ((void**)VT)[meth.offset] = EE->getPointerToFunctionOrStub(func); + } + } + +#ifdef WITH_TRACER + Function* func = makeTracer(cl, false); + + void* codePtr = mvm::MvmModule::executionEngine->getPointerToFunction(func); + ((void**)VT)[VT_TRACER_OFFSET] = codePtr; + func->deleteBody(); +#endif + + // If there is no super, then it's the first VT that we allocate. Assign + // this VT to native types. + if (!(cl->super)) { + ClassArray::initialiseVT(cl); + } +#endif +} + +void JnjvmModuleJIT::setMethod(JavaMethod* meth, void* ptr, const char* name) { + Function* func = getMethodInfo(meth)->getMethod(); + func->setName(name); + assert(ptr && "No value given"); + executionEngine->addGlobalMapping(func, ptr); + func->setLinkage(GlobalValue::ExternalLinkage); +} Modified: vmkit/trunk/lib/JnJVM/Compiler/JnjvmModuleProvider.cpp URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/Compiler/JnjvmModuleProvider.cpp?rev=65555&r1=65554&r2=65555&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/Compiler/JnjvmModuleProvider.cpp (original) +++ vmkit/trunk/lib/JnJVM/Compiler/JnjvmModuleProvider.cpp Thu Feb 26 12:44:00 2009 @@ -147,7 +147,7 @@ LLVMSignatureInfo* LSI = M->getSignatureInfo(sign); if (!stat) { const char* name = cl->printString(); - char* key = (char*)alloca(strlen(name) + 2); + char* key = (char*)alloca(strlen(name) + 16); sprintf(key, "%s%d", name, index); Function* F = TheModule->getFunction(key); if (F) return F; @@ -182,7 +182,7 @@ } JnjvmModuleProvider::JnjvmModuleProvider(JnjvmModule *m) { - TheModule = (Module*)m; + TheModule = m->getLLVMModule(); if (m->executionEngine) { m->protectEngine.lock(); m->executionEngine->addModuleProvider(this); @@ -190,13 +190,13 @@ } JavaNativeFunctionPasses = new llvm::FunctionPassManager(this); - JavaNativeFunctionPasses->add(new llvm::TargetData(m)); + JavaNativeFunctionPasses->add(new llvm::TargetData(TheModule)); // Lower constant calls to lower things like getClass used // on synchronized methods. JavaNativeFunctionPasses->add(createLowerConstantCallsPass()); JavaFunctionPasses = new llvm::FunctionPassManager(this); - JavaFunctionPasses->add(new llvm::TargetData(m)); + JavaFunctionPasses->add(new llvm::TargetData(TheModule)); Function* func = m->JavaObjectAllocateFunction; JavaFunctionPasses->add(mvm::createEscapeAnalysisPass(func)); JavaFunctionPasses->add(createLowerConstantCallsPass()); Modified: vmkit/trunk/lib/JnJVM/Compiler/LowerConstantCalls.cpp URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/Compiler/LowerConstantCalls.cpp?rev=65555&r1=65554&r2=65555&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/Compiler/LowerConstantCalls.cpp (original) +++ vmkit/trunk/lib/JnJVM/Compiler/LowerConstantCalls.cpp Thu Feb 26 12:44:00 2009 @@ -114,8 +114,8 @@ #endif bool LowerConstantCalls::runOnFunction(Function& F) { - JnjvmModule* module = (JnjvmModule*)F.getParent(); JavaMethod* meth = LLVMMethodInfo::get(&F); + JnjvmModule* module = meth->classDef->classLoader->getModule(); bool Changed = false; for (Function::iterator BI = F.begin(), BE = F.end(); BI != BE; BI++) { BasicBlock *Cur = BI; @@ -433,7 +433,7 @@ GlobalVariable* GV = new GlobalVariable(module->JavaCommonClassType, false, GlobalValue::ExternalLinkage, - init, "", module); + init, "", module->getLLVMModule()); Value* LoadedGV = new LoadInst(GV, "", CI); Value* cmp = new ICmpInst(ICmpInst::ICMP_EQ, LoadedGV, init, Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaClass.h URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JavaClass.h?rev=65555&r1=65554&r2=65555&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/JavaClass.h (original) +++ vmkit/trunk/lib/JnJVM/VMCore/JavaClass.h Thu Feb 26 12:44:00 2009 @@ -1080,62 +1080,109 @@ //===----------------------------------------------------------------------===// /// This class of methods takes a variable argument list. - uint32 invokeIntSpecialAP(Jnjvm* vm, UserClass*, JavaObject* obj, va_list ap); - float invokeFloatSpecialAP(Jnjvm* vm, UserClass*, JavaObject* obj, va_list ap); - double invokeDoubleSpecialAP(Jnjvm* vm, UserClass*, JavaObject* obj, va_list ap); - sint64 invokeLongSpecialAP(Jnjvm* vm, UserClass*, JavaObject* obj, va_list ap); - JavaObject* invokeJavaObjectSpecialAP(Jnjvm* vm, UserClass*, JavaObject* obj, va_list ap); - - uint32 invokeIntVirtualAP(Jnjvm* vm, UserClass*, JavaObject* obj, va_list ap); - float invokeFloatVirtualAP(Jnjvm* vm, UserClass*, JavaObject* obj, va_list ap); - double invokeDoubleVirtualAP(Jnjvm* vm, UserClass*, JavaObject* obj, va_list ap); - sint64 invokeLongVirtualAP(Jnjvm* vm, UserClass*, JavaObject* obj, va_list ap); - JavaObject* invokeJavaObjectVirtualAP(Jnjvm* vm, UserClass*, JavaObject* obj, va_list ap); - - uint32 invokeIntStaticAP(Jnjvm* vm, UserClass*, va_list ap); - float invokeFloatStaticAP(Jnjvm* vm, UserClass*, va_list ap); - double invokeDoubleStaticAP(Jnjvm* vm, UserClass*, va_list ap); - sint64 invokeLongStaticAP(Jnjvm* vm, UserClass*, va_list ap); - JavaObject* invokeJavaObjectStaticAP(Jnjvm* vm, UserClass*, va_list ap); + uint32 invokeIntSpecialAP(Jnjvm* vm, UserClass*, JavaObject* obj, va_list ap) + __attribute__ ((noinline)); + float invokeFloatSpecialAP(Jnjvm* vm, UserClass*, JavaObject* obj, va_list ap) + __attribute__ ((noinline)); + double invokeDoubleSpecialAP(Jnjvm* vm, UserClass*, JavaObject* obj, + va_list ap) + __attribute__ ((noinline)); + sint64 invokeLongSpecialAP(Jnjvm* vm, UserClass*, JavaObject* obj, va_list ap) + __attribute__ ((noinline)); + JavaObject* invokeJavaObjectSpecialAP(Jnjvm* vm, UserClass*, JavaObject* obj, + va_list ap) + __attribute__ ((noinline)); + + uint32 invokeIntVirtualAP(Jnjvm* vm, UserClass*, JavaObject* obj, va_list ap) + __attribute__ ((noinline)); + float invokeFloatVirtualAP(Jnjvm* vm, UserClass*, JavaObject* obj, va_list ap) + __attribute__ ((noinline)); + double invokeDoubleVirtualAP(Jnjvm* vm, UserClass*, JavaObject* obj, va_list ap) + __attribute__ ((noinline)); + sint64 invokeLongVirtualAP(Jnjvm* vm, UserClass*, JavaObject* obj, va_list ap) + __attribute__ ((noinline)); + JavaObject* invokeJavaObjectVirtualAP(Jnjvm* vm, UserClass*, JavaObject* obj, va_list ap) + __attribute__ ((noinline)); + + uint32 invokeIntStaticAP(Jnjvm* vm, UserClass*, va_list ap) + __attribute__ ((noinline)); + float invokeFloatStaticAP(Jnjvm* vm, UserClass*, va_list ap) + __attribute__ ((noinline)); + double invokeDoubleStaticAP(Jnjvm* vm, UserClass*, va_list ap) + __attribute__ ((noinline)); + sint64 invokeLongStaticAP(Jnjvm* vm, UserClass*, va_list ap) + __attribute__ ((noinline)); + JavaObject* invokeJavaObjectStaticAP(Jnjvm* vm, UserClass*, va_list ap) + __attribute__ ((noinline)); /// This class of methods takes a buffer which contain the arguments of the /// call. - uint32 invokeIntSpecialBuf(Jnjvm* vm, UserClass*, JavaObject* obj, void* buf); - float invokeFloatSpecialBuf(Jnjvm* vm, UserClass*, JavaObject* obj, void* buf); - double invokeDoubleSpecialBuf(Jnjvm* vm, UserClass*, JavaObject* obj, void* buf); - sint64 invokeLongSpecialBuf(Jnjvm* vm, UserClass*, JavaObject* obj, void* buf); - JavaObject* invokeJavaObjectSpecialBuf(Jnjvm* vm, UserClass*, JavaObject* obj, void* buf); - - uint32 invokeIntVirtualBuf(Jnjvm* vm, UserClass*, JavaObject* obj, void* buf); - float invokeFloatVirtualBuf(Jnjvm* vm, UserClass*, JavaObject* obj, void* buf); - double invokeDoubleVirtualBuf(Jnjvm* vm, UserClass*, JavaObject* obj, void* buf); - sint64 invokeLongVirtualBuf(Jnjvm* vm, UserClass*, JavaObject* obj, void* buf); - JavaObject* invokeJavaObjectVirtualBuf(Jnjvm* vm, UserClass*, JavaObject* obj, void* buf); - - uint32 invokeIntStaticBuf(Jnjvm* vm, UserClass*, void* buf); - float invokeFloatStaticBuf(Jnjvm* vm, UserClass*, void* buf); - double invokeDoubleStaticBuf(Jnjvm* vm, UserClass*, void* buf); - sint64 invokeLongStaticBuf(Jnjvm* vm, UserClass*, void* buf); - JavaObject* invokeJavaObjectStaticBuf(Jnjvm* vm, UserClass*, void* buf); + uint32 invokeIntSpecialBuf(Jnjvm* vm, UserClass*, JavaObject* obj, void* buf) + __attribute__ ((noinline)); + float invokeFloatSpecialBuf(Jnjvm* vm, UserClass*, JavaObject* obj, void* buf) + __attribute__ ((noinline)); + double invokeDoubleSpecialBuf(Jnjvm* vm, UserClass*, JavaObject* obj, void* buf) + __attribute__ ((noinline)); + sint64 invokeLongSpecialBuf(Jnjvm* vm, UserClass*, JavaObject* obj, void* buf) + __attribute__ ((noinline)); + JavaObject* invokeJavaObjectSpecialBuf(Jnjvm* vm, UserClass*, JavaObject* obj, void* buf) + __attribute__ ((noinline)); + + uint32 invokeIntVirtualBuf(Jnjvm* vm, UserClass*, JavaObject* obj, void* buf) + __attribute__ ((noinline)); + float invokeFloatVirtualBuf(Jnjvm* vm, UserClass*, JavaObject* obj, void* buf) + __attribute__ ((noinline)); + double invokeDoubleVirtualBuf(Jnjvm* vm, UserClass*, JavaObject* obj, void* buf) + __attribute__ ((noinline)); + sint64 invokeLongVirtualBuf(Jnjvm* vm, UserClass*, JavaObject* obj, void* buf) + __attribute__ ((noinline)); + JavaObject* invokeJavaObjectVirtualBuf(Jnjvm* vm, UserClass*, JavaObject* obj, void* buf) + __attribute__ ((noinline)); + + uint32 invokeIntStaticBuf(Jnjvm* vm, UserClass*, void* buf) + __attribute__ ((noinline)); + float invokeFloatStaticBuf(Jnjvm* vm, UserClass*, void* buf) + __attribute__ ((noinline)); + double invokeDoubleStaticBuf(Jnjvm* vm, UserClass*, void* buf) + __attribute__ ((noinline)); + sint64 invokeLongStaticBuf(Jnjvm* vm, UserClass*, void* buf) + __attribute__ ((noinline)); + JavaObject* invokeJavaObjectStaticBuf(Jnjvm* vm, UserClass*, void* buf) + __attribute__ ((noinline)); /// This class of methods is variadic. - uint32 invokeIntSpecial(Jnjvm* vm, UserClass*, JavaObject* obj, ...); - float invokeFloatSpecial(Jnjvm* vm, UserClass*, JavaObject* obj, ...); - double invokeDoubleSpecial(Jnjvm* vm, UserClass*, JavaObject* obj, ...); - sint64 invokeLongSpecial(Jnjvm* vm, UserClass*, JavaObject* obj, ...); - JavaObject* invokeJavaObjectSpecial(Jnjvm* vm, UserClass*, JavaObject* obj, ...); - - uint32 invokeIntVirtual(Jnjvm* vm, UserClass*, JavaObject* obj, ...); - float invokeFloatVirtual(Jnjvm* vm, UserClass*, JavaObject* obj, ...); - double invokeDoubleVirtual(Jnjvm* vm, UserClass*, JavaObject* obj, ...); - sint64 invokeLongVirtual(Jnjvm* vm, UserClass*, JavaObject* obj, ...); - JavaObject* invokeJavaObjectVirtual(Jnjvm* vm, UserClass*, JavaObject* obj, ...); - - uint32 invokeIntStatic(Jnjvm* vm, UserClass*, ...); - float invokeFloatStatic(Jnjvm* vm, UserClass*, ...); - double invokeDoubleStatic(Jnjvm* vm, UserClass*, ...); - sint64 invokeLongStatic(Jnjvm* vm, UserClass*, ...); - JavaObject* invokeJavaObjectStatic(Jnjvm* vm, UserClass*, ...); + uint32 invokeIntSpecial(Jnjvm* vm, UserClass*, JavaObject* obj, ...) + __attribute__ ((noinline)); + float invokeFloatSpecial(Jnjvm* vm, UserClass*, JavaObject* obj, ...) + __attribute__ ((noinline)); + double invokeDoubleSpecial(Jnjvm* vm, UserClass*, JavaObject* obj, ...) + __attribute__ ((noinline)); + sint64 invokeLongSpecial(Jnjvm* vm, UserClass*, JavaObject* obj, ...) + __attribute__ ((noinline)); + JavaObject* invokeJavaObjectSpecial(Jnjvm* vm, UserClass*, JavaObject* obj, ...) + __attribute__ ((noinline)); + + uint32 invokeIntVirtual(Jnjvm* vm, UserClass*, JavaObject* obj, ...) + __attribute__ ((noinline)); + float invokeFloatVirtual(Jnjvm* vm, UserClass*, JavaObject* obj, ...) + __attribute__ ((noinline)); + double invokeDoubleVirtual(Jnjvm* vm, UserClass*, JavaObject* obj, ...) + __attribute__ ((noinline)); + sint64 invokeLongVirtual(Jnjvm* vm, UserClass*, JavaObject* obj, ...) + __attribute__ ((noinline)); + JavaObject* invokeJavaObjectVirtual(Jnjvm* vm, UserClass*, JavaObject* obj, ...) + __attribute__ ((noinline)); + + uint32 invokeIntStatic(Jnjvm* vm, UserClass*, ...) + __attribute__ ((noinline)); + float invokeFloatStatic(Jnjvm* vm, UserClass*, ...) + __attribute__ ((noinline)); + double invokeDoubleStatic(Jnjvm* vm, UserClass*, ...) + __attribute__ ((noinline)); + sint64 invokeLongStatic(Jnjvm* vm, UserClass*, ...) + __attribute__ ((noinline)); + JavaObject* invokeJavaObjectStatic(Jnjvm* vm, UserClass*, ...) + __attribute__ ((noinline)); mvm::JITInfo* JInfo; template Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaInitialise.cpp URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JavaInitialise.cpp?rev=65555&r1=65554&r2=65555&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/JavaInitialise.cpp (original) +++ vmkit/trunk/lib/JnJVM/VMCore/JavaInitialise.cpp Thu Feb 26 12:44:00 2009 @@ -66,16 +66,16 @@ } mvm::VirtualMachine* mvm::VirtualMachine::createJVM(mvm::CompilationUnit* C) { - JnjvmBootstraLoader* bootstrapLoader = gc_new(JnjvmBootstrapLoader)(false); + JnjvmBootstraLoader* bootstrapLoader = gc_new(JnjvmBootstrapLoader)(0, 0); Jnjvm* vm = gc_new(Jnjvm)(bootstrapLoader); return vm; } #else mvm::CompilationUnit* -mvm::VirtualMachine::initialiseJVM(bool staticCompilation) { +mvm::VirtualMachine::initialiseJVM() { initialiseVT(); - return gc_new(JnjvmBootstrapLoader)(staticCompilation); + return gc_new(JnjvmBootstrapLoader)(0, 0); } mvm::VirtualMachine* mvm::VirtualMachine::createJVM(mvm::CompilationUnit* C) { Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaRuntimeJIT.cpp URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JavaRuntimeJIT.cpp?rev=65555&r1=65554&r2=65555&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/JavaRuntimeJIT.cpp (original) +++ vmkit/trunk/lib/JnJVM/VMCore/JavaRuntimeJIT.cpp Thu Feb 26 12:44:00 2009 @@ -356,7 +356,7 @@ // Start native because the next instruction after setjmp is a call to a // native function. - th->startNative(1); + th->startNative(2); // Finally, return the buffer that the Java code will use to do the setjmp. return (void*)buf; Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaThread.cpp URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JavaThread.cpp?rev=65555&r1=65554&r2=65555&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/JavaThread.cpp (original) +++ vmkit/trunk/lib/JnJVM/VMCore/JavaThread.cpp Thu Feb 26 12:44:00 2009 @@ -89,6 +89,7 @@ void JavaThread::startJava() { // Caller of this function. void** cur = (void**)FRAME_PTR(); + cur = (void**)cur[0]; addresses.push_back(cur); } @@ -130,7 +131,7 @@ // We end walking the stack when we cross a native -> Java call. Here // the iterator points to a native -> Java call. We dereference addr twice // because a native -> Java call always contains the signature function. - } while (((void***)addr)[0] != *it); + } while (((void***)addr)[0][0] != *it); } } @@ -158,7 +159,7 @@ // We end walking the stack when we cross a native -> Java call. Here // the iterator points to a native -> Java call. We dereference addr twice // because a native -> Java call always contains the signature function. - } while (((void***)addr)[0] != *it); + } while (((void***)addr)[0][0] != *it); } return 0; } @@ -185,7 +186,7 @@ // We end walking the stack when we cross a native -> Java call. Here // the iterator points to a native -> Java call. We dereference addr twice // because a native -> Java call always contains the signature function. - } while (((void***)addr)[0] != *it); + } while (((void***)addr)[0][0] != *it); } return 0; @@ -246,7 +247,7 @@ // End walking the stack when we cross a native -> Java call. Here // the iterator points to a native -> Java call. We dereference addr twice // because a native -> Java call always contains the signature function. - } while (((void***)addr)[0] != *it); + } while (((void***)addr)[0][0] != *it); } while (addr < baseSP && addr < addr[0]) { Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaThread.h URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JavaThread.h?rev=65555&r1=65554&r2=65555&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/JavaThread.h (original) +++ vmkit/trunk/lib/JnJVM/VMCore/JavaThread.h Thu Feb 26 12:44:00 2009 @@ -194,11 +194,11 @@ /// startNative - Record that we are entering native code. /// - void startNative(int level); + void startNative(int level) __attribute__ ((noinline)); /// startJava - Record that we are entering Java code. /// - void startJava(); + void startJava() __attribute__ ((noinline)); /// endNative - Record that we are leaving native code. /// @@ -206,7 +206,7 @@ addresses.pop_back(); } - /// endNative - Record that we are leaving Java code. + /// endJava - Record that we are leaving Java code. /// void endJava() { addresses.pop_back(); @@ -229,7 +229,7 @@ /// printBacktrace - Prints the backtrace of this thread. /// - void printBacktrace(); + void printBacktrace() __attribute__ ((noinline)); /// printJavaBacktrace - Prints the backtrace of this thread. Only prints /// the Java methods on the stack. Modified: vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.cpp URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.cpp?rev=65555&r1=65554&r2=65555&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.cpp (original) +++ vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.cpp Thu Feb 26 12:44:00 2009 @@ -1102,7 +1102,7 @@ static void compileClass(Class* cl) { - JnjvmModule* Mod = cl->classLoader->getModule(); + JnjvmModuleAOT* Mod = (JnjvmModuleAOT*)cl->classLoader->getModule(); // Make sure the class is emitted. Mod->getNativeClass(cl); @@ -1127,14 +1127,14 @@ void Jnjvm::mainCompilerStart(JavaThread* th) { Jnjvm* vm = th->getJVM(); + JnjvmBootstrapLoader* bootstrapLoader = vm->bootstrapLoader; + JnjvmModuleAOT* M = (JnjvmModuleAOT*)bootstrapLoader->getModule(); try { - JnjvmBootstrapLoader* bootstrapLoader = vm->bootstrapLoader; bootstrapLoader->analyseClasspathEnv(vm->classpath); bootstrapLoader->upcalls->initialiseClasspath(bootstrapLoader); uint32 size = strlen(name); - JnjvmModule* M = bootstrapLoader->getModule(); if (size > 4 && (!strcmp(&name[size - 4], ".jar") || !strcmp(&name[size - 4], ".zip"))) { @@ -1215,7 +1215,7 @@ #define SET_INLINE(NAME) { \ const UTF8* name = vm->asciizToUTF8(NAME); \ Class* cl = (Class*)vm->bootstrapLoader->lookupClass(name); \ - if (cl) vm->bootstrapLoader->getModule()->setNoInline(cl); } + if (cl) M->setNoInline(cl); } SET_INLINE("java/util/concurrent/atomic/AtomicReferenceFieldUpdater") SET_INLINE("java/util/concurrent/atomic/AtomicReferenceFieldUpdater" Modified: vmkit/trunk/lib/JnJVM/VMCore/JnjvmClassLoader.cpp URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JnjvmClassLoader.cpp?rev=65555&r1=65554&r2=65555&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/JnjvmClassLoader.cpp (original) +++ vmkit/trunk/lib/JnJVM/VMCore/JnjvmClassLoader.cpp Thu Feb 26 12:44:00 2009 @@ -63,11 +63,9 @@ typedef void (*static_init_t)(JnjvmClassLoader*); -JnjvmBootstrapLoader::JnjvmBootstrapLoader(bool staticCompilation) { +JnjvmBootstrapLoader::JnjvmBootstrapLoader(JnjvmModule* Mod, + JnjvmModuleProvider* MP) { - TheModule = new JnjvmModule("Bootstrap JnJVM", staticCompilation); - TheModuleProvider = new JnjvmModuleProvider(getModule()); - hashUTF8 = new(allocator) UTF8Map(allocator, 0); classes = new(allocator) ClassMap(); javaTypes = new(allocator) TypeMap(); @@ -269,11 +267,14 @@ #undef DEF_UTF8 + TheModule = Mod; + TheModuleProvider = MP; + } JnjvmClassLoader::JnjvmClassLoader(JnjvmClassLoader& JCL, JavaObject* loader, Jnjvm* I) { - TheModule = new JnjvmModule("Applicative loader"); + TheModule = new JnjvmModuleJIT("Applicative loader", JCL.getModule()); TheModuleProvider = new JnjvmModuleProvider(getModule()); bootstrapLoader = JCL.bootstrapLoader; Modified: vmkit/trunk/lib/JnJVM/VMCore/JnjvmClassLoader.h URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JnjvmClassLoader.h?rev=65555&r1=65554&r2=65555&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/JnjvmClassLoader.h (original) +++ vmkit/trunk/lib/JnJVM/VMCore/JnjvmClassLoader.h Thu Feb 26 12:44:00 2009 @@ -116,14 +116,14 @@ /// TheModule - JIT module for compiling methods. /// JnjvmModule* getModule() { - return (JnjvmModule*)TheModule; + return reinterpret_cast(TheModule); } /// TheModuleProvider - JIT module provider for dynamic class loading and /// lazy compilation. /// JnjvmModuleProvider* getModuleProvider() { - return (JnjvmModuleProvider*)TheModuleProvider; + return reinterpret_cast(TheModuleProvider); } /// tracer - Traces a JnjvmClassLoader for GC. @@ -342,7 +342,7 @@ /// createBootstrapLoader - Creates the bootstrap loader, first thing /// to do before any execution of a JVM. /// - JnjvmBootstrapLoader(bool staticCompilation); + JnjvmBootstrapLoader(JnjvmModule* Mod, JnjvmModuleProvider* MP); JnjvmBootstrapLoader() {} virtual JavaString* UTF8ToStr(const UTF8* utf8); Modified: vmkit/trunk/lib/Mvm/Runtime/JIT.cpp URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/Mvm/Runtime/JIT.cpp?rev=65555&r1=65554&r2=65555&view=diff ============================================================================== --- vmkit/trunk/lib/Mvm/Runtime/JIT.cpp (original) +++ vmkit/trunk/lib/Mvm/Runtime/JIT.cpp Thu Feb 26 12:44:00 2009 @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -68,15 +69,11 @@ globalFunctionPasses = new FunctionPassManager(globalModuleProvider); - Module module("unused"); - module.setDataLayout(globalModule->getDataLayout()); - mvm::llvm_runtime::makeLLVMModuleContents(&module); - // Type declaration ptrType = PointerType::getUnqual(Type::Int8Ty); ptr32Type = PointerType::getUnqual(Type::Int32Ty); ptrPtrType = PointerType::getUnqual(ptrType); - pointerSizeType = module.getPointerSize() == llvm::Module::Pointer32 ? + pointerSizeType = globalModule->getPointerSize() == Module::Pointer32 ? Type::Int32Ty : Type::Int64Ty; // Constant declaration @@ -129,10 +126,12 @@ } -MvmModule::MvmModule(const std::string& ModuleID) : llvm::Module(ModuleID) { - Module* module = this; - module->setDataLayout(globalModule->getDataLayout()); - module->setTargetTriple(globalModule->getTargetTriple()); +MvmModule::MvmModule(const std::string& ModuleID) { + TheModule = new Module(ModuleID); + Module* module = TheModule; + + TheModule->setDataLayout(globalModule->getDataLayout()); + TheModule->setTargetTriple(globalModule->getTargetTriple()); mvm::llvm_runtime::makeLLVMModuleContents(module); @@ -145,7 +144,7 @@ unwindResume = module->getFunction("_Unwind_Resume_or_Rethrow"); llvmGetException = module->getFunction("llvm.eh.exception"); - exceptionSelector = (getPointerSize() == llvm::Module::Pointer32 ? + exceptionSelector = (module->getPointerSize() == Module::Pointer32 ? module->getFunction("llvm.eh.selector.i32") : module->getFunction("llvm.eh.selector.i64")); Modified: vmkit/trunk/lib/N3/Mono/MonoString.cpp URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/N3/Mono/MonoString.cpp?rev=65555&r1=65554&r2=65555&view=diff ============================================================================== --- vmkit/trunk/lib/N3/Mono/MonoString.cpp (original) +++ vmkit/trunk/lib/N3/Mono/MonoString.cpp Thu Feb 26 12:44:00 2009 @@ -56,7 +56,7 @@ str->_llvmVar = new GlobalVariable(pty, true, GlobalValue::ExternalLinkage, cons, "", - vm->module); + vm->module->getLLVMModule()); } } return str->_llvmVar; Modified: vmkit/trunk/lib/N3/PNetLib/PNetString.cpp URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/N3/PNetLib/PNetString.cpp?rev=65555&r1=65554&r2=65555&view=diff ============================================================================== --- vmkit/trunk/lib/N3/PNetLib/PNetString.cpp (original) +++ vmkit/trunk/lib/N3/PNetLib/PNetString.cpp Thu Feb 26 12:44:00 2009 @@ -57,7 +57,7 @@ str->_llvmVar = new GlobalVariable(pty, true, GlobalValue::ExternalLinkage, cons, "", - vm->module); + vm->module->getLLVMModule()); } } return str->_llvmVar; Modified: vmkit/trunk/lib/N3/VMCore/CLIJit.cpp URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/N3/VMCore/CLIJit.cpp?rev=65555&r1=65554&r2=65555&view=diff ============================================================================== --- vmkit/trunk/lib/N3/VMCore/CLIJit.cpp (original) +++ vmkit/trunk/lib/N3/VMCore/CLIJit.cpp Thu Feb 26 12:44:00 2009 @@ -151,7 +151,7 @@ Function* func = Function::Create(markAndTraceLLVMType, GlobalValue::ExternalLinkage, "markAndTraceObject", - cl->vm->module); + cl->vm->module->getLLVMModule()); Argument* arg = func->arg_begin(); #ifdef MULTIPLE_GC Argument* GC = ++(func->arg_begin()); @@ -253,7 +253,7 @@ Function* func = Function::Create(markAndTraceLLVMType, GlobalValue::ExternalLinkage, "markAndTraceObject", - cl->vm->module); + cl->vm->module->getLLVMModule()); Argument* arg = func->arg_begin(); #ifdef MULTIPLE_GC @@ -1484,7 +1484,7 @@ classDef->aquire(); if (methPtr == 0) { methPtr = Function::Create(getSignature(genMethod), GlobalValue::GhostLinkage, - printString(), classDef->vm->module); + printString(), classDef->vm->module->getLLVMModule()); classDef->vm->functions->hash(methPtr, this); N3Annotation* A = new N3Annotation(this); methPtr->addAnnotation(A); @@ -1533,10 +1533,11 @@ void CLIJit::initialiseBootstrapVM(N3* vm) { - mvm::MvmModule* module = vm->module; - module->protectEngine.lock(); - module->executionEngine->addModuleProvider(vm->TheModuleProvider); - module->protectEngine.unlock(); + mvm::MvmModule* M = vm->module; + Module* module = M->getLLVMModule(); + M->protectEngine.lock(); + M->executionEngine->addModuleProvider(vm->TheModuleProvider); + M->protectEngine.unlock(); n3::llvm_runtime::makeLLVMModuleContents(module); Modified: vmkit/trunk/lib/N3/VMCore/CLIJitMeta.cpp URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/N3/VMCore/CLIJitMeta.cpp?rev=65555&r1=65554&r2=65555&view=diff ============================================================================== --- vmkit/trunk/lib/N3/VMCore/CLIJitMeta.cpp (original) +++ vmkit/trunk/lib/N3/VMCore/CLIJitMeta.cpp Thu Feb 26 12:44:00 2009 @@ -372,7 +372,7 @@ _llvmVar = new GlobalVariable(pty, true, GlobalValue::ExternalLinkage, cons, "", - vm->module); + vm->module->getLLVMModule()); } release(); @@ -392,7 +392,7 @@ _llvmVar = new GlobalVariable(pty, true, GlobalValue::ExternalLinkage, cons, "", - classDef->vm->module); + classDef->vm->module->getLLVMModule()); } classDef->release(); } @@ -411,7 +411,7 @@ _llvmVar = new GlobalVariable(pty, true, GlobalValue::ExternalLinkage, cons, "", - classDef->vm->module); + classDef->vm->module->getLLVMModule()); } classDef->release(); Modified: vmkit/trunk/lib/N3/VMCore/CLIRuntimeJIT.cpp URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/N3/VMCore/CLIRuntimeJIT.cpp?rev=65555&r1=65554&r2=65555&view=diff ============================================================================== --- vmkit/trunk/lib/N3/VMCore/CLIRuntimeJIT.cpp (original) +++ vmkit/trunk/lib/N3/VMCore/CLIRuntimeJIT.cpp Thu Feb 26 12:44:00 2009 @@ -28,6 +28,8 @@ #include "VMObject.h" #include "VMThread.h" +#include + using namespace n3; using namespace llvm; Modified: vmkit/trunk/lib/N3/VMCore/N3.cpp URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/N3/VMCore/N3.cpp?rev=65555&r1=65554&r2=65555&view=diff ============================================================================== --- vmkit/trunk/lib/N3/VMCore/N3.cpp (original) +++ vmkit/trunk/lib/N3/VMCore/N3.cpp Thu Feb 26 12:44:00 2009 @@ -64,10 +64,10 @@ mvm::MvmModule::executionEngine->getTargetData()->getStringRepresentation(); vm->module = new mvm::MvmModule("Bootstrap N3"); - vm->module->setDataLayout(str); + vm->module->getLLVMModule()->setDataLayout(str); vm->protectModule = new mvm::LockNormal(); vm->functions = FunctionMap::allocate(); - vm->TheModuleProvider = new N3ModuleProvider(vm->module, vm->functions); + vm->TheModuleProvider = new N3ModuleProvider(vm->module->getLLVMModule(), vm->functions); CLIJit::initialiseBootstrapVM(vm); vm->name = "bootstrapN3"; @@ -86,10 +86,10 @@ std::string str = mvm::MvmModule::executionEngine->getTargetData()->getStringRepresentation(); vm->module = new mvm::MvmModule("App Domain"); - vm->module->setDataLayout(str); + vm->module->getLLVMModule()->setDataLayout(str); vm->protectModule = new mvm::LockNormal(); vm->functions = FunctionMap::allocate(); - vm->TheModuleProvider = new N3ModuleProvider(vm->module, vm->functions); + vm->TheModuleProvider = new N3ModuleProvider(vm->module->getLLVMModule(), vm->functions); CLIJit::initialiseAppDomain(vm); Modified: vmkit/trunk/lib/N3/VMCore/VMThread.cpp URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/N3/VMCore/VMThread.cpp?rev=65555&r1=65554&r2=65555&view=diff ============================================================================== --- vmkit/trunk/lib/N3/VMCore/VMThread.cpp (original) +++ vmkit/trunk/lib/N3/VMCore/VMThread.cpp Thu Feb 26 12:44:00 2009 @@ -53,7 +53,7 @@ key->state = StateRunning; key->pendingException = 0; key->perFunctionPasses = new llvm::FunctionPassManager(vm->TheModuleProvider); - key->perFunctionPasses->add(new llvm::TargetData(vm->module)); + key->perFunctionPasses->add(new llvm::TargetData(vm->module->getLLVMModule())); AddStandardCompilePasses(key->perFunctionPasses); return key; } Modified: vmkit/trunk/tools/jnjvm/Main.cpp URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/tools/jnjvm/Main.cpp?rev=65555&r1=65554&r2=65555&view=diff ============================================================================== --- vmkit/trunk/tools/jnjvm/Main.cpp (original) +++ vmkit/trunk/tools/jnjvm/Main.cpp Thu Feb 26 12:44:00 2009 @@ -13,9 +13,13 @@ #include "mvm/VirtualMachine.h" #include "mvm/Threads/Thread.h" +#include "jnjvm/JnjvmModule.h" +#include "jnjvm/JnjvmModuleProvider.h" + #include "llvm/Support/ManagedStatic.h" +using namespace jnjvm; using namespace llvm; using namespace mvm; @@ -27,6 +31,8 @@ Collector::initialise(0); CompilationUnit* CU = VirtualMachine::initialiseJVM(); + CU->TheModule = new JnjvmModuleJIT("JITModule"); + CU->TheModuleProvider = new JnjvmModuleProvider((JnjvmModule*)CU->TheModule); CU->AddStandardCompilePasses(); VirtualMachine* vm = VirtualMachine::createJVM(CU); vm->runApplication(argc, argv); Modified: vmkit/trunk/tools/vmjc/vmjc.cpp URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/tools/vmjc/vmjc.cpp?rev=65555&r1=65554&r2=65555&view=diff ============================================================================== --- vmkit/trunk/tools/vmjc/vmjc.cpp (original) +++ vmkit/trunk/tools/vmjc/vmjc.cpp Thu Feb 26 12:44:00 2009 @@ -16,14 +16,17 @@ //===----------------------------------------------------------------------===// #include "llvm/Module.h" +#include "llvm/ModuleProvider.h" #include "llvm/PassManager.h" #include "llvm/Assembly/PrintModulePass.h" #include "llvm/Config/config.h" #include "llvm/Bitcode/ReaderWriter.h" +#include "llvm/ExecutionEngine/ExecutionEngine.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/PassNameParser.h" +#include "llvm/Support/PluginLoader.h" #include "llvm/Support/Streams.h" #include "llvm/Support/SystemUtils.h" #include "llvm/Support/raw_ostream.h" @@ -38,11 +41,15 @@ #include "mvm/VirtualMachine.h" #include "mvm/Threads/Thread.h" +#include "jnjvm/JnjvmModule.h" +#include "jnjvm/JnjvmModuleProvider.h" + #include #include #include #include +using namespace jnjvm; using namespace llvm; static cl::opt @@ -77,6 +84,23 @@ static cl::opt TargetTriple("mtriple", cl::desc("Override target triple for module")); +static cl::opt +DisableExceptions("disable-exceptions", + cl::desc("Disable Java exceptions")); + +static cl::opt +DisableTracers("disable-tracers", + cl::desc("Disable Java tracers")); + +static cl::opt +DisableStubs("disable-stubs", + cl::desc("Disable Java stubs")); + +static cl::opt +AssumeCompiled("assume-compiled", + cl::desc("Assume external Java classes are compiled")); + + inline void addPass(FunctionPassManager *PM, Pass *P) { // Add the pass to the pass manager... @@ -166,8 +190,16 @@ Collector::initialise(0); Collector::enable(0); - mvm::CompilationUnit* CU = mvm::VirtualMachine::initialiseJVM(true); - addCommandLinePass(CU, argv); + mvm::CompilationUnit* CU = mvm::VirtualMachine::initialiseJVM(); + addCommandLinePass(CU, argv); + JnjvmModuleAOT* Mod = new JnjvmModuleAOT("AOT"); + JnjvmModuleProvider* MP = new JnjvmModuleProvider(Mod); + CU->TheModule = Mod; + CU->TheModuleProvider = MP; + if (DisableExceptions) Mod->disableExceptions(); + if (DisableTracers) Mod->generateTracers = false; + if (DisableStubs) Mod->generateStubs = false; + if (AssumeCompiled) Mod->assumeCompiled = true; mvm::VirtualMachine* vm = mvm::VirtualMachine::createJVM(CU); vm->compile(InputFilename.c_str()); vm->waitForExit(); @@ -218,7 +250,7 @@ } if (Force || !CheckBitcodeOutputToConsole(Out,true)) - WriteBitcodeToFile(CU->TheModule, *Out); + WriteBitcodeToFile(CU->TheModule->getLLVMModule(), *Out); if (Out != &std::cout) { ((std::ofstream*)Out)->close(); Modified: vmkit/trunk/tools/vmkit/Launcher.cpp URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/tools/vmkit/Launcher.cpp?rev=65555&r1=65554&r2=65555&view=diff ============================================================================== --- vmkit/trunk/tools/vmkit/Launcher.cpp (original) +++ vmkit/trunk/tools/vmkit/Launcher.cpp Thu Feb 26 12:44:00 2009 @@ -24,8 +24,12 @@ #include "mvm/VirtualMachine.h" #include "mvm/Threads/Thread.h" +#include "jnjvm/JnjvmModule.h" +#include "jnjvm/JnjvmModuleProvider.h" + #include "CommandLine.h" +using namespace jnjvm; using namespace llvm; enum VMType { @@ -135,6 +139,8 @@ if (VMToRun == RunJava) { #if WITH_JNJVM mvm::CompilationUnit* CU = mvm::VirtualMachine::initialiseJVM(); + CU->TheModule = new JnjvmModuleJIT("JITModule"); + CU->TheModuleProvider = new JnjvmModuleProvider((JnjvmModule*)CU->TheModule); addCommandLinePass(CU, argv); mvm::VirtualMachine* vm = mvm::VirtualMachine::createJVM(CU); vm->runApplication(argc, argv); @@ -152,6 +158,9 @@ #if WITH_JNJVM mvm::CompilationUnit* JVMCompiler = mvm::VirtualMachine::initialiseJVM(); + JVMCompiler->TheModule = new JnjvmModuleJIT("JITModule"); + JVMCompiler->TheModuleProvider = + new JnjvmModuleProvider((JnjvmModule*)JVMCompiler->TheModule); addCommandLinePass(JVMCompiler, argv); MyCl.vmlets["java"] = (mvm::VirtualMachine::createJVM); MyCl.compilers["java"] = JVMCompiler; From nicolas.geoffray at lip6.fr Thu Feb 26 10:49:22 2009 From: nicolas.geoffray at lip6.fr (Nicolas Geoffray) Date: Thu, 26 Feb 2009 18:49:22 -0000 Subject: [vmkit-commits] [vmkit] r65556 - /vmkit/trunk/lib/JnJVM/Compiler/JITInfo.cpp Message-ID: <200902261849.n1QInMlX029554@zion.cs.uiuc.edu> Author: geoffray Date: Thu Feb 26 12:49:22 2009 New Revision: 65556 URL: http://llvm.org/viewvc/llvm-project?rev=65556&view=rev Log: Forgot that file. Added: vmkit/trunk/lib/JnJVM/Compiler/JITInfo.cpp Added: vmkit/trunk/lib/JnJVM/Compiler/JITInfo.cpp URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/Compiler/JITInfo.cpp?rev=65556&view=auto ============================================================================== --- vmkit/trunk/lib/JnJVM/Compiler/JITInfo.cpp (added) +++ vmkit/trunk/lib/JnJVM/Compiler/JITInfo.cpp Thu Feb 26 12:49:22 2009 @@ -0,0 +1,661 @@ +//===--------- JnjvmModule.cpp - Definition of a Jnjvm module -------------===// +// +// JnJVM +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/BasicBlock.h" +#include "llvm/CallingConv.h" +#include "llvm/Constants.h" +#include "llvm/ExecutionEngine/ExecutionEngine.h" +#include "llvm/Instructions.h" +#include "llvm/Support/MutexGuard.h" +#include "llvm/Target/TargetData.h" + + +#include "mvm/JIT.h" + +#include "JavaCache.h" +#include "JavaConstantPool.h" +#include "JavaJIT.h" +#include "JavaString.h" +#include "JavaThread.h" +#include "JavaTypes.h" +#include "JavaUpcalls.h" +#include "Jnjvm.h" +#include "Reader.h" + +#include "jnjvm/JnjvmModule.h" +#include "jnjvm/JnjvmModuleProvider.h" + +#include + +using namespace jnjvm; +using namespace llvm; + +const Type* LLVMClassInfo::getVirtualType() { + if (!virtualType) { + std::vector fields; + + if (classDef->super && classDef->super->super) { + LLVMClassInfo* CLI = + JnjvmModule::getClassInfo((Class*)classDef->super); + fields.push_back(CLI->getVirtualType()->getContainedType(0)); + } else { + fields.push_back(JnjvmModule::JavaObjectType->getContainedType(0)); + } + + for (uint32 i = 0; i < classDef->nbVirtualFields; ++i) { + JavaField& field = classDef->virtualFields[i]; + field.num = i + 1; + Typedef* type = field.getSignature(); + LLVMAssessorInfo& LAI = JnjvmModule::getTypedefInfo(type); + fields.push_back(LAI.llvmType); + } + + + JnjvmModule* Mod = classDef->classLoader->getModule(); + StructType* structType = StructType::get(fields, false); + virtualType = PointerType::getUnqual(structType); + const TargetData* targetData = Mod->TheTargetData; + const StructLayout* sl = targetData->getStructLayout(structType); + + for (uint32 i = 0; i < classDef->nbVirtualFields; ++i) { + JavaField& field = classDef->virtualFields[i]; + field.ptrOffset = sl->getElementOffset(i + 1); + } + + uint64 size = Mod->getTypeSize(structType); + classDef->virtualSize = (uint32)size; + virtualSizeConstant = ConstantInt::get(Type::Int32Ty, size); + + if (!Mod->isStaticCompiling()) { + if (!classDef->virtualVT) { + Mod->makeVT((Class*)classDef); + } else { +#ifdef WITH_TRACER + // So the class is vmjc'ed. Create the virtual tracer. + Function* func = Function::Create(JnjvmModule::MarkAndTraceType, + GlobalValue::ExternalLinkage, + "markAndTraceObject", + Mod->getLLVMModule()); + + void* ptr = ((void**)classDef->virtualVT)[VT_TRACER_OFFSET]; + Mod->executionEngine->addGlobalMapping(func, ptr); + virtualTracerFunction = func; +#endif + } + } else { + Mod->makeVT(classDef); + } + + } + + return virtualType; +} + +const Type* LLVMClassInfo::getStaticType() { + + if (!staticType) { + Class* cl = (Class*)classDef; + std::vector fields; + + for (uint32 i = 0; i < classDef->nbStaticFields; ++i) { + JavaField& field = classDef->staticFields[i]; + field.num = i; + Typedef* type = field.getSignature(); + LLVMAssessorInfo& LAI = JnjvmModule::getTypedefInfo(type); + fields.push_back(LAI.llvmType); + } + + JnjvmModule* Mod = cl->classLoader->getModule(); + StructType* structType = StructType::get(fields, false); + staticType = PointerType::getUnqual(structType); + const TargetData* targetData = Mod->TheTargetData; + const StructLayout* sl = targetData->getStructLayout(structType); + + for (uint32 i = 0; i < classDef->nbStaticFields; ++i) { + JavaField& field = classDef->staticFields[i]; + field.ptrOffset = sl->getElementOffset(i); + } + + uint64 size = Mod->getTypeSize(structType); + cl->staticSize = size; +#ifdef WITH_TRACER + if (!Mod->isStaticCompiling()) { + Function* F = Mod->makeTracer(cl, true); + cl->staticTracer = (void (*)(void*)) (uintptr_t) + Mod->executionEngine->getPointerToFunction(F); + F->deleteBody(); + } +#endif + } + return staticType; +} + + +Value* LLVMClassInfo::getVirtualSize() { + if (!virtualSizeConstant) { + getVirtualType(); + assert(classDef->virtualSize && "Zero size for a class?"); + virtualSizeConstant = + ConstantInt::get(Type::Int32Ty, classDef->virtualSize); + } + return virtualSizeConstant; +} + +Function* LLVMClassInfo::getStaticTracer() { + if (!staticTracerFunction) { + getStaticType(); + } + return staticTracerFunction; +} + +Function* LLVMClassInfo::getVirtualTracer() { + if (!virtualTracerFunction) { + getVirtualType(); + } + return virtualTracerFunction; +} + +Function* LLVMMethodInfo::getMethod() { + if (!methodFunction) { + JnjvmClassLoader* JCL = methodDef->classDef->classLoader; + JnjvmModule* Mod = JCL->getModule(); + if (Mod->isStaticCompiling()) { + + const UTF8* jniConsClName = methodDef->classDef->name; + const UTF8* jniConsName = methodDef->name; + const UTF8* jniConsType = methodDef->type; + sint32 clen = jniConsClName->size; + sint32 mnlen = jniConsName->size; + sint32 mtlen = jniConsType->size; + + char* buf = (char*)alloca(3 + JNI_NAME_PRE_LEN + 1 + + ((mnlen + clen + mtlen) << 1)); + + bool jnjvm = false; + if (isNative(methodDef->access)) { + // Verify if it's defined by JnJVM + JCL->nativeLookup(methodDef, jnjvm, buf); + } + + if (!jnjvm) { + methodDef->jniConsFromMethOverloaded(buf + 1); + memcpy(buf, "JnJVM", 5); + } + + methodFunction = Function::Create(getFunctionType(), + GlobalValue::GhostLinkage, buf, + Mod->getLLVMModule()); + + } else { + + methodFunction = Function::Create(getFunctionType(), + GlobalValue::GhostLinkage, + "", Mod->getLLVMModule()); + + } + methodFunction->addAnnotation(this); + } + return methodFunction; +} + +const FunctionType* LLVMMethodInfo::getFunctionType() { + if (!functionType) { + Signdef* sign = methodDef->getSignature(); + LLVMSignatureInfo* LSI = JnjvmModule::getSignatureInfo(sign); + assert(LSI); + if (isStatic(methodDef->access)) { + functionType = LSI->getStaticType(); + } else { + functionType = LSI->getVirtualType(); + } + } + return functionType; +} + +ConstantInt* LLVMMethodInfo::getOffset() { + if (!offsetConstant) { + JnjvmModule::resolveVirtualClass(methodDef->classDef); + offsetConstant = ConstantInt::get(Type::Int32Ty, methodDef->offset); + } + return offsetConstant; +} + +ConstantInt* LLVMFieldInfo::getOffset() { + if (!offsetConstant) { + if (isStatic(fieldDef->access)) { + JnjvmModule::resolveStaticClass(fieldDef->classDef); + } else { + JnjvmModule::resolveVirtualClass(fieldDef->classDef); + } + + offsetConstant = ConstantInt::get(Type::Int32Ty, fieldDef->num); + } + return offsetConstant; +} + +const llvm::FunctionType* LLVMSignatureInfo::getVirtualType() { + if (!virtualType) { + // Lock here because we are called by arbitrary code + mvm::MvmModule::protectIR(); + std::vector llvmArgs; + uint32 size = signature->nbArguments; + Typedef* const* arguments = signature->getArgumentsType(); + + llvmArgs.push_back(JnjvmModule::JavaObjectType); + + for (uint32 i = 0; i < size; ++i) { + Typedef* type = arguments[i]; + LLVMAssessorInfo& LAI = JnjvmModule::getTypedefInfo(type); + llvmArgs.push_back(LAI.llvmType); + } + +#if defined(ISOLATE_SHARING) + llvmArgs.push_back(JnjvmModule::ConstantPoolType); // cached constant pool +#endif + + LLVMAssessorInfo& LAI = + JnjvmModule::getTypedefInfo(signature->getReturnType()); + virtualType = FunctionType::get(LAI.llvmType, llvmArgs, false); + mvm::MvmModule::unprotectIR(); + } + return virtualType; +} + +const llvm::FunctionType* LLVMSignatureInfo::getStaticType() { + if (!staticType) { + // Lock here because we are called by arbitrary code + mvm::MvmModule::protectIR(); + std::vector llvmArgs; + uint32 size = signature->nbArguments; + Typedef* const* arguments = signature->getArgumentsType(); + + for (uint32 i = 0; i < size; ++i) { + Typedef* type = arguments[i]; + LLVMAssessorInfo& LAI = JnjvmModule::getTypedefInfo(type); + llvmArgs.push_back(LAI.llvmType); + } + +#if defined(ISOLATE_SHARING) + llvmArgs.push_back(JnjvmModule::ConstantPoolType); // cached constant pool +#endif + + LLVMAssessorInfo& LAI = + JnjvmModule::getTypedefInfo(signature->getReturnType()); + staticType = FunctionType::get(LAI.llvmType, llvmArgs, false); + mvm::MvmModule::unprotectIR(); + } + return staticType; +} + +const llvm::FunctionType* LLVMSignatureInfo::getNativeType() { + if (!nativeType) { + // Lock here because we are called by arbitrary code + mvm::MvmModule::protectIR(); + std::vector llvmArgs; + uint32 size = signature->nbArguments; + Typedef* const* arguments = signature->getArgumentsType(); + + llvmArgs.push_back(mvm::MvmModule::ptrType); // JNIEnv + llvmArgs.push_back(JnjvmModule::JavaObjectType); // Class + + for (uint32 i = 0; i < size; ++i) { + Typedef* type = arguments[i]; + LLVMAssessorInfo& LAI = JnjvmModule::getTypedefInfo(type); + llvmArgs.push_back(LAI.llvmType); + } + +#if defined(ISOLATE_SHARING) + llvmArgs.push_back(JnjvmModule::ConstantPoolType); // cached constant pool +#endif + + LLVMAssessorInfo& LAI = + JnjvmModule::getTypedefInfo(signature->getReturnType()); + nativeType = FunctionType::get(LAI.llvmType, llvmArgs, false); + mvm::MvmModule::unprotectIR(); + } + return nativeType; +} + + +Function* LLVMSignatureInfo::createFunctionCallBuf(bool virt) { + + std::vector Args; + + JnjvmModule* Mod = signature->initialLoader->getModule(); + const char* name = 0; + if (Mod->isStaticCompiling()) { + name = virt ? signature->printString("virtual_buf") : + signature->printString("static_buf"); + } else { + name = ""; + } + + Function* res = Function::Create(virt ? getVirtualBufType() : + getStaticBufType(), + GlobalValue::InternalLinkage, name, + Mod->getLLVMModule()); + + BasicBlock* currentBlock = BasicBlock::Create("enter", res); + Function::arg_iterator i = res->arg_begin(); + Value *obj, *ptr, *func; +#if defined(ISOLATE_SHARING) + Value* ctp = i; +#endif + ++i; + func = i; + ++i; + if (virt) { + obj = i; + ++i; + Args.push_back(obj); + } + ptr = i; + + Typedef* const* arguments = signature->getArgumentsType(); + for (uint32 i = 0; i < signature->nbArguments; ++i) { + + LLVMAssessorInfo& LAI = JnjvmModule::getTypedefInfo(arguments[i]); + Value* val = new BitCastInst(ptr, LAI.llvmTypePtr, "", currentBlock); + Value* arg = new LoadInst(val, "", currentBlock); + Args.push_back(arg); + ptr = GetElementPtrInst::Create(ptr, JnjvmModule::constantEight, "", + currentBlock); + } + +#if defined(ISOLATE_SHARING) + Args.push_back(ctp); +#endif + + Value* val = CallInst::Create(func, Args.begin(), Args.end(), "", + currentBlock); + if (res->getFunctionType()->getReturnType() != Type::VoidTy) + ReturnInst::Create(val, currentBlock); + else + ReturnInst::Create(currentBlock); + + return res; +} + +Function* LLVMSignatureInfo::createFunctionCallAP(bool virt) { + + std::vector Args; + + JnjvmModule* Mod = signature->initialLoader->getModule(); + const char* name = 0; + if (Mod->isStaticCompiling()) { + name = virt ? signature->printString("virtual_ap") : + signature->printString("static_ap"); + } else { + name = ""; + } + + Function* res = Function::Create(virt ? getVirtualBufType() : + getStaticBufType(), + GlobalValue::InternalLinkage, name, + Mod->getLLVMModule()); + + BasicBlock* currentBlock = BasicBlock::Create("enter", res); + Function::arg_iterator i = res->arg_begin(); + Value *obj, *ap, *func; +#if defined(ISOLATE_SHARING) + Value* ctp = i; +#endif + ++i; + func = i; + ++i; + if (virt) { + obj = i; + Args.push_back(obj); + ++i; + } + ap = i; + + Typedef* const* arguments = signature->getArgumentsType(); + for (uint32 i = 0; i < signature->nbArguments; ++i) { + LLVMAssessorInfo& LAI = JnjvmModule::getTypedefInfo(arguments[i]); + Args.push_back(new VAArgInst(ap, LAI.llvmType, "", currentBlock)); + } + +#if defined(ISOLATE_SHARING) + Args.push_back(ctp); +#endif + + Value* val = CallInst::Create(func, Args.begin(), Args.end(), "", + currentBlock); + if (res->getFunctionType()->getReturnType() != Type::VoidTy) + ReturnInst::Create(val, currentBlock); + else + ReturnInst::Create(currentBlock); + + return res; +} + +const PointerType* LLVMSignatureInfo::getStaticPtrType() { + if (!staticPtrType) { + staticPtrType = PointerType::getUnqual(getStaticType()); + } + return staticPtrType; +} + +const PointerType* LLVMSignatureInfo::getVirtualPtrType() { + if (!virtualPtrType) { + virtualPtrType = PointerType::getUnqual(getVirtualType()); + } + return virtualPtrType; +} + +const PointerType* LLVMSignatureInfo::getNativePtrType() { + if (!nativePtrType) { + nativePtrType = PointerType::getUnqual(getNativeType()); + } + return nativePtrType; +} + + +const FunctionType* LLVMSignatureInfo::getVirtualBufType() { + if (!virtualBufType) { + // Lock here because we are called by arbitrary code + mvm::MvmModule::protectIR(); + std::vector Args2; + Args2.push_back(JnjvmModule::ConstantPoolType); // ctp + Args2.push_back(getVirtualPtrType()); + Args2.push_back(JnjvmModule::JavaObjectType); + Args2.push_back(JnjvmModule::ptrType); + LLVMAssessorInfo& LAI = + JnjvmModule::getTypedefInfo(signature->getReturnType()); + virtualBufType = FunctionType::get(LAI.llvmType, Args2, false); + mvm::MvmModule::unprotectIR(); + } + return virtualBufType; +} + +const FunctionType* LLVMSignatureInfo::getStaticBufType() { + if (!staticBufType) { + // Lock here because we are called by arbitrary code + mvm::MvmModule::protectIR(); + std::vector Args; + Args.push_back(JnjvmModule::ConstantPoolType); // ctp + Args.push_back(getStaticPtrType()); + Args.push_back(JnjvmModule::ptrType); + LLVMAssessorInfo& LAI = + JnjvmModule::getTypedefInfo(signature->getReturnType()); + staticBufType = FunctionType::get(LAI.llvmType, Args, false); + mvm::MvmModule::unprotectIR(); + } + return staticBufType; +} + +Function* LLVMSignatureInfo::getVirtualBuf() { + if (!virtualBufFunction) { + // Lock here because we are called by arbitrary code + mvm::MvmModule::protectIR(); + virtualBufFunction = createFunctionCallBuf(true); + if (!signature->initialLoader->getModule()->isStaticCompiling()) { + signature->setVirtualCallBuf((intptr_t) + mvm::MvmModule::executionEngine->getPointerToGlobal(virtualBufFunction)); + // Now that it's compiled, we don't need the IR anymore + virtualBufFunction->deleteBody(); + } + mvm::MvmModule::unprotectIR(); + } + return virtualBufFunction; +} + +Function* LLVMSignatureInfo::getVirtualAP() { + if (!virtualAPFunction) { + // Lock here because we are called by arbitrary code + mvm::MvmModule::protectIR(); + virtualAPFunction = createFunctionCallAP(true); + if (!signature->initialLoader->getModule()->isStaticCompiling()) { + signature->setVirtualCallAP((intptr_t) + mvm::MvmModule::executionEngine->getPointerToGlobal(virtualAPFunction)); + // Now that it's compiled, we don't need the IR anymore + virtualAPFunction->deleteBody(); + } + mvm::MvmModule::unprotectIR(); + } + return virtualAPFunction; +} + +Function* LLVMSignatureInfo::getStaticBuf() { + if (!staticBufFunction) { + // Lock here because we are called by arbitrary code + mvm::MvmModule::protectIR(); + staticBufFunction = createFunctionCallBuf(false); + if (!signature->initialLoader->getModule()->isStaticCompiling()) { + signature->setStaticCallBuf((intptr_t) + mvm::MvmModule::executionEngine->getPointerToGlobal(staticBufFunction)); + // Now that it's compiled, we don't need the IR anymore + staticBufFunction->deleteBody(); + } + mvm::MvmModule::unprotectIR(); + } + return staticBufFunction; +} + +Function* LLVMSignatureInfo::getStaticAP() { + if (!staticAPFunction) { + // Lock here because we are called by arbitrary code + mvm::MvmModule::protectIR(); + staticAPFunction = createFunctionCallAP(false); + if (!signature->initialLoader->getModule()->isStaticCompiling()) { + signature->setStaticCallAP((intptr_t) + mvm::MvmModule::executionEngine->getPointerToGlobal(staticAPFunction)); + // Now that it's compiled, we don't need the IR anymore + staticAPFunction->deleteBody(); + } + mvm::MvmModule::unprotectIR(); + } + return staticAPFunction; +} + +void LLVMAssessorInfo::initialise() { + AssessorInfo[I_VOID].llvmType = Type::VoidTy; + AssessorInfo[I_VOID].llvmTypePtr = 0; + AssessorInfo[I_VOID].llvmNullConstant = 0; + AssessorInfo[I_VOID].sizeInBytesConstant = 0; + + AssessorInfo[I_BOOL].llvmType = Type::Int8Ty; + AssessorInfo[I_BOOL].llvmTypePtr = PointerType::getUnqual(Type::Int8Ty); + AssessorInfo[I_BOOL].llvmNullConstant = + Constant::getNullValue(Type::Int8Ty); + AssessorInfo[I_BOOL].sizeInBytesConstant = mvm::MvmModule::constantOne; + + AssessorInfo[I_BYTE].llvmType = Type::Int8Ty; + AssessorInfo[I_BYTE].llvmTypePtr = PointerType::getUnqual(Type::Int8Ty); + AssessorInfo[I_BYTE].llvmNullConstant = + Constant::getNullValue(Type::Int8Ty); + AssessorInfo[I_BYTE].sizeInBytesConstant = mvm::MvmModule::constantOne; + + AssessorInfo[I_SHORT].llvmType = Type::Int16Ty; + AssessorInfo[I_SHORT].llvmTypePtr = PointerType::getUnqual(Type::Int16Ty); + AssessorInfo[I_SHORT].llvmNullConstant = + Constant::getNullValue(Type::Int16Ty); + AssessorInfo[I_SHORT].sizeInBytesConstant = mvm::MvmModule::constantTwo; + + AssessorInfo[I_CHAR].llvmType = Type::Int16Ty; + AssessorInfo[I_CHAR].llvmTypePtr = PointerType::getUnqual(Type::Int16Ty); + AssessorInfo[I_CHAR].llvmNullConstant = + Constant::getNullValue(Type::Int16Ty); + AssessorInfo[I_CHAR].sizeInBytesConstant = mvm::MvmModule::constantTwo; + + AssessorInfo[I_INT].llvmType = Type::Int32Ty; + AssessorInfo[I_INT].llvmTypePtr = PointerType::getUnqual(Type::Int32Ty); + AssessorInfo[I_INT].llvmNullConstant = + Constant::getNullValue(Type::Int32Ty); + AssessorInfo[I_INT].sizeInBytesConstant = mvm::MvmModule::constantFour; + + AssessorInfo[I_FLOAT].llvmType = Type::FloatTy; + AssessorInfo[I_FLOAT].llvmTypePtr = PointerType::getUnqual(Type::FloatTy); + AssessorInfo[I_FLOAT].llvmNullConstant = + Constant::getNullValue(Type::FloatTy); + AssessorInfo[I_FLOAT].sizeInBytesConstant = mvm::MvmModule::constantFour; + + AssessorInfo[I_LONG].llvmType = Type::Int64Ty; + AssessorInfo[I_LONG].llvmTypePtr = PointerType::getUnqual(Type::Int64Ty); + AssessorInfo[I_LONG].llvmNullConstant = + Constant::getNullValue(Type::Int64Ty); + AssessorInfo[I_LONG].sizeInBytesConstant = mvm::MvmModule::constantEight; + + AssessorInfo[I_DOUBLE].llvmType = Type::DoubleTy; + AssessorInfo[I_DOUBLE].llvmTypePtr = PointerType::getUnqual(Type::DoubleTy); + AssessorInfo[I_DOUBLE].llvmNullConstant = + Constant::getNullValue(Type::DoubleTy); + AssessorInfo[I_DOUBLE].sizeInBytesConstant = mvm::MvmModule::constantEight; + + AssessorInfo[I_TAB].llvmType = JnjvmModule::JavaObjectType; + AssessorInfo[I_TAB].llvmTypePtr = + PointerType::getUnqual(JnjvmModule::JavaObjectType); + AssessorInfo[I_TAB].llvmNullConstant = + JnjvmModule::JavaObjectNullConstant; + AssessorInfo[I_TAB].sizeInBytesConstant = mvm::MvmModule::constantPtrSize; + + AssessorInfo[I_REF].llvmType = JnjvmModule::JavaObjectType; + AssessorInfo[I_REF].llvmTypePtr = + PointerType::getUnqual(JnjvmModule::JavaObjectType); + AssessorInfo[I_REF].llvmNullConstant = + JnjvmModule::JavaObjectNullConstant; + AssessorInfo[I_REF].sizeInBytesConstant = mvm::MvmModule::constantPtrSize; +} + +std::map LLVMAssessorInfo::AssessorInfo; + +LLVMAssessorInfo& JnjvmModule::getTypedefInfo(const Typedef* type) { + return LLVMAssessorInfo::AssessorInfo[type->getKey()->elements[0]]; +} + +static AnnotationID JavaMethod_ID( + AnnotationManager::getID("Java::JavaMethod")); + + +LLVMMethodInfo::LLVMMethodInfo(JavaMethod* M) : + llvm::Annotation(JavaMethod_ID), methodDef(M), methodFunction(0), + offsetConstant(0), functionType(0) {} + +JavaMethod* LLVMMethodInfo::get(const llvm::Function* F) { + LLVMMethodInfo *MI = (LLVMMethodInfo*)F->getAnnotation(JavaMethod_ID); + if (MI) return MI->methodDef; + return 0; +} + +LLVMSignatureInfo* JnjvmModule::getSignatureInfo(Signdef* sign) { + return sign->getInfo(); +} + +LLVMClassInfo* JnjvmModule::getClassInfo(Class* cl) { + return cl->getInfo(); +} + +LLVMFieldInfo* JnjvmModule::getFieldInfo(JavaField* field) { + return field->getInfo(); +} + +LLVMMethodInfo* JnjvmModule::getMethodInfo(JavaMethod* method) { + return method->getInfo(); +} From nicolas.geoffray at lip6.fr Thu Feb 26 13:04:51 2009 From: nicolas.geoffray at lip6.fr (Nicolas Geoffray) Date: Thu, 26 Feb 2009 21:04:51 -0000 Subject: [vmkit-commits] [vmkit] r65572 - in /vmkit/trunk: include/jnjvm/JnjvmModule.h include/mvm/JIT.h lib/JnJVM/Compiler/JnjvmModule.cpp lib/JnJVM/Compiler/JnjvmModuleAOT.cpp lib/JnJVM/Compiler/JnjvmModuleJIT.cpp lib/JnJVM/VMCore/JnjvmClassLoader.cpp lib/Mvm/Runtime/JIT.cpp Message-ID: <200902262104.n1QL4pQa001973@zion.cs.uiuc.edu> Author: geoffray Date: Thu Feb 26 15:04:51 2009 New Revision: 65572 URL: http://llvm.org/viewvc/llvm-project?rev=65572&view=rev Log: One step further to run the verifier in JIT mode. The globalModule llvm::Module object holds all external functions. The other llvm::Module created on demand will just copy the declared functions. Modified: vmkit/trunk/include/jnjvm/JnjvmModule.h vmkit/trunk/include/mvm/JIT.h vmkit/trunk/lib/JnJVM/Compiler/JnjvmModule.cpp vmkit/trunk/lib/JnJVM/Compiler/JnjvmModuleAOT.cpp vmkit/trunk/lib/JnJVM/Compiler/JnjvmModuleJIT.cpp vmkit/trunk/lib/JnJVM/VMCore/JnjvmClassLoader.cpp vmkit/trunk/lib/Mvm/Runtime/JIT.cpp Modified: vmkit/trunk/include/jnjvm/JnjvmModule.h URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/include/jnjvm/JnjvmModule.h?rev=65572&r1=65571&r2=65572&view=diff ============================================================================== --- vmkit/trunk/include/jnjvm/JnjvmModule.h (original) +++ vmkit/trunk/include/jnjvm/JnjvmModule.h Thu Feb 26 15:04:51 2009 @@ -341,7 +341,7 @@ private: - void initialise(); + static void initialise(); bool enabledException; @@ -356,7 +356,7 @@ public: - JnjvmModule(const std::string &ModuleID, JnjvmModule* Father = 0); + JnjvmModule(const std::string &ModuleID); virtual bool isStaticCompiling() = 0; @@ -409,7 +409,7 @@ class JnjvmModuleJIT : public JnjvmModule { public: - JnjvmModuleJIT(const std::string &ModuleID, JnjvmModule* Father = 0); + JnjvmModuleJIT(const std::string &ModuleID); virtual bool isStaticCompiling() { return false; @@ -444,7 +444,7 @@ class JnjvmModuleAOT : public JnjvmModule { public: - JnjvmModuleAOT(const std::string &ModuleID, JnjvmModule* Father = 0); + JnjvmModuleAOT(const std::string &ModuleID); virtual bool isStaticCompiling() { return true; Modified: vmkit/trunk/include/mvm/JIT.h URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/include/mvm/JIT.h?rev=65572&r1=65571&r2=65572&view=diff ============================================================================== --- vmkit/trunk/include/mvm/JIT.h (original) +++ vmkit/trunk/include/mvm/JIT.h Thu Feb 26 15:04:51 2009 @@ -184,6 +184,7 @@ static void protectIR(); static void unprotectIR(); + static void copyDefinitions(llvm::Module* Dst, llvm::Module* Src); }; Modified: vmkit/trunk/lib/JnJVM/Compiler/JnjvmModule.cpp URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/Compiler/JnjvmModule.cpp?rev=65572&r1=65571&r2=65572&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/Compiler/JnjvmModule.cpp (original) +++ vmkit/trunk/lib/JnJVM/Compiler/JnjvmModule.cpp Thu Feb 26 15:04:51 2009 @@ -259,8 +259,8 @@ } void JnjvmModule::initialise() { - jnjvm::llvm_runtime::makeLLVMModuleContents(getLLVMModule()); - Module* module = getLLVMModule(); + Module* module = globalModule; + jnjvm::llvm_runtime::makeLLVMModuleContents(module); VTType = PointerType::getUnqual(module->getTypeByName("VT")); @@ -369,37 +369,33 @@ return getMethodInfo(meth)->getMethod(); } -JnjvmModule::JnjvmModule(const std::string &ModuleID, JnjvmModule* Father) : +JnjvmModule::JnjvmModule(const std::string &ModuleID) : MvmModule(ModuleID) { - Module* module = 0; - if (!Father) { - assert(!VTType && "Attempting to create a new initial JnjvmModule"); - enabledException = true; + Module* module = getLLVMModule(); + enabledException = true; + if (!VTType) { initialise(); - module = getLLVMModule(); - } else { - enabledException = Father->enabledException; - module = getLLVMModule(); - module->addTypeName("JavaObject", JavaObjectType); - module->addTypeName("JavaArray", JavaArrayType); - module->addTypeName("JavaCommonClass", JavaCommonClassType); - module->addTypeName("JavaClass", JavaClassType); - module->addTypeName("JavaClassPrimitive", JavaClassPrimitiveType); - module->addTypeName("JavaClassArray", JavaClassArrayType); - module->addTypeName("ArrayUInt8", JavaArrayUInt8Type); - module->addTypeName("ArraySInt8", JavaArraySInt8Type); - module->addTypeName("ArrayUInt16", JavaArrayUInt16Type); - module->addTypeName("ArraySInt16", JavaArraySInt16Type); - module->addTypeName("ArraySInt32", JavaArraySInt32Type); - module->addTypeName("ArrayLong", JavaArrayLongType); - module->addTypeName("ArrayFloat", JavaArrayFloatType); - module->addTypeName("ArrayDouble", JavaArrayDoubleType); - module->addTypeName("ArrayObject", JavaArrayObjectType); - module->addTypeName("CacheNode", CacheNodeType); - module->addTypeName("Enveloppe", EnveloppeType); - module = Father->getLLVMModule(); + copyDefinitions(module, globalModule); } + + module->addTypeName("JavaObject", JavaObjectType); + module->addTypeName("JavaArray", JavaArrayType); + module->addTypeName("JavaCommonClass", JavaCommonClassType); + module->addTypeName("JavaClass", JavaClassType); + module->addTypeName("JavaClassPrimitive", JavaClassPrimitiveType); + module->addTypeName("JavaClassArray", JavaClassArrayType); + module->addTypeName("ArrayUInt8", JavaArrayUInt8Type); + module->addTypeName("ArraySInt8", JavaArraySInt8Type); + module->addTypeName("ArrayUInt16", JavaArrayUInt16Type); + module->addTypeName("ArraySInt16", JavaArraySInt16Type); + module->addTypeName("ArraySInt32", JavaArraySInt32Type); + module->addTypeName("ArrayLong", JavaArrayLongType); + module->addTypeName("ArrayFloat", JavaArrayFloatType); + module->addTypeName("ArrayDouble", JavaArrayDoubleType); + module->addTypeName("ArrayObject", JavaArrayObjectType); + module->addTypeName("CacheNode", CacheNodeType); + module->addTypeName("Enveloppe", EnveloppeType); InterfaceLookupFunction = module->getFunction("jnjvmVirtualLookup"); MultiCallNewFunction = module->getFunction("multiCallNew"); Modified: vmkit/trunk/lib/JnJVM/Compiler/JnjvmModuleAOT.cpp URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/Compiler/JnjvmModuleAOT.cpp?rev=65572&r1=65571&r2=65572&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/Compiler/JnjvmModuleAOT.cpp (original) +++ vmkit/trunk/lib/JnJVM/Compiler/JnjvmModuleAOT.cpp Thu Feb 26 15:04:51 2009 @@ -1194,9 +1194,8 @@ } #endif -JnjvmModuleAOT::JnjvmModuleAOT(const std::string& ModuleID, - JnjvmModule* Father) : - JnjvmModule(ModuleID, Father) { +JnjvmModuleAOT::JnjvmModuleAOT(const std::string& ModuleID) : + JnjvmModule(ModuleID) { generateTracers = true; generateStubs = true; Modified: vmkit/trunk/lib/JnJVM/Compiler/JnjvmModuleJIT.cpp URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/Compiler/JnjvmModuleJIT.cpp?rev=65572&r1=65571&r2=65572&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/Compiler/JnjvmModuleJIT.cpp (original) +++ vmkit/trunk/lib/JnJVM/Compiler/JnjvmModuleJIT.cpp Thu Feb 26 15:04:51 2009 @@ -118,9 +118,8 @@ return ConstantExpr::getIntToPtr(CI, valPtrType); } -JnjvmModuleJIT::JnjvmModuleJIT(const std::string &ModuleID, - JnjvmModule* Father) : - JnjvmModule(ModuleID, Father) { +JnjvmModuleJIT::JnjvmModuleJIT(const std::string &ModuleID) : + JnjvmModule(ModuleID) { ConstantInt* CI = ConstantInt::get(Type::Int64Ty, uint64(JavaArrayVT)); PrimitiveArrayVT = ConstantExpr::getIntToPtr(CI, VTType); Modified: vmkit/trunk/lib/JnJVM/VMCore/JnjvmClassLoader.cpp URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JnjvmClassLoader.cpp?rev=65572&r1=65571&r2=65572&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/JnjvmClassLoader.cpp (original) +++ vmkit/trunk/lib/JnJVM/VMCore/JnjvmClassLoader.cpp Thu Feb 26 15:04:51 2009 @@ -274,7 +274,7 @@ JnjvmClassLoader::JnjvmClassLoader(JnjvmClassLoader& JCL, JavaObject* loader, Jnjvm* I) { - TheModule = new JnjvmModuleJIT("Applicative loader", JCL.getModule()); + TheModule = new JnjvmModuleJIT("Applicative loader"); TheModuleProvider = new JnjvmModuleProvider(getModule()); bootstrapLoader = JCL.bootstrapLoader; Modified: vmkit/trunk/lib/Mvm/Runtime/JIT.cpp URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/Mvm/Runtime/JIT.cpp?rev=65572&r1=65571&r2=65572&view=diff ============================================================================== --- vmkit/trunk/lib/Mvm/Runtime/JIT.cpp (original) +++ vmkit/trunk/lib/Mvm/Runtime/JIT.cpp Thu Feb 26 15:04:51 2009 @@ -68,6 +68,7 @@ globalFunctionPasses = new FunctionPassManager(globalModuleProvider); + mvm::llvm_runtime::makeLLVMModuleContents(globalModule); // Type declaration ptrType = PointerType::getUnqual(Type::Int8Ty); @@ -133,8 +134,8 @@ TheModule->setDataLayout(globalModule->getDataLayout()); TheModule->setTargetTriple(globalModule->getTargetTriple()); - mvm::llvm_runtime::makeLLVMModuleContents(module); - + copyDefinitions(module, globalModule); + printFloatLLVM = module->getFunction("printFloat"); printDoubleLLVM = module->getFunction("printDouble"); printLongLLVM = module->getFunction("printLong"); @@ -254,7 +255,7 @@ return TheTargetData->getTypePaddedSize(type); } -void MvmModule::runPasses(llvm::Function* func, +void MvmModule::runPasses(llvm::Function* func, llvm::FunctionPassManager* pm) { pm->run(*func); } @@ -273,9 +274,6 @@ // void CompilationUnit::AddStandardCompilePasses() { // TODO: enable this when - // - we can call multiple times the makeLLVMModuleContents function generated - // by llc -march=cpp -cppgen=contents - // - intrinsics won't be in the .ll files // - each module will have its declaration of external functions // //PM->add(llvm::createVerifierPass()); // Verify that input is correct @@ -327,3 +325,15 @@ void MvmModule::unprotectIR() { if (executionEngine) executionEngine->lock.release(); } + + +void MvmModule::copyDefinitions(Module* Dst, Module* Src) { + // Loop over all of the functions in the src module, mapping them over + for (Module::const_iterator I = Src->begin(), E = Src->end(); I != E; ++I) { + const Function *SF = I; // SrcFunction + assert(SF->isDeclaration() && + "Don't know how top copy functions with body"); + Function::Create(SF->getFunctionType(), GlobalValue::ExternalLinkage, + SF->getName(), Dst); + } +} From nicolas.geoffray at lip6.fr Thu Feb 26 14:09:09 2009 From: nicolas.geoffray at lip6.fr (Nicolas Geoffray) Date: Thu, 26 Feb 2009 22:09:09 -0000 Subject: [vmkit-commits] [vmkit] r65576 - in /vmkit/trunk: include/jnjvm/JnjvmModule.h lib/JnJVM/VMCore/JnjvmClassLoader.cpp Message-ID: <200902262209.n1QM99cK004474@zion.cs.uiuc.edu> Author: geoffray Date: Thu Feb 26 16:09:09 2009 New Revision: 65576 URL: http://llvm.org/viewvc/llvm-project?rev=65576&view=rev Log: Make the the VMCore of the JVM unaware that it's jitting. Modified: vmkit/trunk/include/jnjvm/JnjvmModule.h vmkit/trunk/lib/JnJVM/VMCore/JnjvmClassLoader.cpp Modified: vmkit/trunk/include/jnjvm/JnjvmModule.h URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/include/jnjvm/JnjvmModule.h?rev=65576&r1=65575&r2=65576&view=diff ============================================================================== --- vmkit/trunk/include/jnjvm/JnjvmModule.h (original) +++ vmkit/trunk/include/jnjvm/JnjvmModule.h Thu Feb 26 16:09:09 2009 @@ -369,6 +369,8 @@ enabledException = false; } + virtual JnjvmModule* Create(std::string ModuleID) = 0; + virtual ~JnjvmModule() {} llvm::Constant* getReferenceArrayVT(); @@ -417,6 +419,10 @@ virtual void makeVT(Class* cl); + virtual JnjvmModule* Create(std::string ModuleID) { + return new JnjvmModuleJIT(ModuleID); + } + virtual llvm::Constant* getFinalObject(JavaObject* obj); virtual JavaObject* getFinalObject(llvm::Value* C); virtual llvm::Constant* getNativeClass(CommonClass* cl); @@ -450,6 +456,10 @@ return true; } + virtual JnjvmModule* Create(std::string ModuleID) { + return new JnjvmModuleAOT(ModuleID); + } + virtual void makeVT(Class* cl); virtual llvm::Constant* getFinalObject(JavaObject* obj); Modified: vmkit/trunk/lib/JnJVM/VMCore/JnjvmClassLoader.cpp URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JnjvmClassLoader.cpp?rev=65576&r1=65575&r2=65576&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/VMCore/JnjvmClassLoader.cpp (original) +++ vmkit/trunk/lib/JnJVM/VMCore/JnjvmClassLoader.cpp Thu Feb 26 16:09:09 2009 @@ -274,9 +274,9 @@ JnjvmClassLoader::JnjvmClassLoader(JnjvmClassLoader& JCL, JavaObject* loader, Jnjvm* I) { - TheModule = new JnjvmModuleJIT("Applicative loader"); - TheModuleProvider = new JnjvmModuleProvider(getModule()); bootstrapLoader = JCL.bootstrapLoader; + TheModule = bootstrapLoader->getModule()->Create("Applicative loader"); + TheModuleProvider = new JnjvmModuleProvider(getModule()); hashUTF8 = new(allocator) UTF8Map(allocator, bootstrapLoader->upcalls->ArrayOfChar); From nicolas.geoffray at lip6.fr Sat Feb 28 03:12:18 2009 From: nicolas.geoffray at lip6.fr (Nicolas Geoffray) Date: Sat, 28 Feb 2009 11:12:18 -0000 Subject: [vmkit-commits] [vmkit] r65691 - /vmkit/trunk/lib/JnJVM/Compiler/JavaJIT.cpp Message-ID: <200902281112.n1SBCKVj001708@zion.cs.uiuc.edu> Author: geoffray Date: Sat Feb 28 05:12:08 2009 New Revision: 65691 URL: http://llvm.org/viewvc/llvm-project?rev=65691&view=rev Log: Disable virtual->special call on final fields optimization for now. Modified: vmkit/trunk/lib/JnJVM/Compiler/JavaJIT.cpp Modified: vmkit/trunk/lib/JnJVM/Compiler/JavaJIT.cpp URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/Compiler/JavaJIT.cpp?rev=65691&r1=65690&r2=65691&view=diff ============================================================================== --- vmkit/trunk/lib/JnJVM/Compiler/JavaJIT.cpp (original) +++ vmkit/trunk/lib/JnJVM/Compiler/JavaJIT.cpp Sat Feb 28 05:12:08 2009 @@ -88,14 +88,16 @@ if (meth && isInterface(meth->classDef->access)) { return invokeInterface(index, true); } - + const UTF8* name = 0; Signdef* signature = ctpInfo->infoOfInterfaceOrVirtualMethod(index, name); +#if 0 Value* obj = stack[signature->nbArguments].first; JavaObject* source = module->getFinalObject(obj); if (source) { return invokeSpecial(index, source->getClass()); } +#endif #if !defined(WITHOUT_VTABLE) Typedef* retTypedef = signature->getReturnType(); @@ -1684,7 +1686,7 @@ } } } - + if (!final) push(new LoadInst(ptr, "", currentBlock), sign->isUnsigned()); if (type == Type::Int64Ty || type == Type::DoubleTy) { push(module->constantZero, false); @@ -1756,7 +1758,7 @@ push(CallInst::Create(F, ptr, "", currentBlock), sign->isUnsigned()); } } - + if (!final) push(new LoadInst(ptr, "", currentBlock), sign->isUnsigned()); if (type == Type::Int64Ty || type == Type::DoubleTy) { push(module->constantZero, false);