blob: bac9919633675afba072acc6d58ffad15cf16d10 [file] [log] [blame]
//===--------- 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/Instructions.h"
#include "llvm/LLVMContext.h"
#include "llvm/Module.h"
#include "llvm/PassManager.h"
#include "llvm/Analysis/LoopPass.h"
#include "llvm/Target/TargetData.h"
#include "mvm/JIT.h"
#include "JavaArray.h"
#include "JavaClass.h"
#include "JavaJIT.h"
#include "JavaTypes.h"
#include "jnjvm/JnjvmModule.h"
#include "jnjvm/JnjvmModuleProvider.h"
using namespace jnjvm;
using namespace llvm;
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
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;
JavaLLVMCompiler::JavaLLVMCompiler(const std::string& str) :
TheModule(new llvm::Module(str, getGlobalContext())),
JavaIntrinsics(TheModule) {
enabledException = true;
cooperativeGC = false;
}
void JavaLLVMCompiler::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 JavaLLVMCompiler::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"
}
}
void JnjvmModule::initialise() {
Module* module = globalModule;
jnjvm::llvm_runtime::makeLLVMModuleContents(module);
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"));
LLVMAssessorInfo::initialise();
}
Function* JavaLLVMCompiler::getMethod(JavaMethod* meth) {
return getMethodInfo(meth)->getMethod();
}
JnjvmModule::JnjvmModule(llvm::Module* module) :
MvmModule(module) {
if (!VTType) {
initialise();
copyDefinitions(module, globalModule);
}
JavaObjectNullConstant =
Constant::getNullValue(JnjvmModule::JavaObjectType);
MaxArraySizeConstant = ConstantInt::get(Type::getInt32Ty(getGlobalContext()),
JavaArray::MaxArraySize);
JavaArraySizeConstant = ConstantInt::get(Type::getInt32Ty(getGlobalContext()),
sizeof(JavaObject) + sizeof(ssize_t));
JavaArrayElementsOffsetConstant = constantTwo;
JavaArraySizeOffsetConstant = constantOne;
JavaObjectLockOffsetConstant = constantOne;
JavaObjectVTOffsetConstant = constantZero;
OffsetClassInVTConstant = constantThree;
OffsetDepthInVTConstant = constantFour;
OffsetDisplayInVTConstant = constantSeven;
OffsetBaseClassVTInVTConstant =
ConstantInt::get(Type::getInt32Ty(getGlobalContext()), 17);
OffsetObjectSizeInClassConstant = constantOne;
OffsetVTInClassConstant =
ConstantInt::get(Type::getInt32Ty(getGlobalContext()), 7);
OffsetTaskClassMirrorInClassConstant = constantTwo;
OffsetStaticInstanceInTaskClassMirrorConstant = constantTwo;
OffsetStatusInTaskClassMirrorConstant = constantZero;
OffsetInitializedInTaskClassMirrorConstant = constantOne;
OffsetIsolateInThreadConstant =
ConstantInt::get(Type::getInt32Ty(getGlobalContext()), 3);
OffsetDoYieldInThreadConstant =
ConstantInt::get(Type::getInt32Ty(getGlobalContext()), 6);
OffsetJNIInThreadConstant =
ConstantInt::get(Type::getInt32Ty(getGlobalContext()), 12);
OffsetJavaExceptionInThreadConstant =
ConstantInt::get(Type::getInt32Ty(getGlobalContext()), 13);
OffsetCXXExceptionInThreadConstant =
ConstantInt::get(Type::getInt32Ty(getGlobalContext()), 14);
ClassReadyConstant =
ConstantInt::get(Type::getInt8Ty(getGlobalContext()), ready);
module->addTypeName("JavaObject", JavaObjectType->getContainedType(0));
module->addTypeName("JavaArray", JavaArrayType->getContainedType(0));
module->addTypeName("JavaCommonClass",
JavaCommonClassType->getContainedType(0));
module->addTypeName("JavaClass", JavaClassType->getContainedType(0));
module->addTypeName("JavaClassPrimitive",
JavaClassPrimitiveType->getContainedType(0));
module->addTypeName("JavaClassArray",
JavaClassArrayType->getContainedType(0));
module->addTypeName("ArrayUInt8", JavaArrayUInt8Type->getContainedType(0));
module->addTypeName("ArraySInt8", JavaArraySInt8Type->getContainedType(0));
module->addTypeName("ArrayUInt16", JavaArrayUInt16Type->getContainedType(0));
module->addTypeName("ArraySInt16", JavaArraySInt16Type->getContainedType(0));
module->addTypeName("ArraySInt32", JavaArraySInt32Type->getContainedType(0));
module->addTypeName("ArrayLong", JavaArrayLongType->getContainedType(0));
module->addTypeName("ArrayFloat", JavaArrayFloatType->getContainedType(0));
module->addTypeName("ArrayDouble", JavaArrayDoubleType->getContainedType(0));
module->addTypeName("ArrayObject", JavaArrayObjectType->getContainedType(0));
module->addTypeName("CacheNode", CacheNodeType->getContainedType(0));
module->addTypeName("Enveloppe", EnveloppeType->getContainedType(0));
InterfaceLookupFunction = module->getFunction("jnjvmInterfaceLookup");
MultiCallNewFunction = module->getFunction("jnjvmMultiCallNew");
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("jnjvmClassLookup");
GetVTFromClassFunction = module->getFunction("getVTFromClass");
GetVTFromClassArrayFunction = module->getFunction("getVTFromClassArray");
GetVTFromCommonClassFunction = module->getFunction("getVTFromCommonClass");
GetBaseClassVTFromVTFunction = module->getFunction("getBaseClassVTFromVT");
GetObjectSizeFromClassFunction =
module->getFunction("getObjectSizeFromClass");
GetClassDelegateeFunction = module->getFunction("getClassDelegatee");
RuntimeDelegateeFunction = module->getFunction("jnjvmRuntimeDelegatee");
IsAssignableFromFunction = module->getFunction("isAssignableFrom");
IsSecondaryClassFunction = module->getFunction("isSecondaryClass");
GetDepthFunction = module->getFunction("getDepth");
GetStaticInstanceFunction = module->getFunction("getStaticInstance");
GetDisplayFunction = module->getFunction("getDisplay");
GetVTInDisplayFunction = module->getFunction("getVTInDisplay");
AquireObjectFunction = module->getFunction("jnjvmJavaObjectAquire");
ReleaseObjectFunction = module->getFunction("jnjvmJavaObjectRelease");
OverflowThinLockFunction = module->getFunction("jnjvmOverflowThinLock");
VirtualFieldLookupFunction = module->getFunction("jnjvmVirtualFieldLookup");
StaticFieldLookupFunction = module->getFunction("jnjvmStaticFieldLookup");
StringLookupFunction = module->getFunction("jnjvmStringLookup");
StartJNIFunction = module->getFunction("jnjvmStartJNI");
EndJNIFunction = module->getFunction("jnjvmEndJNI");
NullPointerExceptionFunction =
module->getFunction("jnjvmNullPointerException");
ClassCastExceptionFunction = module->getFunction("jnjvmClassCastException");
IndexOutOfBoundsExceptionFunction =
module->getFunction("jnjvmIndexOutOfBoundsException");
NegativeArraySizeExceptionFunction =
module->getFunction("jnjvmNegativeArraySizeException");
OutOfMemoryErrorFunction = module->getFunction("jnjvmOutOfMemoryError");
StackOverflowErrorFunction = module->getFunction("jnjvmStackOverflowError");
ArrayStoreExceptionFunction = module->getFunction("jnjvmArrayStoreException");
ArithmeticExceptionFunction = module->getFunction("jnjvmArithmeticException");
JavaObjectAllocateFunction = module->getFunction("gcmalloc");
PrintExecutionFunction = module->getFunction("jnjvmPrintExecution");
PrintMethodStartFunction = module->getFunction("jnjvmPrintMethodStart");
PrintMethodEndFunction = module->getFunction("jnjvmPrintMethodEnd");
ThrowExceptionFunction = module->getFunction("jnjvmThrowException");
GetArrayClassFunction = module->getFunction("jnjvmGetArrayClass");
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_SHARING
EnveloppeLookupFunction = module->getFunction("jnjvmEnveloppeLookup");
GetCtpCacheNodeFunction = module->getFunction("getCtpCacheNode");
GetCtpClassFunction = module->getFunction("getCtpClass");
GetJnjvmExceptionClassFunction =
module->getFunction("getJnjvmExceptionClass");
GetJnjvmArrayClassFunction = module->getFunction("getJnjvmArrayClass");
StaticCtpLookupFunction = module->getFunction("jnjvmStaticCtpLookup");
SpecialCtpLookupFunction = module->getFunction("jnjvmSpecialCtpLookup");
#endif
#ifdef SERVICE
ServiceCallStartFunction = module->getFunction("jnjvmServiceCallStart");
ServiceCallStopFunction = module->getFunction("jnjvmServiceCallStop");
#endif
JavaObjectTracerFunction = module->getFunction("JavaObjectTracer");
EmptyTracerFunction = module->getFunction("EmptyTracer");
JavaArrayTracerFunction = module->getFunction("JavaArrayTracer");
ArrayObjectTracerFunction = module->getFunction("ArrayObjectTracer");
RegularObjectTracerFunction = module->getFunction("RegularObjectTracer");
#ifndef WITHOUT_VTABLE
VirtualLookupFunction = module->getFunction("jnjvmVirtualTableLookup");
#endif
GetLockFunction = module->getFunction("getLock");
ThrowExceptionFromJITFunction =
module->getFunction("jnjvmThrowExceptionFromJIT");
}
Function* JavaLLVMCompiler::parseFunction(JavaMethod* meth) {
LLVMMethodInfo* LMI = getMethodInfo(meth);
Function* func = LMI->getMethod();
// We are jitting. Take the lock.
JnjvmModule::protectIR();
if (func->hasNotBeenReadFromBitcode()) {
JavaJIT jit(this, meth, func);
if (isNative(meth->access)) {
jit.nativeCompile();
JnjvmModule::runPasses(func, JavaNativeFunctionPasses);
} else {
jit.javaCompile();
JnjvmModule::runPasses(func, JnjvmModule::globalFunctionPasses);
JnjvmModule::runPasses(func, JavaFunctionPasses);
}
func->setLinkage(GlobalValue::ExternalLinkage);
}
JnjvmModule::unprotectIR();
return func;
}
JavaMethod* JavaLLVMCompiler::getJavaMethod(llvm::Function* F) {
function_iterator E = functions.end();
function_iterator I = functions.find(F);
if (I == E) return 0;
return I->second;
}
JavaLLVMCompiler::~JavaLLVMCompiler() {
delete JavaFunctionPasses;
delete JavaNativeFunctionPasses;
delete TheModuleProvider;
}
namespace mvm {
llvm::FunctionPass* createEscapeAnalysisPass();
llvm::LoopPass* createLoopSafePointsPass();
}
namespace jnjvm {
llvm::FunctionPass* createLowerConstantCallsPass(JnjvmModule* M);
}
void JavaLLVMCompiler::addJavaPasses() {
JavaNativeFunctionPasses = new FunctionPassManager(TheModuleProvider);
JavaNativeFunctionPasses->add(new TargetData(TheModule));
// Lower constant calls to lower things like getClass used
// on synchronized methods.
JavaNativeFunctionPasses->add(createLowerConstantCallsPass(getIntrinsics()));
JavaFunctionPasses = new FunctionPassManager(TheModuleProvider);
JavaFunctionPasses->add(new TargetData(TheModule));
if (cooperativeGC)
JavaFunctionPasses->add(mvm::createLoopSafePointsPass());
JavaFunctionPasses->add(mvm::createEscapeAnalysisPass());
JavaFunctionPasses->add(createLowerConstantCallsPass(getIntrinsics()));
}