| //===-- LowerJavaRT.cpp - Remove references to RT classes and functions --===// |
| // |
| // The VMKit project |
| // |
| // This file is distributed under the University of Illinois Open Source |
| // License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #include "llvm/Constants.h" |
| #include "llvm/Function.h" |
| #include "llvm/Instructions.h" |
| #include "llvm/LLVMContext.h" |
| #include "llvm/Module.h" |
| #include "llvm/Pass.h" |
| #include "llvm/Support/CallSite.h" |
| #include "llvm/Support/Compiler.h" |
| #include "llvm/Support/Debug.h" |
| #include "llvm/Support/raw_ostream.h" |
| |
| using namespace llvm; |
| |
| namespace { |
| |
| class VISIBILITY_HIDDEN LowerJavaRT : public ModulePass { |
| public: |
| static char ID; |
| LowerJavaRT() : ModulePass((intptr_t)&ID) { } |
| |
| virtual bool runOnModule(Module &M); |
| private: |
| }; |
| char LowerJavaRT::ID = 0; |
| static RegisterPass<LowerJavaRT> X("LowerJavaRT", |
| "Remove references to RT"); |
| |
| bool LowerJavaRT::runOnModule(Module& M) { |
| bool Changed = true; |
| |
| for (Module::iterator I = M.begin(), E = M.end(); I != E;) { |
| Function& GV = *I; |
| ++I; |
| if (!strncmp(GV.getName().data(), "JnJVM_java", 10) || |
| !strncmp(GV.getName().data(), "java", 4)) { |
| if (!strcmp(GV.getName().data(), "JnJVM_java_lang_String_charAt__I")) { |
| Function* F = M.getFunction("MMTkCharAt"); |
| if (!F) |
| F = Function::Create(GV.getFunctionType(), |
| GlobalValue::ExternalLinkage, "MMTkCharAt", &M); |
| |
| GV.replaceAllUsesWith(F); |
| } else if (!strcmp(GV.getName().data(), "JnJVM_java_lang_Object_getClass__")) { |
| Function* F = M.getFunction("MMTkGetClass"); |
| if (!F) |
| F = Function::Create(GV.getFunctionType(), |
| GlobalValue::ExternalLinkage, "MMTkGetClass", &M); |
| GV.replaceAllUsesWith(F); |
| } else { |
| GV.replaceAllUsesWith(Constant::getNullValue(GV.getType())); |
| } |
| GV.eraseFromParent(); |
| } |
| } |
| |
| for (Module::global_iterator I = M.global_begin(), E = M.global_end(); |
| I != E;) { |
| GlobalValue& GV = *I; |
| ++I; |
| if (!strncmp(GV.getName().data(), "JnJVM_java", 10) || |
| !strncmp(GV.getName().data(), "java", 4) || |
| !strncmp(GV.getName().data(), "JnJVM_gnu", 9) || |
| !strncmp(GV.getName().data(), "gnu", 3)) { |
| GV.replaceAllUsesWith(Constant::getNullValue(GV.getType())); |
| GV.eraseFromParent(); |
| } |
| } |
| |
| // Replace gcmalloc with the allocator of MMTk objects in VMKit |
| Function* F = M.getFunction("gcmalloc"); |
| Function* Ma = M.getFunction("AllocateMagicArray"); |
| |
| Function* NewFunction = |
| Function::Create(F->getFunctionType(), GlobalValue::ExternalLinkage, |
| "MMTkMutatorAllocate", &M); |
| |
| F->replaceAllUsesWith(NewFunction); |
| F->eraseFromParent(); |
| |
| Ma->replaceAllUsesWith(NewFunction); |
| Ma->eraseFromParent(); |
| |
| // Declare two global variables for allocating a MutatorContext object |
| // and a CollectorContext object. |
| |
| const Type* Ty = IntegerType::getInt32Ty(M.getContext()); |
| GlobalVariable* GV = M.getGlobalVariable("org_j3_config_Selected_4Collector", |
| false); |
| Constant* C = GV->getInitializer(); |
| C = dyn_cast<Constant>(C->getOperand(1)); |
| new GlobalVariable(M, Ty, true, GlobalValue::ExternalLinkage, |
| C, "MMTkCollectorSize"); |
| |
| |
| GV = M.getGlobalVariable("org_j3_config_Selected_4Mutator", false); |
| C = GV->getInitializer(); |
| C = dyn_cast<Constant>(C->getOperand(1)); |
| new GlobalVariable(M, Ty, true, GlobalValue::ExternalLinkage, |
| C, "MMTkMutatorSize"); |
| |
| |
| GV = M.getGlobalVariable("org_mmtk_plan_MutatorContext_VT", false); |
| ConstantArray* CA = dyn_cast<ConstantArray>(GV->getInitializer()); |
| |
| Function* Alloc = M.getFunction("JnJVM_org_mmtk_plan_MutatorContext_alloc__IIIII"); |
| Function* PostAlloc = M.getFunction("JnJVM_org_mmtk_plan_MutatorContext_postAlloc__Lorg_vmmagic_unboxed_ObjectReference_2Lorg_vmmagic_unboxed_ObjectReference_2II"); |
| Function* CheckAlloc = M.getFunction("JnJVM_org_mmtk_plan_MutatorContext_checkAllocator__III"); |
| uint32_t AllocIndex = 0; |
| uint32_t PostAllocIndex = 0; |
| uint32_t CheckAllocIndex = 0; |
| for (uint32_t i = 0; i < CA->getNumOperands(); ++i) { |
| ConstantExpr* CE = dyn_cast<ConstantExpr>(CA->getOperand(i)); |
| if (CE) { |
| C = dyn_cast<Constant>(CE->getOperand(0)); |
| if (C == Alloc) { |
| AllocIndex = i; |
| } else if (C == PostAlloc) { |
| PostAllocIndex = i; |
| } else if (C == CheckAlloc) { |
| CheckAllocIndex = i; |
| } |
| } |
| } |
| |
| GV = M.getGlobalVariable("org_j3_config_Selected_4Mutator_VT", false); |
| CA = dyn_cast<ConstantArray>(GV->getInitializer()); |
| |
| C = dyn_cast<Constant>(CA->getOperand(AllocIndex)); |
| C = dyn_cast<Constant>(C->getOperand(0)); |
| new GlobalAlias(C->getType(), GlobalValue::ExternalLinkage, "MMTkAlloc", |
| C, &M); |
| |
| C = dyn_cast<Constant>(CA->getOperand(PostAllocIndex)); |
| C = dyn_cast<Constant>(C->getOperand(0)); |
| new GlobalAlias(C->getType(), GlobalValue::ExternalLinkage, "MMTkPostAlloc", |
| C, &M); |
| |
| C = dyn_cast<Constant>(CA->getOperand(CheckAllocIndex)); |
| C = dyn_cast<Constant>(C->getOperand(0)); |
| new GlobalAlias(C->getType(), GlobalValue::ExternalLinkage, |
| "MMTkCheckAllocator", C, &M); |
| |
| |
| |
| GV = M.getGlobalVariable("org_mmtk_plan_Plan_VT", false); |
| CA = dyn_cast<ConstantArray>(GV->getInitializer()); |
| |
| Function* Boot = M.getFunction("JnJVM_org_mmtk_plan_Plan_boot__"); |
| Function* PostBoot = M.getFunction("JnJVM_org_mmtk_plan_Plan_postBoot__"); |
| Function* FullBoot = M.getFunction("JnJVM_org_mmtk_plan_Plan_fullyBooted__"); |
| Function* Exit = M.getFunction("JnJVM_org_mmtk_plan_Plan_notifyExit__I"); |
| uint32_t BootIndex = 0; |
| uint32_t PostBootIndex = 0; |
| uint32_t FullBootIndex = 0; |
| uint32_t ExitIndex = 0; |
| for (uint32_t i = 0; i < CA->getNumOperands(); ++i) { |
| ConstantExpr* CE = dyn_cast<ConstantExpr>(CA->getOperand(i)); |
| if (CE) { |
| C = dyn_cast<Constant>(CE->getOperand(0)); |
| if (C == Boot) { |
| BootIndex = i; |
| } else if (C == PostBoot) { |
| PostBootIndex = i; |
| } else if (C == FullBoot) { |
| FullBootIndex = i; |
| } else if (C == Exit) { |
| ExitIndex = i; |
| } |
| } |
| } |
| |
| GV = M.getGlobalVariable("org_j3_config_Selected_4Plan_VT", false); |
| assert(GV && "No Plan"); |
| CA = dyn_cast<ConstantArray>(GV->getInitializer()); |
| |
| C = CA->getOperand(BootIndex); |
| C = dyn_cast<Constant>(C->getOperand(0)); |
| new GlobalAlias(C->getType(), GlobalValue::ExternalLinkage, "MMTkPlanBoot", |
| C, &M); |
| |
| C = CA->getOperand(PostBootIndex); |
| C = dyn_cast<Constant>(C->getOperand(0)); |
| new GlobalAlias(C->getType(), GlobalValue::ExternalLinkage, |
| "MMTkPlanPostBoot", C, &M); |
| |
| C = CA->getOperand(FullBootIndex); |
| C = dyn_cast<Constant>(C->getOperand(0)); |
| new GlobalAlias(C->getType(), GlobalValue::ExternalLinkage, |
| "MMTkPlanFullBoot", C, &M); |
| |
| C = CA->getOperand(ExitIndex); |
| C = dyn_cast<Constant>(C->getOperand(0)); |
| new GlobalAlias(C->getType(), GlobalValue::ExternalLinkage, "MMTkPlanExit", |
| C, &M); |
| |
| |
| |
| return Changed; |
| } |
| |
| |
| ModulePass* createLowerJavaRT() { |
| return new LowerJavaRT(); |
| } |
| |
| } |