kern: avoid constexpr init for many objects (avoids unnecessary memory clear) (#1668)

This commit is contained in:
SciresM 2021-10-23 15:25:20 -07:00 committed by GitHub
parent 20716cb3de
commit 36e4914be8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
77 changed files with 489 additions and 339 deletions

View file

@ -129,7 +129,7 @@ namespace ams::kern::arch::arm64::cpu {
void ProcessOperation();
public:
constexpr KCacheHelperInterruptHandler() : KInterruptHandler(), m_lock(), m_cv_lock(), m_cv(), m_target_cores(0), m_operation(Operation::Idle) { /* ... */ }
constexpr KCacheHelperInterruptHandler() : KInterruptHandler(), m_lock(), m_cv_lock(), m_cv(util::ConstantInitialize), m_target_cores(0), m_operation(Operation::Idle) { /* ... */ }
void Initialize(s32 core_id) {
/* Reserve a thread from the system limit. */

View file

@ -283,9 +283,6 @@ namespace ams::kern::arch::arm64 {
/* Check that the name is a valid instruction breakpoint. */
R_UNLESS((name - ams::svc::HardwareBreakPointRegisterName_I0) <= num_bp, svc::ResultNotSupported());
/* We may be getting the process, so prepare a scoped reference holder. */
KScopedAutoObject<KProcess> process;
/* Configure flags/value. */
if ((flags & 1) != 0) {
/* We're enabling the breakpoint. Check that the flags are allowable. */

View file

@ -233,7 +233,7 @@ namespace ams::kern::arch::arm64 {
/* Begin the traversal. */
TraversalContext context;
TraversalEntry cur_entry = {};
TraversalEntry cur_entry = { .phys_addr = Null<KPhysicalAddress>, .block_size = 0, .sw_reserved_bits = 0 };
bool cur_valid = false;
TraversalEntry next_entry;
bool next_valid;

View file

@ -345,8 +345,8 @@ namespace ams::kern::board::nintendo::nx {
/* Globals. */
constinit KLightLock g_lock;
constinit u8 g_reserved_asid;
constinit KPhysicalAddress g_memory_controller_address;
constinit KPhysicalAddress g_reserved_table_phys_addr;
constinit KPhysicalAddress g_memory_controller_address{Null<KPhysicalAddress>};
constinit KPhysicalAddress g_reserved_table_phys_addr{Null<KPhysicalAddress>};
constinit KDeviceAsidManager g_asid_manager;
constinit u32 g_saved_page_tables[AsidCount];
constinit u32 g_saved_asid_registers[ams::svc::DeviceName_Count];

View file

@ -66,7 +66,7 @@ namespace ams::kern::board::nintendo::nx {
constinit u64 g_sleep_target_cores;
constinit KLightLock g_request_lock;
constinit KLightLock g_cv_lock;
constinit KLightConditionVariable g_cv;
constinit KLightConditionVariable g_cv{util::ConstantInitialize};
constinit KPhysicalAddress g_sleep_buffer_phys_addrs[cpu::NumCores];
alignas(1_KB) constinit u64 g_sleep_buffers[cpu::NumCores][1_KB / sizeof(u64)];
constinit SavedSystemRegisters g_sleep_system_registers[cpu::NumCores] = {};

View file

@ -43,7 +43,7 @@ namespace ams::kern::board::nintendo::nx {
/* To save space (and because mt19337_t isn't secure anyway), */
/* We will use TinyMT. */
constinit bool g_initialized_random_generator;
constinit util::TinyMT g_random_generator;
constinit util::TinyMT g_random_generator{util::ConstantInitialize};
constinit KSpinLock g_random_lock;
ALWAYS_INLINE size_t GetRealMemorySizeForInit() {

View file

@ -19,7 +19,12 @@ namespace ams::kern {
Result KCapabilities::Initialize(const u32 *caps, s32 num_caps, KProcessPageTable *page_table) {
/* We're initializing an initial process. */
/* Most fields have already been cleared by our constructor. */
m_svc_access_flags.Reset();
m_irq_access_flags.Reset();
m_debug_capabilities = {0};
m_handle_table_size = 0;
m_intended_kernel_version = {0};
m_program_type = 0;
/* Initial processes may run on all cores. */
m_core_mask = cpu::VirtualCoreMask;
@ -38,7 +43,16 @@ namespace ams::kern {
Result KCapabilities::Initialize(svc::KUserPointer<const u32 *> user_caps, s32 num_caps, KProcessPageTable *page_table) {
/* We're initializing a user process. */
/* Most fields have already been cleared by our constructor. */
m_svc_access_flags.Reset();
m_irq_access_flags.Reset();
m_debug_capabilities = {0};
m_handle_table_size = 0;
m_intended_kernel_version = {0};
m_program_type = 0;
/* User processes must specify what cores/priorities they can use. */
m_core_mask = 0;
m_priority_mask = 0;
/* Parse the user capabilities array. */
return this->SetCapabilities(user_caps, num_caps, page_table);

View file

@ -23,7 +23,7 @@ namespace ams::kern {
private:
static constinit inline KLightLock s_req_lock;
static constinit inline KLightLock s_lock;
static constinit inline KLightConditionVariable s_cond_var;
static constinit inline KLightConditionVariable s_cond_var{util::ConstantInitialize};
static constinit inline u64 s_core_mask;
static constinit inline KDpcTask *s_task;
private:

View file

@ -195,9 +195,11 @@ namespace ams::kern::KDumpObject {
char name[9] = {};
{
/* Find the client port process. */
KScopedAutoObject<KProcess> client_port_process;
KProcess *client_port_process = nullptr;
ON_SCOPE_EXIT { if (client_port_process != nullptr) { client_port_process->Close(); } };
{
for (auto it = accessor.begin(); it != end && client_port_process.IsNull(); ++it) {
for (auto it = accessor.begin(); it != end && client_port_process == nullptr; ++it) {
KProcess *cur = static_cast<KProcess *>(std::addressof(*it));
for (size_t j = 0; j < cur->GetHandleTable().GetTableSize(); ++j) {
ams::svc::Handle cur_h = ams::svc::InvalidHandle;
@ -205,6 +207,7 @@ namespace ams::kern::KDumpObject {
if (cur_o.IsNotNull()) {
if (cur_o.GetPointerUnsafe() == client) {
client_port_process = cur;
client_port_process->Open();
break;
}
}
@ -213,7 +216,7 @@ namespace ams::kern::KDumpObject {
}
/* Read the port name. */
if (client_port_process.IsNotNull()) {
if (client_port_process != nullptr) {
if (R_FAILED(client_port_process->GetPageTable().CopyMemoryFromLinearToKernel(KProcessAddress(name), 8, port_name, KMemoryState_None, KMemoryState_None, KMemoryPermission_UserRead, KMemoryAttribute_None, KMemoryAttribute_None))) {
std::memset(name, 0, sizeof(name));
}

View file

@ -26,8 +26,8 @@ namespace ams::kern {
/* Set our members. */
m_heap_address = address;
m_heap_size = size;
m_num_blocks = num_block_shifts;
m_heap_size = size;
m_num_blocks = num_block_shifts;
/* Setup bitmaps. */
u64 *cur_bitmap_storage = GetPointer<u64>(management_address);

View file

@ -706,7 +706,7 @@ namespace ams::kern {
/* Begin traversal. */
TraversalContext context;
TraversalEntry cur_entry = {};
TraversalEntry cur_entry = { .phys_addr = Null<KPhysicalAddress>, .block_size = 0, .sw_reserved_bits = 0 };
bool cur_valid = false;
TraversalEntry next_entry;
bool next_valid;
@ -1400,7 +1400,7 @@ namespace ams::kern {
/* Begin a traversal. */
TraversalContext context;
TraversalEntry cur_entry = {};
TraversalEntry cur_entry = { .phys_addr = Null<KPhysicalAddress>, .block_size = 0, .sw_reserved_bits = 0 };
R_UNLESS(impl.BeginTraversal(std::addressof(cur_entry), std::addressof(context), address), svc::ResultInvalidCurrentMemory());
/* The region we're traversing has to be heap. */
@ -4423,7 +4423,7 @@ namespace ams::kern {
/* Begin traversal. */
TraversalContext context;
TraversalEntry cur_entry = {};
TraversalEntry cur_entry = { .phys_addr = Null<KPhysicalAddress>, .block_size = 0, .sw_reserved_bits = 0 };
bool cur_valid = false;
TraversalEntry next_entry;
bool next_valid;

View file

@ -220,8 +220,8 @@ namespace ams::kern {
/* Set thread fields. */
for (size_t i = 0; i < cpu::NumCores; i++) {
m_running_threads[i] = nullptr;
m_running_thread_idle_counts[i] = 0;
m_pinned_threads[i] = nullptr;
m_running_thread_idle_counts[i] = 0;
}
/* Set max memory based on address space type. */

View file

@ -24,17 +24,11 @@ namespace ams::kern {
}
void KResourceLimit::Initialize() {
/* This should be unnecessary for us, because our constructor will clear all fields. */
/* The following is analagous to what Nintendo's implementation (no constexpr constructor) would do, though. */
/*
m_waiter_count = 0;
for (size_t i = 0; i < util::size(m_limit_values); i++) {
m_limit_values[i] = 0;
m_current_values[i] = 0;
m_current_hints[i] = 0;
m_peak_values[i] = 0;
}
*/
m_waiter_count = 0;
std::memset(m_limit_values, 0, sizeof(m_limit_values));
std::memset(m_current_values, 0, sizeof(m_current_values));
std::memset(m_current_hints, 0, sizeof(m_current_hints));
std::memset(m_peak_values, 0, sizeof(m_peak_values));
}
void KResourceLimit::Finalize() {

View file

@ -973,7 +973,7 @@ namespace ams::kern {
/* Get the request and client thread. */
KSessionRequest *request;
KScopedAutoObject<KThread> client_thread;
KThread *client_thread;
{
KScopedSchedulerLock sl;
@ -991,9 +991,13 @@ namespace ams::kern {
m_request_list.pop_front();
/* Get the thread for the request. */
client_thread = KScopedAutoObject<KThread>(request->GetThread());
R_UNLESS(client_thread.IsNotNull(), svc::ResultSessionClosed());
client_thread = request->GetThread();
R_UNLESS(client_thread != nullptr, svc::ResultSessionClosed());
/* Open the client thread. */
client_thread->Open();
}
ON_SCOPE_EXIT { client_thread->Close(); };
/* Set the request as our current. */
m_current_request = request;
@ -1004,7 +1008,7 @@ namespace ams::kern {
bool recv_list_broken = false;
/* Receive the message. */
Result result = ReceiveMessage(recv_list_broken, server_message, server_buffer_size, server_message_paddr, *client_thread.GetPointerUnsafe(), client_message, client_buffer_size, this, request);
Result result = ReceiveMessage(recv_list_broken, server_message, server_buffer_size, server_message_paddr, *client_thread, client_message, client_buffer_size, this, request);
/* Handle cleanup on receive failure. */
if (R_FAILED(result)) {

View file

@ -132,6 +132,7 @@ namespace ams::kern {
/* Set parent and condvar tree. */
m_parent = nullptr;
m_condvar_tree = nullptr;
m_condvar_key = 0;
/* Set sync booleans. */
m_signaled = false;
@ -179,7 +180,7 @@ namespace ams::kern {
m_current_core_id = phys_core;
/* We haven't released our resource limit hint, and we've spent no time on the cpu. */
m_resource_limit_release_hint = 0;
m_resource_limit_release_hint = false;
m_cpu_time = 0;
/* Setup our kernel stack. */
@ -1328,7 +1329,7 @@ namespace ams::kern {
private:
u64 m_id;
public:
constexpr explicit IdObjectHelper(u64 id) : m_id(id) { /* ... */ }
explicit IdObjectHelper(u64 id) : m_id(id) { /* ... */ }
virtual u64 GetId() const override { return m_id; }
};

View file

@ -42,7 +42,7 @@ namespace ams::kern {
}
}
public:
constexpr KUnusedSlabMemory(size_t size) : m_size(size) { /* ... */ }
KUnusedSlabMemory(size_t size) : m_size(size) { /* ... */ }
constexpr ALWAYS_INLINE KVirtualAddress GetAddress() const { return reinterpret_cast<uintptr_t>(this); }
constexpr ALWAYS_INLINE size_t GetSize() const { return m_size; }