LCOV - code coverage report
Current view: top level - include/llvm/Support - Memory.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 13 13 100.0 %
Date: 2017-09-14 15:23:50 Functions: 0 0 -
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===- llvm/Support/Memory.h - Memory Support -------------------*- C++ -*-===//
       2             : //
       3             : //                     The LLVM Compiler Infrastructure
       4             : //
       5             : // This file is distributed under the University of Illinois Open Source
       6             : // License. See LICENSE.TXT for details.
       7             : //
       8             : //===----------------------------------------------------------------------===//
       9             : //
      10             : // This file declares the llvm::sys::Memory class.
      11             : //
      12             : //===----------------------------------------------------------------------===//
      13             : 
      14             : #ifndef LLVM_SUPPORT_MEMORY_H
      15             : #define LLVM_SUPPORT_MEMORY_H
      16             : 
      17             : #include "llvm/Support/DataTypes.h"
      18             : #include <string>
      19             : #include <system_error>
      20             : 
      21             : namespace llvm {
      22             : namespace sys {
      23             : 
      24             :   /// This class encapsulates the notion of a memory block which has an address
      25             :   /// and a size. It is used by the Memory class (a friend) as the result of
      26             :   /// various memory allocation operations.
      27             :   /// @see Memory
      28             :   /// @brief Memory block abstraction.
      29             :   class MemoryBlock {
      30             :   public:
      31        2819 :     MemoryBlock() : Address(nullptr), Size(0) { }
      32        1674 :     MemoryBlock(void *addr, size_t size) : Address(addr), Size(size) { }
      33             :     void *base() const { return Address; }
      34             :     size_t size() const { return Size; }
      35             : 
      36             :   private:
      37             :     void *Address;    ///< Address of first byte of memory area
      38             :     size_t Size;      ///< Size, in bytes of the memory area
      39             :     friend class Memory;
      40             :   };
      41             : 
      42             :   /// This class provides various memory handling functions that manipulate
      43             :   /// MemoryBlock instances.
      44             :   /// @since 1.4
      45             :   /// @brief An abstraction for memory operations.
      46             :   class Memory {
      47             :   public:
      48             :     enum ProtectionFlags {
      49             :       MF_READ  = 0x1000000,
      50             :       MF_WRITE = 0x2000000,
      51             :       MF_EXEC  = 0x4000000
      52             :     };
      53             : 
      54             :     /// This method allocates a block of memory that is suitable for loading
      55             :     /// dynamically generated code (e.g. JIT). An attempt to allocate
      56             :     /// \p NumBytes bytes of virtual memory is made.
      57             :     /// \p NearBlock may point to an existing allocation in which case
      58             :     /// an attempt is made to allocate more memory near the existing block.
      59             :     /// The actual allocated address is not guaranteed to be near the requested
      60             :     /// address.
      61             :     /// \p Flags is used to set the initial protection flags for the block
      62             :     /// of the memory.
      63             :     /// \p EC [out] returns an object describing any error that occurs.
      64             :     ///
      65             :     /// This method may allocate more than the number of bytes requested.  The
      66             :     /// actual number of bytes allocated is indicated in the returned
      67             :     /// MemoryBlock.
      68             :     ///
      69             :     /// The start of the allocated block must be aligned with the
      70             :     /// system allocation granularity (64K on Windows, page size on Linux).
      71             :     /// If the address following \p NearBlock is not so aligned, it will be
      72             :     /// rounded up to the next allocation granularity boundary.
      73             :     ///
      74             :     /// \r a non-null MemoryBlock if the function was successful,
      75             :     /// otherwise a null MemoryBlock is with \p EC describing the error.
      76             :     ///
      77             :     /// @brief Allocate mapped memory.
      78             :     static MemoryBlock allocateMappedMemory(size_t NumBytes,
      79             :                                             const MemoryBlock *const NearBlock,
      80             :                                             unsigned Flags,
      81             :                                             std::error_code &EC);
      82             : 
      83             :     /// This method releases a block of memory that was allocated with the
      84             :     /// allocateMappedMemory method. It should not be used to release any
      85             :     /// memory block allocated any other way.
      86             :     /// \p Block describes the memory to be released.
      87             :     ///
      88             :     /// \r error_success if the function was successful, or an error_code
      89             :     /// describing the failure if an error occurred.
      90             :     ///
      91             :     /// @brief Release mapped memory.
      92             :     static std::error_code releaseMappedMemory(MemoryBlock &Block);
      93             : 
      94             :     /// This method sets the protection flags for a block of memory to the
      95             :     /// state specified by /p Flags.  The behavior is not specified if the
      96             :     /// memory was not allocated using the allocateMappedMemory method.
      97             :     /// \p Block describes the memory block to be protected.
      98             :     /// \p Flags specifies the new protection state to be assigned to the block.
      99             :     /// \p ErrMsg [out] returns a string describing any error that occurred.
     100             :     ///
     101             :     /// If \p Flags is MF_WRITE, the actual behavior varies
     102             :     /// with the operating system (i.e. MF_READ | MF_WRITE on Windows) and the
     103             :     /// target architecture (i.e. MF_WRITE -> MF_READ | MF_WRITE on i386).
     104             :     ///
     105             :     /// \r error_success if the function was successful, or an error_code
     106             :     /// describing the failure if an error occurred.
     107             :     ///
     108             :     /// @brief Set memory protection state.
     109             :     static std::error_code protectMappedMemory(const MemoryBlock &Block,
     110             :                                                unsigned Flags);
     111             : 
     112             :     /// This method allocates a block of Read/Write/Execute memory that is
     113             :     /// suitable for executing dynamically generated code (e.g. JIT). An
     114             :     /// attempt to allocate \p NumBytes bytes of virtual memory is made.
     115             :     /// \p NearBlock may point to an existing allocation in which case
     116             :     /// an attempt is made to allocate more memory near the existing block.
     117             :     ///
     118             :     /// On success, this returns a non-null memory block, otherwise it returns
     119             :     /// a null memory block and fills in *ErrMsg.
     120             :     ///
     121             :     /// @brief Allocate Read/Write/Execute memory.
     122             :     static MemoryBlock AllocateRWX(size_t NumBytes,
     123             :                                    const MemoryBlock *NearBlock,
     124             :                                    std::string *ErrMsg = nullptr);
     125             : 
     126             :     /// This method releases a block of Read/Write/Execute memory that was
     127             :     /// allocated with the AllocateRWX method. It should not be used to
     128             :     /// release any memory block allocated any other way.
     129             :     ///
     130             :     /// On success, this returns false, otherwise it returns true and fills
     131             :     /// in *ErrMsg.
     132             :     /// @brief Release Read/Write/Execute memory.
     133             :     static bool ReleaseRWX(MemoryBlock &block, std::string *ErrMsg = nullptr);
     134             : 
     135             :     /// InvalidateInstructionCache - Before the JIT can run a block of code
     136             :     /// that has been emitted it must invalidate the instruction cache on some
     137             :     /// platforms.
     138             :     static void InvalidateInstructionCache(const void *Addr, size_t Len);
     139             : 
     140             :     /// setExecutable - Before the JIT can run a block of code, it has to be
     141             :     /// given read and executable privilege. Return true if it is already r-x
     142             :     /// or the system is able to change its previlege.
     143             :     static bool setExecutable(MemoryBlock &M, std::string *ErrMsg = nullptr);
     144             : 
     145             :     /// setWritable - When adding to a block of code, the JIT may need
     146             :     /// to mark a block of code as RW since the protections are on page
     147             :     /// boundaries, and the JIT internal allocations are not page aligned.
     148             :     static bool setWritable(MemoryBlock &M, std::string *ErrMsg = nullptr);
     149             : 
     150             :     /// setRangeExecutable - Mark the page containing a range of addresses
     151             :     /// as executable.
     152             :     static bool setRangeExecutable(const void *Addr, size_t Size);
     153             : 
     154             :     /// setRangeWritable - Mark the page containing a range of addresses
     155             :     /// as writable.
     156             :     static bool setRangeWritable(const void *Addr, size_t Size);
     157             :   };
     158             : 
     159             :   /// Owning version of MemoryBlock.
     160             :   class OwningMemoryBlock {
     161             :   public:
     162          86 :     OwningMemoryBlock() = default;
     163          28 :     explicit OwningMemoryBlock(MemoryBlock M) : M(M) {}
     164          72 :     OwningMemoryBlock(OwningMemoryBlock &&Other) {
     165          36 :       M = Other.M;
     166          36 :       Other.M = MemoryBlock();
     167             :     }
     168             :     OwningMemoryBlock& operator=(OwningMemoryBlock &&Other) {
     169          19 :       M = Other.M;
     170          19 :       Other.M = MemoryBlock();
     171             :       return *this;
     172             :     }
     173          43 :     ~OwningMemoryBlock() {
     174         107 :       Memory::releaseMappedMemory(M);
     175             :     }
     176         103 :     void *base() const { return M.base(); }
     177             :     size_t size() const { return M.size(); }
     178          19 :     MemoryBlock getMemoryBlock() const { return M; }
     179             :   private:
     180             :     MemoryBlock M;
     181             :   };
     182             : 
     183             : }
     184             : }
     185             : 
     186             : #endif

Generated by: LCOV version 1.13