blob: 181bc91dbe47166b1143b349e5aebd1ac6fbadcf [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/IR/BasicBlock.h"
#include "llvm/IR/CallingConv.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/MutexGuard.h"
#include "llvm/IR/DataLayout.h"
#include "vmkit/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;
Type* LLVMClassInfo::getVirtualType() {
if (!virtualType) {
std::vector<llvm::Type*> fields;
const DataLayout* targetData = Compiler->TheDataLayout;
const StructLayout* sl = 0;
StructType* structType = 0;
LLVMContext& context = Compiler->getLLVMModule()->getContext();
if (classDef->super) {
LLVMClassInfo* CLI = Compiler->getClassInfo(classDef->super);
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 initalized");
structType = dyn_cast<StructType>(virtualType->getContainedType(0));
sl = targetData->getStructLayout(structType);
}
uint64 size = targetData->getTypeAllocSize(structType);
virtualSizeConstant = ConstantInt::get(Type::getInt32Ty(context), size);
// TODO: put that elsewhere.
// The class is resolved if it was precompiled.
if ((!classDef->isResolved() || Compiler->isStaticCompiling())
&& 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;
}
Type* LLVMClassInfo::getStaticType() {
if (!staticType) {
Class* cl = (Class*)classDef;
std::vector<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 DataLayout* targetData = Compiler->TheDataLayout;
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 = targetData->getTypeAllocSize(structType);
cl->staticSize = size;
}
}
return staticType;
}
Value* LLVMClassInfo::getVirtualSize() {
if (!virtualSizeConstant) {
getVirtualType();
assert(virtualSizeConstant && "No size for a class?");
}
return virtualSizeConstant;
}
static char* GetMethodName(vmkit::ThreadAllocator& allocator,
JavaMethod* methodDef,
Class* customizeFor) {
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*)allocator.Allocate(
3 + JNI_NAME_PRE_LEN + 1 + ((mnlen + clen + mtlen) << 3));
methodDef->jniConsFromMethOverloaded(buf + 1);
memcpy(buf, "JnJVM", 5);
if (customizeFor != NULL) {
int len = strlen(buf);
UTF8Buffer buffer(customizeFor->name);
buffer.toCompileName("_Customized");
buf[len] = '_';
buf[len + 1] = '_';
memcpy(buf + len + 2, buffer.cString(), strlen(buffer.cString()) + 1);
}
return buf;
}
Function* LLVMMethodInfo::getMethod(Class* customizeFor) {
assert(!isAbstract(methodDef->access));
bool customizing = false;
Function* result = NULL;
if (customizeFor != NULL && isCustomizable) {
customizing = true;
result = customizedVersions[customizeFor];
} else {
result = methodFunction;
}
if (result == NULL) {
if (Compiler->emitFunctionName()) {
vmkit::ThreadAllocator allocator;
char* buf = GetMethodName(
allocator, methodDef, customizing ? customizeFor : NULL);
result = Function::Create(getFunctionType(),
GlobalValue::ExternalWeakLinkage, buf,
Compiler->getLLVMModule());
} else {
result = Function::Create(getFunctionType(),
GlobalValue::ExternalWeakLinkage,
"", Compiler->getLLVMModule());
}
result->setGC("vmkit");
if (Compiler->useCooperativeGC()) {
result->addFnAttr(Attribute::NoInline);
}
result->addFnAttr(Attribute::NoUnwind);
Compiler->functions.insert(std::make_pair(result, methodDef));
if (!Compiler->isStaticCompiling() && !customizing && methodDef->code) {
Compiler->setMethod(result, methodDef->code, result->getName().data());
}
}
if (customizing) {
customizedVersions[customizeFor] = result;
} else {
methodFunction = result;
}
return result;
}
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;
}
llvm::FunctionType* LLVMSignatureInfo::getVirtualType() {
if (!virtualType) {
// Lock here because we are called by arbitrary code
vmkit::VmkitModule::protectIR();
std::vector<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);
}
LLVMAssessorInfo& LAI =
Compiler->getTypedefInfo(signature->getReturnType());
virtualType = FunctionType::get(LAI.llvmType, llvmArgs, false);
vmkit::VmkitModule::unprotectIR();
}
return virtualType;
}
llvm::FunctionType* LLVMSignatureInfo::getStaticType() {
if (!staticType) {
// Lock here because we are called by arbitrary code
vmkit::VmkitModule::protectIR();
std::vector<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);
}
LLVMAssessorInfo& LAI =
Compiler->getTypedefInfo(signature->getReturnType());
staticType = FunctionType::get(LAI.llvmType, llvmArgs, false);
vmkit::VmkitModule::unprotectIR();
}
return staticType;
}
llvm::FunctionType* LLVMSignatureInfo::getNativeType() {
if (!nativeType) {
// Lock here because we are called by arbitrary code
vmkit::VmkitModule::protectIR();
std::vector<llvm::Type*> llvmArgs;
uint32 size = signature->nbArguments;
Typedef* const* arguments = signature->getArgumentsType();
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);
llvm::Type* Ty = LAI.llvmType;
if (Ty == Compiler->getIntrinsics()->JavaObjectType) {
llvmArgs.push_back(LAI.llvmTypePtr);
} else {
llvmArgs.push_back(LAI.llvmType);
}
}
LLVMAssessorInfo& LAI =
Compiler->getTypedefInfo(signature->getReturnType());
llvm::Type* RetType =
LAI.llvmType == Compiler->getIntrinsics()->JavaObjectType ?
LAI.llvmTypePtr : LAI.llvmType;
nativeType = FunctionType::get(RetType, llvmArgs, false);
vmkit::VmkitModule::unprotectIR();
}
return nativeType;
}
llvm::FunctionType* LLVMSignatureInfo::getNativeStubType() {
// Lock here because we are called by arbitrary code
vmkit::VmkitModule::protectIR();
std::vector<llvm::Type*> llvmArgs;
uint32 size = signature->nbArguments;
Typedef* const* arguments = signature->getArgumentsType();
llvm::Type* Ty =
PointerType::getUnqual(Compiler->getIntrinsics()->JavaObjectType);
llvmArgs.push_back(PointerType::getUnqual(getNativeType())); // method
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);
llvm::Type* Ty = LAI.llvmType;
if (Ty == Compiler->getIntrinsics()->JavaObjectType) {
llvmArgs.push_back(LAI.llvmTypePtr);
} else {
llvmArgs.push_back(LAI.llvmType);
}
}
LLVMAssessorInfo& LAI =
Compiler->getTypedefInfo(signature->getReturnType());
llvm::Type* RetType =
LAI.llvmType == Compiler->getIntrinsics()->JavaObjectType ?
LAI.llvmTypePtr : LAI.llvmType;
FunctionType* FTy = FunctionType::get(RetType, llvmArgs, false);
vmkit::VmkitModule::unprotectIR();
return FTy;
}
Function* LLVMSignatureInfo::createFunctionCallBuf(bool virt) {
std::vector<Value*> Args;
LLVMContext& context = Compiler->getLLVMModule()->getContext();
J3Intrinsics& Intrinsics = *Compiler->getIntrinsics();
Function* res = 0;
FunctionType* FTy = virt ? getVirtualBufType() : getStaticBufType();
if (virt) {
res = Compiler->virtualBufs[FTy];
} else {
res = Compiler->staticBufs[FTy];
}
if (res != NULL) {
return res;
}
if (Compiler->isStaticCompiling()) {
vmkit::ThreadAllocator allocator;
const char* type = virt ? "virtual_buf" : "static_buf";
char* buf = (char*)allocator.Allocate(
(signature->keyName->size << 1) + 1 + 11);
signature->nativeName(buf, type);
res = Function::Create(
FTy, GlobalValue::ExternalLinkage, buf, Compiler->getLLVMModule());
} else {
res = Function::Create(
FTy, GlobalValue::ExternalLinkage, "", Compiler->getLLVMModule());
}
BasicBlock* currentBlock = BasicBlock::Create(context, "enter", res);
Function::arg_iterator i = res->arg_begin();
Value *obj, *ptr, *func;
++i;
func = i;
func->setName("func");
++i;
if (virt) {
obj = i;
++i;
Args.push_back(obj);
obj->setName("object");
}
ptr = i;
ptr->setName("nextArgPtr");
Typedef* const* arguments = signature->getArgumentsType();
for (uint32 i = 0; i < signature->nbArguments; ++i) {
LLVMAssessorInfo& LAI = Compiler->getTypedefInfo(arguments[i]);
Value* arg = new LoadInst(ptr, "loadedArg", currentBlock);
if (arguments[i]->isReference()) {
arg = new IntToPtrInst(arg, Intrinsics.JavaObjectType, "", currentBlock);
Value* cmp = new ICmpInst(*currentBlock, ICmpInst::ICMP_EQ,
Intrinsics.JavaObjectNullConstant,
arg, "isNullRefArg");
BasicBlock* endBlock = BasicBlock::Create(context, "refArgDone", res);
BasicBlock* loadBlock = BasicBlock::Create(context, "loadRefArg", res);
PHINode* node = PHINode::Create(Intrinsics.JavaObjectType, 2, "refArg",
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, "loadedRefArg", 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, "arg", currentBlock);
} else if (arguments[i]->isDouble()) {
arg = new BitCastInst(arg, LAI.llvmType, "arg", currentBlock);
} else if (!arguments[i]->isLong()){
arg = new TruncInst(arg, LAI.llvmType, "arg", currentBlock);
}
Args.push_back(arg);
ptr = GetElementPtrInst::Create(ptr, Intrinsics.constantOne,"nextArgPtr",
currentBlock);
}
Value* val = CallInst::Create(func, Args, signature->getReturnType()->isVoid() ? "" : "retVal", currentBlock);
if (!signature->getReturnType()->isVoid()) {
ReturnInst::Create(context, val, currentBlock);
} else {
ReturnInst::Create(context, currentBlock);
}
res->setGC("vmkit");
res->addFnAttr(Attribute::NoInline);
res->addFnAttr(Attribute::NoUnwind);
if (virt) {
Compiler->virtualBufs[FTy] = res;
} else {
Compiler->staticBufs[FTy] = res;
}
return res;
}
Function* LLVMSignatureInfo::createFunctionCallAP(bool virt) {
std::vector<Value*> Args;
J3Intrinsics& Intrinsics = *Compiler->getIntrinsics();
Function* res = NULL;
FunctionType* FTy = virt ? getVirtualBufType() : getStaticBufType();
if (virt) {
res = Compiler->virtualAPs[FTy];
} else {
res = Compiler->staticAPs[FTy];
}
if (res != NULL) {
return res;
}
if (Compiler->isStaticCompiling()) {
vmkit::ThreadAllocator allocator;
const char* type = virt ? "virtual_ap" : "static_ap";
char* buf = (char*)allocator.Allocate(
(signature->keyName->size << 1) + 1 + 11);
signature->nativeName(buf, type);
res = Function::Create(
FTy, GlobalValue::ExternalLinkage, buf, Compiler->getLLVMModule());
} else {
res = Function::Create(
FTy, GlobalValue::ExternalLinkage, "", 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;
++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, 2, "",
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);
}
Value* val = CallInst::Create(func, Args, "", currentBlock);
if (!signature->getReturnType()->isVoid()) {
ReturnInst::Create(context, val, currentBlock);
} else {
ReturnInst::Create(context, currentBlock);
}
res->setGC("vmkit");
res->addFnAttr(Attribute::NoInline);
res->addFnAttr(Attribute::NoUnwind);
if (virt) {
Compiler->virtualAPs[FTy] = res;
} else {
Compiler->staticAPs[FTy] = res;
}
return res;
}
Function* LLVMSignatureInfo::createFunctionStub(bool special, bool virt) {
std::vector<Value*> Args;
std::vector<Value*> FunctionArgs;
std::vector<Value*> TempArgs;
J3Intrinsics& Intrinsics = *Compiler->getIntrinsics();
Function* stub = NULL;
FunctionType* FTy = (virt || special)? getVirtualType() : getStaticType();
if (virt) {
stub = Compiler->virtualStubs[FTy];
} else if (special) {
stub = Compiler->specialStubs[FTy];
} else {
stub = Compiler->staticStubs[FTy];
}
if (stub != NULL) {
return stub;
}
if (Compiler->isStaticCompiling()) {
vmkit::ThreadAllocator allocator;
const char* type = virt ? "virtual_stub" : special ? "special_stub" : "static_stub";
char* buf = (char*)allocator.Allocate(
(signature->keyName->size << 1) + 1 + 11);
signature->nativeName(buf, type);
stub = Function::Create(
FTy, GlobalValue::ExternalLinkage, buf, Compiler->getLLVMModule());
} else {
stub = Function::Create(
FTy, GlobalValue::ExternalLinkage, "", 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(), 2, "retVal", endBlock);
}
for (Function::arg_iterator arg = stub->arg_begin();
arg != stub->arg_end(); ++arg) {
Value* temp = arg;
if (Compiler->useCooperativeGC() &&
arg->getType() == Intrinsics.JavaObjectType) {
temp = new AllocaInst(Intrinsics.JavaObjectType, "arg", currentBlock);
new StoreInst(arg, temp, "", currentBlock);
Value* GCArgs[2] = {
new BitCastInst(temp, Intrinsics.ptrPtrType, "", currentBlock),
Intrinsics.constantPtrNull
};
CallInst::Create(Intrinsics.llvm_gc_gcroot, GCArgs, "", currentBlock);
} else
arg->setName("arg");
TempArgs.push_back(temp);
}
if (virt) {
if (Compiler->useCooperativeGC()) {
Args.push_back(new LoadInst(TempArgs[0], "object", false, currentBlock));
} else {
TempArgs[0]->setName("object");
Args.push_back(TempArgs[0]);
}
}
Value* val = CallInst::Create(virt ? Intrinsics.ResolveVirtualStubFunction :
special ? Intrinsics.ResolveSpecialStubFunction:
Intrinsics.ResolveStaticStubFunction,
Args, "resolvedFuncPtr", currentBlock);
Constant* nullValue = Constant::getNullValue(val->getType());
Value* cmp = new ICmpInst(*currentBlock, ICmpInst::ICMP_EQ,
nullValue, val, "isNotResolved");
BranchInst::Create(endBlock, callBlock, cmp, currentBlock);
if (node) node->addIncoming(Constant::getNullValue(node->getType()),
currentBlock);
currentBlock = callBlock;
Value* Func = new BitCastInst(val, stub->getType(), "resolvedFunc", currentBlock);
int i = 0;
for (Function::arg_iterator arg = stub->arg_begin();
arg != stub->arg_end(); ++arg, ++i) {
Value* temp = arg;
if (Compiler->useCooperativeGC() &&
arg->getType() == Intrinsics.JavaObjectType) {
temp = new LoadInst(TempArgs[i], "arg", false, currentBlock);
} else
temp->setName("arg");
FunctionArgs.push_back(temp);
}
Value* res = CallInst::Create(Func, FunctionArgs, node ? "funcRetVal" : "", 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);
}
stub->setGC("vmkit");
stub->addFnAttr(Attribute::NoInline);
stub->addFnAttr(Attribute::NoUnwind);
if (virt) {
Compiler->virtualStubs[FTy] = stub;
} else if (special) {
Compiler->specialStubs[FTy] = stub;
} else {
Compiler->staticStubs[FTy] = stub;
}
return stub;
}
PointerType* LLVMSignatureInfo::getStaticPtrType() {
if (!staticPtrType) {
staticPtrType = PointerType::getUnqual(getStaticType());
}
return staticPtrType;
}
PointerType* LLVMSignatureInfo::getVirtualPtrType() {
if (!virtualPtrType) {
virtualPtrType = PointerType::getUnqual(getVirtualType());
}
return virtualPtrType;
}
PointerType* LLVMSignatureInfo::getNativePtrType() {
if (!nativePtrType) {
nativePtrType = PointerType::getUnqual(getNativeType());
}
return nativePtrType;
}
FunctionType* LLVMSignatureInfo::getVirtualBufType() {
if (!virtualBufType) {
// Lock here because we are called by arbitrary code
vmkit::VmkitModule::protectIR();
std::vector<llvm::Type*> Args;
Args.push_back(Compiler->getIntrinsics()->ResolvedConstantPoolType); // 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);
vmkit::VmkitModule::unprotectIR();
}
return virtualBufType;
}
FunctionType* LLVMSignatureInfo::getStaticBufType() {
if (!staticBufType) {
// Lock here because we are called by arbitrary code
vmkit::VmkitModule::protectIR();
std::vector<llvm::Type*> Args;
Args.push_back(Compiler->getIntrinsics()->ResolvedConstantPoolType); // 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);
vmkit::VmkitModule::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.
vmkit::VmkitModule::protectIR();
if (!virtualBufFunction) {
virtualBufFunction = createFunctionCallBuf(true);
signature->setVirtualCallBuf(Compiler->GenerateStub(virtualBufFunction));
}
vmkit::VmkitModule::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.
vmkit::VmkitModule::protectIR();
if (!virtualAPFunction) {
virtualAPFunction = createFunctionCallAP(true);
signature->setVirtualCallAP(Compiler->GenerateStub(virtualAPFunction));
}
vmkit::VmkitModule::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.
vmkit::VmkitModule::protectIR();
if (!staticBufFunction) {
staticBufFunction = createFunctionCallBuf(false);
signature->setStaticCallBuf(Compiler->GenerateStub(staticBufFunction));
}
vmkit::VmkitModule::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.
vmkit::VmkitModule::protectIR();
if (!staticAPFunction) {
staticAPFunction = createFunctionCallAP(false);
signature->setStaticCallAP(Compiler->GenerateStub(staticAPFunction));
}
vmkit::VmkitModule::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.
vmkit::VmkitModule::protectIR();
if (!staticStubFunction) {
staticStubFunction = createFunctionStub(false, false);
signature->setStaticCallStub(Compiler->GenerateStub(staticStubFunction));
}
vmkit::VmkitModule::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.
vmkit::VmkitModule::protectIR();
if (!specialStubFunction) {
specialStubFunction = createFunctionStub(true, false);
signature->setSpecialCallStub(Compiler->GenerateStub(specialStubFunction));
}
vmkit::VmkitModule::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.
vmkit::VmkitModule::protectIR();
if (!virtualStubFunction) {
virtualStubFunction = createFunctionStub(false, true);
signature->setVirtualCallStub(Compiler->GenerateStub(virtualStubFunction));
}
vmkit::VmkitModule::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]];
}