1cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor//===- SectionMemoryManager.cpp - Memory manager for MCJIT/RtDyld *- C++ -*-==// 22d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor// 32d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor// The LLVM Compiler Infrastructure 42d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor// 52d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor// This file is distributed under the University of Illinois Open Source 62d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor// License. See LICENSE.TXT for details. 72d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor// 82d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor//===----------------------------------------------------------------------===// 92d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor// 10cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor// This file implements the section-based memory manager used by the MCJIT 11cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor// execution engine and RuntimeDyld 122d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor// 132d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor//===----------------------------------------------------------------------===// 142d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor 152d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor#include "llvm/Config/config.h" 16927ba6a0b36b8219955a657545fcb1c863734993Andrew Kaylor#include "llvm/ExecutionEngine/SectionMemoryManager.h" 17a25ad19a23c20a235e8c8dc7d863324a64ef045eAmara Emerson#include "llvm/Support/MathExtras.h" 18f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar#include "llvm/Support/Process.h" 192d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor 202d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylornamespace llvm { 212d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor 222d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kayloruint8_t *SectionMemoryManager::allocateDataSection(uintptr_t Size, 236eb43d295625cd2ff314c59b49d4fd11f3348cadFilip Pizlo unsigned Alignment, 246eb43d295625cd2ff314c59b49d4fd11f3348cadFilip Pizlo unsigned SectionID, 256eb43d295625cd2ff314c59b49d4fd11f3348cadFilip Pizlo StringRef SectionName, 266eb43d295625cd2ff314c59b49d4fd11f3348cadFilip Pizlo bool IsReadOnly) { 27cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor if (IsReadOnly) 28cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor return allocateSection(RODataMem, Size, Alignment); 29cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor return allocateSection(RWDataMem, Size, Alignment); 302d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor} 312d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor 322d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kayloruint8_t *SectionMemoryManager::allocateCodeSection(uintptr_t Size, 33cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor unsigned Alignment, 346eb43d295625cd2ff314c59b49d4fd11f3348cadFilip Pizlo unsigned SectionID, 356eb43d295625cd2ff314c59b49d4fd11f3348cadFilip Pizlo StringRef SectionName) { 36cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor return allocateSection(CodeMem, Size, Alignment); 37cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor} 38cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor 39cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kayloruint8_t *SectionMemoryManager::allocateSection(MemoryGroup &MemGroup, 40cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor uintptr_t Size, 41cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor unsigned Alignment) { 422d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor if (!Alignment) 432d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor Alignment = 16; 44cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor 45cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor assert(!(Alignment & (Alignment - 1)) && "Alignment must be a power of two."); 46cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor 47cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor uintptr_t RequiredSize = Alignment * ((Size + Alignment - 1)/Alignment + 1); 482d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor uintptr_t Addr = 0; 49cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor 50cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor // Look in the list of free memory regions and use a block there if one 512d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor // is available. 52f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar for (FreeMemBlock &FreeMB : MemGroup.FreeMem) { 53f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (FreeMB.Free.size() >= RequiredSize) { 54f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar Addr = (uintptr_t)FreeMB.Free.base(); 55f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar uintptr_t EndOfBlock = Addr + FreeMB.Free.size(); 562d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor // Align the address. 572d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor Addr = (Addr + Alignment - 1) & ~(uintptr_t)(Alignment - 1); 58f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 59f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (FreeMB.PendingPrefixIndex == (unsigned)-1) { 60f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // The part of the block we're giving out to the user is now pending 61f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MemGroup.PendingMem.push_back(sys::MemoryBlock((void *)Addr, Size)); 62f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 63f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // Remember this pending block, such that future allocations can just 64f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // modify it rather than creating a new one 65f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar FreeMB.PendingPrefixIndex = MemGroup.PendingMem.size() - 1; 66f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } else { 67f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar sys::MemoryBlock &PendingMB = MemGroup.PendingMem[FreeMB.PendingPrefixIndex]; 68f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar PendingMB = sys::MemoryBlock(PendingMB.base(), Addr + Size - (uintptr_t)PendingMB.base()); 69f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 70f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 71f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // Remember how much free space is now left in this block 72f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar FreeMB.Free = sys::MemoryBlock((void *)(Addr + Size), EndOfBlock - Addr - Size); 732d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor return (uint8_t*)Addr; 742d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor } 752d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor } 762d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor 772d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor // No pre-allocated free block was large enough. Allocate a new memory region. 78cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor // Note that all sections get allocated as read-write. The permissions will 79cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor // be updated later based on memory group. 80cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor // 81cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor // FIXME: It would be useful to define a default allocation size (or add 82cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor // it as a constructor parameter) to minimize the number of allocations. 83927ba6a0b36b8219955a657545fcb1c863734993Andrew Kaylor // 84cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor // FIXME: Initialize the Near member for each memory group to avoid 85cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor // interleaving. 86c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines std::error_code ec; 87cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor sys::MemoryBlock MB = sys::Memory::allocateMappedMemory(RequiredSize, 88cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor &MemGroup.Near, 89cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor sys::Memory::MF_READ | 90cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor sys::Memory::MF_WRITE, 91cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor ec); 92cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor if (ec) { 9336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // FIXME: Add error propagation to the interface. 94dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return nullptr; 95cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor } 962d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor 97cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor // Save this address as the basis for our next request 98cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor MemGroup.Near = MB; 99cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor 100f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // Remember that we allocated this memory 101cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor MemGroup.AllocatedMem.push_back(MB); 1022d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor Addr = (uintptr_t)MB.base(); 1032d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor uintptr_t EndOfBlock = Addr + MB.size(); 104cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor 1052d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor // Align the address. 1062d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor Addr = (Addr + Alignment - 1) & ~(uintptr_t)(Alignment - 1); 107cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor 108f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // The part of the block we're giving out to the user is now pending 109f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MemGroup.PendingMem.push_back(sys::MemoryBlock((void *)Addr, Size)); 110f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 111cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor // The allocateMappedMemory may allocate much more memory than we need. In 112cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor // this case, we store the unused memory as a free memory block. 1132d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor unsigned FreeSize = EndOfBlock-Addr-Size; 114f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (FreeSize > 16) { 115f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar FreeMemBlock FreeMB; 116f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar FreeMB.Free = sys::MemoryBlock((void*)(Addr + Size), FreeSize); 117f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar FreeMB.PendingPrefixIndex = (unsigned)-1; 118f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MemGroup.FreeMem.push_back(FreeMB); 119f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 1202d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor 1212d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor // Return aligned address 1222d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor return (uint8_t*)Addr; 1232d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor} 1242d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor 125abb38fe8dec11b1ea7535f84fac8ad0f0af70addDavid Tweedbool SectionMemoryManager::finalizeMemory(std::string *ErrMsg) 126cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor{ 127cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor // FIXME: Should in-progress permissions be reverted if an error occurs? 128c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines std::error_code ec; 129cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor 130cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor // Make code memory executable. 131cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor ec = applyMemoryGroupPermissions(CodeMem, 132cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor sys::Memory::MF_READ | sys::Memory::MF_EXEC); 133cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor if (ec) { 134cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor if (ErrMsg) { 135cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor *ErrMsg = ec.message(); 136cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor } 137cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor return true; 138cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor } 139cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor 140cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor // Make read-only data memory read-only. 141cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor ec = applyMemoryGroupPermissions(RODataMem, 142cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor sys::Memory::MF_READ | sys::Memory::MF_EXEC); 143cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor if (ec) { 144cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor if (ErrMsg) { 145cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor *ErrMsg = ec.message(); 146cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor } 147cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor return true; 148cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor } 149cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor 150cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor // Read-write data memory already has the correct permissions 151cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor 152034f4be273f0ec629da4bc8369578fc195f3212fAndrew Kaylor // Some platforms with separate data cache and instruction cache require 153034f4be273f0ec629da4bc8369578fc195f3212fAndrew Kaylor // explicit cache flush, otherwise JIT code manipulations (like resolved 154034f4be273f0ec629da4bc8369578fc195f3212fAndrew Kaylor // relocations) will get to the data cache but not to the instruction cache. 155034f4be273f0ec629da4bc8369578fc195f3212fAndrew Kaylor invalidateInstructionCache(); 156034f4be273f0ec629da4bc8369578fc195f3212fAndrew Kaylor 157cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor return false; 158cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor} 159cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor 160f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarstatic sys::MemoryBlock trimBlockToPageSize(sys::MemoryBlock M) { 161f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar static const size_t PageSize = sys::Process::getPageSize(); 162f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 163f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar size_t StartOverlap = 164f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar (PageSize - ((uintptr_t)M.base() % PageSize)) % PageSize; 165f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 166f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar size_t TrimmedSize = M.size(); 167f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar TrimmedSize -= StartOverlap; 168f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar TrimmedSize -= TrimmedSize % PageSize; 169f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 170f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar sys::MemoryBlock Trimmed((void *)((uintptr_t)M.base() + StartOverlap), TrimmedSize); 171f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 172f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar assert(((uintptr_t)Trimmed.base() % PageSize) == 0); 173f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar assert((Trimmed.size() % PageSize) == 0); 174f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar assert(M.base() <= Trimmed.base() && Trimmed.size() <= M.size()); 175f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 176f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return Trimmed; 177f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar} 178f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 179f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 180c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstd::error_code 181c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen HinesSectionMemoryManager::applyMemoryGroupPermissions(MemoryGroup &MemGroup, 182c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines unsigned Permissions) { 183f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar for (sys::MemoryBlock &MB : MemGroup.PendingMem) 184f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (std::error_code EC = sys::Memory::protectMappedMemory(MB, Permissions)) 185f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return EC; 186f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 187f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MemGroup.PendingMem.clear(); 188f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 189f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // Now go through free blocks and trim any of them that don't span the entire 190f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // page because one of the pending blocks may have overlapped it. 191f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar for (FreeMemBlock &FreeMB : MemGroup.FreeMem) { 192f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar FreeMB.Free = trimBlockToPageSize(FreeMB.Free); 193f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // We cleared the PendingMem list, so all these pointers are now invalid 194f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar FreeMB.PendingPrefixIndex = (unsigned)-1; 195cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor } 196cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor 197f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // Remove all blocks which are now empty 198f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MemGroup.FreeMem.erase( 199f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar std::remove_if(MemGroup.FreeMem.begin(), MemGroup.FreeMem.end(), 200f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar [](FreeMemBlock &FreeMB) { return FreeMB.Free.size() == 0; }), 201f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MemGroup.FreeMem.end()); 202f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 203c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines return std::error_code(); 204cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor} 205cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor 2062d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylorvoid SectionMemoryManager::invalidateInstructionCache() { 207f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar for (sys::MemoryBlock &Block : CodeMem.PendingMem) 208f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar sys::Memory::InvalidateInstructionCache(Block.base(), Block.size()); 209cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor} 210cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor 2112d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew KaylorSectionMemoryManager::~SectionMemoryManager() { 212f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar for (MemoryGroup *Group : {&CodeMem, &RWDataMem, &RODataMem}) { 213f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar for (sys::MemoryBlock &Block : Group->AllocatedMem) 214f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar sys::Memory::releaseMappedMemory(Block); 215f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 2162d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor} 2172d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor 2182d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor} // namespace llvm 219