diff options
Diffstat (limited to '')
| -rw-r--r-- | src/core/hle/kernel/vm_manager.cpp | 34 | ||||
| -rw-r--r-- | src/core/hle/kernel/vm_manager.h | 36 |
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 | ||
| 296 | ResultCode 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 | |||
| 313 | MemoryInfo VMManager::QueryMemory(VAddr address) const { | 305 | MemoryInfo 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. |