| //===--- LLVMInfo.cpp - Implementation of LLVM info objects for J3---------===// |
| // |
| // The VMKit project |
| // |
| // 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/Instructions.h" |
| #include "llvm/Module.h" |
| #include "llvm/ExecutionEngine/ExecutionEngine.h" |
| #include "llvm/Support/MutexGuard.h" |
| #include "llvm/Target/TargetData.h" |
| |
| |
| #include "mvm/JIT.h" |
| |
| #include "JavaConstantPool.h" |
| #include "JavaString.h" |
| #include "JavaThread.h" |
| #include "JavaTypes.h" |
| #include "JavaUpcalls.h" |
| #include "Jnjvm.h" |
| #include "Reader.h" |
| |
| #include "j3/JavaLLVMCompiler.h" |
| #include "j3/LLVMInfo.h" |
| |
| #include <cstdio> |
| |
| using namespace j3; |
| using namespace llvm; |
| |
| const Type* LLVMClassInfo::getVirtualType() { |
| if (!virtualType) { |
| std::vector<const llvm::Type*> fields; |
| const TargetData* targetData = mvm::MvmModule::TheTargetData; |
| const StructLayout* sl = 0; |
| const StructType* structType = 0; |
| LLVMContext& context = Compiler->getLLVMModule()->getContext(); |
| |
| if (classDef->super) { |
| LLVMClassInfo* CLI = Compiler->getClassInfo(classDef->super); |
| const llvm::Type* Ty = CLI->getVirtualType()->getContainedType(0); |
| fields.push_back(Ty); |
| |
| for (uint32 i = 0; i < classDef->nbVirtualFields; ++i) { |
| JavaField& field = classDef->virtualFields[i]; |
| Typedef* type = field.getSignature(); |
| LLVMAssessorInfo& LAI = Compiler->getTypedefInfo(type); |
| fields.push_back(LAI.llvmType); |
| } |
| |
| |
| structType = StructType::get(context, fields, false); |
| virtualType = PointerType::getUnqual(structType); |
| sl = targetData->getStructLayout(structType); |
| |
| } else { |
| virtualType = Compiler->getIntrinsics()->JavaObjectType; |
| assert(virtualType && "intrinsics not iniitalized"); |
| structType = dyn_cast<const StructType>(virtualType->getContainedType(0)); |
| sl = targetData->getStructLayout(structType); |
| |
| } |
| |
| uint64 size = mvm::MvmModule::getTypeSize(structType); |
| virtualSizeConstant = ConstantInt::get(Type::getInt32Ty(context), size); |
| |
| // TODO: put that elsewhere. |
| if (Compiler == classDef->classLoader->getCompiler()) { |
| for (uint32 i = 0; i < classDef->nbVirtualFields; ++i) { |
| JavaField& field = classDef->virtualFields[i]; |
| field.ptrOffset = sl->getElementOffset(i + 1); |
| field.num = i + 1; |
| } |
| |
| classDef->virtualSize = (uint32)size; |
| classDef->alignment = sl->getAlignment(); |
| |
| Compiler->makeVT(classDef); |
| Compiler->makeIMT(classDef); |
| } |
| } |
| |
| return virtualType; |
| } |
| |
| const Type* LLVMClassInfo::getStaticType() { |
| |
| if (!staticType) { |
| Class* cl = (Class*)classDef; |
| std::vector<const llvm::Type*> fields; |
| |
| LLVMContext& context = Compiler->getLLVMModule()->getContext(); |
| |
| for (uint32 i = 0; i < classDef->nbStaticFields; ++i) { |
| JavaField& field = classDef->staticFields[i]; |
| Typedef* type = field.getSignature(); |
| LLVMAssessorInfo& LAI = Compiler->getTypedefInfo(type); |
| fields.push_back(LAI.llvmType); |
| } |
| |
| StructType* structType = StructType::get(context, fields, false); |
| staticType = PointerType::getUnqual(structType); |
| const TargetData* targetData = mvm::MvmModule::TheTargetData; |
| const StructLayout* sl = targetData->getStructLayout(structType); |
| |
| // TODO: put that elsewhere. |
| if (Compiler == classDef->classLoader->getCompiler()) { |
| for (uint32 i = 0; i < classDef->nbStaticFields; ++i) { |
| JavaField& field = classDef->staticFields[i]; |
| field.num = i; |
| field.ptrOffset = sl->getElementOffset(i); |
| } |
| |
| uint64 size = mvm::MvmModule::getTypeSize(structType); |
| cl->staticSize = size; |
| } |
| } |
| return staticType; |
| } |
| |
| |
| Value* LLVMClassInfo::getVirtualSize() { |
| if (!virtualSizeConstant) { |
| getVirtualType(); |
| assert(virtualSizeConstant && "No size for a class?"); |
| } |
| return virtualSizeConstant; |
| } |
| |
| Function* LLVMMethodInfo::getMethod() { |
| if (!methodFunction) { |
| JnjvmClassLoader* JCL = methodDef->classDef->classLoader; |
| if (Compiler->emitFunctionName()) { |
| 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) << 3)); |
| |
| bool j3 = false; |
| if (isNative(methodDef->access)) { |
| // Verify if it's defined by JnJVM |
| JCL->nativeLookup(methodDef, j3, buf); |
| } |
| |
| if (!j3) { |
| methodDef->jniConsFromMethOverloaded(buf + 1); |
| memcpy(buf, "JnJVM", 5); |
| } |
| |
| methodFunction = Function::Create(getFunctionType(), |
| GlobalValue::ExternalWeakLinkage, buf, |
| Compiler->getLLVMModule()); |
| } else { |
| methodFunction = Function::Create(getFunctionType(), |
| GlobalValue::ExternalWeakLinkage, |
| "", Compiler->getLLVMModule()); |
| } |
| |
| if (Compiler->useCooperativeGC()) { |
| methodFunction->setGC("vmkit"); |
| } |
| |
| Compiler->functions.insert(std::make_pair(methodFunction, methodDef)); |
| if (Compiler != JCL->getCompiler()) { |
| if (mvm::MvmModule::executionEngine && methodDef->code) { |
| methodFunction->setLinkage(GlobalValue::ExternalLinkage); |
| mvm::MvmModule::executionEngine->updateGlobalMapping(methodFunction, |
| methodDef->code); |
| } |
| } |
| } |
| return methodFunction; |
| } |
| |
| const FunctionType* LLVMMethodInfo::getFunctionType() { |
| if (!functionType) { |
| Signdef* sign = methodDef->getSignature(); |
| LLVMSignatureInfo* LSI = Compiler->getSignatureInfo(sign); |
| assert(LSI); |
| if (isStatic(methodDef->access)) { |
| functionType = LSI->getStaticType(); |
| } else { |
| functionType = LSI->getVirtualType(); |
| } |
| } |
| return functionType; |
| } |
| |
| Constant* LLVMMethodInfo::getOffset() { |
| if (!offsetConstant) { |
| LLVMContext& context = Compiler->getLLVMModule()->getContext(); |
| |
| Compiler->resolveVirtualClass(methodDef->classDef); |
| offsetConstant = ConstantInt::get(Type::getInt32Ty(context), |
| methodDef->offset); |
| } |
| return offsetConstant; |
| } |
| |
| Constant* LLVMFieldInfo::getOffset() { |
| if (!offsetConstant) { |
| LLVMContext& context = Compiler->getLLVMModule()->getContext(); |
| |
| if (isStatic(fieldDef->access)) { |
| Compiler->resolveStaticClass(fieldDef->classDef); |
| } else { |
| Compiler->resolveVirtualClass(fieldDef->classDef); |
| } |
| |
| offsetConstant = ConstantInt::get(Type::getInt32Ty(context), 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<const llvm::Type*> llvmArgs; |
| uint32 size = signature->nbArguments; |
| Typedef* const* arguments = signature->getArgumentsType(); |
| |
| llvmArgs.push_back(Compiler->getIntrinsics()->JavaObjectType); |
| |
| for (uint32 i = 0; i < size; ++i) { |
| Typedef* type = arguments[i]; |
| LLVMAssessorInfo& LAI = Compiler->getTypedefInfo(type); |
| llvmArgs.push_back(LAI.llvmType); |
| } |
| |
| #if defined(ISOLATE_SHARING) |
| llvmArgs.push_back(Mod->getIntrinsics()->ConstantPoolType); |
| #endif |
| |
| LLVMAssessorInfo& LAI = |
| Compiler->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<const llvm::Type*> llvmArgs; |
| uint32 size = signature->nbArguments; |
| Typedef* const* arguments = signature->getArgumentsType(); |
| |
| for (uint32 i = 0; i < size; ++i) { |
| Typedef* type = arguments[i]; |
| LLVMAssessorInfo& LAI = Compiler->getTypedefInfo(type); |
| llvmArgs.push_back(LAI.llvmType); |
| } |
| |
| #if defined(ISOLATE_SHARING) |
| // cached constant pool |
| llvmArgs.push_back(Compiler->getIntrinsics()->ConstantPoolType); |
| #endif |
| |
| LLVMAssessorInfo& LAI = |
| Compiler->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<const llvm::Type*> llvmArgs; |
| uint32 size = signature->nbArguments; |
| Typedef* const* arguments = signature->getArgumentsType(); |
| |
| const llvm::Type* Ty = |
| PointerType::getUnqual(Compiler->getIntrinsics()->JavaObjectType); |
| |
| llvmArgs.push_back(Compiler->getIntrinsics()->ptrType); // JNIEnv |
| llvmArgs.push_back(Ty); // Class |
| |
| for (uint32 i = 0; i < size; ++i) { |
| Typedef* type = arguments[i]; |
| LLVMAssessorInfo& LAI = Compiler->getTypedefInfo(type); |
| const llvm::Type* Ty = LAI.llvmType; |
| if (Ty == Compiler->getIntrinsics()->JavaObjectType) { |
| llvmArgs.push_back(LAI.llvmTypePtr); |
| } else { |
| llvmArgs.push_back(LAI.llvmType); |
| } |
| } |
| |
| #if defined(ISOLATE_SHARING) |
| // cached constant pool |
| llvmArgs.push_back(Compiler->getIntrinsics()->ConstantPoolType); |
| #endif |
| |
| LLVMAssessorInfo& LAI = |
| Compiler->getTypedefInfo(signature->getReturnType()); |
| const llvm::Type* RetType = |
| LAI.llvmType == Compiler->getIntrinsics()->JavaObjectType ? |
| LAI.llvmTypePtr : LAI.llvmType; |
| nativeType = FunctionType::get(RetType, llvmArgs, false); |
| mvm::MvmModule::unprotectIR(); |
| } |
| return nativeType; |
| } |
| |
| |
| Function* LLVMSignatureInfo::createFunctionCallBuf(bool virt) { |
| |
| std::vector<Value*> Args; |
| |
| LLVMContext& context = Compiler->getLLVMModule()->getContext(); |
| J3Intrinsics& Intrinsics = *Compiler->getIntrinsics(); |
| Function* res = 0; |
| if (Compiler->isStaticCompiling()) { |
| const char* type = virt ? "virtual_buf" : "static_buf"; |
| char* buf = (char*)alloca((signature->keyName->size << 1) + 1 + 11); |
| signature->nativeName(buf, type); |
| res = Function::Create(virt ? getVirtualBufType() : getStaticBufType(), |
| GlobalValue::ExternalLinkage, buf, |
| Compiler->getLLVMModule()); |
| |
| |
| } else { |
| res = Function::Create(virt ? getVirtualBufType() : getStaticBufType(), |
| GlobalValue::ExternalLinkage, "", |
| Compiler->getLLVMModule()); |
| } |
| |
| BasicBlock* currentBlock = BasicBlock::Create(context, "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 = Compiler->getTypedefInfo(arguments[i]); |
| Value* arg = new LoadInst(ptr, "", currentBlock); |
| |
| if (arguments[i]->isReference()) { |
| arg = new IntToPtrInst(arg, Intrinsics.JavaObjectType, "", currentBlock); |
| Value* cmp = new ICmpInst(*currentBlock, ICmpInst::ICMP_EQ, |
| Intrinsics.JavaObjectNullConstant, |
| arg, ""); |
| BasicBlock* endBlock = BasicBlock::Create(context, "end", res); |
| BasicBlock* loadBlock = BasicBlock::Create(context, "load", res); |
| PHINode* node = PHINode::Create(Intrinsics.JavaObjectType, "", |
| endBlock); |
| node->addIncoming(Intrinsics.JavaObjectNullConstant, currentBlock); |
| BranchInst::Create(endBlock, loadBlock, cmp, currentBlock); |
| currentBlock = loadBlock; |
| arg = new BitCastInst(arg, |
| PointerType::getUnqual(Intrinsics.JavaObjectType), |
| "", currentBlock); |
| arg = new LoadInst(arg, "", false, currentBlock); |
| node->addIncoming(arg, currentBlock); |
| BranchInst::Create(endBlock, currentBlock); |
| currentBlock = endBlock; |
| arg = node; |
| } else if (arguments[i]->isFloat()) { |
| arg = new TruncInst(arg, Compiler->AssessorInfo[I_INT].llvmType, |
| "", currentBlock); |
| arg = new BitCastInst(arg, LAI.llvmType, "", currentBlock); |
| } else if (arguments[i]->isDouble()) { |
| arg = new BitCastInst(arg, LAI.llvmType, "", currentBlock); |
| } else if (!arguments[i]->isLong()){ |
| arg = new TruncInst(arg, LAI.llvmType, "", currentBlock); |
| } |
| Args.push_back(arg); |
| ptr = GetElementPtrInst::Create(ptr, Intrinsics.constantOne,"", |
| currentBlock); |
| } |
| |
| #if defined(ISOLATE_SHARING) |
| Args.push_back(ctp); |
| #endif |
| |
| Value* val = CallInst::Create(func, Args.begin(), Args.end(), "", |
| currentBlock); |
| if (!signature->getReturnType()->isVoid()) |
| ReturnInst::Create(context, val, currentBlock); |
| else |
| ReturnInst::Create(context, currentBlock); |
| |
| return res; |
| } |
| |
| Function* LLVMSignatureInfo::createFunctionCallAP(bool virt) { |
| |
| std::vector<Value*> Args; |
| |
| J3Intrinsics& Intrinsics = *Compiler->getIntrinsics(); |
| std::string name; |
| if (Compiler->isStaticCompiling()) { |
| name += UTF8Buffer(signature->keyName).cString(); |
| name += virt ? "virtual_ap" : "static_ap"; |
| } else { |
| name = ""; |
| } |
| |
| Function* res = Function::Create(virt ? getVirtualBufType() : |
| getStaticBufType(), |
| GlobalValue::InternalLinkage, name, |
| Compiler->getLLVMModule()); |
| LLVMContext& context = Compiler->getLLVMModule()->getContext(); |
| |
| BasicBlock* currentBlock = BasicBlock::Create(context, "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 = Compiler->getTypedefInfo(arguments[i]); |
| Value* arg = new VAArgInst(ap, LAI.llvmType, "", currentBlock); |
| if (arguments[i]->isReference()) { |
| arg = new IntToPtrInst(arg, Intrinsics.JavaObjectType, "", currentBlock); |
| Value* cmp = new ICmpInst(*currentBlock, ICmpInst::ICMP_EQ, |
| Intrinsics.JavaObjectNullConstant, |
| arg, ""); |
| BasicBlock* endBlock = BasicBlock::Create(context, "end", res); |
| BasicBlock* loadBlock = BasicBlock::Create(context, "load", res); |
| PHINode* node = PHINode::Create(Intrinsics.JavaObjectType, "", |
| endBlock); |
| node->addIncoming(Intrinsics.JavaObjectNullConstant, currentBlock); |
| BranchInst::Create(endBlock, loadBlock, cmp, currentBlock); |
| currentBlock = loadBlock; |
| arg = new BitCastInst(arg, |
| PointerType::getUnqual(Intrinsics.JavaObjectType), |
| "", currentBlock); |
| arg = new LoadInst(arg, "", false, currentBlock); |
| node->addIncoming(arg, currentBlock); |
| BranchInst::Create(endBlock, currentBlock); |
| currentBlock = endBlock; |
| arg = node; |
| } |
| Args.push_back(arg); |
| } |
| |
| #if defined(ISOLATE_SHARING) |
| Args.push_back(ctp); |
| #endif |
| |
| Value* val = CallInst::Create(func, Args.begin(), Args.end(), "", |
| currentBlock); |
| if (!signature->getReturnType()->isVoid()) |
| ReturnInst::Create(context, val, currentBlock); |
| else |
| ReturnInst::Create(context, currentBlock); |
| |
| return res; |
| } |
| |
| Function* LLVMSignatureInfo::createFunctionStub(bool special, bool virt) { |
| |
| std::vector<Value*> Args; |
| std::vector<Value*> FunctionArgs; |
| |
| J3Intrinsics& Intrinsics = *Compiler->getIntrinsics(); |
| std::string name; |
| if (Compiler->isStaticCompiling()) { |
| name += UTF8Buffer(signature->keyName).cString(); |
| name += virt ? "virtual_stub" : special ? "special_stub" : "static_stub"; |
| } else { |
| name = ""; |
| } |
| |
| Function* stub = Function::Create((virt || special) ? getVirtualType() : |
| getStaticType(), |
| GlobalValue::InternalLinkage, name, |
| Compiler->getLLVMModule()); |
| LLVMContext& context = Compiler->getLLVMModule()->getContext(); |
| |
| BasicBlock* currentBlock = BasicBlock::Create(context, "enter", stub); |
| BasicBlock* endBlock = BasicBlock::Create(context, "end", stub); |
| BasicBlock* callBlock = BasicBlock::Create(context, "call", stub); |
| PHINode* node = NULL; |
| if (!signature->getReturnType()->isVoid()) { |
| node = PHINode::Create(stub->getReturnType(), "", endBlock); |
| } |
| |
| Function::arg_iterator arg = stub->arg_begin(); |
| Value *obj = NULL; |
| if (virt) { |
| obj = arg; |
| Args.push_back(obj); |
| } |
| |
| for (; arg != stub->arg_end() ; ++arg) { |
| FunctionArgs.push_back(arg); |
| if (Compiler->useCooperativeGC()) { |
| if (arg->getType() == Intrinsics.JavaObjectType) { |
| Value* GCArgs[2] = { |
| new BitCastInst(arg, Intrinsics.ptrPtrType, "", currentBlock), |
| Intrinsics.constantPtrNull |
| }; |
| |
| CallInst::Create(Intrinsics.llvm_gc_gcroot, GCArgs, GCArgs + 2, "", |
| currentBlock); |
| } |
| } |
| } |
| |
| Value* val = CallInst::Create(virt ? Intrinsics.ResolveVirtualStubFunction : |
| special ? Intrinsics.ResolveSpecialStubFunction: |
| Intrinsics.ResolveStaticStubFunction, |
| Args.begin(), Args.end(), "", currentBlock); |
| |
| Constant* nullValue = Constant::getNullValue(val->getType()); |
| Value* cmp = new ICmpInst(*currentBlock, ICmpInst::ICMP_EQ, |
| nullValue, val, ""); |
| BranchInst::Create(endBlock, callBlock, cmp, currentBlock); |
| if (node) node->addIncoming(Constant::getNullValue(node->getType()), |
| currentBlock); |
| |
| currentBlock = callBlock; |
| Value* Func = new BitCastInst(val, stub->getType(), "", currentBlock); |
| Value* res = CallInst::Create(Func, FunctionArgs.begin(), FunctionArgs.end(), |
| "", currentBlock); |
| if (node) node->addIncoming(res, currentBlock); |
| BranchInst::Create(endBlock, currentBlock); |
| |
| currentBlock = endBlock; |
| if (node) { |
| ReturnInst::Create(context, node, currentBlock); |
| } else { |
| ReturnInst::Create(context, currentBlock); |
| } |
| |
| return stub; |
| } |
| |
| 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<const llvm::Type*> Args; |
| Args.push_back(Compiler->getIntrinsics()->ConstantPoolType); // ctp |
| Args.push_back(getVirtualPtrType()); |
| Args.push_back(Compiler->getIntrinsics()->JavaObjectType); |
| Args.push_back(Compiler->AssessorInfo[I_LONG].llvmTypePtr); |
| LLVMAssessorInfo& LAI = |
| Compiler->getTypedefInfo(signature->getReturnType()); |
| virtualBufType = FunctionType::get(LAI.llvmType, Args, 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<const llvm::Type*> Args; |
| Args.push_back(Compiler->getIntrinsics()->ConstantPoolType); // ctp |
| Args.push_back(getStaticPtrType()); |
| Args.push_back(Compiler->AssessorInfo[I_LONG].llvmTypePtr); |
| LLVMAssessorInfo& LAI = |
| Compiler->getTypedefInfo(signature->getReturnType()); |
| staticBufType = FunctionType::get(LAI.llvmType, Args, false); |
| mvm::MvmModule::unprotectIR(); |
| } |
| return staticBufType; |
| } |
| |
| Function* LLVMSignatureInfo::getVirtualBuf() { |
| // Lock here because we are called by arbitrary code. Also put that here |
| // because we are waiting on virtualBufFunction to have an address. |
| mvm::MvmModule::protectIR(); |
| if (!virtualBufFunction) { |
| virtualBufFunction = createFunctionCallBuf(true); |
| if (!Compiler->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() { |
| // Lock here because we are called by arbitrary code. Also put that here |
| // because we are waiting on virtualAPFunction to have an address. |
| mvm::MvmModule::protectIR(); |
| if (!virtualAPFunction) { |
| virtualAPFunction = createFunctionCallAP(true); |
| if (!Compiler->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() { |
| // Lock here because we are called by arbitrary code. Also put that here |
| // because we are waiting on staticBufFunction to have an address. |
| mvm::MvmModule::protectIR(); |
| if (!staticBufFunction) { |
| staticBufFunction = createFunctionCallBuf(false); |
| if (!Compiler->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() { |
| // Lock here because we are called by arbitrary code. Also put that here |
| // because we are waiting on staticAPFunction to have an address. |
| mvm::MvmModule::protectIR(); |
| if (!staticAPFunction) { |
| staticAPFunction = createFunctionCallAP(false); |
| if (!Compiler->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; |
| } |
| |
| Function* LLVMSignatureInfo::getStaticStub() { |
| // Lock here because we are called by arbitrary code. Also put that here |
| // because we are waiting on staticStubFunction to have an address. |
| mvm::MvmModule::protectIR(); |
| if (!staticStubFunction) { |
| staticStubFunction = createFunctionStub(false, false); |
| if (!Compiler->isStaticCompiling()) { |
| signature->setStaticCallStub((intptr_t) |
| mvm::MvmModule::executionEngine->getPointerToGlobal(staticStubFunction)); |
| // Now that it's compiled, we don't need the IR anymore |
| staticStubFunction->deleteBody(); |
| } |
| } |
| mvm::MvmModule::unprotectIR(); |
| return staticStubFunction; |
| } |
| |
| Function* LLVMSignatureInfo::getSpecialStub() { |
| // Lock here because we are called by arbitrary code. Also put that here |
| // because we are waiting on specialStubFunction to have an address. |
| mvm::MvmModule::protectIR(); |
| if (!specialStubFunction) { |
| specialStubFunction = createFunctionStub(true, false); |
| if (!Compiler->isStaticCompiling()) { |
| signature->setSpecialCallStub((intptr_t) |
| mvm::MvmModule::executionEngine->getPointerToGlobal(specialStubFunction)); |
| // Now that it's compiled, we don't need the IR anymore |
| specialStubFunction->deleteBody(); |
| } |
| } |
| mvm::MvmModule::unprotectIR(); |
| return specialStubFunction; |
| } |
| |
| Function* LLVMSignatureInfo::getVirtualStub() { |
| // Lock here because we are called by arbitrary code. Also put that here |
| // because we are waiting on virtualStubFunction to have an address. |
| mvm::MvmModule::protectIR(); |
| if (!virtualStubFunction) { |
| virtualStubFunction = createFunctionStub(false, true); |
| if (!Compiler->isStaticCompiling()) { |
| signature->setVirtualCallStub((intptr_t) |
| mvm::MvmModule::executionEngine->getPointerToGlobal(virtualStubFunction)); |
| // Now that it's compiled, we don't need the IR anymore |
| virtualStubFunction->deleteBody(); |
| } |
| } |
| mvm::MvmModule::unprotectIR(); |
| return virtualStubFunction; |
| } |
| |
| void JavaLLVMCompiler::initialiseAssessorInfo() { |
| AssessorInfo[I_VOID].llvmType = Type::getVoidTy(getLLVMContext()); |
| AssessorInfo[I_VOID].llvmTypePtr = 0; |
| AssessorInfo[I_VOID].logSizeInBytesConstant = 0; |
| |
| AssessorInfo[I_BOOL].llvmType = Type::getInt8Ty(getLLVMContext()); |
| AssessorInfo[I_BOOL].llvmTypePtr = |
| PointerType::getUnqual(Type::getInt8Ty(getLLVMContext())); |
| AssessorInfo[I_BOOL].logSizeInBytesConstant = 0; |
| |
| AssessorInfo[I_BYTE].llvmType = Type::getInt8Ty(getLLVMContext()); |
| AssessorInfo[I_BYTE].llvmTypePtr = |
| PointerType::getUnqual(Type::getInt8Ty(getLLVMContext())); |
| AssessorInfo[I_BYTE].logSizeInBytesConstant = 0; |
| |
| AssessorInfo[I_SHORT].llvmType = Type::getInt16Ty(getLLVMContext()); |
| AssessorInfo[I_SHORT].llvmTypePtr = |
| PointerType::getUnqual(Type::getInt16Ty(getLLVMContext())); |
| AssessorInfo[I_SHORT].logSizeInBytesConstant = 1; |
| |
| AssessorInfo[I_CHAR].llvmType = Type::getInt16Ty(getLLVMContext()); |
| AssessorInfo[I_CHAR].llvmTypePtr = |
| PointerType::getUnqual(Type::getInt16Ty(getLLVMContext())); |
| AssessorInfo[I_CHAR].logSizeInBytesConstant = 1; |
| |
| AssessorInfo[I_INT].llvmType = Type::getInt32Ty(getLLVMContext()); |
| AssessorInfo[I_INT].llvmTypePtr = |
| PointerType::getUnqual(Type::getInt32Ty(getLLVMContext())); |
| AssessorInfo[I_INT].logSizeInBytesConstant = 2; |
| |
| AssessorInfo[I_FLOAT].llvmType = Type::getFloatTy(getLLVMContext()); |
| AssessorInfo[I_FLOAT].llvmTypePtr = |
| PointerType::getUnqual(Type::getFloatTy(getLLVMContext())); |
| AssessorInfo[I_FLOAT].logSizeInBytesConstant = 2; |
| |
| AssessorInfo[I_LONG].llvmType = Type::getInt64Ty(getLLVMContext()); |
| AssessorInfo[I_LONG].llvmTypePtr = |
| PointerType::getUnqual(Type::getInt64Ty(getLLVMContext())); |
| AssessorInfo[I_LONG].logSizeInBytesConstant = 3; |
| |
| AssessorInfo[I_DOUBLE].llvmType = Type::getDoubleTy(getLLVMContext()); |
| AssessorInfo[I_DOUBLE].llvmTypePtr = |
| PointerType::getUnqual(Type::getDoubleTy(getLLVMContext())); |
| AssessorInfo[I_DOUBLE].logSizeInBytesConstant = 3; |
| |
| AssessorInfo[I_TAB].llvmType = JavaIntrinsics.JavaObjectType; |
| AssessorInfo[I_TAB].llvmTypePtr = |
| PointerType::getUnqual(AssessorInfo[I_TAB].llvmType); |
| AssessorInfo[I_TAB].logSizeInBytesConstant = sizeof(JavaObject*) == 8 ? 3 : 2; |
| |
| AssessorInfo[I_REF].llvmType = AssessorInfo[I_TAB].llvmType; |
| AssessorInfo[I_REF].llvmTypePtr = AssessorInfo[I_TAB].llvmTypePtr; |
| AssessorInfo[I_REF].logSizeInBytesConstant = sizeof(JavaObject*) == 8 ? 3 : 2; |
| } |
| |
| LLVMAssessorInfo& JavaLLVMCompiler::getTypedefInfo(const Typedef* type) { |
| return AssessorInfo[type->getKey()->elements[0]]; |
| } |