llvm.org GIT mirror llvm / fcbe5b7
Layer the memory manager between the JIT and the runtime Dyld. The JITMemory manager references LLVM IR constructs directly, while the runtime Dyld works at a lower level and can handle objects which may not originate from LLVM IR. Introduce a new layer for the memory manager to handle the interface between them. For the MCJIT, this layer will be almost entirely simply a call-through w/ translation between the IR objects and symbol names. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@128851 91177308-0d34-0410-b5e6-96231b3b80d8 Jim Grosbach 8 years ago
5 changed file(s) with 64 addition(s) and 25 deletion(s). Raw diff Collapse all Expand all
2020
2121 class RuntimeDyldImpl;
2222 class MemoryBuffer;
23 class JITMemoryManager;
23
24 // RuntimeDyld clients often want to handle the memory management of
25 // what gets placed where. For JIT clients, this is an abstraction layer
26 // over the JITMemoryManager, which references objects by their source
27 // representations in LLVM IR.
28 // FIXME: As the RuntimeDyld fills out, additional routines will be needed
29 // for the varying types of objects to be allocated.
30 class RTDyldMemoryManager {
31 RTDyldMemoryManager(const RTDyldMemoryManager&); // DO NOT IMPLEMENT
32 void operator=(const RTDyldMemoryManager&); // DO NOT IMPLEMENT
33 public:
34 RTDyldMemoryManager() {}
35
36 // Allocate ActualSize bytes, or more, for the named function. Return
37 // a pointer to the allocated memory and update Size to reflect how much
38 // memory was acutally allocated.
39 virtual uint64_t startFunctionBody(const char *Name, uintptr_t &Size) = 0;
40
41 // Mark the end of the function, including how much of the allocated
42 // memory was actually used.
43 virtual void endFunctionBody(const char *Name, uint64_t FunctionStart,
44 uint64_t FunctionEnd) = 0;
45 };
2446
2547 class RuntimeDyld {
2648 RuntimeDyld(const RuntimeDyld &); // DO NOT IMPLEMENT
3052 // interface.
3153 RuntimeDyldImpl *Dyld;
3254 public:
33 RuntimeDyld(JITMemoryManager*);
55 RuntimeDyld(RTDyldMemoryManager*);
3456 ~RuntimeDyld();
3557
3658 bool loadObject(MemoryBuffer *InputBuffer);
37 void *getSymbolAddress(StringRef Name);
59 uint64_t getSymbolAddress(StringRef Name);
60 void reassignSymbolAddress(StringRef Name, uint64_t Addr);
3861 // FIXME: Should be parameterized to get the memory block associated with
3962 // a particular loaded object.
4063 sys::MemoryBlock getMemoryBlock();
77 //===----------------------------------------------------------------------===//
88
99 #include "MCJIT.h"
10 #include "MCJITMemoryManager.h"
1011 #include "llvm/DerivedTypes.h"
1112 #include "llvm/Function.h"
1213 #include "llvm/ExecutionEngine/GenericValue.h"
5657
5758 // If the target supports JIT code generation, create the JIT.
5859 if (TargetJITInfo *TJ = TM->getJITInfo())
59 return new MCJIT(M, TM, *TJ, JMM, OptLevel, GVsWithCode);
60 return new MCJIT(M, TM, *TJ, new MCJITMemoryManager(JMM), OptLevel,
61 GVsWithCode);
6062
6163 if (ErrorStr)
6264 *ErrorStr = "target does not support JIT code generation";
6466 }
6567
6668 MCJIT::MCJIT(Module *m, TargetMachine *tm, TargetJITInfo &tji,
67 JITMemoryManager *JMM, CodeGenOpt::Level OptLevel,
69 RTDyldMemoryManager *MM, CodeGenOpt::Level OptLevel,
6870 bool AllocateGVsWithCode)
69 : ExecutionEngine(m), TM(tm), M(m), OS(Buffer), Dyld(JMM) {
71 : ExecutionEngine(m), TM(tm), MemMgr(MM), M(m), OS(Buffer), Dyld(MM) {
7072
7173 PM.add(new TargetData(*TM->getTargetData()));
7274
9395 }
9496
9597 MCJIT::~MCJIT() {
98 delete MemMgr;
9699 }
97100
98101 void *MCJIT::getPointerToBasicBlock(BasicBlock *BB) {
109112 }
110113
111114 Twine Name = TM->getMCAsmInfo()->getGlobalPrefix() + F->getName();
112 return Dyld.getSymbolAddress(Name.str());
115 return (void*)Dyld.getSymbolAddress(Name.str());
113116 }
114117
115118 void *MCJIT::recompileAndRelinkFunction(Function *F) {
2323
2424 class MCJIT : public ExecutionEngine {
2525 MCJIT(Module *M, TargetMachine *tm, TargetJITInfo &tji,
26 JITMemoryManager *JMM, CodeGenOpt::Level OptLevel,
26 RTDyldMemoryManager *MemMgr, CodeGenOpt::Level OptLevel,
2727 bool AllocateGVsWithCode);
2828
2929 TargetMachine *TM;
3030 MCContext *Ctx;
31 RTDyldMemoryManager *MemMgr;
3132
3233 // FIXME: These may need moved to a separate 'jitstate' member like the
3334 // non-MC JIT does for multithreading and such. Just keep them here for now.
1717 #include "llvm/ADT/StringRef.h"
1818 #include "llvm/ADT/Twine.h"
1919 #include "llvm/ExecutionEngine/RuntimeDyld.h"
20 #include "llvm/ExecutionEngine/JITMemoryManager.h"
2120 #include "llvm/Object/MachOObject.h"
2221 #include "llvm/Support/Debug.h"
2322 #include "llvm/Support/ErrorHandling.h"
3433 unsigned CPUType;
3534 unsigned CPUSubtype;
3635
37 // The JITMemoryManager to load objects into.
38 JITMemoryManager *JMM;
36 // The MemoryManager to load objects into.
37 RTDyldMemoryManager *MemMgr;
3938
4039 // Master symbol table. As modules are loaded and external symbols are
4140 // resolved, their addresses are stored here.
42 StringMap<void*> SymbolTable;
41 StringMap<uint64_t> SymbolTable;
4342
4443 // FIXME: Should have multiple data blocks, one for each loaded chunk of
4544 // compiled code.
7170 const InMemoryStruct &SymtabLC);
7271
7372 public:
74 RuntimeDyldImpl(JITMemoryManager *jmm) : JMM(jmm), HasError(false) {}
73 RuntimeDyldImpl(RTDyldMemoryManager *mm) : MemMgr(mm), HasError(false) {}
7574
7675 bool loadObject(MemoryBuffer *InputBuffer);
7776
78 void *getSymbolAddress(StringRef Name) {
77 uint64_t getSymbolAddress(StringRef Name) {
7978 // Use lookup() rather than [] because we don't want to add an entry
8079 // if there isn't one already, which the [] operator does.
8180 return SymbolTable.lookup(Name);
313312 void *SectionBase = SectionBases[Index];
314313
315314 // Get the symbol address.
316 void *Address = (char*) SectionBase + STE->Value;
315 uint64_t Address = (uint64_t)SectionBase + STE->Value;
317316
318317 // FIXME: Check the symbol type and flags.
319318 if (STE->Type != 0xF)
334333 }
335334
336335 // We've loaded the section; now mark the functions in it as executable.
337 // FIXME: We really should use the JITMemoryManager for this.
336 // FIXME: We really should use the MemoryManager for this.
338337 sys::Memory::setRangeExecutable(Data.base(), Data.size());
339338
340339 return false;
413412 void *SectionBase = SectionBases[Index];
414413
415414 // Get the symbol address.
416 void *Address = (char*) SectionBase + STE->Value;
415 uint64_t Address = (uint64_t) SectionBase + STE->Value;
417416
418417 // FIXME: Check the symbol type and flags.
419418 if (STE->Type != 0xF)
433432 }
434433
435434 // We've loaded the section; now mark the functions in it as executable.
436 // FIXME: We really should use the JITMemoryManager for this.
435 // FIXME: We really should use the MemoryManager for this.
437436 sys::Memory::setRangeExecutable(Data.base(), Data.size());
438437
439438 return false;
529528
530529 //===----------------------------------------------------------------------===//
531530 // RuntimeDyld class implementation
532 RuntimeDyld::RuntimeDyld(JITMemoryManager *JMM) {
533 Dyld = new RuntimeDyldImpl(JMM);
531 RuntimeDyld::RuntimeDyld(RTDyldMemoryManager *MM) {
532 Dyld = new RuntimeDyldImpl(MM);
534533 }
535534
536535 RuntimeDyld::~RuntimeDyld() {
541540 return Dyld->loadObject(InputBuffer);
542541 }
543542
544 void *RuntimeDyld::getSymbolAddress(StringRef Name) {
543 uint64_t RuntimeDyld::getSymbolAddress(StringRef Name) {
545544 return Dyld->getSymbolAddress(Name);
546545 }
547546
1212
1313 #include "llvm/ADT/StringMap.h"
1414 #include "llvm/ADT/OwningPtr.h"
15 #include "llvm/ExecutionEngine/JITMemoryManager.h"
1615 #include "llvm/ExecutionEngine/RuntimeDyld.h"
1716 #include "llvm/Object/MachOObject.h"
1817 #include "llvm/Support/CommandLine.h"
4039
4140 /* *** */
4241
42 // A trivial memory manager that doesn't do anything fancy, just uses the
43 // support library allocation routines directly.
44 class TrivialMemoryManager : public RTDyldMemoryManager {
45 public:
46 uint64_t startFunctionBody(const char *Name, uintptr_t &Size);
47 void endFunctionBody(const char *Name, uint64_t FunctionStart,
48 uint64_t FunctionEnd) {}
49 };
50
51 uint64_t TrivialMemoryManager::startFunctionBody(const char *Name,
52 uintptr_t &Size) {
53 return (uint64_t)sys::Memory::AllocateRWX(Size, 0, 0).base();
54 }
55
4356 static const char *ProgramName;
4457
4558 static void Message(const char *Type, const Twine &Msg) {
6073 return Error("unable to read input: '" + ec.message() + "'");
6174
6275 // Instantiate a dynamic linker.
63 RuntimeDyld Dyld(JITMemoryManager::CreateDefaultMemManager());
76 RuntimeDyld Dyld(new TrivialMemoryManager);
6477
6578 // Load the object file into it.
6679 if (Dyld.loadObject(InputBuffer.take())) {
6881 }
6982
7083 // Get the address of "_main".
71 void *MainAddress = Dyld.getSymbolAddress("_main");
84 uint64_t MainAddress = Dyld.getSymbolAddress("_main");
7285 if (MainAddress == 0)
7386 return Error("no definition for '_main'");
7487
8295 return Error("unable to mark function executable: '" + ErrorStr + "'");
8396
8497 // Dispatch to _main().
85 errs() << "loaded '_main' at: " << MainAddress << "\n";
98 errs() << "loaded '_main' at: " << (void*)MainAddress << "\n";
8699
87100 int (*Main)(int, const char**) =
88101 (int(*)(int,const char**)) uintptr_t(MainAddress);