1 //===- llvm/Support/Memory.h - Memory Support -------------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 // This file declares the llvm::sys::Memory class.
11 //===----------------------------------------------------------------------===//
13 #ifndef LLVM_SUPPORT_MEMORY_H
14 #define LLVM_SUPPORT_MEMORY_H
16 #include "llvm/Support/DataTypes.h"
18 #include <system_error>
23 /// This class encapsulates the notion of a memory block which has an address
24 /// and a size. It is used by the Memory class (a friend) as the result of
25 /// various memory allocation operations.
27 /// Memory block abstraction.
30 MemoryBlock() : Address(nullptr), Size(0) { }
31 MemoryBlock(void *addr
, size_t size
) : Address(addr
), Size(size
) { }
32 void *base() const { return Address
; }
33 size_t size() const { return Size
; }
36 void *Address
; ///< Address of first byte of memory area
37 size_t Size
; ///< Size, in bytes of the memory area
41 /// This class provides various memory handling functions that manipulate
42 /// MemoryBlock instances.
44 /// An abstraction for memory operations.
47 enum ProtectionFlags
{
53 /// This method allocates a block of memory that is suitable for loading
54 /// dynamically generated code (e.g. JIT). An attempt to allocate
55 /// \p NumBytes bytes of virtual memory is made.
56 /// \p NearBlock may point to an existing allocation in which case
57 /// an attempt is made to allocate more memory near the existing block.
58 /// The actual allocated address is not guaranteed to be near the requested
60 /// \p Flags is used to set the initial protection flags for the block
62 /// \p EC [out] returns an object describing any error that occurs.
64 /// This method may allocate more than the number of bytes requested. The
65 /// actual number of bytes allocated is indicated in the returned
68 /// The start of the allocated block must be aligned with the
69 /// system allocation granularity (64K on Windows, page size on Linux).
70 /// If the address following \p NearBlock is not so aligned, it will be
71 /// rounded up to the next allocation granularity boundary.
73 /// \r a non-null MemoryBlock if the function was successful,
74 /// otherwise a null MemoryBlock is with \p EC describing the error.
76 /// Allocate mapped memory.
77 static MemoryBlock
allocateMappedMemory(size_t NumBytes
,
78 const MemoryBlock
*const NearBlock
,
82 /// This method releases a block of memory that was allocated with the
83 /// allocateMappedMemory method. It should not be used to release any
84 /// memory block allocated any other way.
85 /// \p Block describes the memory to be released.
87 /// \r error_success if the function was successful, or an error_code
88 /// describing the failure if an error occurred.
90 /// Release mapped memory.
91 static std::error_code
releaseMappedMemory(MemoryBlock
&Block
);
93 /// This method sets the protection flags for a block of memory to the
94 /// state specified by /p Flags. The behavior is not specified if the
95 /// memory was not allocated using the allocateMappedMemory method.
96 /// \p Block describes the memory block to be protected.
97 /// \p Flags specifies the new protection state to be assigned to the block.
98 /// \p ErrMsg [out] returns a string describing any error that occurred.
100 /// If \p Flags is MF_WRITE, the actual behavior varies
101 /// with the operating system (i.e. MF_READ | MF_WRITE on Windows) and the
102 /// target architecture (i.e. MF_WRITE -> MF_READ | MF_WRITE on i386).
104 /// \r error_success if the function was successful, or an error_code
105 /// describing the failure if an error occurred.
107 /// Set memory protection state.
108 static std::error_code
protectMappedMemory(const MemoryBlock
&Block
,
111 /// InvalidateInstructionCache - Before the JIT can run a block of code
112 /// that has been emitted it must invalidate the instruction cache on some
114 static void InvalidateInstructionCache(const void *Addr
, size_t Len
);
117 /// Owning version of MemoryBlock.
118 class OwningMemoryBlock
{
120 OwningMemoryBlock() = default;
121 explicit OwningMemoryBlock(MemoryBlock M
) : M(M
) {}
122 OwningMemoryBlock(OwningMemoryBlock
&&Other
) {
124 Other
.M
= MemoryBlock();
126 OwningMemoryBlock
& operator=(OwningMemoryBlock
&&Other
) {
128 Other
.M
= MemoryBlock();
131 ~OwningMemoryBlock() {
132 Memory::releaseMappedMemory(M
);
134 void *base() const { return M
.base(); }
135 size_t size() const { return M
.size(); }
136 MemoryBlock
getMemoryBlock() const { return M
; }