aboutsummaryrefslogtreecommitdiff
path: root/src/core/hle/kernel/vm_manager.cpp
diff options
context:
space:
mode:
authorLioncash <mathew1800@gmail.com>2019-07-24 07:24:19 -0400
committerLioncash <mathew1800@gmail.com>2019-08-29 19:29:43 -0400
commitaed2815ba60e5e7efb38ef8c04e65b21a3af8ca1 (patch)
treeb943949eaf77425109202f00aa365814b455c0ad /src/core/hle/kernel/vm_manager.cpp
parenteb1f6e7cddd78a7dce85a527d527fe4a73a6147e (diff)
kernel/vm_manager: Reserve memory ahead of time for slow path in MergeAdjacentVMA
Avoids potentially expensive (depending on the size of the memory block) allocations by reserving the necessary memory before performing both insertions. This avoids scenarios where the second insert may cause a reallocation to occur.
Diffstat (limited to 'src/core/hle/kernel/vm_manager.cpp')
-rw-r--r--src/core/hle/kernel/vm_manager.cpp5
1 files changed, 4 insertions, 1 deletions
diff --git a/src/core/hle/kernel/vm_manager.cpp b/src/core/hle/kernel/vm_manager.cpp
index 721f7cc44d..6b2d78cc81 100644
--- a/src/core/hle/kernel/vm_manager.cpp
+++ b/src/core/hle/kernel/vm_manager.cpp
@@ -765,11 +765,14 @@ void VMManager::MergeAdjacentVMA(VirtualMemoryArea& left, const VirtualMemoryAre
// Fast case: left is an entire backing block.
left.backing_block->insert(left.backing_block->end(), right_begin, right_end);
} else {
+ // Slow case: make a new memory block for left and right.
const auto left_begin = left.backing_block->begin() + left.offset;
const auto left_end = left_begin + left.size;
+ const auto left_size = static_cast<std::size_t>(std::distance(left_begin, left_end));
+ const auto right_size = static_cast<std::size_t>(std::distance(right_begin, right_end));
- // Slow case: make a new memory block for left and right.
auto new_memory = std::make_shared<PhysicalMemory>();
+ new_memory->reserve(left_size + right_size);
new_memory->insert(new_memory->end(), left_begin, left_end);
new_memory->insert(new_memory->end(), right_begin, right_end);