Recommit [NFC] Better encapsulation of llvm::Optional Storage
[llvm-complete.git] / include / llvm / Support / Memory.h
blob2f4cafe40c805bdc77f4581ed877b5cbea365647
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.
11 //===----------------------------------------------------------------------===//
13 #ifndef LLVM_SUPPORT_MEMORY_H
14 #define LLVM_SUPPORT_MEMORY_H
16 #include "llvm/Support/DataTypes.h"
17 #include <string>
18 #include <system_error>
20 namespace llvm {
21 namespace sys {
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.
26 /// @see Memory
27 /// Memory block abstraction.
28 class MemoryBlock {
29 public:
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; }
35 private:
36 void *Address; ///< Address of first byte of memory area
37 size_t Size; ///< Size, in bytes of the memory area
38 friend class Memory;
41 /// This class provides various memory handling functions that manipulate
42 /// MemoryBlock instances.
43 /// @since 1.4
44 /// An abstraction for memory operations.
45 class Memory {
46 public:
47 enum ProtectionFlags {
48 MF_READ = 0x1000000,
49 MF_WRITE = 0x2000000,
50 MF_EXEC = 0x4000000
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
59 /// address.
60 /// \p Flags is used to set the initial protection flags for the block
61 /// of the memory.
62 /// \p EC [out] returns an object describing any error that occurs.
63 ///
64 /// This method may allocate more than the number of bytes requested. The
65 /// actual number of bytes allocated is indicated in the returned
66 /// MemoryBlock.
67 ///
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.
72 ///
73 /// \r a non-null MemoryBlock if the function was successful,
74 /// otherwise a null MemoryBlock is with \p EC describing the error.
75 ///
76 /// Allocate mapped memory.
77 static MemoryBlock allocateMappedMemory(size_t NumBytes,
78 const MemoryBlock *const NearBlock,
79 unsigned Flags,
80 std::error_code &EC);
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.
86 ///
87 /// \r error_success if the function was successful, or an error_code
88 /// describing the failure if an error occurred.
89 ///
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.
99 ///
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,
109 unsigned Flags);
111 /// InvalidateInstructionCache - Before the JIT can run a block of code
112 /// that has been emitted it must invalidate the instruction cache on some
113 /// platforms.
114 static void InvalidateInstructionCache(const void *Addr, size_t Len);
117 /// Owning version of MemoryBlock.
118 class OwningMemoryBlock {
119 public:
120 OwningMemoryBlock() = default;
121 explicit OwningMemoryBlock(MemoryBlock M) : M(M) {}
122 OwningMemoryBlock(OwningMemoryBlock &&Other) {
123 M = Other.M;
124 Other.M = MemoryBlock();
126 OwningMemoryBlock& operator=(OwningMemoryBlock &&Other) {
127 M = Other.M;
128 Other.M = MemoryBlock();
129 return *this;
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; }
137 private:
138 MemoryBlock M;
144 #endif