summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
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.