diff options
| author | 2018-11-13 11:06:33 -0500 | |
|---|---|---|
| committer | 2018-11-13 13:08:19 -0500 | |
| commit | b8e885c6e5de880d68e9b43480ee6f6423375b09 (patch) | |
| tree | 9893b285c0dc75fc8bc61a1c7568789e84c6c72f /src/core/hle/kernel/process.cpp | |
| parent | Merge pull request #1628 from greggameplayer/Texture2DArray (diff) | |
| download | yuzu-b8e885c6e5de880d68e9b43480ee6f6423375b09.tar.gz yuzu-b8e885c6e5de880d68e9b43480ee6f6423375b09.tar.xz yuzu-b8e885c6e5de880d68e9b43480ee6f6423375b09.zip | |
kernel/process: Migrate heap-related memory management out of the process class and into the vm manager
Avoids a breach of responsibilities in the interface and keeps the
direct code for memory management within the VMManager class.
Diffstat (limited to 'src/core/hle/kernel/process.cpp')
| -rw-r--r-- | src/core/hle/kernel/process.cpp | 76 |
1 files changed, 3 insertions, 73 deletions
diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp index 420218d59..e78e3a950 100644 --- a/src/core/hle/kernel/process.cpp +++ b/src/core/hle/kernel/process.cpp | |||
| @@ -5,11 +5,9 @@ | |||
| 5 | #include <algorithm> | 5 | #include <algorithm> |
| 6 | #include <memory> | 6 | #include <memory> |
| 7 | #include "common/assert.h" | 7 | #include "common/assert.h" |
| 8 | #include "common/common_funcs.h" | ||
| 9 | #include "common/logging/log.h" | 8 | #include "common/logging/log.h" |
| 10 | #include "core/core.h" | 9 | #include "core/core.h" |
| 11 | #include "core/file_sys/program_metadata.h" | 10 | #include "core/file_sys/program_metadata.h" |
| 12 | #include "core/hle/kernel/errors.h" | ||
| 13 | #include "core/hle/kernel/kernel.h" | 11 | #include "core/hle/kernel/kernel.h" |
| 14 | #include "core/hle/kernel/process.h" | 12 | #include "core/hle/kernel/process.h" |
| 15 | #include "core/hle/kernel/resource_limit.h" | 13 | #include "core/hle/kernel/resource_limit.h" |
| @@ -241,83 +239,15 @@ void Process::LoadModule(CodeSet module_, VAddr base_addr) { | |||
| 241 | } | 239 | } |
| 242 | 240 | ||
| 243 | ResultVal<VAddr> Process::HeapAllocate(VAddr target, u64 size, VMAPermission perms) { | 241 | ResultVal<VAddr> Process::HeapAllocate(VAddr target, u64 size, VMAPermission perms) { |
| 244 | if (target < vm_manager.GetHeapRegionBaseAddress() || | 242 | return vm_manager.HeapAllocate(target, size, perms); |
| 245 | target + size > vm_manager.GetHeapRegionEndAddress() || target + size < target) { | ||
| 246 | return ERR_INVALID_ADDRESS; | ||
| 247 | } | ||
| 248 | |||
| 249 | if (heap_memory == nullptr) { | ||
| 250 | // Initialize heap | ||
| 251 | heap_memory = std::make_shared<std::vector<u8>>(); | ||
| 252 | heap_start = heap_end = target; | ||
| 253 | } else { | ||
| 254 | vm_manager.UnmapRange(heap_start, heap_end - heap_start); | ||
| 255 | } | ||
| 256 | |||
| 257 | // If necessary, expand backing vector to cover new heap extents. | ||
| 258 | if (target < heap_start) { | ||
| 259 | heap_memory->insert(begin(*heap_memory), heap_start - target, 0); | ||
| 260 | heap_start = target; | ||
| 261 | vm_manager.RefreshMemoryBlockMappings(heap_memory.get()); | ||
| 262 | } | ||
| 263 | if (target + size > heap_end) { | ||
| 264 | heap_memory->insert(end(*heap_memory), (target + size) - heap_end, 0); | ||
| 265 | heap_end = target + size; | ||
| 266 | vm_manager.RefreshMemoryBlockMappings(heap_memory.get()); | ||
| 267 | } | ||
| 268 | ASSERT(heap_end - heap_start == heap_memory->size()); | ||
| 269 | |||
| 270 | CASCADE_RESULT(auto vma, vm_manager.MapMemoryBlock(target, heap_memory, target - heap_start, | ||
| 271 | size, MemoryState::Heap)); | ||
| 272 | vm_manager.Reprotect(vma, perms); | ||
| 273 | |||
| 274 | heap_used = size; | ||
| 275 | |||
| 276 | return MakeResult<VAddr>(heap_end - size); | ||
| 277 | } | 243 | } |
| 278 | 244 | ||
| 279 | ResultCode Process::HeapFree(VAddr target, u32 size) { | 245 | ResultCode Process::HeapFree(VAddr target, u32 size) { |
| 280 | if (target < vm_manager.GetHeapRegionBaseAddress() || | 246 | return vm_manager.HeapFree(target, size); |
| 281 | target + size > vm_manager.GetHeapRegionEndAddress() || target + size < target) { | ||
| 282 | return ERR_INVALID_ADDRESS; | ||
| 283 | } | ||
| 284 | |||
| 285 | if (size == 0) { | ||
| 286 | return RESULT_SUCCESS; | ||
| 287 | } | ||
| 288 | |||
| 289 | ResultCode result = vm_manager.UnmapRange(target, size); | ||
| 290 | if (result.IsError()) | ||
| 291 | return result; | ||
| 292 | |||
| 293 | heap_used -= size; | ||
| 294 | |||
| 295 | return RESULT_SUCCESS; | ||
| 296 | } | 247 | } |
| 297 | 248 | ||
| 298 | ResultCode Process::MirrorMemory(VAddr dst_addr, VAddr src_addr, u64 size) { | 249 | ResultCode Process::MirrorMemory(VAddr dst_addr, VAddr src_addr, u64 size) { |
| 299 | auto vma = vm_manager.FindVMA(src_addr); | 250 | return vm_manager.MirrorMemory(dst_addr, src_addr, size); |
| 300 | |||
| 301 | ASSERT_MSG(vma != vm_manager.vma_map.end(), "Invalid memory address"); | ||
| 302 | ASSERT_MSG(vma->second.backing_block, "Backing block doesn't exist for address"); | ||
| 303 | |||
| 304 | // The returned VMA might be a bigger one encompassing the desired address. | ||
| 305 | auto vma_offset = src_addr - vma->first; | ||
| 306 | ASSERT_MSG(vma_offset + size <= vma->second.size, | ||
| 307 | "Shared memory exceeds bounds of mapped block"); | ||
| 308 | |||
| 309 | const std::shared_ptr<std::vector<u8>>& backing_block = vma->second.backing_block; | ||
| 310 | std::size_t backing_block_offset = vma->second.offset + vma_offset; | ||
| 311 | |||
| 312 | CASCADE_RESULT(auto new_vma, | ||
| 313 | vm_manager.MapMemoryBlock(dst_addr, backing_block, backing_block_offset, size, | ||
| 314 | MemoryState::Mapped)); | ||
| 315 | // Protect mirror with permissions from old region | ||
| 316 | vm_manager.Reprotect(new_vma, vma->second.permissions); | ||
| 317 | // Remove permissions from old region | ||
| 318 | vm_manager.Reprotect(vma, VMAPermission::None); | ||
| 319 | |||
| 320 | return RESULT_SUCCESS; | ||
| 321 | } | 251 | } |
| 322 | 252 | ||
| 323 | ResultCode Process::UnmapMemory(VAddr dst_addr, VAddr /*src_addr*/, u64 size) { | 253 | ResultCode Process::UnmapMemory(VAddr dst_addr, VAddr /*src_addr*/, u64 size) { |