| //===--------- 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/CallingConv.h" |
| #include "llvm/Instructions.h" |
| #include "llvm/Support/MutexGuard.h" |
| |
| |
| #include "mvm/JIT.h" |
| |
| #include "JavaThread.h" |
| #include "JavaTypes.h" |
| #include "Jnjvm.h" |
| #include "JnjvmModule.h" |
| #include "JnjvmModuleProvider.h" |
| |
| |
| using namespace jnjvm; |
| using namespace llvm; |
| |
| |
| #ifdef WITH_TRACER |
| const llvm::FunctionType* JnjvmModule::MarkAndTraceType = 0; |
| #endif |
| |
| const llvm::Type* JnjvmModule::JavaObjectType = 0; |
| const llvm::Type* JnjvmModule::JavaArrayType = 0; |
| const llvm::Type* JnjvmModule::JavaArrayUInt8Type = 0; |
| const llvm::Type* JnjvmModule::JavaArraySInt8Type = 0; |
| const llvm::Type* JnjvmModule::JavaArrayUInt16Type = 0; |
| const llvm::Type* JnjvmModule::JavaArraySInt16Type = 0; |
| const llvm::Type* JnjvmModule::JavaArrayUInt32Type = 0; |
| const llvm::Type* JnjvmModule::JavaArraySInt32Type = 0; |
| const llvm::Type* JnjvmModule::JavaArrayFloatType = 0; |
| const llvm::Type* JnjvmModule::JavaArrayDoubleType = 0; |
| const llvm::Type* JnjvmModule::JavaArrayLongType = 0; |
| const llvm::Type* JnjvmModule::JavaArrayObjectType = 0; |
| const llvm::Type* JnjvmModule::CacheNodeType = 0; |
| const llvm::Type* JnjvmModule::EnveloppeType = 0; |
| const llvm::Type* JnjvmModule::JnjvmType = 0; |
| const llvm::Type* JnjvmModule::ConstantPoolType = 0; |
| |
| llvm::Constant* JnjvmModule::JavaObjectNullConstant; |
| llvm::Constant* JnjvmModule::UTF8NullConstant; |
| llvm::Constant* JnjvmModule::JavaClassNullConstant; |
| llvm::Constant* JnjvmModule::MaxArraySizeConstant; |
| llvm::Constant* JnjvmModule::JavaObjectSizeConstant; |
| llvm::Constant* JnjvmModule::JavaArraySizeConstant; |
| llvm::ConstantInt* JnjvmModule::OffsetObjectSizeInClassConstant; |
| llvm::ConstantInt* JnjvmModule::OffsetVTInClassConstant; |
| llvm::ConstantInt* JnjvmModule::OffsetDepthInClassConstant; |
| llvm::ConstantInt* JnjvmModule::OffsetDisplayInClassConstant; |
| llvm::ConstantInt* JnjvmModule::OffsetStatusInClassConstant; |
| llvm::ConstantInt* JnjvmModule::OffsetTaskClassMirrorInClassConstant; |
| llvm::ConstantInt* JnjvmModule::OffsetStaticInstanceInTaskClassMirrorConstant; |
| llvm::ConstantInt* JnjvmModule::OffsetStatusInTaskClassMirrorConstant; |
| llvm::ConstantInt* JnjvmModule::ClassReadyConstant; |
| const llvm::Type* JnjvmModule::JavaClassType; |
| const llvm::Type* JnjvmModule::VTType; |
| llvm::ConstantInt* JnjvmModule::JavaArrayElementsOffsetConstant; |
| llvm::ConstantInt* JnjvmModule::JavaArraySizeOffsetConstant; |
| llvm::ConstantInt* JnjvmModule::JavaObjectLockOffsetConstant; |
| llvm::ConstantInt* JnjvmModule::JavaObjectClassOffsetConstant; |
| |
| Value* JnjvmModule::getNativeClass(CommonClass* classDef) { |
| llvm::GlobalVariable* varGV = 0; |
| native_class_iterator End = nativeClasses.end(); |
| native_class_iterator I = nativeClasses.find(classDef); |
| if (I == End) { |
| Constant* cons = |
| ConstantExpr::getIntToPtr(ConstantInt::get(Type::Int64Ty, |
| uint64_t (classDef)), |
| JnjvmModule::JavaClassType); |
| |
| varGV = new GlobalVariable(JnjvmModule::JavaClassType, !staticCompilation, |
| GlobalValue::ExternalLinkage, |
| cons, "", this); |
| |
| nativeClasses.insert(std::make_pair(classDef, varGV)); |
| } else { |
| varGV = I->second; |
| } |
| return varGV; |
| } |
| |
| Value* JnjvmModule::getConstantPool(JavaConstantPool* ctp) { |
| llvm::GlobalVariable* varGV = 0; |
| constant_pool_iterator End = constantPools.end(); |
| constant_pool_iterator I = constantPools.find(ctp); |
| if (I == End) { |
| void* ptr = ctp->ctpRes; |
| assert(ptr && "No constant pool found"); |
| Constant* cons = |
| ConstantExpr::getIntToPtr(ConstantInt::get(Type::Int64Ty, uint64(ptr)), |
| mvm::MvmModule::ptrPtrType); |
| varGV = new GlobalVariable(mvm::MvmModule::ptrPtrType, !staticCompilation, |
| GlobalValue::ExternalLinkage, |
| cons, "", this); |
| constantPools.insert(std::make_pair(ctp, varGV)); |
| } else { |
| varGV = I->second; |
| } |
| return varGV; |
| } |
| |
| Value* JnjvmModule::getString(JavaString* str) { |
| llvm::GlobalVariable* varGV; |
| string_iterator SI = strings.find(str); |
| if (SI != strings.end()) { |
| varGV = SI->second; |
| } else { |
| void* ptr = str; |
| assert(ptr && "No string given"); |
| Constant* cons = |
| ConstantExpr::getIntToPtr(ConstantInt::get(Type::Int64Ty, uint64(ptr)), |
| JnjvmModule::JavaObjectType); |
| varGV = new GlobalVariable(JnjvmModule::JavaObjectType, !staticCompilation, |
| GlobalValue::ExternalLinkage, |
| cons, "", this); |
| strings.insert(std::make_pair(str, varGV)); |
| } |
| return varGV; |
| } |
| |
| Value* JnjvmModule::getEnveloppe(Enveloppe* enveloppe) { |
| llvm::GlobalVariable* varGV; |
| enveloppe_iterator SI = enveloppes.find(enveloppe); |
| if (SI != enveloppes.end()) { |
| varGV = SI->second; |
| } else { |
| void* ptr = enveloppe; |
| assert(ptr && "No enveloppe given"); |
| Constant* cons = |
| ConstantExpr::getIntToPtr(ConstantInt::get(Type::Int64Ty, uint64(ptr)), |
| JnjvmModule::EnveloppeType); |
| varGV = new GlobalVariable(JnjvmModule::EnveloppeType, !staticCompilation, |
| GlobalValue::ExternalLinkage, |
| cons, "", this); |
| enveloppes.insert(std::make_pair(enveloppe, varGV)); |
| } |
| return varGV; |
| } |
| |
| Value* JnjvmModule::getJavaClass(CommonClass* cl) { |
| llvm::GlobalVariable* varGV = 0; |
| java_class_iterator End = javaClasses.end(); |
| java_class_iterator I = javaClasses.find(cl); |
| if (I == End) { |
| |
| JavaObject* obj = isStaticCompiling() ? 0 : |
| cl->getClassDelegatee(JavaThread::get()->getJVM()); |
| assert((obj || isStaticCompiling()) && "Delegatee not created"); |
| Constant* cons = |
| ConstantExpr::getIntToPtr(ConstantInt::get(Type::Int64Ty, uint64(obj)), |
| JnjvmModule::JavaObjectType); |
| varGV = new GlobalVariable(JnjvmModule::JavaObjectType, !staticCompilation, |
| GlobalValue::ExternalLinkage, |
| cons, "", this); |
| |
| javaClasses.insert(std::make_pair(cl, varGV)); |
| } else { |
| varGV = I->second; |
| } |
| return varGV; |
| } |
| |
| Value* JnjvmModule::getStaticInstance(Class* classDef) { |
| llvm::GlobalVariable* varGV = 0; |
| static_instance_iterator End = staticInstances.end(); |
| static_instance_iterator I = staticInstances.find(classDef); |
| if (I == End) { |
| LLVMClassInfo* LCI = getClassInfo(classDef); |
| LCI->getStaticType(); |
| JavaObject* obj = ((Class*)classDef)->getStaticInstance(); |
| #ifndef ISOLATE |
| if (!obj && !isStaticCompiling()) { |
| Class* cl = (Class*)classDef; |
| classDef->acquire(); |
| obj = cl->getStaticInstance(); |
| if (!obj) { |
| // Allocate now so that compiled code can reference it. |
| obj = cl->allocateStaticInstance(JavaThread::get()->getJVM()); |
| } |
| classDef->release(); |
| } |
| #endif |
| Constant* cons = |
| ConstantExpr::getIntToPtr(ConstantInt::get(Type::Int64Ty, |
| uint64_t (obj)), JnjvmModule::JavaObjectType); |
| |
| varGV = new GlobalVariable(JnjvmModule::JavaObjectType, !staticCompilation, |
| GlobalValue::ExternalLinkage, |
| cons, "", this); |
| |
| staticInstances.insert(std::make_pair(classDef, varGV)); |
| } else { |
| varGV = I->second; |
| } |
| |
| return varGV; |
| } |
| |
| Value* JnjvmModule::getVirtualTable(CommonClass* classDef) { |
| llvm::GlobalVariable* varGV = 0; |
| virtual_table_iterator End = virtualTables.end(); |
| virtual_table_iterator I = virtualTables.find(classDef); |
| if (I == End) { |
| if (!classDef->isArray() && !classDef->isPrimitive()) { |
| LLVMClassInfo* LCI = getClassInfo((Class*)classDef); |
| LCI->getVirtualType(); |
| } |
| assert((classDef->virtualVT || isStaticCompiling()) && |
| "Virtual VT not created"); |
| Constant* cons = |
| ConstantExpr::getIntToPtr(ConstantInt::get(Type::Int64Ty, |
| uint64_t(classDef->virtualVT)), |
| JnjvmModule::VTType); |
| varGV = new GlobalVariable(JnjvmModule::VTType, !staticCompilation, |
| GlobalValue::ExternalLinkage, |
| cons, "", this); |
| |
| virtualTables.insert(std::make_pair(classDef, varGV)); |
| } else { |
| varGV = I->second; |
| } |
| return varGV; |
| } |
| |
| Value* JnjvmModule::getNativeFunction(JavaMethod* meth, void* ptr) { |
| llvm::GlobalVariable* varGV = 0; |
| native_function_iterator End = nativeFunctions.end(); |
| native_function_iterator I = nativeFunctions.find(meth); |
| if (I == End) { |
| |
| |
| LLVMSignatureInfo* LSI = getSignatureInfo(meth->getSignature()); |
| const llvm::Type* valPtrType = LSI->getNativePtrType(); |
| |
| assert((ptr || isStaticCompiling()) && "No native function given"); |
| |
| Constant* cons = |
| ConstantExpr::getIntToPtr(ConstantInt::get(Type::Int64Ty, uint64_t(ptr)), |
| valPtrType); |
| |
| varGV = new GlobalVariable(valPtrType, !staticCompilation, |
| GlobalValue::ExternalLinkage, |
| cons, "", this); |
| |
| nativeFunctions.insert(std::make_pair(meth, varGV)); |
| } else { |
| varGV = I->second; |
| } |
| return varGV; |
| } |
| |
| #ifndef WITHOUT_VTABLE |
| VirtualTable* JnjvmModule::allocateVT(Class* cl) { |
| for (uint32 i = 0; i < cl->nbVirtualMethods; ++i) { |
| JavaMethod& meth = cl->virtualMethods[i]; |
| if (meth.name->equals(cl->classLoader->bootstrapLoader->finalize)) { |
| meth.offset = 0; |
| } else { |
| JavaMethod* parent = cl->super? |
| cl->super->lookupMethodDontThrow(meth.name, meth.type, false, true, |
| 0) : |
| 0; |
| |
| uint64_t offset = 0; |
| if (!parent) { |
| offset = cl->virtualTableSize++; |
| meth.offset = offset; |
| } else { |
| offset = parent->offset; |
| meth.offset = parent->offset; |
| } |
| } |
| } |
| |
| uint64 size = cl->virtualTableSize; |
| mvm::BumpPtrAllocator& allocator = cl->classLoader->allocator; |
| VirtualTable* VT = (VirtualTable*)allocator.Allocate(size * sizeof(void*)); |
| if (cl->super) { |
| Class* super = (Class*)cl->super; |
| assert(cl->virtualTableSize >= cl->super->virtualTableSize && |
| "Super VT bigger than own VT"); |
| assert(super->virtualVT && "Super does not have a VT!"); |
| memcpy(VT, super->virtualVT, cl->super->virtualTableSize * sizeof(void*)); |
| } else { |
| memcpy(VT, JavaObject::VT, VT_SIZE); |
| } |
| return VT; |
| } |
| #endif |
| |
| |
| llvm::Function* JnjvmModule::makeTracer(Class* cl, bool stat) { |
| |
| LLVMClassInfo* LCI = (LLVMClassInfo*)getClassInfo(cl); |
| const Type* type = stat ? LCI->getStaticType() : LCI->getVirtualType(); |
| JavaField* fields = 0; |
| uint32 nbFields = 0; |
| if (stat) { |
| fields = cl->getStaticFields(); |
| nbFields = cl->nbStaticFields; |
| } else { |
| fields = cl->getVirtualFields(); |
| nbFields = cl->nbVirtualFields; |
| } |
| |
| Function* func = Function::Create(JnjvmModule::MarkAndTraceType, |
| GlobalValue::ExternalLinkage, |
| "markAndTraceObject", |
| this); |
| |
| Constant* zero = mvm::MvmModule::constantZero; |
| Argument* arg = func->arg_begin(); |
| BasicBlock* block = BasicBlock::Create("", func); |
| llvm::Value* realArg = new BitCastInst(arg, type, "", block); |
| |
| std::vector<Value*> Args; |
| Args.push_back(arg); |
| #ifdef MULTIPLE_GC |
| Value* GC = ++func->arg_begin(); |
| Args.push_back(GC); |
| #endif |
| if (stat || cl->super == 0) { |
| CallInst::Create(JavaObjectTracerFunction, Args.begin(), Args.end(), |
| "", block); |
| } else { |
| LLVMClassInfo* LCP = (LLVMClassInfo*)getClassInfo((Class*)(cl->super)); |
| CallInst::Create(LCP->getVirtualTracer(), Args.begin(), |
| Args.end(), "", block); |
| } |
| |
| for (uint32 i = 0; i < nbFields; ++i) { |
| JavaField& cur = fields[i]; |
| if (cur.getSignature()->trace()) { |
| LLVMFieldInfo* LFI = getFieldInfo(&cur); |
| std::vector<Value*> args; //size = 2 |
| args.push_back(zero); |
| args.push_back(LFI->getOffset()); |
| Value* ptr = GetElementPtrInst::Create(realArg, args.begin(), args.end(), |
| "",block); |
| Value* val = new LoadInst(ptr, "", block); |
| Value* valCast = new BitCastInst(val, JnjvmModule::JavaObjectType, "", |
| block); |
| std::vector<Value*> Args; |
| Args.push_back(valCast); |
| #ifdef MULTIPLE_GC |
| Args.push_back(GC); |
| #endif |
| CallInst::Create(JnjvmModule::MarkAndTraceFunction, Args.begin(), |
| Args.end(), "", block); |
| } |
| } |
| |
| ReturnInst::Create(block); |
| |
| if (!stat) { |
| LCI->virtualTracerFunction = func; |
| } else { |
| LCI->staticTracerFunction = func; |
| } |
| |
| return func; |
| } |
| |
| VirtualTable* JnjvmModule::makeVT(Class* cl, bool stat) { |
| |
| VirtualTable* VT = 0; |
| #ifndef WITHOUT_VTABLE |
| if (stat) { |
| #endif |
| mvm::BumpPtrAllocator& allocator = cl->classLoader->allocator; |
| VT = (VirtualTable*)allocator.Allocate(VT_SIZE); |
| memcpy(VT, JavaObject::VT, VT_SIZE); |
| #ifndef WITHOUT_VTABLE |
| } else { |
| if (cl->super) { |
| cl->virtualTableSize = cl->super->virtualTableSize; |
| } else { |
| cl->virtualTableSize = VT_NB_FUNCS; |
| } |
| |
| // Allocate the virtual table. |
| VT = allocateVT(cl); |
| |
| // Fill the virtual table with function pointers. |
| ExecutionEngine* EE = mvm::MvmModule::executionEngine; |
| for (uint32 i = 0; i < cl->nbVirtualMethods; ++i) { |
| JavaMethod& meth = cl->virtualMethods[i]; |
| LLVMMethodInfo* LMI = getMethodInfo(&meth); |
| Function* func = LMI->getMethod(); |
| |
| // Special handling for finalize method. Don't put a finalizer |
| // if there is none, or if it is empty. |
| if (meth.offset == 0) { |
| #ifdef ISOLATE_SHARING |
| ((void**)VT)[0] = 0; |
| #else |
| JnjvmClassLoader* loader = cl->classLoader; |
| Function* func = loader->getModuleProvider()->parseFunction(&meth); |
| if (!cl->super) meth.canBeInlined = true; |
| Function::iterator BB = func->begin(); |
| BasicBlock::iterator I = BB->begin(); |
| if (isa<ReturnInst>(I)) { |
| ((void**)VT)[0] = 0; |
| } else { |
| // LLVM does not allow recursive compilation. Create the code now. |
| ((void**)VT)[0] = EE->getPointerToFunction(func); |
| } |
| } |
| #endif |
| |
| if (staticCompilation) { |
| ((void**)VT)[meth.offset] = func; |
| } else { |
| ((void**)VT)[meth.offset] = EE->getPointerToFunctionOrStub(func); |
| } |
| } |
| |
| // If there is no super, then it's the first VT that we allocate. Assign |
| // this VT to native types. |
| if (!(cl->super)) { |
| uint32 size = (cl->virtualTableSize - VT_NB_FUNCS) * sizeof(void*); |
| #define COPY(CLASS) \ |
| memcpy((void*)((uintptr_t)CLASS::VT + VT_SIZE), \ |
| (void*)((uintptr_t)VT + VT_SIZE), size); |
| |
| COPY(JavaArray) |
| COPY(JavaObject) |
| COPY(ArrayObject) |
| |
| #undef COPY |
| } |
| } |
| #endif |
| |
| #ifdef WITH_TRACER |
| llvm::Function* func = makeTracer(cl, stat); |
| |
| if (staticCompilation) { |
| ((void**)VT)[VT_TRACER_OFFSET] = func; |
| } else { |
| void* codePtr = mvm::MvmModule::executionEngine->getPointerToFunction(func); |
| ((void**)VT)[VT_TRACER_OFFSET] = codePtr; |
| func->deleteBody(); |
| } |
| |
| |
| #endif |
| return VT; |
| } |
| |
| |
| const Type* LLVMClassInfo::getVirtualType() { |
| if (!virtualType) { |
| std::vector<const llvm::Type*> fields; |
| |
| if (classDef->super) { |
| LLVMClassInfo* CLI = |
| JnjvmModule::getClassInfo((Class*)classDef->super); |
| fields.push_back(CLI->getVirtualType()->getContainedType(0)); |
| } else { |
| fields.push_back(JnjvmModule::JavaObjectType->getContainedType(0)); |
| } |
| |
| for (uint32 i = 0; i < classDef->nbVirtualFields; ++i) { |
| JavaField& field = classDef->virtualFields[i]; |
| field.num = i; |
| Typedef* type = field.getSignature(); |
| LLVMAssessorInfo& LAI = JnjvmModule::getTypedefInfo(type); |
| fields.push_back(LAI.llvmType); |
| } |
| |
| |
| StructType* structType = StructType::get(fields, false); |
| virtualType = PointerType::getUnqual(structType); |
| ExecutionEngine* engine = mvm::MvmModule::executionEngine; |
| const TargetData* targetData = engine->getTargetData(); |
| const StructLayout* sl = targetData->getStructLayout(structType); |
| |
| for (uint32 i = 0; i < classDef->nbVirtualFields; ++i) { |
| JavaField& field = classDef->virtualFields[i]; |
| field.ptrOffset = sl->getElementOffset(i + 1); |
| } |
| |
| uint64 size = mvm::MvmModule::getTypeSize(structType); |
| classDef->virtualSize = (uint32)size; |
| virtualSizeConstant = ConstantInt::get(Type::Int32Ty, size); |
| |
| JnjvmModule* Mod = classDef->classLoader->getModule(); |
| if (!Mod->isStaticCompiling()) { |
| classDef->virtualVT = Mod->makeVT((Class*)classDef, false); |
| } |
| |
| |
| } |
| |
| return virtualType; |
| } |
| |
| const Type* LLVMClassInfo::getStaticType() { |
| |
| if (!staticType) { |
| Class* cl = (Class*)classDef; |
| std::vector<const llvm::Type*> fields; |
| fields.push_back(JnjvmModule::JavaObjectType->getContainedType(0)); |
| |
| for (uint32 i = 0; i < classDef->nbStaticFields; ++i) { |
| JavaField& field = classDef->staticFields[i]; |
| field.num = i; |
| Typedef* type = field.getSignature(); |
| LLVMAssessorInfo& LAI = JnjvmModule::getTypedefInfo(type); |
| fields.push_back(LAI.llvmType); |
| } |
| |
| StructType* structType = StructType::get(fields, false); |
| staticType = PointerType::getUnqual(structType); |
| ExecutionEngine* engine = mvm::MvmModule::executionEngine; |
| const TargetData* targetData = engine->getTargetData(); |
| const StructLayout* sl = targetData->getStructLayout(structType); |
| |
| for (uint32 i = 0; i < classDef->nbStaticFields; ++i) { |
| JavaField& field = classDef->staticFields[i]; |
| field.ptrOffset = sl->getElementOffset(i + 1); |
| } |
| |
| uint64 size = mvm::MvmModule::getTypeSize(structType); |
| cl->staticSize = size; |
| |
| JnjvmModule* Mod = cl->classLoader->getModule(); |
| if (!Mod->isStaticCompiling()) { |
| cl->staticVT = Mod->makeVT((Class*)classDef, true); |
| } |
| } |
| return staticType; |
| } |
| |
| |
| Value* LLVMClassInfo::getVirtualSize() { |
| if (!virtualSizeConstant) { |
| getVirtualType(); |
| virtualSizeConstant = |
| ConstantInt::get(Type::Int32Ty, classDef->virtualSize); |
| } |
| return virtualSizeConstant; |
| } |
| |
| Function* LLVMClassInfo::getStaticTracer() { |
| if (!staticTracerFunction) { |
| getStaticType(); |
| } |
| return staticTracerFunction; |
| } |
| |
| Function* LLVMClassInfo::getVirtualTracer() { |
| if (!virtualTracerFunction) { |
| getVirtualType(); |
| } |
| return virtualTracerFunction; |
| } |
| |
| Function* LLVMMethodInfo::getMethod() { |
| if (!methodFunction) { |
| JnjvmClassLoader* JCL = methodDef->classDef->classLoader; |
| JnjvmModule* Mod = JCL->getModule(); |
| if (Mod->isStaticCompiling()) { |
| const UTF8* jniConsClName = methodDef->classDef->name; |
| const UTF8* jniConsName = methodDef->name; |
| const UTF8* jniConsType = methodDef->type; |
| sint32 clen = jniConsClName->size; |
| sint32 mnlen = jniConsName->size; |
| sint32 mtlen = jniConsType->size; |
| |
| char* buf = |
| (char*)alloca(3 + JNI_NAME_PRE_LEN + mnlen + clen + (mtlen << 1)); |
| methodDef->jniConsFromMeth3(buf); |
| methodFunction = Function::Create(getFunctionType(), |
| GlobalValue::GhostLinkage, buf, Mod); |
| |
| } else { |
| |
| methodFunction = Function::Create(getFunctionType(), |
| GlobalValue::GhostLinkage, |
| "", Mod); |
| |
| } |
| methodFunction->addAnnotation(this); |
| } |
| return methodFunction; |
| } |
| |
| const FunctionType* LLVMMethodInfo::getFunctionType() { |
| if (!functionType) { |
| Signdef* sign = methodDef->getSignature(); |
| LLVMSignatureInfo* LSI = JnjvmModule::getSignatureInfo(sign); |
| assert(LSI); |
| if (isStatic(methodDef->access)) { |
| functionType = LSI->getStaticType(); |
| } else { |
| functionType = LSI->getVirtualType(); |
| } |
| } |
| return functionType; |
| } |
| |
| ConstantInt* LLVMMethodInfo::getOffset() { |
| if (!offsetConstant) { |
| JnjvmModule::resolveVirtualClass(methodDef->classDef); |
| offsetConstant = ConstantInt::get(Type::Int32Ty, methodDef->offset); |
| } |
| return offsetConstant; |
| } |
| |
| ConstantInt* LLVMFieldInfo::getOffset() { |
| if (!offsetConstant) { |
| if (isStatic(fieldDef->access)) { |
| JnjvmModule::resolveStaticClass(fieldDef->classDef); |
| } else { |
| JnjvmModule::resolveVirtualClass(fieldDef->classDef); |
| } |
| // Increment by one because zero is JavaObject |
| offsetConstant = ConstantInt::get(Type::Int32Ty, fieldDef->num + 1); |
| } |
| return offsetConstant; |
| } |
| |
| const llvm::FunctionType* LLVMSignatureInfo::getVirtualType() { |
| if (!virtualType) { |
| // Lock here because we are called by arbitrary code |
| llvm::MutexGuard locked(mvm::MvmModule::executionEngine->lock); |
| std::vector<const llvm::Type*> llvmArgs; |
| unsigned int size = signature->args.size(); |
| |
| llvmArgs.push_back(JnjvmModule::JavaObjectType); |
| |
| for (uint32 i = 0; i < size; ++i) { |
| Typedef* type = signature->args.at(i); |
| LLVMAssessorInfo& LAI = JnjvmModule::getTypedefInfo(type); |
| llvmArgs.push_back(LAI.llvmType); |
| } |
| |
| #if defined(ISOLATE_SHARING) |
| llvmArgs.push_back(JnjvmModule::ConstantPoolType); // cached constant pool |
| #endif |
| |
| LLVMAssessorInfo& LAI = JnjvmModule::getTypedefInfo(signature->ret); |
| virtualType = FunctionType::get(LAI.llvmType, llvmArgs, false); |
| } |
| return virtualType; |
| } |
| |
| const llvm::FunctionType* LLVMSignatureInfo::getStaticType() { |
| if (!staticType) { |
| // Lock here because we are called by arbitrary code |
| llvm::MutexGuard locked(mvm::MvmModule::executionEngine->lock); |
| std::vector<const llvm::Type*> llvmArgs; |
| unsigned int size = signature->args.size(); |
| |
| for (uint32 i = 0; i < size; ++i) { |
| Typedef* type = signature->args.at(i); |
| LLVMAssessorInfo& LAI = JnjvmModule::getTypedefInfo(type); |
| llvmArgs.push_back(LAI.llvmType); |
| } |
| |
| #if defined(ISOLATE_SHARING) |
| llvmArgs.push_back(JnjvmModule::ConstantPoolType); // cached constant pool |
| #endif |
| |
| LLVMAssessorInfo& LAI = JnjvmModule::getTypedefInfo(signature->ret); |
| staticType = FunctionType::get(LAI.llvmType, llvmArgs, false); |
| } |
| return staticType; |
| } |
| |
| const llvm::FunctionType* LLVMSignatureInfo::getNativeType() { |
| if (!nativeType) { |
| // Lock here because we are called by arbitrary code |
| llvm::MutexGuard locked(mvm::MvmModule::executionEngine->lock); |
| std::vector<const llvm::Type*> llvmArgs; |
| unsigned int size = signature->args.size(); |
| |
| llvmArgs.push_back(mvm::MvmModule::ptrType); // JNIEnv |
| llvmArgs.push_back(JnjvmModule::JavaObjectType); // Class |
| |
| for (uint32 i = 0; i < size; ++i) { |
| Typedef* type = signature->args.at(i); |
| LLVMAssessorInfo& LAI = JnjvmModule::getTypedefInfo(type); |
| llvmArgs.push_back(LAI.llvmType); |
| } |
| |
| #if defined(ISOLATE_SHARING) |
| llvmArgs.push_back(JnjvmModule::ConstantPoolType); // cached constant pool |
| #endif |
| |
| LLVMAssessorInfo& LAI = JnjvmModule::getTypedefInfo(signature->ret); |
| nativeType = FunctionType::get(LAI.llvmType, llvmArgs, false); |
| } |
| return nativeType; |
| } |
| |
| |
| Function* LLVMSignatureInfo::createFunctionCallBuf(bool virt) { |
| |
| std::vector<Value*> Args; |
| |
| Function* res = Function::Create(virt ? getVirtualBufType() : |
| getStaticBufType(), |
| GlobalValue::ExternalLinkage, |
| signature->printString(), |
| signature->initialLoader->TheModule); |
| |
| BasicBlock* currentBlock = BasicBlock::Create("enter", res); |
| Function::arg_iterator i = res->arg_begin(); |
| Value *obj, *ptr, *func; |
| #if defined(ISOLATE_SHARING) |
| Value* ctp = i; |
| #endif |
| ++i; |
| func = i; |
| ++i; |
| if (virt) { |
| obj = i; |
| ++i; |
| Args.push_back(obj); |
| } |
| ptr = i; |
| |
| for (std::vector<Typedef*>::iterator i = signature->args.begin(), |
| e = signature->args.end(); i!= e; ++i) { |
| |
| LLVMAssessorInfo& LAI = JnjvmModule::getTypedefInfo(*i); |
| Value* val = new BitCastInst(ptr, LAI.llvmTypePtr, "", currentBlock); |
| Value* arg = new LoadInst(val, "", currentBlock); |
| Args.push_back(arg); |
| ptr = GetElementPtrInst::Create(ptr, JnjvmModule::constantEight, "", |
| currentBlock); |
| } |
| |
| #if defined(ISOLATE_SHARING) |
| Args.push_back(ctp); |
| #endif |
| |
| Value* val = CallInst::Create(func, Args.begin(), Args.end(), "", |
| currentBlock); |
| if (res->getFunctionType()->getReturnType() != Type::VoidTy) |
| ReturnInst::Create(val, currentBlock); |
| else |
| ReturnInst::Create(currentBlock); |
| |
| return res; |
| } |
| |
| Function* LLVMSignatureInfo::createFunctionCallAP(bool virt) { |
| |
| std::vector<Value*> Args; |
| |
| Function* res = Function::Create(virt ? getVirtualBufType() : |
| getStaticBufType(), |
| GlobalValue::ExternalLinkage, |
| signature->printString(), |
| signature->initialLoader->TheModule); |
| |
| BasicBlock* currentBlock = BasicBlock::Create("enter", res); |
| Function::arg_iterator i = res->arg_begin(); |
| Value *obj, *ap, *func; |
| #if defined(ISOLATE_SHARING) |
| Value* ctp = i; |
| #endif |
| ++i; |
| func = i; |
| ++i; |
| if (virt) { |
| obj = i; |
| Args.push_back(obj); |
| ++i; |
| } |
| ap = i; |
| |
| for (std::vector<Typedef*>::iterator i = signature->args.begin(), |
| e = signature->args.end(); i!= e; i++) { |
| LLVMAssessorInfo& LAI = JnjvmModule::getTypedefInfo(*i); |
| Args.push_back(new VAArgInst(ap, LAI.llvmType, "", currentBlock)); |
| } |
| |
| #if defined(ISOLATE_SHARING) |
| Args.push_back(ctp); |
| #endif |
| |
| Value* val = CallInst::Create(func, Args.begin(), Args.end(), "", |
| currentBlock); |
| if (res->getFunctionType()->getReturnType() != Type::VoidTy) |
| ReturnInst::Create(val, currentBlock); |
| else |
| ReturnInst::Create(currentBlock); |
| |
| return res; |
| } |
| |
| const PointerType* LLVMSignatureInfo::getStaticPtrType() { |
| if (!staticPtrType) { |
| staticPtrType = PointerType::getUnqual(getStaticType()); |
| } |
| return staticPtrType; |
| } |
| |
| const PointerType* LLVMSignatureInfo::getVirtualPtrType() { |
| if (!virtualPtrType) { |
| virtualPtrType = PointerType::getUnqual(getVirtualType()); |
| } |
| return virtualPtrType; |
| } |
| |
| const PointerType* LLVMSignatureInfo::getNativePtrType() { |
| if (!nativePtrType) { |
| nativePtrType = PointerType::getUnqual(getNativeType()); |
| } |
| return nativePtrType; |
| } |
| |
| |
| const FunctionType* LLVMSignatureInfo::getVirtualBufType() { |
| if (!virtualBufType) { |
| // Lock here because we are called by arbitrary code |
| llvm::MutexGuard locked(mvm::MvmModule::executionEngine->lock); |
| std::vector<const llvm::Type*> Args2; |
| Args2.push_back(JnjvmModule::ConstantPoolType); // ctp |
| Args2.push_back(getVirtualPtrType()); |
| Args2.push_back(JnjvmModule::JavaObjectType); |
| Args2.push_back(JnjvmModule::ptrType); |
| LLVMAssessorInfo& LAI = JnjvmModule::getTypedefInfo(signature->ret); |
| virtualBufType = FunctionType::get(LAI.llvmType, Args2, false); |
| } |
| return virtualBufType; |
| } |
| |
| const FunctionType* LLVMSignatureInfo::getStaticBufType() { |
| if (!staticBufType) { |
| // Lock here because we are called by arbitrary code |
| llvm::MutexGuard locked(mvm::MvmModule::executionEngine->lock); |
| std::vector<const llvm::Type*> Args; |
| Args.push_back(JnjvmModule::ConstantPoolType); // ctp |
| Args.push_back(getStaticPtrType()); |
| Args.push_back(JnjvmModule::ptrType); |
| LLVMAssessorInfo& LAI = JnjvmModule::getTypedefInfo(signature->ret); |
| staticBufType = FunctionType::get(LAI.llvmType, Args, false); |
| } |
| return staticBufType; |
| } |
| |
| Function* LLVMSignatureInfo::getVirtualBuf() { |
| if (!virtualBufFunction) { |
| // Lock here because we are called by arbitrary code |
| llvm::MutexGuard locked(mvm::MvmModule::executionEngine->lock); |
| virtualBufFunction = createFunctionCallBuf(true); |
| signature->setVirtualCallBuf((intptr_t) |
| mvm::MvmModule::executionEngine->getPointerToGlobal(virtualBufFunction)); |
| virtualBufFunction->deleteBody(); |
| } |
| return virtualBufFunction; |
| } |
| |
| Function* LLVMSignatureInfo::getVirtualAP() { |
| if (!virtualAPFunction) { |
| // Lock here because we are called by arbitrary code |
| llvm::MutexGuard locked(mvm::MvmModule::executionEngine->lock); |
| virtualAPFunction = createFunctionCallAP(true); |
| signature->setVirtualCallAP((intptr_t) |
| mvm::MvmModule::executionEngine->getPointerToGlobal(virtualAPFunction)); |
| virtualAPFunction->deleteBody(); |
| } |
| return virtualAPFunction; |
| } |
| |
| Function* LLVMSignatureInfo::getStaticBuf() { |
| if (!staticBufFunction) { |
| // Lock here because we are called by arbitrary code |
| llvm::MutexGuard locked(mvm::MvmModule::executionEngine->lock); |
| staticBufFunction = createFunctionCallBuf(false); |
| signature->setStaticCallBuf((intptr_t) |
| mvm::MvmModule::executionEngine->getPointerToGlobal(staticBufFunction)); |
| staticBufFunction->deleteBody(); |
| } |
| return staticBufFunction; |
| } |
| |
| Function* LLVMSignatureInfo::getStaticAP() { |
| if (!staticAPFunction) { |
| // Lock here because we are called by arbitrary code |
| llvm::MutexGuard locked(mvm::MvmModule::executionEngine->lock); |
| staticAPFunction = createFunctionCallAP(false); |
| signature->setStaticCallAP((intptr_t) |
| mvm::MvmModule::executionEngine->getPointerToGlobal(staticAPFunction)); |
| staticAPFunction->deleteBody(); |
| } |
| return staticAPFunction; |
| } |
| |
| void JnjvmModule::resolveVirtualClass(Class* cl) { |
| // Lock here because we may be called by a class resolver |
| llvm::MutexGuard locked(mvm::MvmModule::executionEngine->lock); |
| LLVMClassInfo* LCI = (LLVMClassInfo*)getClassInfo(cl); |
| LCI->getVirtualType(); |
| } |
| |
| void JnjvmModule::resolveStaticClass(Class* cl) { |
| // Lock here because we may be called by a class initializer |
| llvm::MutexGuard locked(mvm::MvmModule::executionEngine->lock); |
| LLVMClassInfo* LCI = (LLVMClassInfo*)getClassInfo(cl); |
| LCI->getStaticType(); |
| } |
| |
| |
| namespace jnjvm { |
| namespace llvm_runtime { |
| #include "LLVMRuntime.inc" |
| } |
| } |
| |
| Module* JnjvmModule::initialModule; |
| |
| void JnjvmModule::initialise() { |
| jnjvm::llvm_runtime::makeLLVMModuleContents(this); |
| Module* module = this; |
| initialModule = this; |
| |
| VTType = module->getTypeByName("VT"); |
| |
| JnjvmType = |
| PointerType::getUnqual(module->getTypeByName("Jnjvm")); |
| ConstantPoolType = |
| PointerType::getUnqual(module->getTypeByName("ConstantPool")); |
| |
| JavaObjectType = |
| PointerType::getUnqual(module->getTypeByName("JavaObject")); |
| |
| JavaArrayType = |
| PointerType::getUnqual(module->getTypeByName("JavaArray")); |
| |
| 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")); |
| |
| #ifdef WITH_TRACER |
| MarkAndTraceType = module->getFunction("MarkAndTrace")->getFunctionType(); |
| #endif |
| |
| UTF8NullConstant = Constant::getNullValue(JavaArrayUInt16Type); |
| JavaClassNullConstant = Constant::getNullValue(JavaClassType); |
| JavaObjectNullConstant = Constant::getNullValue(JnjvmModule::JavaObjectType); |
| MaxArraySizeConstant = ConstantInt::get(Type::Int32Ty, |
| JavaArray::MaxArraySize); |
| JavaObjectSizeConstant = ConstantInt::get(Type::Int32Ty, sizeof(JavaObject)); |
| JavaArraySizeConstant = |
| ConstantInt::get(Type::Int32Ty, sizeof(JavaObject) + sizeof(ssize_t)); |
| |
| |
| JavaArrayElementsOffsetConstant = mvm::MvmModule::constantTwo; |
| JavaArraySizeOffsetConstant = mvm::MvmModule::constantOne; |
| JavaObjectLockOffsetConstant = mvm::MvmModule::constantTwo; |
| JavaObjectClassOffsetConstant = mvm::MvmModule::constantOne; |
| |
| OffsetObjectSizeInClassConstant = mvm::MvmModule::constantOne; |
| OffsetVTInClassConstant = mvm::MvmModule::constantTwo; |
| OffsetDisplayInClassConstant = mvm::MvmModule::constantThree; |
| OffsetDepthInClassConstant = mvm::MvmModule::constantFour; |
| OffsetStatusInClassConstant = mvm::MvmModule::constantFive; |
| OffsetTaskClassMirrorInClassConstant = mvm::MvmModule::constantSix; |
| OffsetStaticInstanceInTaskClassMirrorConstant = mvm::MvmModule::constantTwo; |
| OffsetStatusInTaskClassMirrorConstant = mvm::MvmModule::constantZero; |
| |
| ClassReadyConstant = ConstantInt::get(Type::Int32Ty, ready); |
| |
| LLVMAssessorInfo::initialise(); |
| } |
| |
| void JnjvmModule::setMethod(JavaMethod* meth, const char* name) { |
| llvm::Function* func = getMethodInfo(meth)->getMethod(); |
| func->setName(name); |
| func->setLinkage(llvm::GlobalValue::ExternalLinkage); |
| } |
| |
| void* JnjvmModule::getMethod(JavaMethod* meth) { |
| return getMethodInfo(meth)->getMethod(); |
| } |
| |
| JnjvmModule::JnjvmModule(const std::string &ModuleID, bool sc) : |
| MvmModule(ModuleID) { |
| |
| std::string str = |
| mvm::MvmModule::executionEngine->getTargetData()->getStringRepresentation(); |
| setDataLayout(str); |
| staticCompilation = sc; |
| if (!VTType) initialise(); |
| |
| Module* module = initialModule; |
| |
| InterfaceLookupFunction = module->getFunction("jnjvmVirtualLookup"); |
| MultiCallNewFunction = module->getFunction("multiCallNew"); |
| InitialisationCheckFunction = module->getFunction("initialisationCheck"); |
| ForceInitialisationCheckFunction = |
| module->getFunction("forceInitialisationCheck"); |
| InitialiseClassFunction = module->getFunction("jnjvmRuntimeInitialiseClass"); |
| |
| GetConstantPoolAtFunction = module->getFunction("getConstantPoolAt"); |
| ArrayLengthFunction = module->getFunction("arrayLength"); |
| GetVTFunction = module->getFunction("getVT"); |
| GetClassFunction = module->getFunction("getClass"); |
| ClassLookupFunction = module->getFunction("classLookup"); |
| GetVTFromClassFunction = module->getFunction("getVTFromClass"); |
| GetObjectSizeFromClassFunction = |
| module->getFunction("getObjectSizeFromClass"); |
| |
| GetClassDelegateeFunction = module->getFunction("getClassDelegatee"); |
| InstanceOfFunction = module->getFunction("instanceOf"); |
| IsAssignableFromFunction = module->getFunction("isAssignableFrom"); |
| ImplementsFunction = module->getFunction("implements"); |
| InstantiationOfArrayFunction = module->getFunction("instantiationOfArray"); |
| GetDepthFunction = module->getFunction("getDepth"); |
| GetStaticInstanceFunction = module->getFunction("getStaticInstance"); |
| GetDisplayFunction = module->getFunction("getDisplay"); |
| GetClassInDisplayFunction = module->getFunction("getClassInDisplay"); |
| AquireObjectFunction = module->getFunction("JavaObjectAquire"); |
| ReleaseObjectFunction = module->getFunction("JavaObjectRelease"); |
| OverflowThinLockFunction = module->getFunction("overflowThinLock"); |
| |
| VirtualFieldLookupFunction = module->getFunction("virtualFieldLookup"); |
| StaticFieldLookupFunction = module->getFunction("staticFieldLookup"); |
| |
| GetExceptionFunction = module->getFunction("JavaThreadGetException"); |
| GetJavaExceptionFunction = module->getFunction("JavaThreadGetJavaException"); |
| CompareExceptionFunction = module->getFunction("JavaThreadCompareException"); |
| JniProceedPendingExceptionFunction = |
| module->getFunction("jniProceedPendingException"); |
| GetSJLJBufferFunction = module->getFunction("getSJLJBuffer"); |
| |
| NullPointerExceptionFunction = |
| module->getFunction("jnjvmNullPointerException"); |
| ClassCastExceptionFunction = module->getFunction("jnjvmClassCastException"); |
| IndexOutOfBoundsExceptionFunction = |
| module->getFunction("indexOutOfBoundsException"); |
| NegativeArraySizeExceptionFunction = |
| module->getFunction("negativeArraySizeException"); |
| OutOfMemoryErrorFunction = module->getFunction("outOfMemoryError"); |
| |
| JavaObjectAllocateFunction = module->getFunction("gcmalloc"); |
| |
| PrintExecutionFunction = module->getFunction("printExecution"); |
| PrintMethodStartFunction = module->getFunction("printMethodStart"); |
| PrintMethodEndFunction = module->getFunction("printMethodEnd"); |
| |
| ThrowExceptionFunction = module->getFunction("JavaThreadThrowException"); |
| |
| ClearExceptionFunction = module->getFunction("JavaThreadClearException"); |
| |
| GetArrayClassFunction = module->getFunction("getArrayClass"); |
| |
| |
| #ifdef ISOLATE |
| StringLookupFunction = module->getFunction("stringLookup"); |
| #ifdef ISOLATE_SHARING |
| EnveloppeLookupFunction = module->getFunction("enveloppeLookup"); |
| GetCtpCacheNodeFunction = module->getFunction("getCtpCacheNode"); |
| GetCtpClassFunction = module->getFunction("getCtpClass"); |
| GetJnjvmExceptionClassFunction = |
| module->getFunction("getJnjvmExceptionClass"); |
| GetJnjvmArrayClassFunction = module->getFunction("getJnjvmArrayClass"); |
| StaticCtpLookupFunction = module->getFunction("staticCtpLookup"); |
| SpecialCtpLookupFunction = module->getFunction("specialCtpLookup"); |
| #endif |
| #endif |
| |
| #ifdef SERVICE |
| ServiceCallStartFunction = module->getFunction("serviceCallStart"); |
| ServiceCallStopFunction = module->getFunction("serviceCallStop"); |
| #endif |
| |
| #ifdef WITH_TRACER |
| MarkAndTraceFunction = module->getFunction("MarkAndTrace"); |
| JavaObjectTracerFunction = module->getFunction("JavaObjectTracer"); |
| #endif |
| |
| #ifndef WITHOUT_VTABLE |
| VirtualLookupFunction = module->getFunction("vtableLookup"); |
| #endif |
| |
| GetLockFunction = module->getFunction("getLock"); |
| } |
| |
| void LLVMAssessorInfo::initialise() { |
| AssessorInfo[I_VOID].llvmType = Type::VoidTy; |
| AssessorInfo[I_VOID].llvmTypePtr = 0; |
| AssessorInfo[I_VOID].llvmNullConstant = 0; |
| AssessorInfo[I_VOID].sizeInBytesConstant = 0; |
| |
| AssessorInfo[I_BOOL].llvmType = Type::Int8Ty; |
| AssessorInfo[I_BOOL].llvmTypePtr = PointerType::getUnqual(Type::Int8Ty); |
| AssessorInfo[I_BOOL].llvmNullConstant = |
| Constant::getNullValue(Type::Int8Ty); |
| AssessorInfo[I_BOOL].sizeInBytesConstant = mvm::MvmModule::constantOne; |
| |
| AssessorInfo[I_BYTE].llvmType = Type::Int8Ty; |
| AssessorInfo[I_BYTE].llvmTypePtr = PointerType::getUnqual(Type::Int8Ty); |
| AssessorInfo[I_BYTE].llvmNullConstant = |
| Constant::getNullValue(Type::Int8Ty); |
| AssessorInfo[I_BYTE].sizeInBytesConstant = mvm::MvmModule::constantOne; |
| |
| AssessorInfo[I_SHORT].llvmType = Type::Int16Ty; |
| AssessorInfo[I_SHORT].llvmTypePtr = PointerType::getUnqual(Type::Int16Ty); |
| AssessorInfo[I_SHORT].llvmNullConstant = |
| Constant::getNullValue(Type::Int16Ty); |
| AssessorInfo[I_SHORT].sizeInBytesConstant = mvm::MvmModule::constantTwo; |
| |
| AssessorInfo[I_CHAR].llvmType = Type::Int16Ty; |
| AssessorInfo[I_CHAR].llvmTypePtr = PointerType::getUnqual(Type::Int16Ty); |
| AssessorInfo[I_CHAR].llvmNullConstant = |
| Constant::getNullValue(Type::Int16Ty); |
| AssessorInfo[I_CHAR].sizeInBytesConstant = mvm::MvmModule::constantTwo; |
| |
| AssessorInfo[I_INT].llvmType = Type::Int32Ty; |
| AssessorInfo[I_INT].llvmTypePtr = PointerType::getUnqual(Type::Int32Ty); |
| AssessorInfo[I_INT].llvmNullConstant = |
| Constant::getNullValue(Type::Int32Ty); |
| AssessorInfo[I_INT].sizeInBytesConstant = mvm::MvmModule::constantFour; |
| |
| AssessorInfo[I_FLOAT].llvmType = Type::FloatTy; |
| AssessorInfo[I_FLOAT].llvmTypePtr = PointerType::getUnqual(Type::FloatTy); |
| AssessorInfo[I_FLOAT].llvmNullConstant = |
| Constant::getNullValue(Type::FloatTy); |
| AssessorInfo[I_FLOAT].sizeInBytesConstant = mvm::MvmModule::constantFour; |
| |
| AssessorInfo[I_LONG].llvmType = Type::Int64Ty; |
| AssessorInfo[I_LONG].llvmTypePtr = PointerType::getUnqual(Type::Int64Ty); |
| AssessorInfo[I_LONG].llvmNullConstant = |
| Constant::getNullValue(Type::Int64Ty); |
| AssessorInfo[I_LONG].sizeInBytesConstant = mvm::MvmModule::constantEight; |
| |
| AssessorInfo[I_DOUBLE].llvmType = Type::DoubleTy; |
| AssessorInfo[I_DOUBLE].llvmTypePtr = PointerType::getUnqual(Type::DoubleTy); |
| AssessorInfo[I_DOUBLE].llvmNullConstant = |
| Constant::getNullValue(Type::DoubleTy); |
| AssessorInfo[I_DOUBLE].sizeInBytesConstant = mvm::MvmModule::constantEight; |
| |
| AssessorInfo[I_TAB].llvmType = JnjvmModule::JavaObjectType; |
| AssessorInfo[I_TAB].llvmTypePtr = |
| PointerType::getUnqual(JnjvmModule::JavaObjectType); |
| AssessorInfo[I_TAB].llvmNullConstant = |
| JnjvmModule::JavaObjectNullConstant; |
| AssessorInfo[I_TAB].sizeInBytesConstant = mvm::MvmModule::constantPtrSize; |
| |
| AssessorInfo[I_REF].llvmType = JnjvmModule::JavaObjectType; |
| AssessorInfo[I_REF].llvmTypePtr = |
| PointerType::getUnqual(JnjvmModule::JavaObjectType); |
| AssessorInfo[I_REF].llvmNullConstant = |
| JnjvmModule::JavaObjectNullConstant; |
| AssessorInfo[I_REF].sizeInBytesConstant = mvm::MvmModule::constantPtrSize; |
| } |
| |
| std::map<const char, LLVMAssessorInfo> LLVMAssessorInfo::AssessorInfo; |
| |
| LLVMAssessorInfo& JnjvmModule::getTypedefInfo(Typedef* type) { |
| return LLVMAssessorInfo::AssessorInfo[type->getKey()->elements[0]]; |
| } |
| |
| static AnnotationID JavaMethod_ID( |
| AnnotationManager::getID("Java::JavaMethod")); |
| |
| |
| LLVMMethodInfo::LLVMMethodInfo(JavaMethod* M) : |
| llvm::Annotation(JavaMethod_ID), methodDef(M), methodFunction(0), |
| offsetConstant(0), functionType(0) {} |
| |
| JavaMethod* LLVMMethodInfo::get(const llvm::Function* F) { |
| LLVMMethodInfo *MI = (LLVMMethodInfo*)F->getAnnotation(JavaMethod_ID); |
| if (MI) return MI->methodDef; |
| return 0; |
| } |
| |
| #ifdef SERVICE |
| Value* JnjvmModule::getIsolate(Jnjvm* isolate) { |
| llvm::GlobalVariable* varGV = 0; |
| isolate_iterator End = isolates.end(); |
| isolate_iterator I = isolates.find(isolate); |
| if (I == End) { |
| |
| |
| Constant* cons = |
| ConstantExpr::getIntToPtr(ConstantInt::get(Type::Int64Ty, |
| uint64_t(isolate)), |
| ptrType); |
| |
| varGV = new GlobalVariable(ptrType, !staticCompilation, |
| GlobalValue::ExternalLinkage, |
| cons, "", this); |
| |
| isolates.insert(std::make_pair(isolate, varGV)); |
| } else { |
| varGV = I->second; |
| } |
| return varGV; |
| } |
| #endif |