diff options
Diffstat (limited to 'unittests/ExecutionEngine/MCJIT/SectionMemoryManager.h')
-rw-r--r-- | unittests/ExecutionEngine/MCJIT/SectionMemoryManager.h | 90 |
1 files changed, 73 insertions, 17 deletions
diff --git a/unittests/ExecutionEngine/MCJIT/SectionMemoryManager.h b/unittests/ExecutionEngine/MCJIT/SectionMemoryManager.h index 968ee63..7d5a5ff 100644 --- a/unittests/ExecutionEngine/MCJIT/SectionMemoryManager.h +++ b/unittests/ExecutionEngine/MCJIT/SectionMemoryManager.h @@ -1,4 +1,4 @@ -//===-- SectionMemoryManager.h - Memory allocator for MCJIT -----*- C++ -*-===// +//===- SectionMemoryManager.h - Memory manager for MCJIT/RtDyld -*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -8,7 +8,7 @@ //===----------------------------------------------------------------------===// // // This file contains the declaration of a section-based memory manager used by -// the MCJIT execution engine. +// the MCJIT execution engine and RuntimeDyld. // //===----------------------------------------------------------------------===// @@ -22,42 +22,97 @@ namespace llvm { -// Section-based memory manager for MCJIT +/// 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. +/// +/// This memory manager allocates all section memory as read-write. The +/// RuntimeDyld will copy JITed section memory into these allocated blocks +/// and perform any necessary linking and relocations. +/// +/// 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 +/// 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; public: - SectionMemoryManager() { } - ~SectionMemoryManager(); + virtual ~SectionMemoryManager(); + /// \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); + /// \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); + unsigned SectionID, + bool isReadOnly); - virtual bool applyPermissions(std::string *ErrMsg) { return false; } + /// \brief Applies section-specific memory permissions. + /// + /// 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. + /// + /// \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); - // Invalidate instruction cache for code sections. Some platforms with - // separate data cache and instruction cache require explicit cache flush, - // otherwise JIT code manipulations (like resolved relocations) will get to - // the data cache but not to the instruction cache. + /// \brief Invalidate instruction cache for code sections. + /// + /// Some platforms with separate data cache and instruction cache require + /// 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 not called by RuntimeDyld or MCJIT during the load + /// process. Clients may call this function when needed. See the lli + /// tool for example use. virtual void invalidateInstructionCache(); private: + struct MemoryGroup { + SmallVector<sys::MemoryBlock, 16> AllocatedMem; + SmallVector<sys::MemoryBlock, 16> FreeMem; + sys::MemoryBlock Near; + }; - SmallVector<sys::MemoryBlock, 16> AllocatedDataMem; - SmallVector<sys::MemoryBlock, 16> AllocatedCodeMem; - SmallVector<sys::MemoryBlock, 16> FreeCodeMem; + uint8_t *allocateSection(MemoryGroup &MemGroup, uintptr_t Size, + unsigned Alignment); -public: + error_code applyMemoryGroupPermissions(MemoryGroup &MemGroup, + unsigned Permissions); + + MemoryGroup CodeMem; + MemoryGroup RWDataMem; + MemoryGroup RODataMem; +public: /// - /// Functions below are not used by MCJIT, but must be implemented because - /// they are declared as pure virtuals in the base class. + /// 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() { @@ -118,3 +173,4 @@ public: } #endif // LLVM_EXECUTION_ENGINE_SECTION_MEMORY_MANAGER_H + |