Remove memory allocations in some hot paths

This commit is contained in:
Kelebek1
2023-05-23 14:45:54 +01:00
parent e3122c5b46
commit 5da70f7197
84 changed files with 501 additions and 458 deletions

View File

@ -3,6 +3,7 @@
#include "common/assert.h"
#include "common/common_types.h"
#include "common/scratch_buffer.h"
#include "core/hle/kernel/k_scheduler.h"
#include "core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h"
#include "core/hle/kernel/k_synchronization_object.h"
@ -75,7 +76,7 @@ Result KSynchronizationObject::Wait(KernelCore& kernel, s32* out_index,
KSynchronizationObject** objects, const s32 num_objects,
s64 timeout) {
// Allocate space on stack for thread nodes.
std::vector<ThreadListNode> thread_nodes(num_objects);
std::array<ThreadListNode, Svc::ArgumentHandleCountMax> thread_nodes;
// Prepare for wait.
KThread* thread = GetCurrentThreadPointer(kernel);

View File

@ -909,7 +909,7 @@ Result KThread::SetActivity(Svc::ThreadActivity activity) {
R_SUCCEED();
}
Result KThread::GetThreadContext3(std::vector<u8>& out) {
Result KThread::GetThreadContext3(Common::ScratchBuffer<u8>& out) {
// Lock ourselves.
KScopedLightLock lk{m_activity_pause_lock};
@ -927,15 +927,13 @@ Result KThread::GetThreadContext3(std::vector<u8>& out) {
// Mask away mode bits, interrupt bits, IL bit, and other reserved bits.
auto context = GetContext64();
context.pstate &= 0xFF0FFE20;
out.resize(sizeof(context));
out.resize_destructive(sizeof(context));
std::memcpy(out.data(), std::addressof(context), sizeof(context));
} else {
// Mask away mode bits, interrupt bits, IL bit, and other reserved bits.
auto context = GetContext32();
context.cpsr &= 0xFF0FFE20;
out.resize(sizeof(context));
out.resize_destructive(sizeof(context));
std::memcpy(out.data(), std::addressof(context), sizeof(context));
}
}

View File

@ -15,6 +15,7 @@
#include "common/intrusive_list.h"
#include "common/intrusive_red_black_tree.h"
#include "common/scratch_buffer.h"
#include "common/spin_lock.h"
#include "core/arm/arm_interface.h"
#include "core/hle/kernel/k_affinity_mask.h"
@ -567,7 +568,7 @@ public:
void RemoveWaiter(KThread* thread);
Result GetThreadContext3(std::vector<u8>& out);
Result GetThreadContext3(Common::ScratchBuffer<u8>& out);
KThread* RemoveUserWaiterByKey(bool* out_has_waiters, KProcessAddress key) {
return this->RemoveWaiterByKey(out_has_waiters, key, false);

View File

@ -2,6 +2,7 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#include "common/scope_exit.h"
#include "common/scratch_buffer.h"
#include "core/core.h"
#include "core/hle/kernel/k_client_session.h"
#include "core/hle/kernel/k_process.h"
@ -45,11 +46,11 @@ Result ReplyAndReceive(Core::System& system, s32* out_index, uint64_t handles_ad
handles_addr, static_cast<u64>(sizeof(Handle) * num_handles)),
ResultInvalidPointer);
std::vector<Handle> handles(num_handles);
std::array<Handle, Svc::ArgumentHandleCountMax> handles;
GetCurrentMemory(kernel).ReadBlock(handles_addr, handles.data(), sizeof(Handle) * num_handles);
// Convert handle list to object table.
std::vector<KSynchronizationObject*> objs(num_handles);
std::array<KSynchronizationObject*, Svc::ArgumentHandleCountMax> objs;
R_UNLESS(handle_table.GetMultipleObjects<KSynchronizationObject>(objs.data(), handles.data(),
num_handles),
ResultInvalidHandle);
@ -80,7 +81,7 @@ Result ReplyAndReceive(Core::System& system, s32* out_index, uint64_t handles_ad
// Wait for an object.
s32 index;
Result result = KSynchronizationObject::Wait(kernel, std::addressof(index), objs.data(),
static_cast<s32>(objs.size()), timeout_ns);
num_handles, timeout_ns);
if (result == ResultTimedOut) {
R_RETURN(result);
}

View File

@ -2,6 +2,7 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#include "common/scope_exit.h"
#include "common/scratch_buffer.h"
#include "core/core.h"
#include "core/hle/kernel/k_process.h"
#include "core/hle/kernel/k_readable_event.h"
@ -54,7 +55,7 @@ static Result WaitSynchronization(Core::System& system, int32_t* out_index, cons
// Get the synchronization context.
auto& kernel = system.Kernel();
auto& handle_table = GetCurrentProcess(kernel).GetHandleTable();
std::vector<KSynchronizationObject*> objs(num_handles);
std::array<KSynchronizationObject*, Svc::ArgumentHandleCountMax> objs;
// Copy user handles.
if (num_handles > 0) {
@ -72,8 +73,8 @@ static Result WaitSynchronization(Core::System& system, int32_t* out_index, cons
});
// Wait on the objects.
Result res = KSynchronizationObject::Wait(kernel, out_index, objs.data(),
static_cast<s32>(objs.size()), timeout_ns);
Result res =
KSynchronizationObject::Wait(kernel, out_index, objs.data(), num_handles, timeout_ns);
R_SUCCEED_IF(res == ResultSessionClosed);
R_RETURN(res);
@ -87,8 +88,7 @@ Result WaitSynchronization(Core::System& system, int32_t* out_index, u64 user_ha
// Ensure number of handles is valid.
R_UNLESS(0 <= num_handles && num_handles <= Svc::ArgumentHandleCountMax, ResultOutOfRange);
std::vector<Handle> handles(num_handles);
std::array<Handle, Svc::ArgumentHandleCountMax> handles;
if (num_handles > 0) {
GetCurrentMemory(system.Kernel())
.ReadBlock(user_handles, handles.data(), num_handles * sizeof(Handle));

View File

@ -174,7 +174,7 @@ Result GetThreadContext3(Core::System& system, u64 out_context, Handle thread_ha
}
// Get the thread context.
std::vector<u8> context;
static thread_local Common::ScratchBuffer<u8> context;
R_TRY(thread->GetThreadContext3(context));
// Copy the thread context to user space.