-//===- llvm/Support/Memory.h - Memory Support --------------------*- C++ -*-===//
+//===- llvm/Support/Memory.h - Memory Support -------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
#define LLVM_SUPPORT_MEMORY_H
#include "llvm/Support/DataTypes.h"
-#include "llvm/Support/system_error.h"
#include <string>
+#include <system_error>
namespace llvm {
namespace sys {
/// @brief Memory block abstraction.
class MemoryBlock {
public:
- MemoryBlock() : Address(0), Size(0) { }
+ MemoryBlock() : Address(nullptr), Size(0) { }
MemoryBlock(void *addr, size_t size) : Address(addr), Size(size) { }
void *base() const { return Address; }
size_t size() const { return Size; }
+
private:
void *Address; ///< Address of first byte of memory area
size_t Size; ///< Size, in bytes of the memory area
/// If the address following \p NearBlock is not so aligned, it will be
/// rounded up to the next allocation granularity boundary.
///
- /// \r a non-null MemoryBlock if the function was successful,
+ /// \r a non-null MemoryBlock if the function was successful,
/// otherwise a null MemoryBlock is with \p EC describing the error.
///
/// @brief Allocate mapped memory.
static MemoryBlock allocateMappedMemory(size_t NumBytes,
const MemoryBlock *const NearBlock,
unsigned Flags,
- error_code &EC);
+ std::error_code &EC);
/// This method releases a block of memory that was allocated with the
/// allocateMappedMemory method. It should not be used to release any
///
/// \r error_success if the function was successful, or an error_code
/// describing the failure if an error occurred.
- ///
+ ///
/// @brief Release mapped memory.
- static error_code releaseMappedMemory(MemoryBlock &Block);
+ static std::error_code releaseMappedMemory(MemoryBlock &Block);
/// This method sets the protection flags for a block of memory to the
/// state specified by /p Flags. The behavior is not specified if the
/// describing the failure if an error occurred.
///
/// @brief Set memory protection state.
- static error_code protectMappedMemory(const MemoryBlock &Block,
- unsigned Flags);
+ static std::error_code protectMappedMemory(const MemoryBlock &Block,
+ unsigned Flags);
/// This method allocates a block of Read/Write/Execute memory that is
/// suitable for executing dynamically generated code (e.g. JIT). An
/// @brief Allocate Read/Write/Execute memory.
static MemoryBlock AllocateRWX(size_t NumBytes,
const MemoryBlock *NearBlock,
- std::string *ErrMsg = 0);
+ std::string *ErrMsg = nullptr);
/// This method releases a block of Read/Write/Execute memory that was
/// allocated with the AllocateRWX method. It should not be used to
/// On success, this returns false, otherwise it returns true and fills
/// in *ErrMsg.
/// @brief Release Read/Write/Execute memory.
- static bool ReleaseRWX(MemoryBlock &block, std::string *ErrMsg = 0);
-
+ static bool ReleaseRWX(MemoryBlock &block, std::string *ErrMsg = nullptr);
/// InvalidateInstructionCache - Before the JIT can run a block of code
/// that has been emitted it must invalidate the instruction cache on some
/// setExecutable - Before the JIT can run a block of code, it has to be
/// given read and executable privilege. Return true if it is already r-x
/// or the system is able to change its previlege.
- static bool setExecutable(MemoryBlock &M, std::string *ErrMsg = 0);
+ static bool setExecutable(MemoryBlock &M, std::string *ErrMsg = nullptr);
/// setWritable - When adding to a block of code, the JIT may need
/// to mark a block of code as RW since the protections are on page
/// boundaries, and the JIT internal allocations are not page aligned.
- static bool setWritable(MemoryBlock &M, std::string *ErrMsg = 0);
+ static bool setWritable(MemoryBlock &M, std::string *ErrMsg = nullptr);
/// setRangeExecutable - Mark the page containing a range of addresses
/// as executable.
/// as writable.
static bool setRangeWritable(const void *Addr, size_t Size);
};
+
+ /// Owning version of MemoryBlock.
+ class OwningMemoryBlock {
+ public:
+ OwningMemoryBlock() = default;
+ explicit OwningMemoryBlock(MemoryBlock M) : M(M) {}
+ OwningMemoryBlock(OwningMemoryBlock &&Other) {
+ M = Other.M;
+ Other.M = MemoryBlock();
+ }
+ OwningMemoryBlock& operator=(OwningMemoryBlock &&Other) {
+ M = Other.M;
+ Other.M = MemoryBlock();
+ return *this;
+ }
+ ~OwningMemoryBlock() {
+ Memory::releaseMappedMemory(M);
+ }
+ void *base() const { return M.base(); }
+ size_t size() const { return M.size(); }
+ MemoryBlock getMemoryBlock() const { return M; }
+ private:
+ MemoryBlock M;
+ };
+
}
}