summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Lioncash2019-03-24 16:30:45 -0400
committerGravatar Lioncash2019-03-24 17:08:30 -0400
commit1e92ba27855a40d928265debfdf2478248e40eaf (patch)
tree75d964749fc4374ed41fa6685d0ffff7b9c05ec4
parentkernel/vm_manager: Rename HeapAllocate to SetHeapSize (diff)
downloadyuzu-1e92ba27855a40d928265debfdf2478248e40eaf.tar.gz
yuzu-1e92ba27855a40d928265debfdf2478248e40eaf.tar.xz
yuzu-1e92ba27855a40d928265debfdf2478248e40eaf.zip
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.
Diffstat (limited to '')
-rw-r--r--src/core/hle/kernel/vm_manager.cpp34
-rw-r--r--src/core/hle/kernel/vm_manager.h36
2 files changed, 46 insertions, 24 deletions
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<VAddr> VMManager::SetHeapSize(u64 size) {
274 UnmapRange(heap_region_base, GetCurrentHeapSize()); 274 UnmapRange(heap_region_base, GetCurrentHeapSize());
275 } 275 }
276 276
277 // If necessary, expand backing vector to cover new heap extents. 277 // If necessary, expand backing vector to cover new heap extents in
278 if (size > GetCurrentHeapSize()) { 278 // the case of allocating. Otherwise, shrink the backing memory,
279 const u64 alloc_size = size - GetCurrentHeapSize(); 279 // if a smaller heap has been requested.
280 const u64 old_heap_size = GetCurrentHeapSize();
281 if (size > old_heap_size) {
282 const u64 alloc_size = size - old_heap_size;
280 283
281 heap_memory->insert(heap_memory->end(), alloc_size, 0); 284 heap_memory->insert(heap_memory->end(), alloc_size, 0);
282 heap_end = heap_region_base + size; 285 RefreshMemoryBlockMappings(heap_memory.get());
286 } else if (size < old_heap_size) {
287 heap_memory->resize(size);
288 heap_memory->shrink_to_fit();
289
283 RefreshMemoryBlockMappings(heap_memory.get()); 290 RefreshMemoryBlockMappings(heap_memory.get());
284 } 291 }
292
293 heap_end = heap_region_base + size;
285 ASSERT(GetCurrentHeapSize() == heap_memory->size()); 294 ASSERT(GetCurrentHeapSize() == heap_memory->size());
286 295
287 const auto mapping_result = 296 const auto mapping_result =
@@ -293,23 +302,6 @@ ResultVal<VAddr> VMManager::SetHeapSize(u64 size) {
293 return MakeResult<VAddr>(heap_region_base); 302 return MakeResult<VAddr>(heap_region_base);
294} 303}
295 304
296ResultCode VMManager::HeapFree(VAddr target, u64 size) {
297 if (!IsWithinHeapRegion(target, size)) {
298 return ERR_INVALID_ADDRESS;
299 }
300
301 if (size == 0) {
302 return RESULT_SUCCESS;
303 }
304
305 const ResultCode result = UnmapRange(target, size);
306 if (result.IsError()) {
307 return result;
308 }
309
310 return RESULT_SUCCESS;
311}
312
313MemoryInfo VMManager::QueryMemory(VAddr address) const { 305MemoryInfo VMManager::QueryMemory(VAddr address) const {
314 const auto vma = FindVMA(address); 306 const auto vma = FindVMA(address);
315 MemoryInfo memory_info{}; 307 MemoryInfo memory_info{};
diff --git a/src/core/hle/kernel/vm_manager.h b/src/core/hle/kernel/vm_manager.h
index cab748364..6f484b7bf 100644
--- a/src/core/hle/kernel/vm_manager.h
+++ b/src/core/hle/kernel/vm_manager.h
@@ -380,11 +380,41 @@ public:
380 /// Changes the permissions of a range of addresses, splitting VMAs as necessary. 380 /// Changes the permissions of a range of addresses, splitting VMAs as necessary.
381 ResultCode ReprotectRange(VAddr target, u64 size, VMAPermission new_perms); 381 ResultCode ReprotectRange(VAddr target, u64 size, VMAPermission new_perms);
382 382
383 ResultVal<VAddr> SetHeapSize(u64 size);
384 ResultCode HeapFree(VAddr target, u64 size);
385
386 ResultCode MirrorMemory(VAddr dst_addr, VAddr src_addr, u64 size, MemoryState state); 383 ResultCode MirrorMemory(VAddr dst_addr, VAddr src_addr, u64 size, MemoryState state);
387 384
385 /// Attempts to allocate a heap with the given size.
386 ///
387 /// @param size The size of the heap to allocate in bytes.
388 ///
389 /// @note If a heap is currently allocated, and this is called
390 /// with a size that is equal to the size of the current heap,
391 /// then this function will do nothing and return the current
392 /// heap's starting address, as there's no need to perform
393 /// any additional heap allocation work.
394 ///
395 /// @note If a heap is currently allocated, and this is called
396 /// with a size less than the current heap's size, then
397 /// this function will attempt to shrink the heap.
398 ///
399 /// @note If a heap is currently allocated, and this is called
400 /// with a size larger than the current heap's size, then
401 /// this function will attempt to extend the size of the heap.
402 ///
403 /// @returns A result indicating either success or failure.
404 /// <p>
405 /// If successful, this function will return a result
406 /// containing the starting address to the allocated heap.
407 /// <p>
408 /// If unsuccessful, this function will return a result
409 /// containing an error code.
410 ///
411 /// @pre The given size must lie within the allowable heap
412 /// memory region managed by this VMManager instance.
413 /// Failure to abide by this will result in ERR_OUT_OF_MEMORY
414 /// being returned as the result.
415 ///
416 ResultVal<VAddr> SetHeapSize(u64 size);
417
388 /// Queries the memory manager for information about the given address. 418 /// Queries the memory manager for information about the given address.
389 /// 419 ///
390 /// @param address The address to query the memory manager about for information. 420 /// @param address The address to query the memory manager about for information.