From 1e92ba27855a40d928265debfdf2478248e40eaf Mon Sep 17 00:00:00 2001 From: Lioncash Date: Sun, 24 Mar 2019 16:30:45 -0400 Subject: kernel/vm_manager: Handle shrinking of the heap size within SetHeapSize() One behavior that we weren't handling properly in our heap allocation process was the ability for the heap to be shrunk down in size if a larger size was previously requested. This adds the basic behavior to do so and also gets rid of HeapFree, as it's no longer necessary now that we have allocations and deallocations going through the same API function. While we're at it, fully document the behavior that this function performs. --- src/core/hle/kernel/vm_manager.cpp | 34 +++++++++++++--------------------- 1 file changed, 13 insertions(+), 21 deletions(-) (limited to 'src/core/hle/kernel/vm_manager.cpp') diff --git a/src/core/hle/kernel/vm_manager.cpp b/src/core/hle/kernel/vm_manager.cpp index 523fe63e9..ec0a480ce 100644 --- a/src/core/hle/kernel/vm_manager.cpp +++ b/src/core/hle/kernel/vm_manager.cpp @@ -274,14 +274,23 @@ ResultVal VMManager::SetHeapSize(u64 size) { UnmapRange(heap_region_base, GetCurrentHeapSize()); } - // If necessary, expand backing vector to cover new heap extents. - if (size > GetCurrentHeapSize()) { - const u64 alloc_size = size - GetCurrentHeapSize(); + // If necessary, expand backing vector to cover new heap extents in + // the case of allocating. Otherwise, shrink the backing memory, + // if a smaller heap has been requested. + const u64 old_heap_size = GetCurrentHeapSize(); + if (size > old_heap_size) { + const u64 alloc_size = size - old_heap_size; heap_memory->insert(heap_memory->end(), alloc_size, 0); - heap_end = heap_region_base + size; + RefreshMemoryBlockMappings(heap_memory.get()); + } else if (size < old_heap_size) { + heap_memory->resize(size); + heap_memory->shrink_to_fit(); + RefreshMemoryBlockMappings(heap_memory.get()); } + + heap_end = heap_region_base + size; ASSERT(GetCurrentHeapSize() == heap_memory->size()); const auto mapping_result = @@ -293,23 +302,6 @@ ResultVal VMManager::SetHeapSize(u64 size) { return MakeResult(heap_region_base); } -ResultCode VMManager::HeapFree(VAddr target, u64 size) { - if (!IsWithinHeapRegion(target, size)) { - return ERR_INVALID_ADDRESS; - } - - if (size == 0) { - return RESULT_SUCCESS; - } - - const ResultCode result = UnmapRange(target, size); - if (result.IsError()) { - return result; - } - - return RESULT_SUCCESS; -} - MemoryInfo VMManager::QueryMemory(VAddr address) const { const auto vma = FindVMA(address); MemoryInfo memory_info{}; -- cgit v1.2.3