blob: a8d967c08f55cb5330524394bb901937f738592e [file] [log] [blame]
//===--- 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]];
}