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 : /// Memory block abstraction.
29 : class MemoryBlock {
30 : public:
31 3157 : MemoryBlock() : Address(nullptr), Size(0) { }
32 1131 : MemoryBlock(void *addr, size_t size) : Address(addr), Size(size) { }
33 0 : void *base() const { return Address; }
34 0 : 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 : /// 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 : /// 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 : /// 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 : /// Set memory protection state.
109 : static std::error_code protectMappedMemory(const MemoryBlock &Block,
110 : unsigned Flags);
111 :
112 : /// InvalidateInstructionCache - Before the JIT can run a block of code
113 : /// that has been emitted it must invalidate the instruction cache on some
114 : /// platforms.
115 : static void InvalidateInstructionCache(const void *Addr, size_t Len);
116 : };
117 :
118 : /// Owning version of MemoryBlock.
119 : class OwningMemoryBlock {
120 : public:
121 : OwningMemoryBlock() = default;
122 29 : explicit OwningMemoryBlock(MemoryBlock M) : M(M) {}
123 : OwningMemoryBlock(OwningMemoryBlock &&Other) {
124 57 : M = Other.M;
125 57 : Other.M = MemoryBlock();
126 : }
127 : OwningMemoryBlock& operator=(OwningMemoryBlock &&Other) {
128 39 : M = Other.M;
129 39 : Other.M = MemoryBlock();
130 : return *this;
131 : }
132 15 : ~OwningMemoryBlock() {
133 111 : Memory::releaseMappedMemory(M);
134 : }
135 598 : void *base() const { return M.base(); }
136 108 : size_t size() const { return M.size(); }
137 0 : MemoryBlock getMemoryBlock() const { return M; }
138 : private:
139 : MemoryBlock M;
140 : };
141 :
142 : }
143 : }
144 :
145 : #endif
|