Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. //===- llvm/Support/Memory.h - Memory Support -------------------*- C++ -*-===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // This file declares the llvm::sys::Memory class.
  10. //
  11. //===----------------------------------------------------------------------===//
  12.  
  13. #ifndef LLVM_SUPPORT_MEMORY_H
  14. #define LLVM_SUPPORT_MEMORY_H
  15.  
  16. #include "llvm/Support/DataTypes.h"
  17. #include <system_error>
  18.  
  19. namespace llvm {
  20.  
  21. // Forward declare raw_ostream: it is used for debug dumping below.
  22. class raw_ostream;
  23.  
  24. namespace sys {
  25.  
  26.   /// This class encapsulates the notion of a memory block which has an address
  27.   /// and a size. It is used by the Memory class (a friend) as the result of
  28.   /// various memory allocation operations.
  29.   /// @see Memory
  30.   /// Memory block abstraction.
  31.   class MemoryBlock {
  32.   public:
  33.     MemoryBlock() : Address(nullptr), AllocatedSize(0) {}
  34.     MemoryBlock(void *addr, size_t allocatedSize)
  35.         : Address(addr), AllocatedSize(allocatedSize) {}
  36.     void *base() const { return Address; }
  37.     /// The size as it was allocated. This is always greater or equal to the
  38.     /// size that was originally requested.
  39.     size_t allocatedSize() const { return AllocatedSize; }
  40.  
  41.   private:
  42.     void *Address;    ///< Address of first byte of memory area
  43.     size_t AllocatedSize; ///< Size, in bytes of the memory area
  44.     unsigned Flags = 0;
  45.     friend class Memory;
  46.   };
  47.  
  48.   /// This class provides various memory handling functions that manipulate
  49.   /// MemoryBlock instances.
  50.   /// @since 1.4
  51.   /// An abstraction for memory operations.
  52.   class Memory {
  53.   public:
  54.     enum ProtectionFlags {
  55.       MF_READ = 0x1000000,
  56.       MF_WRITE = 0x2000000,
  57.       MF_EXEC = 0x4000000,
  58.       MF_RWE_MASK = 0x7000000,
  59.  
  60.       /// The \p MF_HUGE_HINT flag is used to indicate that the request for
  61.       /// a memory block should be satisfied with large pages if possible.
  62.       /// This is only a hint and small pages will be used as fallback.
  63.       ///
  64.       /// The presence or absence of this flag in the returned memory block
  65.       /// is (at least currently) *not* a reliable indicator that the memory
  66.       /// block will use or will not use large pages. On some systems a request
  67.       /// without this flag can be backed by large pages without this flag being
  68.       /// set, and on some other systems a request with this flag can fallback
  69.       /// to small pages without this flag being cleared.
  70.       MF_HUGE_HINT = 0x0000001
  71.     };
  72.  
  73.     /// This method allocates a block of memory that is suitable for loading
  74.     /// dynamically generated code (e.g. JIT). An attempt to allocate
  75.     /// \p NumBytes bytes of virtual memory is made.
  76.     /// \p NearBlock may point to an existing allocation in which case
  77.     /// an attempt is made to allocate more memory near the existing block.
  78.     /// The actual allocated address is not guaranteed to be near the requested
  79.     /// address.
  80.     /// \p Flags is used to set the initial protection flags for the block
  81.     /// of the memory.
  82.     /// \p EC [out] returns an object describing any error that occurs.
  83.     ///
  84.     /// This method may allocate more than the number of bytes requested.  The
  85.     /// actual number of bytes allocated is indicated in the returned
  86.     /// MemoryBlock.
  87.     ///
  88.     /// The start of the allocated block must be aligned with the
  89.     /// system allocation granularity (64K on Windows, page size on Linux).
  90.     /// If the address following \p NearBlock is not so aligned, it will be
  91.     /// rounded up to the next allocation granularity boundary.
  92.     ///
  93.     /// \r a non-null MemoryBlock if the function was successful,
  94.     /// otherwise a null MemoryBlock is with \p EC describing the error.
  95.     ///
  96.     /// Allocate mapped memory.
  97.     static MemoryBlock allocateMappedMemory(size_t NumBytes,
  98.                                             const MemoryBlock *const NearBlock,
  99.                                             unsigned Flags,
  100.                                             std::error_code &EC);
  101.  
  102.     /// This method releases a block of memory that was allocated with the
  103.     /// allocateMappedMemory method. It should not be used to release any
  104.     /// memory block allocated any other way.
  105.     /// \p Block describes the memory to be released.
  106.     ///
  107.     /// \r error_success if the function was successful, or an error_code
  108.     /// describing the failure if an error occurred.
  109.     ///
  110.     /// Release mapped memory.
  111.     static std::error_code releaseMappedMemory(MemoryBlock &Block);
  112.  
  113.     /// This method sets the protection flags for a block of memory to the
  114.     /// state specified by /p Flags.  The behavior is not specified if the
  115.     /// memory was not allocated using the allocateMappedMemory method.
  116.     /// \p Block describes the memory block to be protected.
  117.     /// \p Flags specifies the new protection state to be assigned to the block.
  118.     ///
  119.     /// If \p Flags is MF_WRITE, the actual behavior varies
  120.     /// with the operating system (i.e. MF_READ | MF_WRITE on Windows) and the
  121.     /// target architecture (i.e. MF_WRITE -> MF_READ | MF_WRITE on i386).
  122.     ///
  123.     /// \r error_success if the function was successful, or an error_code
  124.     /// describing the failure if an error occurred.
  125.     ///
  126.     /// Set memory protection state.
  127.     static std::error_code protectMappedMemory(const MemoryBlock &Block,
  128.                                                unsigned Flags);
  129.  
  130.     /// InvalidateInstructionCache - Before the JIT can run a block of code
  131.     /// that has been emitted it must invalidate the instruction cache on some
  132.     /// platforms.
  133.     static void InvalidateInstructionCache(const void *Addr, size_t Len);
  134.   };
  135.  
  136.   /// Owning version of MemoryBlock.
  137.   class OwningMemoryBlock {
  138.   public:
  139.     OwningMemoryBlock() = default;
  140.     explicit OwningMemoryBlock(MemoryBlock M) : M(M) {}
  141.     OwningMemoryBlock(OwningMemoryBlock &&Other) {
  142.       M = Other.M;
  143.       Other.M = MemoryBlock();
  144.     }
  145.     OwningMemoryBlock& operator=(OwningMemoryBlock &&Other) {
  146.       M = Other.M;
  147.       Other.M = MemoryBlock();
  148.       return *this;
  149.     }
  150.     ~OwningMemoryBlock() {
  151.       if (M.base())
  152.         Memory::releaseMappedMemory(M);
  153.     }
  154.     void *base() const { return M.base(); }
  155.     /// The size as it was allocated. This is always greater or equal to the
  156.     /// size that was originally requested.
  157.     size_t allocatedSize() const { return M.allocatedSize(); }
  158.     MemoryBlock getMemoryBlock() const { return M; }
  159.     std::error_code release() {
  160.       std::error_code EC;
  161.       if (M.base()) {
  162.         EC = Memory::releaseMappedMemory(M);
  163.         M = MemoryBlock();
  164.       }
  165.       return EC;
  166.     }
  167.   private:
  168.     MemoryBlock M;
  169.   };
  170.  
  171. #ifndef NDEBUG
  172.   /// Debugging output for Memory::ProtectionFlags.
  173.   raw_ostream &operator<<(raw_ostream &OS, const Memory::ProtectionFlags &PF);
  174.  
  175.   /// Debugging output for MemoryBlock.
  176.   raw_ostream &operator<<(raw_ostream &OS, const MemoryBlock &MB);
  177. #endif // ifndef NDEBUG
  178.   }    // end namespace sys
  179.   }    // end namespace llvm
  180.  
  181. #endif
  182.