X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=blobdiff_plain;f=include%2Fllvm%2FExecutionEngine%2FSectionMemoryManager.h;h=7bb96eb8b71b20b1b7b942f487095e76073e106d;hp=9ac8c92524a0915534fe82401e3f8f951aad4efc;hb=d357cbfd502448626ab1a445ca2ea3852eab6bd6;hpb=034f4be273f0ec629da4bc8369578fc195f3212f diff --git a/include/llvm/ExecutionEngine/SectionMemoryManager.h b/include/llvm/ExecutionEngine/SectionMemoryManager.h index 9ac8c92524a..7bb96eb8b71 100644 --- a/include/llvm/ExecutionEngine/SectionMemoryManager.h +++ b/include/llvm/ExecutionEngine/SectionMemoryManager.h @@ -16,12 +16,11 @@ #define LLVM_EXECUTIONENGINE_SECTIONMEMORYMANAGER_H #include "llvm/ADT/SmallVector.h" -#include "llvm/ExecutionEngine/JITMemoryManager.h" +#include "llvm/ExecutionEngine/RTDyldMemoryManager.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/Memory.h" namespace llvm { - /// This is a simple memory manager which implements the methods called by /// the RuntimeDyld class to allocate memory for section-based loading of /// objects, usually those generated by the MCJIT execution engine. @@ -33,53 +32,46 @@ namespace llvm { /// Any client using this memory manager MUST ensure that section-specific /// page permissions have been applied before attempting to execute functions /// in the JITed object. Permissions can be applied either by calling -/// MCJIT::finalizeObject or by calling SectionMemoryManager::applyPermissions +/// MCJIT::finalizeObject or by calling SectionMemoryManager::finalizeMemory /// directly. Clients of MCJIT should call MCJIT::finalizeObject. -class SectionMemoryManager : public JITMemoryManager { - SectionMemoryManager(const SectionMemoryManager&) LLVM_DELETED_FUNCTION; - void operator=(const SectionMemoryManager&) LLVM_DELETED_FUNCTION; +class SectionMemoryManager : public RTDyldMemoryManager { + SectionMemoryManager(const SectionMemoryManager&) = delete; + void operator=(const SectionMemoryManager&) = delete; public: SectionMemoryManager() { } - virtual ~SectionMemoryManager(); + ~SectionMemoryManager() override; /// \brief Allocates a memory block of (at least) the given size suitable for /// executable code. /// /// The value of \p Alignment must be a power of two. If \p Alignment is zero /// a default alignment of 16 will be used. - virtual uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment, - unsigned SectionID); + uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment, + unsigned SectionID, + StringRef SectionName) override; /// \brief Allocates a memory block of (at least) the given size suitable for /// executable code. /// /// The value of \p Alignment must be a power of two. If \p Alignment is zero /// a default alignment of 16 will be used. - virtual uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment, - unsigned SectionID, - bool isReadOnly); + uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment, + unsigned SectionID, StringRef SectionName, + bool isReadOnly) override; - /// \brief Applies section-specific memory permissions. + /// \brief Update section-specific memory permissions and other attributes. /// /// This method is called when object loading is complete and section page /// permissions can be applied. It is up to the memory manager implementation /// to decide whether or not to act on this method. The memory manager will /// typically allocate all sections as read-write and then apply specific /// permissions when this method is called. Code sections cannot be executed - /// until this function has been called. + /// until this function has been called. In addition, any cache coherency + /// operations needed to reliably use the memory are also performed. /// /// \returns true if an error occurred, false otherwise. - virtual bool applyPermissions(std::string *ErrMsg = 0); - - /// This method returns the address of the specified function. As such it is - /// only useful for resolving library symbols, not code generated symbols. - /// - /// If \p AbortOnFailure is false and no function with the given name is - /// found, this function returns a null pointer. Otherwise, it prints a - /// message to stderr and aborts. - virtual void *getPointerToNamedFunction(const std::string &Name, - bool AbortOnFailure = true); + bool finalizeMemory(std::string *ErrMsg = nullptr) override; /// \brief Invalidate instruction cache for code sections. /// @@ -87,88 +79,45 @@ public: /// explicit cache flush, otherwise JIT code manipulations (like resolved /// relocations) will get to the data cache but not to the instruction cache. /// - /// This method is called from applyPermissions. + /// This method is called from finalizeMemory. virtual void invalidateInstructionCache(); private: + struct FreeMemBlock { + // The actual block of free memory + sys::MemoryBlock Free; + // If there is a pending allocation from the same reservation right before + // this block, store it's index in PendingMem, to be able to update the + // pending region if part of this block is allocated, rather than having to + // create a new one + unsigned PendingPrefixIndex; + }; + struct MemoryGroup { - SmallVector AllocatedMem; - SmallVector FreeMem; - sys::MemoryBlock Near; + // PendingMem contains all blocks of memory (subblocks of AllocatedMem) + // which have not yet had their permissions applied, but have been given + // out to the user. FreeMem contains all block of memory, which have + // neither had their permissions applied, nor been given out to the user. + SmallVector PendingMem; + SmallVector FreeMem; + + // All memory blocks that have been requested from the system + SmallVector AllocatedMem; + + sys::MemoryBlock Near; }; uint8_t *allocateSection(MemoryGroup &MemGroup, uintptr_t Size, unsigned Alignment); - error_code applyMemoryGroupPermissions(MemoryGroup &MemGroup, - unsigned Permissions); + std::error_code applyMemoryGroupPermissions(MemoryGroup &MemGroup, + unsigned Permissions); MemoryGroup CodeMem; MemoryGroup RWDataMem; MemoryGroup RODataMem; - -public: - /// - /// Functions below are not used by MCJIT or RuntimeDyld, but must be - /// implemented because they are declared as pure virtuals in the base class. - /// - - virtual void setMemoryWritable() { - llvm_unreachable("Unexpected call!"); - } - virtual void setMemoryExecutable() { - llvm_unreachable("Unexpected call!"); - } - virtual void setPoisonMemory(bool poison) { - llvm_unreachable("Unexpected call!"); - } - virtual void AllocateGOT() { - llvm_unreachable("Unexpected call!"); - } - virtual uint8_t *getGOTBase() const { - llvm_unreachable("Unexpected call!"); - return 0; - } - virtual uint8_t *startFunctionBody(const Function *F, - uintptr_t &ActualSize){ - llvm_unreachable("Unexpected call!"); - return 0; - } - virtual uint8_t *allocateStub(const GlobalValue *F, unsigned StubSize, - unsigned Alignment) { - llvm_unreachable("Unexpected call!"); - return 0; - } - virtual void endFunctionBody(const Function *F, uint8_t *FunctionStart, - uint8_t *FunctionEnd) { - llvm_unreachable("Unexpected call!"); - } - virtual uint8_t *allocateSpace(intptr_t Size, unsigned Alignment) { - llvm_unreachable("Unexpected call!"); - return 0; - } - virtual uint8_t *allocateGlobal(uintptr_t Size, unsigned Alignment) { - llvm_unreachable("Unexpected call!"); - return 0; - } - virtual void deallocateFunctionBody(void *Body) { - llvm_unreachable("Unexpected call!"); - } - virtual uint8_t *startExceptionTable(const Function *F, - uintptr_t &ActualSize) { - llvm_unreachable("Unexpected call!"); - return 0; - } - virtual void endExceptionTable(const Function *F, uint8_t *TableStart, - uint8_t *TableEnd, uint8_t *FrameRegister) { - llvm_unreachable("Unexpected call!"); - } - virtual void deallocateExceptionTable(void *ET) { - llvm_unreachable("Unexpected call!"); - } }; } #endif // LLVM_EXECUTION_ENGINE_SECTION_MEMORY_MANAGER_H -