From 36e4914be85ecbf0be43997af5f0b5e2a524747d Mon Sep 17 00:00:00 2001 From: SciresM Date: Sat, 23 Oct 2021 15:25:20 -0700 Subject: [PATCH] kern: avoid constexpr init for many objects (avoids unnecessary memory clear) (#1668) --- .../arch/arm64/kern_k_page_table.hpp | 3 +- .../arch/arm64/kern_k_page_table_impl.hpp | 4 +- .../arch/arm64/kern_k_process_page_table.hpp | 2 - .../arm64/kern_k_supervisor_page_table.hpp | 2 +- .../arch/arm64/kern_k_thread_context.hpp | 3 +- .../nintendo/nx/kern_k_device_page_table.hpp | 7 +- .../mesosphere/kern_k_address_arbiter.hpp | 2 +- .../include/mesosphere/kern_k_auto_object.hpp | 14 +- .../mesosphere/kern_k_capabilities.hpp | 19 +-- .../include/mesosphere/kern_k_client_port.hpp | 4 +- .../mesosphere/kern_k_client_session.hpp | 3 +- .../mesosphere/kern_k_condition_variable.hpp | 2 +- .../include/mesosphere/kern_k_debug_base.hpp | 2 +- .../kern_k_device_address_space.hpp | 2 +- .../kern_k_dynamic_page_manager.hpp | 2 +- .../mesosphere/kern_k_dynamic_slab_heap.hpp | 2 +- .../include/mesosphere/kern_k_event.hpp | 7 +- .../mesosphere/kern_k_handle_table.hpp | 8 +- .../mesosphere/kern_k_interrupt_event.hpp | 4 +- .../include/mesosphere/kern_k_io_pool.hpp | 2 +- .../include/mesosphere/kern_k_io_region.hpp | 6 +- .../kern_k_light_client_session.hpp | 2 +- .../kern_k_light_condition_variable.hpp | 4 +- .../include/mesosphere/kern_k_light_lock.hpp | 2 +- .../kern_k_light_server_session.hpp | 2 +- .../mesosphere/kern_k_light_session.hpp | 6 +- .../mesosphere/kern_k_memory_block.hpp | 32 +++-- .../kern_k_memory_block_manager.hpp | 6 +- .../mesosphere/kern_k_memory_layout.hpp | 12 +- .../mesosphere/kern_k_memory_manager.hpp | 2 +- .../mesosphere/kern_k_memory_region.hpp | 7 +- .../include/mesosphere/kern_k_object_name.hpp | 2 - .../include/mesosphere/kern_k_page_bitmap.hpp | 2 +- .../include/mesosphere/kern_k_page_group.hpp | 8 +- .../include/mesosphere/kern_k_page_heap.hpp | 4 +- .../mesosphere/kern_k_page_table_base.hpp | 91 +++++++----- .../mesosphere/kern_k_page_table_manager.hpp | 5 +- .../include/mesosphere/kern_k_port.hpp | 2 +- .../include/mesosphere/kern_k_process.hpp | 136 +++++++++--------- .../mesosphere/kern_k_readable_event.hpp | 4 +- .../mesosphere/kern_k_resource_limit.hpp | 10 +- .../include/mesosphere/kern_k_scheduler.hpp | 3 +- .../include/mesosphere/kern_k_server_port.hpp | 3 +- .../mesosphere/kern_k_server_session.hpp | 3 +- .../include/mesosphere/kern_k_session.hpp | 8 +- .../mesosphere/kern_k_session_request.hpp | 22 +-- .../mesosphere/kern_k_shared_memory_info.hpp | 2 +- .../kern_k_synchronization_object.hpp | 3 +- .../include/mesosphere/kern_k_thread.hpp | 123 +++++++++------- .../mesosphere/kern_k_thread_local_page.hpp | 6 +- .../include/mesosphere/kern_k_timer_task.hpp | 3 +- .../mesosphere/kern_k_typed_address.hpp | 14 +- .../include/mesosphere/kern_slab_helpers.hpp | 4 +- .../source/arch/arm64/kern_cpu.cpp | 2 +- .../source/arch/arm64/kern_k_debug.cpp | 3 - .../source/arch/arm64/kern_k_page_table.cpp | 2 +- .../nintendo/nx/kern_k_device_page_table.cpp | 4 +- .../nintendo/nx/kern_k_sleep_manager.cpp | 2 +- .../nintendo/nx/kern_k_system_control.cpp | 2 +- .../source/kern_k_capabilities.cpp | 18 ++- .../source/kern_k_dpc_manager.cpp | 2 +- .../source/kern_k_dump_object.cpp | 9 +- .../libmesosphere/source/kern_k_page_heap.cpp | 4 +- .../source/kern_k_page_table_base.cpp | 6 +- .../libmesosphere/source/kern_k_process.cpp | 2 +- .../source/kern_k_resource_limit.cpp | 16 +-- .../source/kern_k_server_session.cpp | 12 +- .../libmesosphere/source/kern_k_thread.cpp | 5 +- .../source/kern_k_unused_slab_memory.cpp | 2 +- .../source/os/impl/os_rng_manager_impl.hpp | 2 +- .../libstratosphere/source/os/os_random.cpp | 2 +- .../include/vapours/freebsd/tree.hpp | 12 +- .../util/util_intrusive_red_black_tree.hpp | 5 +- .../include/vapours/util/util_tinymt.hpp | 5 +- .../include/vapours/util/util_type_traits.hpp | 3 + .../source/kern_kernel_instantiations.cpp | 73 +++++++++- .../dmnt/source/cheat/impl/dmnt_cheat_api.cpp | 2 +- 77 files changed, 489 insertions(+), 339 deletions(-) diff --git a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table.hpp b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table.hpp index b3ce9da1d..6886261da 100644 --- a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table.hpp +++ b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table.hpp @@ -168,7 +168,8 @@ namespace ams::kern::arch::arm64 { return entry; } public: - constexpr KPageTable() : KPageTableBase(), m_manager(), m_ttbr(), m_asid() { /* ... */ } + constexpr explicit KPageTable(util::ConstantInitializeTag) : KPageTableBase(util::ConstantInitialize), m_manager(), m_ttbr(), m_asid() { /* ... */ } + explicit KPageTable() { /* ... */ } static NOINLINE void Initialize(s32 core_id); diff --git a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table_impl.hpp b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table_impl.hpp index 64ab64c36..bdf461a0c 100644 --- a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table_impl.hpp +++ b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table_impl.hpp @@ -105,7 +105,9 @@ namespace ams::kern::arch::arm64 { return GetL3EntryFromTable(KMemoryLayout::GetLinearVirtualAddress(entry->GetTable()), address); } public: - constexpr KPageTableImpl() : m_table(), m_is_kernel(), m_num_entries() { /* ... */ } + constexpr explicit KPageTableImpl(util::ConstantInitializeTag) : m_table(), m_is_kernel(), m_num_entries() { /* ... */ } + + explicit KPageTableImpl() { /* ... */ } NOINLINE void InitializeForKernel(void *tb, KVirtualAddress start, KVirtualAddress end); NOINLINE void InitializeForProcess(void *tb, KVirtualAddress start, KVirtualAddress end); diff --git a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_process_page_table.hpp b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_process_page_table.hpp index ba851d0eb..99839cb0e 100644 --- a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_process_page_table.hpp +++ b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_process_page_table.hpp @@ -23,8 +23,6 @@ namespace ams::kern::arch::arm64 { private: KPageTable m_page_table; public: - constexpr KProcessPageTable() : m_page_table() { /* ... */ } - void Activate(u64 id) { /* Activate the page table with the specified contextidr. */ m_page_table.Activate(id); diff --git a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_supervisor_page_table.hpp b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_supervisor_page_table.hpp index e9dfa185b..19f1dade7 100644 --- a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_supervisor_page_table.hpp +++ b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_supervisor_page_table.hpp @@ -25,7 +25,7 @@ namespace ams::kern::arch::arm64 { KPageTable m_page_table; u64 m_ttbr0_identity[cpu::NumCores]; public: - constexpr KSupervisorPageTable() : m_page_table(), m_ttbr0_identity() { /* ... */ } + constexpr KSupervisorPageTable() : m_page_table(util::ConstantInitialize), m_ttbr0_identity() { /* ... */ } NOINLINE void Initialize(s32 core_id); diff --git a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_thread_context.hpp b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_thread_context.hpp index eb83269b5..b4fb3a08c 100644 --- a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_thread_context.hpp +++ b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_thread_context.hpp @@ -57,7 +57,8 @@ namespace ams::kern::arch::arm64 { static void RestoreFpuRegisters64(const KThreadContext &); static void RestoreFpuRegisters32(const KThreadContext &); public: - constexpr explicit KThreadContext() : m_callee_saved(), m_lr(), m_sp(), m_cpacr(), m_fpcr(), m_fpsr(), m_fpu_registers(), m_locked() { /* ... */ } + constexpr explicit KThreadContext(util::ConstantInitializeTag) : m_callee_saved(), m_lr(), m_sp(), m_cpacr(), m_fpcr(), m_fpsr(), m_fpu_registers(), m_locked() { /* ... */ } + explicit KThreadContext() { /* ... */ } Result Initialize(KVirtualAddress u_pc, KVirtualAddress k_sp, KVirtualAddress u_sp, uintptr_t arg, bool is_user, bool is_64_bit, bool is_main); Result Finalize(); diff --git a/libraries/libmesosphere/include/mesosphere/board/nintendo/nx/kern_k_device_page_table.hpp b/libraries/libmesosphere/include/mesosphere/board/nintendo/nx/kern_k_device_page_table.hpp index 7b2ace84c..d5a8e9b3f 100644 --- a/libraries/libmesosphere/include/mesosphere/board/nintendo/nx/kern_k_device_page_table.hpp +++ b/libraries/libmesosphere/include/mesosphere/board/nintendo/nx/kern_k_device_page_table.hpp @@ -61,7 +61,12 @@ namespace ams::kern::board::nintendo::nx { return KPageTable::GetPageTablePhysicalAddress(addr); } public: - constexpr KDevicePageTable() : m_tables(), m_table_asids(), m_attached_device(), m_attached_value(), m_detached_value(), m_hs_attached_value(), m_hs_detached_value() { /* ... */ } + constexpr KDevicePageTable() + : m_tables{Null, Null, Null, Null}, + m_table_asids(), m_attached_device(), m_attached_value(), m_detached_value(), m_hs_attached_value(), m_hs_detached_value() + { + /* ... */ + } Result Initialize(u64 space_address, u64 space_size); void Finalize(); diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_address_arbiter.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_address_arbiter.hpp index 91f41a342..f413d7bbc 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_address_arbiter.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_address_arbiter.hpp @@ -25,7 +25,7 @@ namespace ams::kern { private: ThreadTree m_tree; public: - constexpr KAddressArbiter() : m_tree() { /* ... */ } + constexpr KAddressArbiter() = default; Result SignalToAddress(uintptr_t addr, ams::svc::SignalType type, s32 value, s32 count) { switch (type) { diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_auto_object.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_auto_object.hpp index aa12f494f..32b7259de 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_auto_object.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_auto_object.hpp @@ -121,7 +121,7 @@ namespace ams::kern { public: static KAutoObject *Create(KAutoObject *ptr); public: - constexpr ALWAYS_INLINE explicit KAutoObject() : m_next_closed_object(nullptr), m_ref_count(0) + constexpr ALWAYS_INLINE explicit KAutoObject(util::ConstantInitializeTag) : m_next_closed_object(nullptr), m_ref_count(0) #if defined(MESOSPHERE_ENABLE_DEVIRTUALIZED_DYNAMIC_CAST) , m_class_token(0) #endif @@ -129,6 +129,8 @@ namespace ams::kern { MESOSPHERE_ASSERT_THIS(); } + ALWAYS_INLINE explicit KAutoObject() : m_ref_count(0) { MESOSPHERE_ASSERT_THIS(); } + /* Destroy is responsible for destroying the auto object's resources when ref_count hits zero. */ virtual void Destroy() { MESOSPHERE_ASSERT_THIS(); } @@ -208,9 +210,11 @@ namespace ams::kern { class KAutoObjectWithListBase : public KAutoObject { private: - void *m_alignment_forcer_unused[0]{}; + void *m_alignment_forcer_unused[0]; public: - constexpr ALWAYS_INLINE KAutoObjectWithListBase() = default; + constexpr ALWAYS_INLINE explicit KAutoObjectWithListBase(util::ConstantInitializeTag) : KAutoObject(util::ConstantInitialize), m_alignment_forcer_unused{} { /* ... */ } + + ALWAYS_INLINE explicit KAutoObjectWithListBase() { /* ... */ } }; class KAutoObjectWithList : public KAutoObjectWithListBase { @@ -219,7 +223,8 @@ namespace ams::kern { private: util::IntrusiveRedBlackTreeNode m_list_node; public: - constexpr ALWAYS_INLINE KAutoObjectWithList() : m_list_node() { /* ... */ } + constexpr ALWAYS_INLINE KAutoObjectWithList(util::ConstantInitializeTag) : KAutoObjectWithListBase(util::ConstantInitialize), m_list_node(util::ConstantInitialize) { /* ... */ } + ALWAYS_INLINE explicit KAutoObjectWithList() { /* ... */ } static ALWAYS_INLINE int Compare(const KAutoObjectWithList &lhs, const KAutoObjectWithList &rhs) { const u64 lid = lhs.GetId(); @@ -252,7 +257,6 @@ namespace ams::kern { std::swap(m_obj, rhs.m_obj); } public: - constexpr ALWAYS_INLINE KScopedAutoObject() : m_obj(nullptr) { /* ... */ } constexpr ALWAYS_INLINE KScopedAutoObject(T *o) : m_obj(o) { if (m_obj != nullptr) { m_obj->Open(); diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_capabilities.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_capabilities.hpp index f1c53d98c..fd69590b8 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_capabilities.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_capabilities.hpp @@ -171,14 +171,14 @@ namespace ams::kern { CapabilityFlag | CapabilityFlag; private: - svc::SvcAccessFlagSet m_svc_access_flags{}; - InterruptFlagSet m_irq_access_flags{}; - u64 m_core_mask{}; - u64 m_priority_mask{}; - util::BitPack32 m_debug_capabilities{0}; - s32 m_handle_table_size{}; - util::BitPack32 m_intended_kernel_version{0}; - u32 m_program_type{}; + svc::SvcAccessFlagSet m_svc_access_flags; + InterruptFlagSet m_irq_access_flags; + u64 m_core_mask; + u64 m_priority_mask; + util::BitPack32 m_debug_capabilities; + s32 m_handle_table_size; + util::BitPack32 m_intended_kernel_version; + u32 m_program_type; private: constexpr bool SetSvcAllowed(u32 id) { if (AMS_LIKELY(id < m_svc_access_flags.GetCount())) { @@ -213,7 +213,8 @@ namespace ams::kern { Result SetCapabilities(const u32 *caps, s32 num_caps, KProcessPageTable *page_table); Result SetCapabilities(svc::KUserPointer user_caps, s32 num_caps, KProcessPageTable *page_table); public: - constexpr KCapabilities() = default; + constexpr explicit KCapabilities(util::ConstantInitializeTag) : m_svc_access_flags{}, m_irq_access_flags{}, m_core_mask{}, m_priority_mask{}, m_debug_capabilities{0}, m_handle_table_size{}, m_intended_kernel_version{}, m_program_type{} { /* ... */ } + KCapabilities() { /* ... */ } Result Initialize(const u32 *caps, s32 num_caps, KProcessPageTable *page_table); Result Initialize(svc::KUserPointer user_caps, s32 num_caps, KProcessPageTable *page_table); diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_client_port.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_client_port.hpp index f4cd50fe4..daad415f1 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_client_port.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_client_port.hpp @@ -33,7 +33,9 @@ namespace ams::kern { s32 m_max_sessions; KPort *m_parent; public: - constexpr KClientPort() : m_num_sessions(0), m_peak_sessions(0), m_max_sessions(), m_parent() { /* ... */ } + constexpr explicit KClientPort(util::ConstantInitializeTag) : KSynchronizationObject(util::ConstantInitialize), m_num_sessions(0), m_peak_sessions(0), m_max_sessions(), m_parent() { /* ... */ } + + explicit KClientPort() { /* ... */ } void Initialize(KPort *parent, s32 max_sessions); void OnSessionFinalized(); diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_client_session.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_client_session.hpp index 03b6c64ed..1f190b4a3 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_client_session.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_client_session.hpp @@ -27,7 +27,8 @@ namespace ams::kern { private: KSession *m_parent; public: - constexpr KClientSession() : m_parent() { /* ... */ } + constexpr explicit KClientSession(util::ConstantInitializeTag) : KAutoObject(util::ConstantInitialize), m_parent() { /* ... */ } + explicit KClientSession() { /* ... */ } void Initialize(KSession *parent) { /* Set member variables. */ diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_condition_variable.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_condition_variable.hpp index 650e54b73..de0187bf7 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_condition_variable.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_condition_variable.hpp @@ -26,7 +26,7 @@ namespace ams::kern { private: ThreadTree m_tree; public: - constexpr KConditionVariable() : m_tree() { /* ... */ } + constexpr KConditionVariable() = default; /* Arbitration. */ static Result SignalToAddress(KProcessAddress addr); diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_debug_base.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_debug_base.hpp index ff8797866..5b036f2ee 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_debug_base.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_debug_base.hpp @@ -33,7 +33,7 @@ namespace ams::kern { KProcess::State m_old_process_state; bool m_is_attached; public: - explicit KDebugBase() : m_event_info_list(), m_process_holder(), m_lock() { /* ... */ } + explicit KDebugBase() { /* ... */ } protected: bool Is64Bit() const; public: diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_device_address_space.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_device_address_space.hpp index aef0518b2..6a9d4e536 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_device_address_space.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_device_address_space.hpp @@ -30,7 +30,7 @@ namespace ams::kern { u64 m_space_size; bool m_is_initialized; public: - constexpr KDeviceAddressSpace() : m_lock(), m_table(), m_space_address(), m_space_size(), m_is_initialized() { /* ... */ } + explicit KDeviceAddressSpace() : m_is_initialized(false) { /* ... */ } Result Initialize(u64 address, u64 size); virtual void Finalize() override; diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_dynamic_page_manager.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_dynamic_page_manager.hpp index 629ba403c..15f2c91ce 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_dynamic_page_manager.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_dynamic_page_manager.hpp @@ -40,7 +40,7 @@ namespace ams::kern { KVirtualAddress m_address; size_t m_size; public: - KDynamicPageManager() : m_lock(), m_page_bitmap(), m_used(), m_peak(), m_count(), m_address(), m_size() { /* ... */ } + KDynamicPageManager() : m_lock(), m_page_bitmap(), m_used(), m_peak(), m_count(), m_address(Null), m_size() { /* ... */ } Result Initialize(KVirtualAddress memory, size_t sz) { /* We need to have positive size. */ diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_dynamic_slab_heap.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_dynamic_slab_heap.hpp index a4f687ce5..3a462fa59 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_dynamic_slab_heap.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_dynamic_slab_heap.hpp @@ -32,7 +32,7 @@ namespace ams::kern { util::Atomic m_used{0}; util::Atomic m_peak{0}; util::Atomic m_count{0}; - KVirtualAddress m_address{}; + KVirtualAddress m_address{Null}; size_t m_size{}; public: constexpr KDynamicSlabHeap() = default; diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_event.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_event.hpp index ae1d62f99..55b3b12ee 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_event.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_event.hpp @@ -29,12 +29,15 @@ namespace ams::kern { bool m_initialized; bool m_readable_event_destroyed; public: - constexpr KEvent() - : m_readable_event(), m_owner(), m_initialized(), m_readable_event_destroyed() + constexpr explicit KEvent(util::ConstantInitializeTag) + : KAutoObjectWithSlabHeapAndContainer(util::ConstantInitialize), + m_readable_event(util::ConstantInitialize), m_owner(), m_initialized(), m_readable_event_destroyed() { /* ... */ } + explicit KEvent() : m_readable_event(), m_owner(), m_initialized(), m_readable_event_destroyed() { /* ... */ } + void Initialize(); virtual void Finalize() override; diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_handle_table.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_handle_table.hpp index 7d86e0dc9..503652686 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_handle_table.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_handle_table.hpp @@ -63,16 +63,16 @@ namespace ams::kern { private: EntryInfo m_entry_infos[MaxTableSize]; KAutoObject *m_objects[MaxTableSize]; + mutable KSpinLock m_lock; s32 m_free_head_index; u16 m_table_size; u16 m_max_count; u16 m_next_linear_id; u16 m_count; - mutable KSpinLock m_lock; public: - constexpr KHandleTable() : - m_entry_infos(), m_objects(), m_free_head_index(-1), m_table_size(0), m_max_count(0), m_next_linear_id(MinLinearId), m_count(0), m_lock() - { MESOSPHERE_ASSERT_THIS(); } + constexpr explicit KHandleTable(util::ConstantInitializeTag) : m_entry_infos(), m_objects(), m_lock(), m_free_head_index(-1), m_table_size(), m_max_count(), m_next_linear_id(MinLinearId), m_count() { /* ... */ } + + explicit KHandleTable() : m_free_head_index(-1), m_lock(), m_count() { MESOSPHERE_ASSERT_THIS(); } constexpr NOINLINE Result Initialize(s32 size) { MESOSPHERE_ASSERT_THIS(); diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_interrupt_event.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_interrupt_event.hpp index 010aa10d1..595414ce1 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_interrupt_event.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_interrupt_event.hpp @@ -31,7 +31,9 @@ namespace ams::kern { s32 m_core_id; bool m_is_initialized; public: - constexpr KInterruptEvent() : m_interrupt_id(-1), m_core_id(-1), m_is_initialized(false) { /* ... */ } + constexpr explicit KInterruptEvent(util::ConstantInitializeTag) : KAutoObjectWithSlabHeapAndContainer(util::ConstantInitialize), m_interrupt_id(-1), m_core_id(-1), m_is_initialized(false) { /* ... */ } + + explicit KInterruptEvent() : m_interrupt_id(-1), m_is_initialized(false) { /* ... */ } Result Initialize(int32_t interrupt_name, ams::svc::InterruptType type); virtual void Finalize() override; diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_io_pool.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_io_pool.hpp index de20219c1..4a0a52f6e 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_io_pool.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_io_pool.hpp @@ -33,7 +33,7 @@ namespace ams::kern { public: static bool IsValidIoPoolType(ams::svc::IoPoolType pool_type); public: - explicit KIoPool() : m_lock(), m_io_region_list(), m_is_initialized(false) { + explicit KIoPool() : m_is_initialized(false) { /* ... */ } diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_io_region.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_io_region.hpp index 4d9d7b2b0..2da4c328b 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_io_region.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_io_region.hpp @@ -40,11 +40,7 @@ namespace ams::kern { util::IntrusiveListNode m_process_list_node; util::IntrusiveListNode m_pool_list_node; public: - explicit KIoRegion() - : m_lock(), m_pool(nullptr), m_is_initialized(false), m_process_list_node(), m_pool_list_node() - { - /* ... */ - } + explicit KIoRegion() : m_pool(nullptr), m_is_initialized(false) { /* ... */ } Result Initialize(KIoPool *pool, KPhysicalAddress phys_addr, size_t size, ams::svc::MemoryMapping mapping, ams::svc::MemoryPermission perm); virtual void Finalize() override; diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_light_client_session.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_light_client_session.hpp index 331e419e6..615dace1e 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_light_client_session.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_light_client_session.hpp @@ -26,7 +26,7 @@ namespace ams::kern { private: KLightSession *m_parent; public: - constexpr KLightClientSession() : m_parent() { /* ... */ } + explicit KLightClientSession() { /* ... */ } void Initialize(KLightSession *parent) { /* Set member variables. */ diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_light_condition_variable.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_light_condition_variable.hpp index cd2746736..3a6d61e22 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_light_condition_variable.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_light_condition_variable.hpp @@ -26,7 +26,9 @@ namespace ams::kern { private: KThread::WaiterList m_wait_list; public: - constexpr ALWAYS_INLINE KLightConditionVariable() : m_wait_list() { /* ... */ } + constexpr explicit ALWAYS_INLINE KLightConditionVariable(util::ConstantInitializeTag) : m_wait_list() { /* ... */ } + + explicit ALWAYS_INLINE KLightConditionVariable() { /* ... */ } public: void Wait(KLightLock *lock, s64 timeout = -1ll, bool allow_terminating_thread = true); void Broadcast(); diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_light_lock.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_light_lock.hpp index bb5443823..63c6a2f94 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_light_lock.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_light_lock.hpp @@ -25,7 +25,7 @@ namespace ams::kern { private: util::Atomic m_tag; public: - constexpr KLightLock() : m_tag(0) { /* ... */ } + constexpr ALWAYS_INLINE KLightLock() : m_tag(0) { /* ... */ } void Lock() { MESOSPHERE_ASSERT_THIS(); diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_light_server_session.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_light_server_session.hpp index 4f3d4f0d3..d6dd63369 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_light_server_session.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_light_server_session.hpp @@ -32,7 +32,7 @@ namespace ams::kern { u64 m_server_thread_id; KThread *m_server_thread; public: - constexpr KLightServerSession() : m_parent(), m_request_list(), m_current_request(), m_server_thread_id(), m_server_thread() { /* ... */ } + explicit KLightServerSession() : m_current_request(nullptr), m_server_thread_id(std::numeric_limits::max()), m_server_thread() { /* ... */ } void Initialize(KLightSession *parent) { /* Set member variables. */ diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_light_session.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_light_session.hpp index fe58cb38b..417e84ec7 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_light_session.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_light_session.hpp @@ -46,11 +46,7 @@ namespace ams::kern { KProcess *m_process; bool m_initialized; public: - constexpr KLightSession() - : m_server(), m_client(), m_state(State::Invalid), m_port(), m_name(), m_process(), m_initialized() - { - /* ... */ - } + explicit KLightSession() : m_state(State::Invalid), m_process(), m_initialized() { /* ... */ } void Initialize(KClientPort *client_port, uintptr_t name); virtual void Finalize() override; diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_memory_block.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_memory_block.hpp index 9700a80f3..37fd444e4 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_memory_block.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_memory_block.hpp @@ -349,28 +349,30 @@ namespace ams::kern { }; } public: - constexpr KMemoryBlock() - : m_device_disable_merge_left_count(), m_device_disable_merge_right_count(), m_address(), m_num_pages(), m_memory_state(KMemoryState_None), m_ipc_lock_count(), m_device_use_count(), m_ipc_disable_merge_count(), m_permission(), m_original_permission(), m_attribute(), m_disable_merge_attribute() - { - /* ... */ - } + explicit KMemoryBlock() { /* ... */ } - constexpr KMemoryBlock(KProcessAddress addr, size_t np, KMemoryState ms, KMemoryPermission p, KMemoryAttribute attr) - : m_device_disable_merge_left_count(), m_device_disable_merge_right_count(), m_address(addr), m_num_pages(np), m_memory_state(ms), m_ipc_lock_count(0), m_device_use_count(0), m_ipc_disable_merge_count(), m_permission(p), m_original_permission(KMemoryPermission_None), m_attribute(attr), m_disable_merge_attribute() + constexpr KMemoryBlock(util::ConstantInitializeTag, KProcessAddress addr, size_t np, KMemoryState ms, KMemoryPermission p, KMemoryAttribute attr) + : util::IntrusiveRedBlackTreeBaseNode(util::ConstantInitialize), m_device_disable_merge_left_count(), + m_device_disable_merge_right_count(), m_address(addr), m_num_pages(np), m_memory_state(ms), m_ipc_lock_count(0), + m_device_use_count(0), m_ipc_disable_merge_count(), m_permission(p), m_original_permission(KMemoryPermission_None), + m_attribute(attr), m_disable_merge_attribute() { /* ... */ } constexpr void Initialize(KProcessAddress addr, size_t np, KMemoryState ms, KMemoryPermission p, KMemoryAttribute attr) { MESOSPHERE_ASSERT_THIS(); - m_address = addr; - m_num_pages = np; - m_memory_state = ms; - m_ipc_lock_count = 0; - m_device_use_count = 0; - m_permission = p; - m_original_permission = KMemoryPermission_None; - m_attribute = attr; + m_device_disable_merge_left_count = 0; + m_device_disable_merge_right_count = 0; + m_address = addr; + m_num_pages = np; + m_memory_state = ms; + m_ipc_lock_count = 0; + m_device_use_count = 0; + m_permission = p; + m_original_permission = KMemoryPermission_None; + m_attribute = attr; + m_disable_merge_attribute = KMemoryBlockDisableMergeAttribute_None; } constexpr bool HasProperties(KMemoryState s, KMemoryPermission p, KMemoryAttribute a) const { diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_memory_block_manager.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_memory_block_manager.hpp index 3048b4672..ddf6f7dbe 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_memory_block_manager.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_memory_block_manager.hpp @@ -88,7 +88,9 @@ namespace ams::kern { private: void CoalesceForUpdate(KMemoryBlockManagerUpdateAllocator *allocator, KProcessAddress address, size_t num_pages); public: - constexpr KMemoryBlockManager() : m_memory_block_tree(), m_start_address(), m_end_address() { /* ... */ } + constexpr explicit KMemoryBlockManager(util::ConstantInitializeTag) : m_memory_block_tree(), m_start_address(Null), m_end_address(Null) { /* ... */ } + + explicit KMemoryBlockManager() { /* ... */ } iterator end() { return m_memory_block_tree.end(); } const_iterator end() const { return m_memory_block_tree.end(); } @@ -105,7 +107,7 @@ namespace ams::kern { void UpdateIfMatch(KMemoryBlockManagerUpdateAllocator *allocator, KProcessAddress address, size_t num_pages, KMemoryState test_state, KMemoryPermission test_perm, KMemoryAttribute test_attr, KMemoryState state, KMemoryPermission perm, KMemoryAttribute attr); iterator FindIterator(KProcessAddress address) const { - return m_memory_block_tree.find(KMemoryBlock(address, 1, KMemoryState_Free, KMemoryPermission_None, KMemoryAttribute_None)); + return m_memory_block_tree.find(KMemoryBlock(util::ConstantInitialize, address, 1, KMemoryState_Free, KMemoryPermission_None, KMemoryAttribute_None)); } const KMemoryBlock *FindBlock(KProcessAddress address) const { diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_memory_layout.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_memory_layout.hpp index 2710aa09b..66ee75ab6 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_memory_layout.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_memory_layout.hpp @@ -54,12 +54,12 @@ namespace ams::kern { class KMemoryLayout { private: - static /* constinit */ inline uintptr_t s_linear_phys_to_virt_diff; - static /* constinit */ inline uintptr_t s_linear_virt_to_phys_diff; - static /* constinit */ inline KMemoryRegionTree s_virtual_tree; - static /* constinit */ inline KMemoryRegionTree s_physical_tree; - static /* constinit */ inline KMemoryRegionTree s_virtual_linear_tree; - static /* constinit */ inline KMemoryRegionTree s_physical_linear_tree; + static constinit inline uintptr_t s_linear_phys_to_virt_diff; + static constinit inline uintptr_t s_linear_virt_to_phys_diff; + static constinit inline KMemoryRegionTree s_virtual_tree; + static constinit inline KMemoryRegionTree s_physical_tree; + static constinit inline KMemoryRegionTree s_virtual_linear_tree; + static constinit inline KMemoryRegionTree s_physical_linear_tree; private: template requires IsKTypedAddress static ALWAYS_INLINE bool IsTypedAddress(const KMemoryRegion *®ion, AddressType address, KMemoryRegionTree &tree, KMemoryRegionType type) { diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_memory_manager.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_memory_manager.hpp index 2743888b5..59929ffd3 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_memory_manager.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_memory_manager.hpp @@ -68,7 +68,7 @@ namespace ams::kern { Impl *m_next; Impl *m_prev; public: - Impl() : m_heap(), m_page_reference_counts(), m_management_region(), m_pool(), m_next(), m_prev() { /* ... */ } + Impl() : m_heap(), m_page_reference_counts(), m_management_region(Null), m_pool(), m_next(), m_prev() { /* ... */ } size_t Initialize(KPhysicalAddress address, size_t size, KVirtualAddress management, KVirtualAddress management_end, Pool p); diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_memory_region.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_memory_region.hpp index 9b4e2f4f7..a905d8e7c 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_memory_region.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_memory_region.hpp @@ -43,13 +43,14 @@ namespace ams::kern { } } public: - constexpr ALWAYS_INLINE KMemoryRegion() : m_address(0), m_pair_address(0), m_last_address(0), m_attributes(0), m_type_id(0) { /* ... */ } - constexpr ALWAYS_INLINE KMemoryRegion(uintptr_t a, size_t la, uintptr_t p, u32 r, u32 t) : + constexpr ALWAYS_INLINE KMemoryRegion() : util::IntrusiveRedBlackTreeBaseNode(util::ConstantInitialize), m_address(0), m_pair_address(0), m_last_address(0), m_attributes(0), m_type_id(0) { /* ... */ } + + ALWAYS_INLINE KMemoryRegion(uintptr_t a, size_t la, uintptr_t p, u32 r, u32 t) : m_address(a), m_pair_address(p), m_last_address(la), m_attributes(r), m_type_id(t) { /* ... */ } - constexpr ALWAYS_INLINE KMemoryRegion(uintptr_t a, size_t la, u32 r, u32 t) : KMemoryRegion(a, la, std::numeric_limits::max(), r, t) { /* ... */ } + ALWAYS_INLINE KMemoryRegion(uintptr_t a, size_t la, u32 r, u32 t) : KMemoryRegion(a, la, std::numeric_limits::max(), r, t) { /* ... */ } private: constexpr ALWAYS_INLINE void Reset(uintptr_t a, uintptr_t la, uintptr_t p, u32 r, u32 t) { m_address = a; diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_object_name.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_object_name.hpp index 1823938b3..c7ac703b9 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_object_name.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_object_name.hpp @@ -29,8 +29,6 @@ namespace ams::kern { private: char m_name[NameLengthMax]; KAutoObject *m_object; - public: - constexpr KObjectName() : m_name(), m_object() { /* ... */ } public: static Result NewFromName(KAutoObject *obj, const char *name); static Result Delete(KAutoObject *obj, const char *name); diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_page_bitmap.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_page_bitmap.hpp index c946b6989..7f9cea68b 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_page_bitmap.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_page_bitmap.hpp @@ -43,7 +43,7 @@ namespace ams::kern { return rnd_bit; } public: - RandomBitGenerator() : m_rng(), m_entropy(), m_bits_available() { + RandomBitGenerator() : m_entropy(), m_bits_available() { m_rng.Initialize(static_cast(KSystemControl::GenerateRandomU64())); } diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_page_group.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_page_group.hpp index 06d0b0130..9ed9a8582 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_page_group.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_page_group.hpp @@ -28,11 +28,11 @@ namespace ams::kern { private: friend class KPageGroup; private: - KBlockInfo *m_next{}; - u32 m_page_index{}; - u32 m_num_pages{}; + KBlockInfo *m_next; + u32 m_page_index; + u32 m_num_pages; public: - constexpr KBlockInfo() = default; + KBlockInfo() : m_next(nullptr) { /* ... */ } constexpr ALWAYS_INLINE void Initialize(KPhysicalAddress addr, size_t np) { MESOSPHERE_ASSERT(util::IsAligned(GetInteger(addr), PageSize)); diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_page_heap.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_page_heap.hpp index c7cd5d8da..8998d5267 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_page_heap.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_page_heap.hpp @@ -59,7 +59,7 @@ namespace ams::kern { size_t m_block_shift; size_t m_next_block_shift; public: - Block() : m_bitmap(), m_heap_address(), m_end_offset(), m_block_shift(), m_next_block_shift() { /* ... */ } + Block() : m_bitmap(), m_heap_address(Null), m_end_offset(), m_block_shift(), m_next_block_shift() { /* ... */ } constexpr size_t GetShift() const { return m_block_shift; } constexpr size_t GetNextShift() const { return m_next_block_shift; } @@ -134,7 +134,7 @@ namespace ams::kern { void FreeBlock(KPhysicalAddress block, s32 index); public: - KPageHeap() : m_heap_address(), m_heap_size(), m_initial_used_size(), m_num_blocks(), m_blocks() { /* ... */ } + KPageHeap() : m_heap_address(Null), m_heap_size(), m_initial_used_size(), m_num_blocks(), m_blocks() { /* ... */ } constexpr KPhysicalAddress GetAddress() const { return m_heap_address; } constexpr size_t GetSize() const { return m_heap_size; } diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_page_table_base.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_page_table_base.hpp index 5f4746358..0152f1321 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_page_table_base.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_page_table_base.hpp @@ -144,45 +144,60 @@ namespace ams::kern { PageLinkedList *GetPageList() { return std::addressof(m_ll); } }; private: - KProcessAddress m_address_space_start{}; - KProcessAddress m_address_space_end{}; - KProcessAddress m_heap_region_start{}; - KProcessAddress m_heap_region_end{}; - KProcessAddress m_current_heap_end{}; - KProcessAddress m_alias_region_start{}; - KProcessAddress m_alias_region_end{}; - KProcessAddress m_stack_region_start{}; - KProcessAddress m_stack_region_end{}; - KProcessAddress m_kernel_map_region_start{}; - KProcessAddress m_kernel_map_region_end{}; - KProcessAddress m_alias_code_region_start{}; - KProcessAddress m_alias_code_region_end{}; - KProcessAddress m_code_region_start{}; - KProcessAddress m_code_region_end{}; - size_t m_max_heap_size{}; - size_t m_mapped_physical_memory_size{}; - size_t m_mapped_unsafe_physical_memory{}; - size_t m_mapped_ipc_server_memory{}; - mutable KLightLock m_general_lock{}; - mutable KLightLock m_map_physical_memory_lock{}; - KLightLock m_device_map_lock{}; - KPageTableImpl m_impl{}; - KMemoryBlockManager m_memory_block_manager{}; - u32 m_allocate_option{}; - u32 m_address_space_width{}; - bool m_is_kernel{}; - bool m_enable_aslr{}; - bool m_enable_device_address_space_merge{}; - KMemoryBlockSlabManager *m_memory_block_slab_manager{}; - KBlockInfoManager *m_block_info_manager{}; - KResourceLimit *m_resource_limit{}; - const KMemoryRegion *m_cached_physical_linear_region{}; - const KMemoryRegion *m_cached_physical_heap_region{}; - MemoryFillValue m_heap_fill_value{}; - MemoryFillValue m_ipc_fill_value{}; - MemoryFillValue m_stack_fill_value{}; + KProcessAddress m_address_space_start; + KProcessAddress m_address_space_end; + KProcessAddress m_heap_region_start; + KProcessAddress m_heap_region_end; + KProcessAddress m_current_heap_end; + KProcessAddress m_alias_region_start; + KProcessAddress m_alias_region_end; + KProcessAddress m_stack_region_start; + KProcessAddress m_stack_region_end; + KProcessAddress m_kernel_map_region_start; + KProcessAddress m_kernel_map_region_end; + KProcessAddress m_alias_code_region_start; + KProcessAddress m_alias_code_region_end; + KProcessAddress m_code_region_start; + KProcessAddress m_code_region_end; + size_t m_max_heap_size; + size_t m_mapped_physical_memory_size; + size_t m_mapped_unsafe_physical_memory; + size_t m_mapped_ipc_server_memory; + mutable KLightLock m_general_lock; + mutable KLightLock m_map_physical_memory_lock; + KLightLock m_device_map_lock; + KPageTableImpl m_impl; + KMemoryBlockManager m_memory_block_manager; + u32 m_allocate_option; + u32 m_address_space_width; + bool m_is_kernel; + bool m_enable_aslr; + bool m_enable_device_address_space_merge; + KMemoryBlockSlabManager *m_memory_block_slab_manager; + KBlockInfoManager *m_block_info_manager; + KResourceLimit *m_resource_limit; + const KMemoryRegion *m_cached_physical_linear_region; + const KMemoryRegion *m_cached_physical_heap_region; + MemoryFillValue m_heap_fill_value; + MemoryFillValue m_ipc_fill_value; + MemoryFillValue m_stack_fill_value; public: - constexpr KPageTableBase() { /* ... */ } + constexpr explicit KPageTableBase(util::ConstantInitializeTag) + : m_address_space_start(Null), m_address_space_end(Null), m_heap_region_start(Null), + m_heap_region_end(Null), m_current_heap_end(Null), m_alias_region_start(Null), + m_alias_region_end(Null), m_stack_region_start(Null), m_stack_region_end(Null), + m_kernel_map_region_start(Null), m_kernel_map_region_end(Null), m_alias_code_region_start(Null), + m_alias_code_region_end(Null), m_code_region_start(Null), m_code_region_end(Null), + m_max_heap_size(), m_mapped_physical_memory_size(), m_mapped_unsafe_physical_memory(), m_mapped_ipc_server_memory(), m_general_lock(), + m_map_physical_memory_lock(), m_device_map_lock(), m_impl(util::ConstantInitialize), m_memory_block_manager(util::ConstantInitialize), + m_allocate_option(), m_address_space_width(), m_is_kernel(), m_enable_aslr(), m_enable_device_address_space_merge(), + m_memory_block_slab_manager(), m_block_info_manager(), m_resource_limit(), m_cached_physical_linear_region(), m_cached_physical_heap_region(), + m_heap_fill_value(), m_ipc_fill_value(), m_stack_fill_value() + { + /* ... */ + } + + explicit KPageTableBase() { /* ... */ } NOINLINE Result InitializeForKernel(bool is_64_bit, void *table, KVirtualAddress start, KVirtualAddress end); NOINLINE Result InitializeForProcess(ams::svc::CreateProcessFlag as_type, bool enable_aslr, bool enable_device_address_space_merge, bool from_back, KMemoryManager::Pool pool, void *table, KProcessAddress start, KProcessAddress end, KProcessAddress code_address, size_t code_size, KMemoryBlockSlabManager *mem_block_slab_manager, KBlockInfoManager *block_info_manager, KResourceLimit *resource_limit); diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_page_table_manager.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_page_table_manager.hpp index 85ddc6998..bf1546b63 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_page_table_manager.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_page_table_manager.hpp @@ -27,9 +27,10 @@ namespace ams::kern { private: using BaseHeap = KDynamicResourceManager; private: - KPageTableSlabHeap *m_pt_heap{}; + KPageTableSlabHeap *m_pt_heap; public: - constexpr KPageTableManager() = default; + constexpr explicit KPageTableManager(util::ConstantInitializeTag) : m_pt_heap() { /* ... */ } + explicit KPageTableManager() { /* ... */ } ALWAYS_INLINE void Initialize(KDynamicPageManager *page_allocator, KPageTableSlabHeap *pt_heap) { m_pt_heap = pt_heap; diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_port.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_port.hpp index 8dcdc54f7..1f3344159 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_port.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_port.hpp @@ -41,7 +41,7 @@ namespace ams::kern { State m_state; bool m_is_light; public: - constexpr KPort() : m_server(), m_client(), m_name(), m_state(State::Invalid), m_is_light() { /* ... */ } + explicit KPort() : m_state(State::Invalid), m_is_light() { /* ... */ } static void PostDestroy(uintptr_t arg) { MESOSPHERE_UNUSED(arg); /* ... */ } diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_process.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_process.hpp index 311db71ed..fac619bff 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_process.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_process.hpp @@ -57,73 +57,73 @@ namespace ams::kern { using TLPTree = util::IntrusiveRedBlackTreeBaseTraits::TreeType; using TLPIterator = TLPTree::iterator; private: - KProcessPageTable m_page_table{}; - util::Atomic m_used_kernel_memory_size{0}; - TLPTree m_fully_used_tlp_tree{}; - TLPTree m_partially_used_tlp_tree{}; - s32 m_ideal_core_id{}; - void *m_attached_object{}; - KResourceLimit *m_resource_limit{}; - KVirtualAddress m_system_resource_address{}; - size_t m_system_resource_num_pages{}; - size_t m_memory_release_hint{}; - State m_state{}; - KLightLock m_state_lock{}; - KLightLock m_list_lock{}; - KConditionVariable m_cond_var{}; - KAddressArbiter m_address_arbiter{}; - u64 m_entropy[4]{}; - bool m_is_signaled{}; - bool m_is_initialized{}; - bool m_is_application{}; - char m_name[13]{}; - util::Atomic m_num_running_threads{0}; - u32 m_flags{}; - KMemoryManager::Pool m_memory_pool{}; - s64 m_schedule_count{}; - KCapabilities m_capabilities{}; - ams::svc::ProgramId m_program_id{}; - u64 m_process_id{}; - s64 m_creation_time{}; - KProcessAddress m_code_address{}; - size_t m_code_size{}; - size_t m_main_thread_stack_size{}; - size_t m_max_process_memory{}; - u32 m_version{}; - KHandleTable m_handle_table{}; - KProcessAddress m_plr_address{}; - void *m_plr_heap_address{}; - KThread *m_exception_thread{}; - ThreadList m_thread_list{}; - SharedMemoryInfoList m_shared_memory_list{}; - IoRegionList m_io_region_list{}; - bool m_is_suspended{}; - bool m_is_immortal{}; - bool m_is_jit_debug{}; - bool m_is_handle_table_initialized{}; - ams::svc::DebugEvent m_jit_debug_event_type{}; - ams::svc::DebugException m_jit_debug_exception_type{}; - uintptr_t m_jit_debug_params[4]{}; - u64 m_jit_debug_thread_id{}; - KWaitObject m_wait_object{}; - KThread *m_running_threads[cpu::NumCores]{}; - u64 m_running_thread_idle_counts[cpu::NumCores]{}; - KThread *m_pinned_threads[cpu::NumCores]{}; - util::Atomic m_cpu_time{0}; - util::Atomic m_num_process_switches{0}; - util::Atomic m_num_thread_switches{0}; - util::Atomic m_num_fpu_switches{0}; - util::Atomic m_num_supervisor_calls{0}; - util::Atomic m_num_ipc_messages{0}; - util::Atomic m_num_ipc_replies{0}; - util::Atomic m_num_ipc_receives{0}; - KDynamicPageManager m_dynamic_page_manager{}; - KMemoryBlockSlabManager m_memory_block_slab_manager{}; - KBlockInfoManager m_block_info_manager{}; - KPageTableManager m_page_table_manager{}; - KMemoryBlockSlabHeap m_memory_block_heap{}; - KBlockInfoSlabHeap m_block_info_heap{}; - KPageTableSlabHeap m_page_table_heap{}; + KProcessPageTable m_page_table; + util::Atomic m_used_kernel_memory_size; + TLPTree m_fully_used_tlp_tree; + TLPTree m_partially_used_tlp_tree; + s32 m_ideal_core_id; + void *m_attached_object; + KResourceLimit *m_resource_limit; + KVirtualAddress m_system_resource_address; + size_t m_system_resource_num_pages; + size_t m_memory_release_hint; + State m_state; + KLightLock m_state_lock; + KLightLock m_list_lock; + KConditionVariable m_cond_var; + KAddressArbiter m_address_arbiter; + u64 m_entropy[4]; + bool m_is_signaled; + bool m_is_initialized; + bool m_is_application; + char m_name[13]; + util::Atomic m_num_running_threads; + u32 m_flags; + KMemoryManager::Pool m_memory_pool; + s64 m_schedule_count; + KCapabilities m_capabilities; + ams::svc::ProgramId m_program_id; + u64 m_process_id; + s64 m_creation_time; + KProcessAddress m_code_address; + size_t m_code_size; + size_t m_main_thread_stack_size; + size_t m_max_process_memory; + u32 m_version; + KHandleTable m_handle_table; + KProcessAddress m_plr_address; + void *m_plr_heap_address; + KThread *m_exception_thread; + ThreadList m_thread_list; + SharedMemoryInfoList m_shared_memory_list; + IoRegionList m_io_region_list; + bool m_is_suspended; + bool m_is_immortal; + bool m_is_jit_debug; + bool m_is_handle_table_initialized; + ams::svc::DebugEvent m_jit_debug_event_type; + ams::svc::DebugException m_jit_debug_exception_type; + uintptr_t m_jit_debug_params[4]; + u64 m_jit_debug_thread_id; + KWaitObject m_wait_object; + KThread *m_running_threads[cpu::NumCores]; + u64 m_running_thread_idle_counts[cpu::NumCores]; + KThread *m_pinned_threads[cpu::NumCores]; + util::Atomic m_cpu_time; + util::Atomic m_num_process_switches; + util::Atomic m_num_thread_switches; + util::Atomic m_num_fpu_switches; + util::Atomic m_num_supervisor_calls; + util::Atomic m_num_ipc_messages; + util::Atomic m_num_ipc_replies; + util::Atomic m_num_ipc_receives; + KDynamicPageManager m_dynamic_page_manager; + KMemoryBlockSlabManager m_memory_block_slab_manager; + KBlockInfoManager m_block_info_manager; + KPageTableManager m_page_table_manager; + KMemoryBlockSlabHeap m_memory_block_heap; + KBlockInfoSlabHeap m_block_info_heap; + KPageTableSlabHeap m_page_table_heap; private: Result Initialize(const ams::svc::CreateProcessParameter ¶ms); @@ -145,7 +145,7 @@ namespace ams::kern { m_pinned_threads[core_id] = nullptr; } public: - KProcess() { /* ... */ } + explicit KProcess() : m_is_initialized(false) { /* ... */ } Result Initialize(const ams::svc::CreateProcessParameter ¶ms, const KPageGroup &pg, const u32 *caps, s32 num_caps, KResourceLimit *res_limit, KMemoryManager::Pool pool, bool immortal); Result Initialize(const ams::svc::CreateProcessParameter ¶ms, svc::KUserPointer caps, s32 num_caps, KResourceLimit *res_limit, KMemoryManager::Pool pool); diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_readable_event.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_readable_event.hpp index 0dd77e20c..12c83b8e6 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_readable_event.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_readable_event.hpp @@ -27,7 +27,9 @@ namespace ams::kern { bool m_is_signaled; KEvent *m_parent; public: - constexpr explicit KReadableEvent() : KSynchronizationObject(), m_is_signaled(), m_parent() { MESOSPHERE_ASSERT_THIS(); } + constexpr explicit KReadableEvent(util::ConstantInitializeTag) : KSynchronizationObject(util::ConstantInitialize), m_is_signaled(), m_parent() { MESOSPHERE_ASSERT_THIS(); } + + explicit KReadableEvent() { /* ... */ } void Initialize(KEvent *parent); diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_resource_limit.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_resource_limit.hpp index 36ef16854..5b21a5282 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_resource_limit.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_resource_limit.hpp @@ -33,7 +33,15 @@ namespace ams::kern { s32 m_waiter_count; KLightConditionVariable m_cond_var; public: - constexpr ALWAYS_INLINE KResourceLimit() : m_limit_values(), m_current_values(), m_current_hints(), m_peak_values(), m_lock(), m_waiter_count(), m_cond_var() { /* ... */ } + constexpr explicit ALWAYS_INLINE KResourceLimit(util::ConstantInitializeTag) + : KAutoObjectWithSlabHeapAndContainer(util::ConstantInitialize), + m_limit_values(), m_current_values(), m_current_hints(), m_peak_values(), m_lock(), m_waiter_count(), + m_cond_var(util::ConstantInitialize) + { + /* ... */ + } + + explicit ALWAYS_INLINE KResourceLimit() { /* ... */ } static void PostDestroy(uintptr_t arg) { MESOSPHERE_UNUSED(arg); /* ... */ } diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_scheduler.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_scheduler.hpp index 24f1c7048..45123fe02 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_scheduler.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_scheduler.hpp @@ -62,8 +62,7 @@ namespace ams::kern { KThread *m_idle_thread; util::Atomic m_current_thread; public: - constexpr KScheduler() - : m_state(), m_is_active(false), m_core_id(0), m_last_context_switch_time(0), m_idle_thread(nullptr), m_current_thread(nullptr) + constexpr KScheduler() : m_state(), m_is_active(false), m_core_id(0), m_last_context_switch_time(0), m_idle_thread(nullptr), m_current_thread(nullptr) { m_state.needs_scheduling = true; m_state.interrupt_task_runnable = false; diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_server_port.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_server_port.hpp index 179081901..9253ee8a6 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_server_port.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_server_port.hpp @@ -34,7 +34,8 @@ namespace ams::kern { LightSessionList m_light_session_list; KPort *m_parent; public: - constexpr KServerPort() : m_session_list(), m_light_session_list(), m_parent() { /* ... */ } + constexpr explicit KServerPort(util::ConstantInitializeTag) : KSynchronizationObject(util::ConstantInitialize), m_session_list(), m_light_session_list(), m_parent() { /* ... */ } + explicit KServerPort() { /* ... */ } void Initialize(KPort *parent); void EnqueueSession(KServerSession *session); diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_server_session.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_server_session.hpp index 2ac680048..db8de1250 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_server_session.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_server_session.hpp @@ -33,7 +33,8 @@ namespace ams::kern { KSessionRequest *m_current_request; KLightLock m_lock; public: - constexpr KServerSession() : m_parent(), m_request_list(), m_current_request(), m_lock() { /* ... */ } + constexpr explicit KServerSession(util::ConstantInitializeTag) : KSynchronizationObject(util::ConstantInitialize), m_parent(), m_request_list(), m_current_request(), m_lock() { /* ... */ } + explicit KServerSession() : m_current_request(nullptr), m_lock() { /* ... */ } virtual void Destroy() override; diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_session.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_session.hpp index a149e0a2d..9f0352a1d 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_session.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_session.hpp @@ -51,12 +51,16 @@ namespace ams::kern { return static_cast(m_atomic_state.Load()); } public: - constexpr KSession() - : m_atomic_state(static_cast::type>(State::Invalid)), m_initialized(), m_server(), m_client(), m_port(), m_name(), m_process() + constexpr explicit KSession(util::ConstantInitializeTag) + : KAutoObjectWithSlabHeapAndContainer(util::ConstantInitialize), + m_atomic_state(static_cast::type>(State::Invalid)), m_initialized(), + m_server(util::ConstantInitialize), m_client(util::ConstantInitialize), m_port(), m_name(), m_process() { /* ... */ } + explicit KSession() : m_atomic_state(util::ToUnderlying(State::Invalid)), m_initialized(false), m_process(nullptr) { /* ... */ } + void Initialize(KClientPort *client_port, uintptr_t name); virtual void Finalize() override; diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_session_request.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_session_request.hpp index 23d11b585..33fa7effa 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_session_request.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_session_request.hpp @@ -33,14 +33,14 @@ namespace ams::kern { class Mapping { private: - KProcessAddress m_client_address; - KProcessAddress m_server_address; + uintptr_t m_client_address; + uintptr_t m_server_address; size_t m_size; KMemoryState m_state; public: constexpr void Set(KProcessAddress c, KProcessAddress s, size_t sz, KMemoryState st) { - m_client_address = c; - m_server_address = s; + m_client_address = GetInteger(c); + m_server_address = GetInteger(s); m_size = sz; m_state = st; } @@ -57,7 +57,9 @@ namespace ams::kern { u8 m_num_recv; u8 m_num_exch; public: - constexpr explicit SessionMappings() : m_static_mappings(), m_mappings(), m_num_send(), m_num_recv(), m_num_exch() { /* ... */ } + constexpr explicit SessionMappings(util::ConstantInitializeTag) : m_static_mappings(), m_mappings(), m_num_send(), m_num_recv(), m_num_exch() { /* ... */ } + + explicit SessionMappings() : m_mappings(nullptr), m_num_send(), m_num_recv(), m_num_exch() { /* ... */ } void Initialize() { /* ... */ } void Finalize(); @@ -119,8 +121,6 @@ namespace ams::kern { return m_mappings[index - NumStaticMappings]; } } - - }; private: SessionMappings m_mappings; @@ -130,11 +130,13 @@ namespace ams::kern { uintptr_t m_address; size_t m_size; public: - constexpr KSessionRequest() : m_mappings(), m_thread(), m_server(), m_event(), m_address(), m_size() { /* ... */ } + constexpr explicit KSessionRequest(util::ConstantInitializeTag) : KAutoObject(util::ConstantInitialize), m_mappings(util::ConstantInitialize), m_thread(), m_server(), m_event(), m_address(), m_size() { /* ... */ } + + explicit KSessionRequest() : m_thread(nullptr), m_server(nullptr), m_event(nullptr) { /* ... */ } static KSessionRequest *Create() { KSessionRequest *req = KSessionRequest::Allocate(); - if (req != nullptr) { + if (AMS_LIKELY(req != nullptr)) { KAutoObject::Create(req); } return req; @@ -142,7 +144,7 @@ namespace ams::kern { static KSessionRequest *CreateFromUnusedSlabMemory() { KSessionRequest *req = KSessionRequest::AllocateFromUnusedSlabMemory(); - if (req != nullptr) { + if (AMS_LIKELY(req != nullptr)) { KAutoObject::Create(req); } return req; diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_shared_memory_info.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_shared_memory_info.hpp index b539a4bab..c423a205e 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_shared_memory_info.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_shared_memory_info.hpp @@ -26,7 +26,7 @@ namespace ams::kern { KSharedMemory *m_shared_memory; size_t m_reference_count; public: - constexpr KSharedMemoryInfo() : m_shared_memory(), m_reference_count() { /* ... */ } + explicit KSharedMemoryInfo() { /* ... */ } ~KSharedMemoryInfo() { /* ... */ } constexpr void Initialize(KSharedMemory *m) { diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_synchronization_object.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_synchronization_object.hpp index 6f1c880a2..ce022a58b 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_synchronization_object.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_synchronization_object.hpp @@ -32,7 +32,8 @@ namespace ams::kern { ThreadListNode *m_thread_list_head; ThreadListNode *m_thread_list_tail; protected: - constexpr ALWAYS_INLINE explicit KSynchronizationObject() : KAutoObjectWithList(), m_thread_list_head(), m_thread_list_tail() { MESOSPHERE_ASSERT_THIS(); } + constexpr ALWAYS_INLINE explicit KSynchronizationObject(util::ConstantInitializeTag) : KAutoObjectWithList(util::ConstantInitialize), m_thread_list_head(), m_thread_list_tail() { MESOSPHERE_ASSERT_THIS(); } + ALWAYS_INLINE explicit KSynchronizationObject() : m_thread_list_head(), m_thread_list_tail() { MESOSPHERE_ASSERT_THIS(); } virtual void OnFinalizeSynchronizationObject() { MESOSPHERE_ASSERT_THIS(); } diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_thread.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_thread.hpp index 23295e572..480626b9f 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_thread.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_thread.hpp @@ -120,8 +120,6 @@ namespace ams::kern { KThread *m_prev; KThread *m_next; public: - constexpr QueueEntry() : m_prev(nullptr), m_next(nullptr) { /* ... */ } - constexpr void Initialize() { m_prev = nullptr; m_next = nullptr; @@ -140,7 +138,9 @@ namespace ams::kern { KSynchronizationObject *m_sync_objects[ams::svc::ArgumentHandleCountMax]; ams::svc::Handle m_handles[ams::svc::ArgumentHandleCountMax * (sizeof(KSynchronizationObject *) / sizeof(ams::svc::Handle))]; - constexpr SyncObjectBuffer() : m_sync_objects() { /* ... */ } + constexpr explicit SyncObjectBuffer(util::ConstantInitializeTag) : m_sync_objects() { /* ... */ } + + explicit SyncObjectBuffer() { /* ... */ } }; static_assert(sizeof(SyncObjectBuffer::m_sync_objects) == sizeof(SyncObjectBuffer::m_handles)); @@ -177,64 +177,79 @@ namespace ams::kern { static_assert(ams::util::HasRedBlackKeyType); static_assert(std::same_as, ConditionVariableComparator::RedBlackKeyType>); private: - util::IntrusiveListNode m_process_list_node{}; - util::IntrusiveRedBlackTreeNode m_condvar_arbiter_tree_node{}; - s32 m_priority{}; + util::IntrusiveListNode m_process_list_node; + util::IntrusiveRedBlackTreeNode m_condvar_arbiter_tree_node; + s32 m_priority; using ConditionVariableThreadTreeTraits = util::IntrusiveRedBlackTreeMemberTraitsDeferredAssert<&KThread::m_condvar_arbiter_tree_node>; using ConditionVariableThreadTree = ConditionVariableThreadTreeTraits::TreeType; - ConditionVariableThreadTree *m_condvar_tree{}; - uintptr_t m_condvar_key{}; - alignas(16) KThreadContext m_thread_context{}; - u64 m_virtual_affinity_mask{}; - KAffinityMask m_physical_affinity_mask{}; - u64 m_thread_id{}; - util::Atomic m_cpu_time{0}; - KProcessAddress m_address_key{}; - KProcess *m_parent{}; - void *m_kernel_stack_top{}; - u32 *m_light_ipc_data{}; - KProcessAddress m_tls_address{}; - void *m_tls_heap_address{}; - KLightLock m_activity_pause_lock{}; - SyncObjectBuffer m_sync_object_buffer{}; - s64 m_schedule_count{}; - s64 m_last_scheduled_tick{}; - QueueEntry m_per_core_priority_queue_entry[cpu::NumCores]{}; - KThreadQueue *m_wait_queue{}; - WaiterList m_waiter_list{}; - WaiterList m_pinned_waiter_list{}; - KThread *m_lock_owner{}; - uintptr_t m_debug_params[3]{}; - KAutoObject *m_closed_object{}; - u32 m_address_key_value{}; - u32 m_suspend_request_flags{}; - u32 m_suspend_allowed_flags{}; - s32 m_synced_index{}; + ConditionVariableThreadTree *m_condvar_tree; + uintptr_t m_condvar_key; + alignas(16) KThreadContext m_thread_context; + u64 m_virtual_affinity_mask; + KAffinityMask m_physical_affinity_mask; + u64 m_thread_id; + util::Atomic m_cpu_time; + KProcessAddress m_address_key; + KProcess *m_parent; + void *m_kernel_stack_top; + u32 *m_light_ipc_data; + KProcessAddress m_tls_address; + void *m_tls_heap_address; + KLightLock m_activity_pause_lock; + SyncObjectBuffer m_sync_object_buffer; + s64 m_schedule_count; + s64 m_last_scheduled_tick; + QueueEntry m_per_core_priority_queue_entry[cpu::NumCores]; + KThreadQueue *m_wait_queue; + WaiterList m_waiter_list; + WaiterList m_pinned_waiter_list; + KThread *m_lock_owner; + uintptr_t m_debug_params[3]; + KAutoObject *m_closed_object; + u32 m_address_key_value; + u32 m_suspend_request_flags; + u32 m_suspend_allowed_flags; + s32 m_synced_index; Result m_wait_result; Result m_debug_exception_result; - s32 m_base_priority{}; - s32 m_base_priority_on_unpin{}; - s32 m_physical_ideal_core_id{}; - s32 m_virtual_ideal_core_id{}; - s32 m_num_kernel_waiters{}; - s32 m_current_core_id{}; - s32 m_core_id{}; - KAffinityMask m_original_physical_affinity_mask{}; - s32 m_original_physical_ideal_core_id{}; - s32 m_num_core_migration_disables{}; - ThreadState m_thread_state{}; - util::Atomic m_termination_requested{false}; - bool m_wait_cancelled{}; - bool m_cancellable{}; - bool m_signaled{}; - bool m_initialized{}; - bool m_debug_attached{}; - s8 m_priority_inheritance_count{}; - bool m_resource_limit_release_hint{}; + s32 m_base_priority; + s32 m_base_priority_on_unpin; + s32 m_physical_ideal_core_id; + s32 m_virtual_ideal_core_id; + s32 m_num_kernel_waiters; + s32 m_current_core_id; + s32 m_core_id; + KAffinityMask m_original_physical_affinity_mask; + s32 m_original_physical_ideal_core_id; + s32 m_num_core_migration_disables; + ThreadState m_thread_state; + util::Atomic m_termination_requested; + bool m_wait_cancelled; + bool m_cancellable; + bool m_signaled; + bool m_initialized; + bool m_debug_attached; + s8 m_priority_inheritance_count; + bool m_resource_limit_release_hint; public: - constexpr KThread() : m_wait_result(svc::ResultNoSynchronizationObject()), m_debug_exception_result(ResultSuccess()) { /* ... */ } + constexpr explicit KThread(util::ConstantInitializeTag) + : KAutoObjectWithSlabHeapAndContainer(util::ConstantInitialize), KTimerTask(util::ConstantInitialize), + m_process_list_node{}, m_condvar_arbiter_tree_node{util::ConstantInitialize}, m_priority{-1}, m_condvar_tree{}, m_condvar_key{}, + m_thread_context{util::ConstantInitialize}, m_virtual_affinity_mask{}, m_physical_affinity_mask{}, m_thread_id{}, m_cpu_time{0}, m_address_key{Null}, m_parent{}, + m_kernel_stack_top{}, m_light_ipc_data{}, m_tls_address{Null}, m_tls_heap_address{}, m_activity_pause_lock{}, m_sync_object_buffer{util::ConstantInitialize}, + m_schedule_count{}, m_last_scheduled_tick{}, m_per_core_priority_queue_entry{}, m_wait_queue{}, m_waiter_list{}, m_pinned_waiter_list{}, + m_lock_owner{}, m_debug_params{}, m_closed_object{}, m_address_key_value{}, m_suspend_request_flags{}, m_suspend_allowed_flags{}, m_synced_index{}, + m_wait_result{svc::ResultNoSynchronizationObject()}, m_debug_exception_result{ResultSuccess()}, m_base_priority{}, m_base_priority_on_unpin{}, + m_physical_ideal_core_id{}, m_virtual_ideal_core_id{}, m_num_kernel_waiters{}, m_current_core_id{}, m_core_id{}, m_original_physical_affinity_mask{}, + m_original_physical_ideal_core_id{}, m_num_core_migration_disables{}, m_thread_state{}, m_termination_requested{false}, m_wait_cancelled{}, + m_cancellable{}, m_signaled{}, m_initialized{}, m_debug_attached{}, m_priority_inheritance_count{}, m_resource_limit_release_hint{} + { + /* ... */ + } + + explicit KThread() : m_priority(-1), m_condvar_tree(nullptr), m_condvar_key(0), m_parent(nullptr), m_initialized(false) { /* ... */ } Result Initialize(KThreadFunction func, uintptr_t arg, void *kern_stack_top, KProcessAddress user_stack_top, s32 prio, s32 virt_core, KProcess *owner, ThreadType type); private: diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_thread_local_page.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_thread_local_page.hpp index 64d508ca2..ec7c43640 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_thread_local_page.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_thread_local_page.hpp @@ -33,13 +33,13 @@ namespace ams::kern { KProcess *m_owner; bool m_is_region_free[RegionsPerPage]; public: - constexpr explicit KThreadLocalPage(KProcessAddress addr) : m_virt_addr(addr), m_owner(nullptr), m_is_region_free() { - for (size_t i = 0; i < RegionsPerPage; i++) { + explicit KThreadLocalPage(KProcessAddress addr) : m_virt_addr(addr), m_owner(nullptr) { + for (size_t i = 0; i < util::size(m_is_region_free); i++) { m_is_region_free[i] = true; } } - constexpr explicit KThreadLocalPage() : KThreadLocalPage(Null) { /* ... */ } + explicit KThreadLocalPage() : KThreadLocalPage(Null) { /* ... */ } constexpr ALWAYS_INLINE KProcessAddress GetAddress() const { return m_virt_addr; } diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_timer_task.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_timer_task.hpp index b67447bbc..79347cfcb 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_timer_task.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_timer_task.hpp @@ -30,7 +30,8 @@ namespace ams::kern { } } public: - constexpr ALWAYS_INLINE KTimerTask() : m_time(0) { /* ... */ } + constexpr explicit ALWAYS_INLINE KTimerTask(util::ConstantInitializeTag) : util::IntrusiveRedBlackTreeBaseNode(util::ConstantInitialize), m_time(0) { /* ... */ } + explicit ALWAYS_INLINE KTimerTask() : m_time(0) { /* ... */ } constexpr ALWAYS_INLINE void SetTime(s64 t) { m_time = t; diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_typed_address.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_typed_address.hpp index ee07b30f6..1456977d3 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_typed_address.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_typed_address.hpp @@ -26,7 +26,7 @@ namespace ams::kern { uintptr_t m_address; public: /* Constructors. */ - constexpr ALWAYS_INLINE KTypedAddress() : m_address(0) { /* ... */ } + ALWAYS_INLINE KTypedAddress() { /* ... */ } constexpr ALWAYS_INLINE KTypedAddress(uintptr_t a) : m_address(a) { /* ... */ } template constexpr ALWAYS_INLINE explicit KTypedAddress(U *ptr) : m_address(reinterpret_cast(ptr)) { /* ... */ } @@ -146,13 +146,13 @@ namespace ams::kern { } template - constexpr ALWAYS_INLINE T *GetPointer(KTypedAddress address) { - return CONST_FOLD(reinterpret_cast(address.GetValue())); + ALWAYS_INLINE T *GetPointer(KTypedAddress address) { + return reinterpret_cast(address.GetValue()); } template - constexpr ALWAYS_INLINE void *GetVoidPointer(KTypedAddress address) { - return CONST_FOLD(reinterpret_cast(address.GetValue())); + ALWAYS_INLINE void *GetVoidPointer(KTypedAddress address) { + return reinterpret_cast(address.GetValue()); } #else @@ -170,12 +170,12 @@ namespace ams::kern { template constexpr ALWAYS_INLINE T *GetPointer(uintptr_t address) { - return CONST_FOLD(reinterpret_cast(address)); + return reinterpret_cast(address); } template constexpr ALWAYS_INLINE void *GetVoidPointer(uintptr_t address) { - return CONST_FOLD(reinterpret_cast(address)); + return reinterpret_cast(address); } #endif diff --git a/libraries/libmesosphere/include/mesosphere/kern_slab_helpers.hpp b/libraries/libmesosphere/include/mesosphere/kern_slab_helpers.hpp index 8335d05b8..5eb753081 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_slab_helpers.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_slab_helpers.hpp @@ -85,7 +85,9 @@ namespace ams::kern { ALWAYS_INLINE ~ListAccessor() { /* ... */ } }; public: - constexpr KAutoObjectWithSlabHeapAndContainer() = default; + constexpr explicit KAutoObjectWithSlabHeapAndContainer(util::ConstantInitializeTag) : Base(util::ConstantInitialize) { /* ... */ } + + explicit KAutoObjectWithSlabHeapAndContainer() { /* ... */ } virtual void Destroy() override { const bool is_initialized = this->IsInitialized(); diff --git a/libraries/libmesosphere/source/arch/arm64/kern_cpu.cpp b/libraries/libmesosphere/source/arch/arm64/kern_cpu.cpp index 3f3e83125..c050a3b19 100644 --- a/libraries/libmesosphere/source/arch/arm64/kern_cpu.cpp +++ b/libraries/libmesosphere/source/arch/arm64/kern_cpu.cpp @@ -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. */ diff --git a/libraries/libmesosphere/source/arch/arm64/kern_k_debug.cpp b/libraries/libmesosphere/source/arch/arm64/kern_k_debug.cpp index 390d3e7f4..c065f69b7 100644 --- a/libraries/libmesosphere/source/arch/arm64/kern_k_debug.cpp +++ b/libraries/libmesosphere/source/arch/arm64/kern_k_debug.cpp @@ -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 process; - /* Configure flags/value. */ if ((flags & 1) != 0) { /* We're enabling the breakpoint. Check that the flags are allowable. */ diff --git a/libraries/libmesosphere/source/arch/arm64/kern_k_page_table.cpp b/libraries/libmesosphere/source/arch/arm64/kern_k_page_table.cpp index c8c2f27c4..3e6a92f21 100644 --- a/libraries/libmesosphere/source/arch/arm64/kern_k_page_table.cpp +++ b/libraries/libmesosphere/source/arch/arm64/kern_k_page_table.cpp @@ -233,7 +233,7 @@ namespace ams::kern::arch::arm64 { /* Begin the traversal. */ TraversalContext context; - TraversalEntry cur_entry = {}; + TraversalEntry cur_entry = { .phys_addr = Null, .block_size = 0, .sw_reserved_bits = 0 }; bool cur_valid = false; TraversalEntry next_entry; bool next_valid; diff --git a/libraries/libmesosphere/source/board/nintendo/nx/kern_k_device_page_table.cpp b/libraries/libmesosphere/source/board/nintendo/nx/kern_k_device_page_table.cpp index 7dd7f55fd..1a244b362 100644 --- a/libraries/libmesosphere/source/board/nintendo/nx/kern_k_device_page_table.cpp +++ b/libraries/libmesosphere/source/board/nintendo/nx/kern_k_device_page_table.cpp @@ -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}; + constinit KPhysicalAddress g_reserved_table_phys_addr{Null}; constinit KDeviceAsidManager g_asid_manager; constinit u32 g_saved_page_tables[AsidCount]; constinit u32 g_saved_asid_registers[ams::svc::DeviceName_Count]; diff --git a/libraries/libmesosphere/source/board/nintendo/nx/kern_k_sleep_manager.cpp b/libraries/libmesosphere/source/board/nintendo/nx/kern_k_sleep_manager.cpp index 75e884715..2a08929cb 100644 --- a/libraries/libmesosphere/source/board/nintendo/nx/kern_k_sleep_manager.cpp +++ b/libraries/libmesosphere/source/board/nintendo/nx/kern_k_sleep_manager.cpp @@ -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] = {}; diff --git a/libraries/libmesosphere/source/board/nintendo/nx/kern_k_system_control.cpp b/libraries/libmesosphere/source/board/nintendo/nx/kern_k_system_control.cpp index 51ff4f96b..aa22f91f2 100644 --- a/libraries/libmesosphere/source/board/nintendo/nx/kern_k_system_control.cpp +++ b/libraries/libmesosphere/source/board/nintendo/nx/kern_k_system_control.cpp @@ -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() { diff --git a/libraries/libmesosphere/source/kern_k_capabilities.cpp b/libraries/libmesosphere/source/kern_k_capabilities.cpp index b29c8b7b9..d2000e632 100644 --- a/libraries/libmesosphere/source/kern_k_capabilities.cpp +++ b/libraries/libmesosphere/source/kern_k_capabilities.cpp @@ -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 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); diff --git a/libraries/libmesosphere/source/kern_k_dpc_manager.cpp b/libraries/libmesosphere/source/kern_k_dpc_manager.cpp index cd71c5d5c..9d2218e24 100644 --- a/libraries/libmesosphere/source/kern_k_dpc_manager.cpp +++ b/libraries/libmesosphere/source/kern_k_dpc_manager.cpp @@ -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: diff --git a/libraries/libmesosphere/source/kern_k_dump_object.cpp b/libraries/libmesosphere/source/kern_k_dump_object.cpp index 8c4c13163..05e3dd406 100644 --- a/libraries/libmesosphere/source/kern_k_dump_object.cpp +++ b/libraries/libmesosphere/source/kern_k_dump_object.cpp @@ -195,9 +195,11 @@ namespace ams::kern::KDumpObject { char name[9] = {}; { /* Find the client port process. */ - KScopedAutoObject 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(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)); } diff --git a/libraries/libmesosphere/source/kern_k_page_heap.cpp b/libraries/libmesosphere/source/kern_k_page_heap.cpp index fb00f3d0e..a7c3426cc 100644 --- a/libraries/libmesosphere/source/kern_k_page_heap.cpp +++ b/libraries/libmesosphere/source/kern_k_page_heap.cpp @@ -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(management_address); diff --git a/libraries/libmesosphere/source/kern_k_page_table_base.cpp b/libraries/libmesosphere/source/kern_k_page_table_base.cpp index 5afc9ac84..150996768 100644 --- a/libraries/libmesosphere/source/kern_k_page_table_base.cpp +++ b/libraries/libmesosphere/source/kern_k_page_table_base.cpp @@ -706,7 +706,7 @@ namespace ams::kern { /* Begin traversal. */ TraversalContext context; - TraversalEntry cur_entry = {}; + TraversalEntry cur_entry = { .phys_addr = Null, .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, .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, .block_size = 0, .sw_reserved_bits = 0 }; bool cur_valid = false; TraversalEntry next_entry; bool next_valid; diff --git a/libraries/libmesosphere/source/kern_k_process.cpp b/libraries/libmesosphere/source/kern_k_process.cpp index 9e2771b5d..72e8b9867 100644 --- a/libraries/libmesosphere/source/kern_k_process.cpp +++ b/libraries/libmesosphere/source/kern_k_process.cpp @@ -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. */ diff --git a/libraries/libmesosphere/source/kern_k_resource_limit.cpp b/libraries/libmesosphere/source/kern_k_resource_limit.cpp index 22438ad74..66937a5b7 100644 --- a/libraries/libmesosphere/source/kern_k_resource_limit.cpp +++ b/libraries/libmesosphere/source/kern_k_resource_limit.cpp @@ -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() { diff --git a/libraries/libmesosphere/source/kern_k_server_session.cpp b/libraries/libmesosphere/source/kern_k_server_session.cpp index e45d3e973..ceb0b3a12 100644 --- a/libraries/libmesosphere/source/kern_k_server_session.cpp +++ b/libraries/libmesosphere/source/kern_k_server_session.cpp @@ -973,7 +973,7 @@ namespace ams::kern { /* Get the request and client thread. */ KSessionRequest *request; - KScopedAutoObject 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(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)) { diff --git a/libraries/libmesosphere/source/kern_k_thread.cpp b/libraries/libmesosphere/source/kern_k_thread.cpp index 48993313c..122852731 100644 --- a/libraries/libmesosphere/source/kern_k_thread.cpp +++ b/libraries/libmesosphere/source/kern_k_thread.cpp @@ -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; } }; diff --git a/libraries/libmesosphere/source/kern_k_unused_slab_memory.cpp b/libraries/libmesosphere/source/kern_k_unused_slab_memory.cpp index f287f38f6..7da5d059c 100644 --- a/libraries/libmesosphere/source/kern_k_unused_slab_memory.cpp +++ b/libraries/libmesosphere/source/kern_k_unused_slab_memory.cpp @@ -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(this); } constexpr ALWAYS_INLINE size_t GetSize() const { return m_size; } diff --git a/libraries/libstratosphere/source/os/impl/os_rng_manager_impl.hpp b/libraries/libstratosphere/source/os/impl/os_rng_manager_impl.hpp index 86c5ab50d..f84060236 100644 --- a/libraries/libstratosphere/source/os/impl/os_rng_manager_impl.hpp +++ b/libraries/libstratosphere/source/os/impl/os_rng_manager_impl.hpp @@ -26,7 +26,7 @@ namespace ams::os::impl { private: void Initialize(); public: - constexpr RngManager() : m_mt(), m_lock(), m_initialized() { /* ... */ } + RngManager() : m_mt(), m_lock(), m_initialized() { /* ... */ } public: u64 GenerateRandomU64(); }; diff --git a/libraries/libstratosphere/source/os/os_random.cpp b/libraries/libstratosphere/source/os/os_random.cpp index 0d5dafbae..2e602d310 100644 --- a/libraries/libstratosphere/source/os/os_random.cpp +++ b/libraries/libstratosphere/source/os/os_random.cpp @@ -20,7 +20,7 @@ namespace ams::os { namespace { - constinit util::TinyMT g_random; + constinit util::TinyMT g_random{util::ConstantInitialize}; constinit os::SdkMutex g_random_mutex; constinit bool g_initialized_random; diff --git a/libraries/libvapours/include/vapours/freebsd/tree.hpp b/libraries/libvapours/include/vapours/freebsd/tree.hpp index 7d2a893e0..8e19edabd 100644 --- a/libraries/libvapours/include/vapours/freebsd/tree.hpp +++ b/libraries/libvapours/include/vapours/freebsd/tree.hpp @@ -28,6 +28,7 @@ #pragma once #include #include +#include #pragma GCC push_options #pragma GCC optimize ("-O3") @@ -57,11 +58,14 @@ namespace ams::freebsd { template class RBEntry { private: - T *m_rbe_left = nullptr; - T *m_rbe_right = nullptr; - T *m_rbe_parent = nullptr; - RBColor m_rbe_color = RBColor::RB_BLACK; + T *m_rbe_left ; + T *m_rbe_right; + T *m_rbe_parent; + RBColor m_rbe_color; public: + constexpr ALWAYS_INLINE explicit RBEntry(util::ConstantInitializeTag) : m_rbe_left(nullptr), m_rbe_right(nullptr), m_rbe_parent(nullptr), m_rbe_color(RBColor::RB_BLACK) { /* ... */ } + explicit ALWAYS_INLINE RBEntry() { /* ... */ } + [[nodiscard]] constexpr ALWAYS_INLINE T *Left() { return m_rbe_left; } [[nodiscard]] constexpr ALWAYS_INLINE const T *Left() const { return m_rbe_left; } diff --git a/libraries/libvapours/include/vapours/util/util_intrusive_red_black_tree.hpp b/libraries/libvapours/include/vapours/util/util_intrusive_red_black_tree.hpp index d423f5b79..f22f8ea68 100644 --- a/libraries/libvapours/include/vapours/util/util_intrusive_red_black_tree.hpp +++ b/libraries/libvapours/include/vapours/util/util_intrusive_red_black_tree.hpp @@ -39,7 +39,8 @@ namespace ams::util { private: RBEntry m_entry; public: - constexpr ALWAYS_INLINE IntrusiveRedBlackTreeNode() = default; + constexpr explicit ALWAYS_INLINE IntrusiveRedBlackTreeNode(util::ConstantInitializeTag) : m_entry(util::ConstantInitialize) { /* ... */ } + explicit ALWAYS_INLINE IntrusiveRedBlackTreeNode() { /* ... */ } [[nodiscard]] constexpr ALWAYS_INLINE RBEntry &GetRBEntry() { return m_entry; } [[nodiscard]] constexpr ALWAYS_INLINE const RBEntry &GetRBEntry() const { return m_entry; } @@ -544,6 +545,8 @@ namespace ams::util { template class alignas(void *) IntrusiveRedBlackTreeBaseNode : public IntrusiveRedBlackTreeNode { public: + using IntrusiveRedBlackTreeNode::IntrusiveRedBlackTreeNode; + constexpr ALWAYS_INLINE Derived *GetPrev() { return static_cast< Derived *>(static_cast< IntrusiveRedBlackTreeBaseNode *>(impl::IntrusiveRedBlackTreeImpl::GetPrev(this))); } constexpr ALWAYS_INLINE const Derived *GetPrev() const { return static_cast(static_cast(impl::IntrusiveRedBlackTreeImpl::GetPrev(this))); } diff --git a/libraries/libvapours/include/vapours/util/util_tinymt.hpp b/libraries/libvapours/include/vapours/util/util_tinymt.hpp index 2fe771ade..173eb471c 100644 --- a/libraries/libvapours/include/vapours/util/util_tinymt.hpp +++ b/libraries/libvapours/include/vapours/util/util_tinymt.hpp @@ -102,9 +102,8 @@ namespace ams::util { state2 ^= y; } public: - constexpr TinyMT() : m_state() { /* ... */ } - - /* Public API. */ + constexpr explicit TinyMT(util::ConstantInitializeTag) : m_state() { /* ... */ } + explicit TinyMT() { /* ... */ } /* Initialization. */ void Initialize(u32 seed) { diff --git a/libraries/libvapours/include/vapours/util/util_type_traits.hpp b/libraries/libvapours/include/vapours/util/util_type_traits.hpp index 65a0443f9..dea601140 100644 --- a/libraries/libvapours/include/vapours/util/util_type_traits.hpp +++ b/libraries/libvapours/include/vapours/util/util_type_traits.hpp @@ -23,4 +23,7 @@ namespace ams::util { template using is_pod = std::bool_constant::value && std::is_trivial::value>; + struct ConstantInitializeTag final {}; + constexpr inline const ConstantInitializeTag ConstantInitialize{}; + } diff --git a/mesosphere/kernel/source/kern_kernel_instantiations.cpp b/mesosphere/kernel/source/kern_kernel_instantiations.cpp index d4bd9e8b1..1fa873826 100644 --- a/mesosphere/kernel/source/kern_kernel_instantiations.cpp +++ b/mesosphere/kernel/source/kern_kernel_instantiations.cpp @@ -19,7 +19,7 @@ namespace ams::kern { /* Declare kernel data members in kernel TU. */ constinit Kernel::State Kernel::s_state = Kernel::State::Invalid; - constinit KResourceLimit Kernel::s_system_resource_limit; + constinit KResourceLimit Kernel::s_system_resource_limit{util::ConstantInitialize}; KMemoryManager Kernel::s_memory_manager; constinit KSupervisorPageTable Kernel::s_supervisor_page_table; constinit KUnsafeMemory Kernel::s_unsafe_memory; @@ -33,8 +33,8 @@ namespace ams::kern { constinit KMemoryBlockSlabHeap Kernel::s_app_memory_block_heap; constinit KMemoryBlockSlabHeap Kernel::s_sys_memory_block_heap; constinit KBlockInfoSlabHeap Kernel::s_block_info_heap; - constinit KPageTableManager Kernel::s_app_page_table_manager; - constinit KPageTableManager Kernel::s_sys_page_table_manager; + constinit KPageTableManager Kernel::s_app_page_table_manager{util::ConstantInitialize}; + constinit KPageTableManager Kernel::s_sys_page_table_manager{util::ConstantInitialize}; constinit KMemoryBlockSlabManager Kernel::s_app_memory_block_manager; constinit KMemoryBlockSlabManager Kernel::s_sys_memory_block_manager; constinit KBlockInfoManager Kernel::s_app_block_info_manager; @@ -42,11 +42,70 @@ namespace ams::kern { namespace { - constinit std::array g_main_threads; - constinit std::array g_idle_threads; + template requires (N > 0) + union KThreadArray { + struct RecursiveHolder { + KThread m_thread; + KThreadArray m_next; + + consteval RecursiveHolder() : m_thread{util::ConstantInitialize}, m_next() { /* ... */ } + } m_holder; + KThread m_arr[N]; + + consteval KThreadArray() : m_holder() { /* ... */ } + }; + + template<> + union KThreadArray<1>{ + struct RecursiveHolder { + KThread m_thread; + + consteval RecursiveHolder() : m_thread{util::ConstantInitialize} { /* ... */ } + } m_holder; + KThread m_arr[1]; + + consteval KThreadArray() : m_holder() { /* ... */ } + }; + + template + consteval bool IsKThreadArrayValid(const KThreadArray &v, const KThread *thread) { + if (std::addressof(v.m_holder.m_thread) != thread) { + return false; + } + + if constexpr (Ix == 1) { + return true; + } else { + return IsKThreadArrayValid(v.m_holder.m_next, thread + 1); + } + } + + template + consteval bool IsKThreadArrayValid() { + const KThreadArray v{}; + + if (!IsKThreadArrayValid(v, v.m_arr)) { + return false; + } + + if constexpr (N == 1) { + return true; + } else { + return IsKThreadArrayValid(); + } + } + + static_assert(IsKThreadArrayValid()); + + constinit KThreadArray g_main_threads; + constinit KThreadArray g_idle_threads; + + static_assert(sizeof(g_main_threads) == cpu::NumCores * sizeof(KThread)); + static_assert(sizeof(g_main_threads.m_holder) == sizeof(g_main_threads.m_arr)); + } - KThread &Kernel::GetMainThread(s32 core_id) { return g_main_threads[core_id]; } - KThread &Kernel::GetIdleThread(s32 core_id) { return g_idle_threads[core_id]; } + KThread &Kernel::GetMainThread(s32 core_id) { return g_main_threads.m_arr[core_id]; } + KThread &Kernel::GetIdleThread(s32 core_id) { return g_idle_threads.m_arr[core_id]; } } diff --git a/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_api.cpp b/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_api.cpp index b481fb0cb..7db61d819 100644 --- a/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_api.cpp +++ b/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_api.cpp @@ -33,7 +33,7 @@ namespace ams::dmnt::cheat::impl { u64 m_address; FrozenAddressValue m_value; public: - constexpr FrozenAddressMapEntry(u64 address, FrozenAddressValue value) : m_address(address), m_value(value) { /* ... */ } + FrozenAddressMapEntry(u64 address, FrozenAddressValue value) : m_address(address), m_value(value) { /* ... */ } constexpr u64 GetAddress() const { return m_address; }