Mercurial > hg > CbC > CbC_llvm
comparison lib/ExecutionEngine/SectionMemoryManager.cpp @ 147:c2174574ed3a
LLVM 10
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Wed, 14 Aug 2019 16:55:33 +0900 |
parents | 3a76565eade5 |
children |
comparison
equal
deleted
inserted
replaced
134:3a76565eade5 | 147:c2174574ed3a |
---|---|
1 //===- SectionMemoryManager.cpp - Memory manager for MCJIT/RtDyld *- C++ -*-==// | 1 //===- SectionMemoryManager.cpp - Memory manager for MCJIT/RtDyld *- C++ -*-==// |
2 // | 2 // |
3 // The LLVM Compiler Infrastructure | 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 // | 4 // See https://llvm.org/LICENSE.txt for license information. |
5 // This file is distributed under the University of Illinois Open Source | 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 // License. See LICENSE.TXT for details. | |
7 // | 6 // |
8 //===----------------------------------------------------------------------===// | 7 //===----------------------------------------------------------------------===// |
9 // | 8 // |
10 // This file implements the section-based memory manager used by the MCJIT | 9 // This file implements the section-based memory manager used by the MCJIT |
11 // execution engine and RuntimeDyld | 10 // execution engine and RuntimeDyld |
63 }(); | 62 }(); |
64 | 63 |
65 // Look in the list of free memory regions and use a block there if one | 64 // Look in the list of free memory regions and use a block there if one |
66 // is available. | 65 // is available. |
67 for (FreeMemBlock &FreeMB : MemGroup.FreeMem) { | 66 for (FreeMemBlock &FreeMB : MemGroup.FreeMem) { |
68 if (FreeMB.Free.size() >= RequiredSize) { | 67 if (FreeMB.Free.allocatedSize() >= RequiredSize) { |
69 Addr = (uintptr_t)FreeMB.Free.base(); | 68 Addr = (uintptr_t)FreeMB.Free.base(); |
70 uintptr_t EndOfBlock = Addr + FreeMB.Free.size(); | 69 uintptr_t EndOfBlock = Addr + FreeMB.Free.allocatedSize(); |
71 // Align the address. | 70 // Align the address. |
72 Addr = (Addr + Alignment - 1) & ~(uintptr_t)(Alignment - 1); | 71 Addr = (Addr + Alignment - 1) & ~(uintptr_t)(Alignment - 1); |
73 | 72 |
74 if (FreeMB.PendingPrefixIndex == (unsigned)-1) { | 73 if (FreeMB.PendingPrefixIndex == (unsigned)-1) { |
75 // The part of the block we're giving out to the user is now pending | 74 // The part of the block we're giving out to the user is now pending |
114 MemGroup.Near = MB; | 113 MemGroup.Near = MB; |
115 | 114 |
116 // Remember that we allocated this memory | 115 // Remember that we allocated this memory |
117 MemGroup.AllocatedMem.push_back(MB); | 116 MemGroup.AllocatedMem.push_back(MB); |
118 Addr = (uintptr_t)MB.base(); | 117 Addr = (uintptr_t)MB.base(); |
119 uintptr_t EndOfBlock = Addr + MB.size(); | 118 uintptr_t EndOfBlock = Addr + MB.allocatedSize(); |
120 | 119 |
121 // Align the address. | 120 // Align the address. |
122 Addr = (Addr + Alignment - 1) & ~(uintptr_t)(Alignment - 1); | 121 Addr = (Addr + Alignment - 1) & ~(uintptr_t)(Alignment - 1); |
123 | 122 |
124 // The part of the block we're giving out to the user is now pending | 123 // The part of the block we're giving out to the user is now pending |
171 | 170 |
172 return false; | 171 return false; |
173 } | 172 } |
174 | 173 |
175 static sys::MemoryBlock trimBlockToPageSize(sys::MemoryBlock M) { | 174 static sys::MemoryBlock trimBlockToPageSize(sys::MemoryBlock M) { |
176 static const size_t PageSize = sys::Process::getPageSize(); | 175 static const size_t PageSize = sys::Process::getPageSizeEstimate(); |
177 | 176 |
178 size_t StartOverlap = | 177 size_t StartOverlap = |
179 (PageSize - ((uintptr_t)M.base() % PageSize)) % PageSize; | 178 (PageSize - ((uintptr_t)M.base() % PageSize)) % PageSize; |
180 | 179 |
181 size_t TrimmedSize = M.size(); | 180 size_t TrimmedSize = M.allocatedSize(); |
182 TrimmedSize -= StartOverlap; | 181 TrimmedSize -= StartOverlap; |
183 TrimmedSize -= TrimmedSize % PageSize; | 182 TrimmedSize -= TrimmedSize % PageSize; |
184 | 183 |
185 sys::MemoryBlock Trimmed((void *)((uintptr_t)M.base() + StartOverlap), | 184 sys::MemoryBlock Trimmed((void *)((uintptr_t)M.base() + StartOverlap), |
186 TrimmedSize); | 185 TrimmedSize); |
187 | 186 |
188 assert(((uintptr_t)Trimmed.base() % PageSize) == 0); | 187 assert(((uintptr_t)Trimmed.base() % PageSize) == 0); |
189 assert((Trimmed.size() % PageSize) == 0); | 188 assert((Trimmed.allocatedSize() % PageSize) == 0); |
190 assert(M.base() <= Trimmed.base() && Trimmed.size() <= M.size()); | 189 assert(M.base() <= Trimmed.base() && |
190 Trimmed.allocatedSize() <= M.allocatedSize()); | |
191 | 191 |
192 return Trimmed; | 192 return Trimmed; |
193 } | 193 } |
194 | 194 |
195 std::error_code | 195 std::error_code |
208 // We cleared the PendingMem list, so all these pointers are now invalid | 208 // We cleared the PendingMem list, so all these pointers are now invalid |
209 FreeMB.PendingPrefixIndex = (unsigned)-1; | 209 FreeMB.PendingPrefixIndex = (unsigned)-1; |
210 } | 210 } |
211 | 211 |
212 // Remove all blocks which are now empty | 212 // Remove all blocks which are now empty |
213 MemGroup.FreeMem.erase( | 213 MemGroup.FreeMem.erase(remove_if(MemGroup.FreeMem, |
214 remove_if(MemGroup.FreeMem, | 214 [](FreeMemBlock &FreeMB) { |
215 [](FreeMemBlock &FreeMB) { return FreeMB.Free.size() == 0; }), | 215 return FreeMB.Free.allocatedSize() == 0; |
216 MemGroup.FreeMem.end()); | 216 }), |
217 MemGroup.FreeMem.end()); | |
217 | 218 |
218 return std::error_code(); | 219 return std::error_code(); |
219 } | 220 } |
220 | 221 |
221 void SectionMemoryManager::invalidateInstructionCache() { | 222 void SectionMemoryManager::invalidateInstructionCache() { |
222 for (sys::MemoryBlock &Block : CodeMem.PendingMem) | 223 for (sys::MemoryBlock &Block : CodeMem.PendingMem) |
223 sys::Memory::InvalidateInstructionCache(Block.base(), Block.size()); | 224 sys::Memory::InvalidateInstructionCache(Block.base(), |
225 Block.allocatedSize()); | |
224 } | 226 } |
225 | 227 |
226 SectionMemoryManager::~SectionMemoryManager() { | 228 SectionMemoryManager::~SectionMemoryManager() { |
227 for (MemoryGroup *Group : {&CodeMem, &RWDataMem, &RODataMem}) { | 229 for (MemoryGroup *Group : {&CodeMem, &RWDataMem, &RODataMem}) { |
228 for (sys::MemoryBlock &Block : Group->AllocatedMem) | 230 for (sys::MemoryBlock &Block : Group->AllocatedMem) |
229 MMapper.releaseMappedMemory(Block); | 231 MMapper.releaseMappedMemory(Block); |
230 } | 232 } |
231 } | 233 } |
232 | 234 |
233 SectionMemoryManager::MemoryMapper::~MemoryMapper() {} | 235 SectionMemoryManager::MemoryMapper::~MemoryMapper() {} |
236 | |
237 void SectionMemoryManager::anchor() {} | |
234 | 238 |
235 namespace { | 239 namespace { |
236 // Trivial implementation of SectionMemoryManager::MemoryMapper that just calls | 240 // Trivial implementation of SectionMemoryManager::MemoryMapper that just calls |
237 // into sys::Memory. | 241 // into sys::Memory. |
238 class DefaultMMapper final : public SectionMemoryManager::MemoryMapper { | 242 class DefaultMMapper final : public SectionMemoryManager::MemoryMapper { |