diff options
Diffstat (limited to 'include/llvm/ExecutionEngine')
-rw-r--r-- | include/llvm/ExecutionEngine/ExecutionEngine.h | 57 | ||||
-rw-r--r-- | include/llvm/ExecutionEngine/JITMemoryManager.h | 18 | ||||
-rw-r--r-- | include/llvm/ExecutionEngine/RuntimeDyld.h | 75 |
3 files changed, 121 insertions, 29 deletions
diff --git a/include/llvm/ExecutionEngine/ExecutionEngine.h b/include/llvm/ExecutionEngine/ExecutionEngine.h index 71698fa..a01ad3a 100644 --- a/include/llvm/ExecutionEngine/ExecutionEngine.h +++ b/include/llvm/ExecutionEngine/ExecutionEngine.h @@ -21,6 +21,7 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/ValueMap.h" +#include "llvm/ADT/DenseMap.h" #include "llvm/Support/ValueHandle.h" #include "llvm/Support/Mutex.h" #include "llvm/Target/TargetMachine.h" @@ -117,11 +118,11 @@ protected: /// The list of Modules that we are JIT'ing from. We use a SmallVector to /// optimize for the case where there is only one module. SmallVector<Module*, 1> Modules; - + void setTargetData(const TargetData *td) { TD = td; } - + /// getMemoryforGV - Allocate memory for a global variable. virtual char *getMemoryForGV(const GlobalVariable *GV); @@ -155,13 +156,15 @@ protected: /// pointer is invoked to create it. If this returns null, the JIT will /// abort. void *(*LazyFunctionCreator)(const std::string &); - + /// ExceptionTableRegister - If Exception Handling is set, the JIT will /// register dwarf tables with this function. typedef void (*EERegisterFn)(void*); EERegisterFn ExceptionTableRegister; EERegisterFn ExceptionTableDeregister; - std::vector<void*> AllExceptionTables; + /// This maps functions to their exception tables frames. + DenseMap<const Function*, void*> AllExceptionTables; + public: /// lock - This lock protects the ExecutionEngine, JIT, JITResolver and @@ -182,7 +185,7 @@ public: /// \param GVsWithCode - Allocating globals with code breaks /// freeMachineCodeForFunction and is probably unsafe and bad for performance. /// However, we have clients who depend on this behavior, so we must support - /// it. Eventually, when we're willing to break some backwards compatability, + /// it. Eventually, when we're willing to break some backwards compatibility, /// this flag should be flipped to false, so that by default /// freeMachineCodeForFunction works. static ExecutionEngine *create(Module *M, @@ -213,7 +216,7 @@ public: virtual void addModule(Module *M) { Modules.push_back(M); } - + //===--------------------------------------------------------------------===// const TargetData *getTargetData() const { return TD; } @@ -226,7 +229,7 @@ public: /// defines FnName. This is very slow operation and shouldn't be used for /// general code. Function *FindFunctionNamed(const char *FnName); - + /// runFunction - Execute the specified function with the specified arguments, /// and return the result. virtual GenericValue runFunction(Function *F, @@ -243,8 +246,8 @@ public: /// /// \param isDtors - Run the destructors instead of constructors. void runStaticConstructorsDestructors(Module *module, bool isDtors); - - + + /// runFunctionAsMain - This is a helper function which wraps runFunction to /// handle the common task of starting up main with the specified argc, argv, /// and envp parameters. @@ -259,21 +262,21 @@ public: /// existing data in memory. Mappings are automatically removed when their /// GlobalValue is destroyed. void addGlobalMapping(const GlobalValue *GV, void *Addr); - + /// clearAllGlobalMappings - Clear all global mappings and start over again, /// for use in dynamic compilation scenarios to move globals. void clearAllGlobalMappings(); - + /// clearGlobalMappingsFromModule - Clear all global mappings that came from a /// particular module, because it has been removed from the JIT. void clearGlobalMappingsFromModule(Module *M); - + /// updateGlobalMapping - Replace an existing mapping for GV with a new /// address. This updates both maps as required. If "Addr" is null, the /// entry for the global is removed from the mappings. This returns the old /// value of the pointer, or null if it was not in the map. void *updateGlobalMapping(const GlobalValue *GV, void *Addr); - + /// getPointerToGlobalIfAvailable - This returns the address of the specified /// global value if it is has already been codegen'd, otherwise it returns /// null. @@ -294,7 +297,7 @@ public: /// different ways. Return the representation for a blockaddress of the /// specified block. virtual void *getPointerToBasicBlock(BasicBlock *BB) = 0; - + /// getPointerToFunctionOrStub - If the specified function has been /// code-gen'd, return a pointer to the function. If not, compile it, or use /// a stub to implement lazy compilation if available. See @@ -398,7 +401,7 @@ public: void InstallLazyFunctionCreator(void* (*P)(const std::string &)) { LazyFunctionCreator = P; } - + /// InstallExceptionTableRegister - The JIT will use the given function /// to register the exception tables it generates. void InstallExceptionTableRegister(EERegisterFn F) { @@ -407,13 +410,26 @@ public: void InstallExceptionTableDeregister(EERegisterFn F) { ExceptionTableDeregister = F; } - + /// RegisterTable - Registers the given pointer as an exception table. It /// uses the ExceptionTableRegister function. - void RegisterTable(void* res) { + void RegisterTable(const Function *fn, void* res) { if (ExceptionTableRegister) { ExceptionTableRegister(res); - AllExceptionTables.push_back(res); + AllExceptionTables[fn] = res; + } + } + + /// DeregisterTable - Deregisters the exception frame previously registered + /// for the given function. + void DeregisterTable(const Function *Fn) { + if (ExceptionTableDeregister) { + DenseMap<const Function*, void*>::iterator frame = + AllExceptionTables.find(Fn); + if(frame != AllExceptionTables.end()) { + ExceptionTableDeregister(frame->second); + AllExceptionTables.erase(frame); + } } } @@ -429,7 +445,7 @@ protected: void EmitGlobalVariable(const GlobalVariable *GV); GenericValue getConstantValue(const Constant *C); - void LoadValueFromMemory(GenericValue &Result, GenericValue *Ptr, + void LoadValueFromMemory(GenericValue &Result, GenericValue *Ptr, const Type *Ty); }; @@ -540,8 +556,9 @@ public: /// setUseMCJIT - Set whether the MC-JIT implementation should be used /// (experimental). - void setUseMCJIT(bool Value) { + EngineBuilder &setUseMCJIT(bool Value) { UseMCJIT = Value; + return *this; } /// setMAttrs - Set cpu-specific attributes. diff --git a/include/llvm/ExecutionEngine/JITMemoryManager.h b/include/llvm/ExecutionEngine/JITMemoryManager.h index 3841418..a63f0da 100644 --- a/include/llvm/ExecutionEngine/JITMemoryManager.h +++ b/include/llvm/ExecutionEngine/JITMemoryManager.h @@ -29,11 +29,11 @@ protected: public: JITMemoryManager() : HasGOT(false) {} virtual ~JITMemoryManager(); - + /// CreateDefaultMemManager - This is used to create the default /// JIT Memory Manager if the client does not provide one to the JIT. static JITMemoryManager *CreateDefaultMemManager(); - + /// setMemoryWritable - When code generation is in progress, /// the code pages may need permissions changed. virtual void setMemoryWritable() = 0; @@ -55,16 +55,16 @@ public: /// method is invoked to allocate it. This method is required to set HasGOT /// to true. virtual void AllocateGOT() = 0; - + /// isManagingGOT - Return true if the AllocateGOT method is called. bool isManagingGOT() const { return HasGOT; } - + /// getGOTBase - If this is managing a Global Offset Table, this method should /// return a pointer to its base. virtual uint8_t *getGOTBase() const = 0; - + //===--------------------------------------------------------------------===// // Main Allocation Functions //===--------------------------------------------------------------------===// @@ -91,11 +91,11 @@ public: /// startFunctionBody. virtual uint8_t *allocateStub(const GlobalValue* F, unsigned StubSize, unsigned Alignment) = 0; - + /// endFunctionBody - This method is called when the JIT is done codegen'ing /// the specified function. At this point we know the size of the JIT /// compiled function. This passes in FunctionStart (which was returned by - /// the startFunctionBody method) and FunctionEnd which is a pointer to the + /// the startFunctionBody method) and FunctionEnd which is a pointer to the /// actual end of the function. This method should mark the space allocated /// and remember where it is in case the client wants to deallocate it. virtual void endFunctionBody(const Function *F, uint8_t *FunctionStart, @@ -113,12 +113,12 @@ public: /// been deallocated yet. This is never called when the JIT is currently /// emitting a function. virtual void deallocateFunctionBody(void *Body) = 0; - + /// startExceptionTable - When we finished JITing the function, if exception /// handling is set, we emit the exception table. virtual uint8_t* startExceptionTable(const Function* F, uintptr_t &ActualSize) = 0; - + /// endExceptionTable - This method is called when the JIT is done emitting /// the exception table. virtual void endExceptionTable(const Function *F, uint8_t *TableStart, diff --git a/include/llvm/ExecutionEngine/RuntimeDyld.h b/include/llvm/ExecutionEngine/RuntimeDyld.h new file mode 100644 index 0000000..3dc65e3 --- /dev/null +++ b/include/llvm/ExecutionEngine/RuntimeDyld.h @@ -0,0 +1,75 @@ +//===-- RuntimeDyld.h - Run-time dynamic linker for MC-JIT ------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Interface for the runtime dynamic linker facilities of the MC-JIT. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_RUNTIME_DYLD_H +#define LLVM_RUNTIME_DYLD_H + +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/Memory.h" + +namespace llvm { + +class RuntimeDyldImpl; +class MemoryBuffer; + +// RuntimeDyld clients often want to handle the memory management of +// what gets placed where. For JIT clients, this is an abstraction layer +// over the JITMemoryManager, which references objects by their source +// representations in LLVM IR. +// FIXME: As the RuntimeDyld fills out, additional routines will be needed +// for the varying types of objects to be allocated. +class RTDyldMemoryManager { + RTDyldMemoryManager(const RTDyldMemoryManager&); // DO NOT IMPLEMENT + void operator=(const RTDyldMemoryManager&); // DO NOT IMPLEMENT +public: + RTDyldMemoryManager() {} + virtual ~RTDyldMemoryManager(); + + // Allocate ActualSize bytes, or more, for the named function. Return + // a pointer to the allocated memory and update Size to reflect how much + // memory was acutally allocated. + virtual uint8_t *startFunctionBody(const char *Name, uintptr_t &Size) = 0; + + // Mark the end of the function, including how much of the allocated + // memory was actually used. + virtual void endFunctionBody(const char *Name, uint8_t *FunctionStart, + uint8_t *FunctionEnd) = 0; +}; + +class RuntimeDyld { + RuntimeDyld(const RuntimeDyld &); // DO NOT IMPLEMENT + void operator=(const RuntimeDyld &); // DO NOT IMPLEMENT + + // RuntimeDyldImpl is the actual class. RuntimeDyld is just the public + // interface. + RuntimeDyldImpl *Dyld; +public: + RuntimeDyld(RTDyldMemoryManager*); + ~RuntimeDyld(); + + bool loadObject(MemoryBuffer *InputBuffer); + // Get the address of our local copy of the symbol. This may or may not + // be the address used for relocation (clients can copy the data around + // and resolve relocatons based on where they put it). + void *getSymbolAddress(StringRef Name); + // Resolve the relocations for all symbols we currently know about. + void resolveRelocations(); + // Change the address associated with a symbol when resolving relocations. + // Any relocations already associated with the symbol will be re-resolved. + void reassignSymbolAddress(StringRef Name, uint8_t *Addr); + StringRef getErrorString(); +}; + +} // end namespace llvm + +#endif |