summaryrefslogtreecommitdiff
path: root/src/core/hle/kernel/process.cpp
diff options
context:
space:
mode:
authorGravatar Lioncash2018-11-13 11:06:33 -0500
committerGravatar Lioncash2018-11-13 13:08:19 -0500
commitb8e885c6e5de880d68e9b43480ee6f6423375b09 (patch)
tree9893b285c0dc75fc8bc61a1c7568789e84c6c72f /src/core/hle/kernel/process.cpp
parentMerge pull request #1628 from greggameplayer/Texture2DArray (diff)
downloadyuzu-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.cpp76
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
243ResultVal<VAddr> Process::HeapAllocate(VAddr target, u64 size, VMAPermission perms) { 241ResultVal<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
279ResultCode Process::HeapFree(VAddr target, u32 size) { 245ResultCode 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
298ResultCode Process::MirrorMemory(VAddr dst_addr, VAddr src_addr, u64 size) { 249ResultCode 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
323ResultCode Process::UnmapMemory(VAddr dst_addr, VAddr /*src_addr*/, u64 size) { 253ResultCode Process::UnmapMemory(VAddr dst_addr, VAddr /*src_addr*/, u64 size) {