mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2024-11-24 07:40:26 +01:00
kern: devirtualize several KAutoObject functions
This commit is contained in:
parent
2490bbf4f9
commit
436613401a
@ -139,7 +139,9 @@ namespace ams::kern {
|
||||
virtual void Destroy() { MESOSPHERE_ASSERT_THIS(); }
|
||||
|
||||
/* Finalize is responsible for cleaning up resource, but does not destroy the object. */
|
||||
virtual void Finalize() { MESOSPHERE_ASSERT_THIS(); }
|
||||
/* NOTE: This is a virtual function in official kernel, but because everything which uses it */
|
||||
/* is already using CRTP for slab heap, we have devirtualized it for performance gain. */
|
||||
/* virtual void Finalize() { MESOSPHERE_ASSERT_THIS(); } */
|
||||
|
||||
virtual KProcess *GetOwner() const { return nullptr; }
|
||||
|
||||
|
@ -36,7 +36,6 @@ namespace ams::kern {
|
||||
}
|
||||
|
||||
virtual void Destroy() override;
|
||||
static void PostDestroy(uintptr_t arg) { MESOSPHERE_UNUSED(arg); /* ... */ }
|
||||
|
||||
constexpr KSession *GetParent() const { return m_parent; }
|
||||
|
||||
|
@ -36,14 +36,14 @@ namespace ams::kern {
|
||||
}
|
||||
|
||||
Result Initialize(KProcessAddress address, size_t size);
|
||||
virtual void Finalize() override;
|
||||
void Finalize();
|
||||
|
||||
Result Map(KProcessAddress address, size_t size);
|
||||
Result Unmap(KProcessAddress address, size_t size);
|
||||
Result MapToOwner(KProcessAddress address, size_t size, ams::svc::MemoryPermission perm);
|
||||
Result UnmapFromOwner(KProcessAddress address, size_t size);
|
||||
|
||||
virtual bool IsInitialized() const override { return m_is_initialized; }
|
||||
bool IsInitialized() const { return m_is_initialized; }
|
||||
static void PostDestroy(uintptr_t arg) { MESOSPHERE_UNUSED(arg); /* ... */ }
|
||||
|
||||
KProcess *GetOwner() const { return m_owner; }
|
||||
|
@ -33,9 +33,9 @@ namespace ams::kern {
|
||||
explicit KDeviceAddressSpace() : m_is_initialized(false) { /* ... */ }
|
||||
|
||||
Result Initialize(u64 address, u64 size);
|
||||
virtual void Finalize() override;
|
||||
void Finalize();
|
||||
|
||||
virtual bool IsInitialized() const override { return m_is_initialized; }
|
||||
bool IsInitialized() const { return m_is_initialized; }
|
||||
static void PostDestroy(uintptr_t arg) { MESOSPHERE_UNUSED(arg); /* ... */ }
|
||||
|
||||
Result Attach(ams::svc::DeviceName device_name);
|
||||
|
@ -39,10 +39,10 @@ namespace ams::kern {
|
||||
explicit KEvent() : m_readable_event(), m_owner(), m_initialized(), m_readable_event_destroyed() { /* ... */ }
|
||||
|
||||
void Initialize();
|
||||
virtual void Finalize() override;
|
||||
void Finalize();
|
||||
|
||||
virtual bool IsInitialized() const override { return m_initialized; }
|
||||
virtual uintptr_t GetPostDestroyArgument() const override { return reinterpret_cast<uintptr_t>(m_owner); }
|
||||
bool IsInitialized() const { return m_initialized; }
|
||||
uintptr_t GetPostDestroyArgument() const { return reinterpret_cast<uintptr_t>(m_owner); }
|
||||
|
||||
static void PostDestroy(uintptr_t arg);
|
||||
|
||||
|
@ -36,11 +36,11 @@ namespace ams::kern {
|
||||
explicit KInterruptEvent() : m_interrupt_id(-1), m_is_initialized(false) { /* ... */ }
|
||||
|
||||
Result Initialize(int32_t interrupt_name, ams::svc::InterruptType type);
|
||||
virtual void Finalize() override;
|
||||
void Finalize();
|
||||
|
||||
virtual Result Reset() override;
|
||||
|
||||
virtual bool IsInitialized() const override { return m_is_initialized; }
|
||||
bool IsInitialized() const { return m_is_initialized; }
|
||||
|
||||
static void PostDestroy(uintptr_t arg) { MESOSPHERE_UNUSED(arg); /* ... */ }
|
||||
|
||||
|
@ -38,9 +38,9 @@ namespace ams::kern {
|
||||
}
|
||||
|
||||
Result Initialize(ams::svc::IoPoolType pool_type);
|
||||
virtual void Finalize() override;
|
||||
void Finalize();
|
||||
|
||||
virtual bool IsInitialized() const override { return m_is_initialized; }
|
||||
bool IsInitialized() const { return m_is_initialized; }
|
||||
static void PostDestroy(uintptr_t arg) { MESOSPHERE_UNUSED(arg); /* ... */ }
|
||||
|
||||
Result AddIoRegion(KIoRegion *region);
|
||||
|
@ -43,9 +43,9 @@ namespace ams::kern {
|
||||
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;
|
||||
void Finalize();
|
||||
|
||||
virtual bool IsInitialized() const override { return m_is_initialized; }
|
||||
bool IsInitialized() const { return m_is_initialized; }
|
||||
static void PostDestroy(uintptr_t arg) { MESOSPHERE_UNUSED(arg); /* ... */ }
|
||||
|
||||
Result Map(KProcessAddress address, size_t size, ams::svc::MemoryPermission map_perm);
|
||||
|
@ -34,7 +34,6 @@ namespace ams::kern {
|
||||
}
|
||||
|
||||
virtual void Destroy() override;
|
||||
static void PostDestroy(uintptr_t arg) { MESOSPHERE_UNUSED(arg); /* ... */ }
|
||||
|
||||
constexpr const KLightSession *GetParent() const { return m_parent; }
|
||||
|
||||
|
@ -40,7 +40,6 @@ namespace ams::kern {
|
||||
}
|
||||
|
||||
virtual void Destroy() override;
|
||||
static void PostDestroy(uintptr_t arg) { MESOSPHERE_UNUSED(arg); /* ... */ }
|
||||
|
||||
constexpr const KLightSession *GetParent() const { return m_parent; }
|
||||
|
||||
|
@ -49,10 +49,10 @@ namespace ams::kern {
|
||||
explicit KLightSession() : m_state(State::Invalid), m_process(), m_initialized() { /* ... */ }
|
||||
|
||||
void Initialize(KClientPort *client_port, uintptr_t name);
|
||||
virtual void Finalize() override;
|
||||
void Finalize();
|
||||
|
||||
virtual bool IsInitialized() const override { return m_initialized; }
|
||||
virtual uintptr_t GetPostDestroyArgument() const override { return reinterpret_cast<uintptr_t>(m_process); }
|
||||
bool IsInitialized() const { return m_initialized; }
|
||||
uintptr_t GetPostDestroyArgument() const { return reinterpret_cast<uintptr_t>(m_process); }
|
||||
|
||||
static void PostDestroy(uintptr_t arg);
|
||||
|
||||
|
@ -46,6 +46,8 @@ namespace ams::kern {
|
||||
static void PostDestroy(uintptr_t arg) { MESOSPHERE_UNUSED(arg); /* ... */ }
|
||||
|
||||
void Initialize(s32 max_sessions, bool is_light, uintptr_t name);
|
||||
void Finalize() { /* ... */ }
|
||||
|
||||
void OnClientClosed();
|
||||
void OnServerClosed();
|
||||
|
||||
|
@ -384,11 +384,11 @@ namespace ams::kern {
|
||||
}
|
||||
public:
|
||||
/* Overridden parent functions. */
|
||||
virtual bool IsInitialized() const override { return m_is_initialized; }
|
||||
bool IsInitialized() const { return m_is_initialized; }
|
||||
|
||||
static void PostDestroy(uintptr_t arg) { MESOSPHERE_UNUSED(arg); /* ... */ }
|
||||
|
||||
virtual void Finalize() override;
|
||||
void Finalize();
|
||||
|
||||
virtual u64 GetId() const override final { return this->GetProcessId(); }
|
||||
|
||||
|
@ -46,7 +46,7 @@ namespace ams::kern {
|
||||
static void PostDestroy(uintptr_t arg) { MESOSPHERE_UNUSED(arg); /* ... */ }
|
||||
|
||||
void Initialize();
|
||||
virtual void Finalize() override;
|
||||
void Finalize();
|
||||
|
||||
s64 GetLimitValue(ams::svc::LimitableResource which) const;
|
||||
s64 GetCurrentValue(ams::svc::LimitableResource which) const;
|
||||
|
@ -62,10 +62,10 @@ namespace ams::kern {
|
||||
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;
|
||||
void Finalize();
|
||||
|
||||
virtual bool IsInitialized() const override { return m_initialized; }
|
||||
virtual uintptr_t GetPostDestroyArgument() const override { return reinterpret_cast<uintptr_t>(m_process); }
|
||||
bool IsInitialized() const { return m_initialized; }
|
||||
uintptr_t GetPostDestroyArgument() const { return reinterpret_cast<uintptr_t>(m_process); }
|
||||
|
||||
static void PostDestroy(uintptr_t arg);
|
||||
|
||||
|
@ -169,20 +169,6 @@ namespace ams::kern {
|
||||
}
|
||||
}
|
||||
|
||||
virtual void Finalize() override {
|
||||
m_mappings.Finalize();
|
||||
|
||||
if (m_thread) {
|
||||
m_thread->Close();
|
||||
}
|
||||
if (m_event) {
|
||||
m_event->Close();
|
||||
}
|
||||
if (m_server) {
|
||||
m_server->Close();
|
||||
}
|
||||
}
|
||||
|
||||
static void PostDestroy(uintptr_t arg) { MESOSPHERE_UNUSED(arg); /* ... */ }
|
||||
|
||||
constexpr ALWAYS_INLINE KThread *GetThread() const { return m_thread; }
|
||||
@ -229,6 +215,21 @@ namespace ams::kern {
|
||||
constexpr ALWAYS_INLINE KProcessAddress GetExchangeServerAddress(size_t i) const { return m_mappings.GetExchangeServerAddress(i); }
|
||||
constexpr ALWAYS_INLINE size_t GetExchangeSize(size_t i) const { return m_mappings.GetExchangeSize(i); }
|
||||
constexpr ALWAYS_INLINE KMemoryState GetExchangeMemoryState(size_t i) const { return m_mappings.GetExchangeMemoryState(i); }
|
||||
private:
|
||||
/* NOTE: This is public and virtual in Nintendo's kernel. */
|
||||
void Finalize() {
|
||||
m_mappings.Finalize();
|
||||
|
||||
if (m_thread) {
|
||||
m_thread->Close();
|
||||
}
|
||||
if (m_event) {
|
||||
m_event->Close();
|
||||
}
|
||||
if (m_server) {
|
||||
m_server->Close();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -42,9 +42,9 @@ namespace ams::kern {
|
||||
}
|
||||
|
||||
Result Initialize(KProcess *owner, size_t size, ams::svc::MemoryPermission own_perm, ams::svc::MemoryPermission rem_perm);
|
||||
virtual void Finalize() override;
|
||||
void Finalize();
|
||||
|
||||
virtual bool IsInitialized() const override { return m_is_initialized; }
|
||||
bool IsInitialized() const { return m_is_initialized; }
|
||||
static void PostDestroy(uintptr_t arg) { MESOSPHERE_UNUSED(arg); /* ... */ }
|
||||
|
||||
Result Map(KProcessPageTable *table, KProcessAddress address, size_t size, KProcess *process, ams::svc::MemoryPermission map_perm);
|
||||
|
@ -44,7 +44,7 @@ namespace ams::kern {
|
||||
public:
|
||||
static Result Wait(s32 *out_index, KSynchronizationObject **objects, const s32 num_objects, s64 timeout);
|
||||
public:
|
||||
virtual void Finalize() override;
|
||||
void Finalize();
|
||||
virtual bool IsSignaled() const { AMS_INFINITE_LOOP(); }
|
||||
|
||||
void DumpWaiters();
|
||||
|
@ -612,12 +612,13 @@ namespace ams::kern {
|
||||
/* Overridden parent functions. */
|
||||
virtual u64 GetId() const override final { return this->GetThreadId(); }
|
||||
|
||||
virtual bool IsInitialized() const override { return m_initialized; }
|
||||
virtual uintptr_t GetPostDestroyArgument() const override { return reinterpret_cast<uintptr_t>(m_parent) | (m_resource_limit_release_hint ? 1 : 0); }
|
||||
bool IsInitialized() const { return m_initialized; }
|
||||
uintptr_t GetPostDestroyArgument() const { return reinterpret_cast<uintptr_t>(m_parent) | (m_resource_limit_release_hint ? 1 : 0); }
|
||||
|
||||
static void PostDestroy(uintptr_t arg);
|
||||
|
||||
virtual void Finalize() override;
|
||||
void Finalize();
|
||||
|
||||
virtual bool IsSignaled() const override;
|
||||
virtual void OnTimer() override;
|
||||
virtual void DoWorkerTask() override;
|
||||
|
@ -36,10 +36,10 @@ namespace ams::kern {
|
||||
}
|
||||
|
||||
Result Initialize(KProcessAddress addr, size_t size, ams::svc::MemoryPermission own_perm);
|
||||
virtual void Finalize() override;
|
||||
void Finalize();
|
||||
|
||||
virtual bool IsInitialized() const override { return m_is_initialized; }
|
||||
virtual uintptr_t GetPostDestroyArgument() const override { return reinterpret_cast<uintptr_t>(m_owner); }
|
||||
bool IsInitialized() const { return m_is_initialized; }
|
||||
uintptr_t GetPostDestroyArgument() const { return reinterpret_cast<uintptr_t>(m_owner); }
|
||||
static void PostDestroy(uintptr_t arg);
|
||||
|
||||
Result Map(KProcessAddress address, size_t size, ams::svc::MemoryPermission map_perm);
|
||||
|
@ -64,9 +64,8 @@ namespace ams::kern {
|
||||
static size_t GetNumRemaining() { return s_slab_heap.GetNumRemaining(); }
|
||||
};
|
||||
|
||||
template<typename Derived, typename Base, bool SupportDynamicExpansion = false>
|
||||
template<typename Derived, typename Base, bool SupportDynamicExpansion = false> requires std::derived_from<Base, KAutoObjectWithList>
|
||||
class KAutoObjectWithSlabHeapAndContainer : public Base {
|
||||
static_assert(std::is_base_of<KAutoObjectWithList, Base>::value);
|
||||
private:
|
||||
static constinit inline KSlabHeap<Derived, SupportDynamicExpansion> s_slab_heap;
|
||||
static constinit inline KAutoObjectWithListContainer s_container;
|
||||
@ -84,28 +83,44 @@ namespace ams::kern {
|
||||
ALWAYS_INLINE ListAccessor() : KAutoObjectWithListContainer::ListAccessor(s_container) { /* ... */ }
|
||||
ALWAYS_INLINE ~ListAccessor() { /* ... */ }
|
||||
};
|
||||
private:
|
||||
static ALWAYS_INLINE bool IsInitialized(const Derived *obj) {
|
||||
if constexpr (requires { { obj->IsInitialized() } -> std::same_as<bool>; }) {
|
||||
return obj->IsInitialized();
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE uintptr_t GetPostDestroyArgument(const Derived *obj) {
|
||||
if constexpr (requires { { obj->GetPostDestroyArgument() } -> std::same_as<uintptr_t>; }) {
|
||||
return obj->GetPostDestroyArgument();
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
public:
|
||||
constexpr explicit KAutoObjectWithSlabHeapAndContainer(util::ConstantInitializeTag) : Base(util::ConstantInitialize) { /* ... */ }
|
||||
|
||||
explicit KAutoObjectWithSlabHeapAndContainer() { /* ... */ }
|
||||
|
||||
virtual void Destroy() override {
|
||||
const bool is_initialized = this->IsInitialized();
|
||||
uintptr_t arg = 0;
|
||||
if (is_initialized) {
|
||||
/* NOTE: IsInitialized() and GetPostDestroyArgument() are virtual functions declared in this class, */
|
||||
/* in Nintendo's kernel. We fully devirtualize them, as Destroy() is the only user of them. */
|
||||
/* We also devirtualize KAutoObject::Finalize(), which is only used by this function in Nintendo's kernel. */
|
||||
virtual void Destroy() override final {
|
||||
Derived * const derived = static_cast<Derived *>(this);
|
||||
|
||||
if (IsInitialized(derived)) {
|
||||
s_container.Unregister(this);
|
||||
arg = this->GetPostDestroyArgument();
|
||||
this->Finalize();
|
||||
}
|
||||
Free(static_cast<Derived *>(this));
|
||||
if (is_initialized) {
|
||||
const uintptr_t arg = GetPostDestroyArgument(derived);
|
||||
derived->Finalize();
|
||||
Free(derived);
|
||||
Derived::PostDestroy(arg);
|
||||
} else {
|
||||
Free(derived);
|
||||
}
|
||||
}
|
||||
|
||||
virtual bool IsInitialized() const { return true; }
|
||||
virtual uintptr_t GetPostDestroyArgument() const { return 0; }
|
||||
|
||||
size_t GetSlabIndex() const {
|
||||
return s_slab_heap.GetObjectIndex(static_cast<const Derived *>(this));
|
||||
}
|
||||
|
@ -67,9 +67,6 @@ namespace ams::kern {
|
||||
|
||||
/* Close our reference to our owner. */
|
||||
m_owner->Close();
|
||||
|
||||
/* Perform inherited finalization. */
|
||||
KAutoObjectWithSlabHeapAndContainer<KCodeMemory, KAutoObjectWithList>::Finalize();
|
||||
}
|
||||
|
||||
Result KCodeMemory::Map(KProcessAddress address, size_t size) {
|
||||
|
@ -43,9 +43,6 @@ namespace ams::kern {
|
||||
|
||||
/* Finalize the table. */
|
||||
m_table.Finalize();
|
||||
|
||||
/* Finalize base. */
|
||||
KAutoObjectWithSlabHeapAndContainer<KDeviceAddressSpace, KAutoObjectWithList>::Finalize();
|
||||
}
|
||||
|
||||
Result KDeviceAddressSpace::Attach(ams::svc::DeviceName device_name) {
|
||||
|
@ -36,8 +36,6 @@ namespace ams::kern {
|
||||
|
||||
void KEvent::Finalize() {
|
||||
MESOSPHERE_ASSERT_THIS();
|
||||
|
||||
KAutoObjectWithSlabHeapAndContainer<KEvent, KAutoObjectWithList, true>::Finalize();
|
||||
}
|
||||
|
||||
Result KEvent::Signal() {
|
||||
|
@ -54,7 +54,7 @@ namespace ams::kern {
|
||||
g_interrupt_event_task_table[m_interrupt_id]->Unregister(m_interrupt_id, m_core_id);
|
||||
|
||||
/* Perform inherited finalization. */
|
||||
KAutoObjectWithSlabHeapAndContainer<KInterruptEvent, KReadableEvent>::Finalize();
|
||||
KReadableEvent::Finalize();
|
||||
}
|
||||
|
||||
Result KInterruptEvent::Reset() {
|
||||
|
@ -183,7 +183,7 @@ namespace ams::kern {
|
||||
MESOSPHERE_LOG("KProcess::Finalize() pid=%ld name=%-12s\n", m_process_id, m_name);
|
||||
|
||||
/* Perform inherited finalization. */
|
||||
KAutoObjectWithSlabHeapAndContainer<KProcess, KSynchronizationObject>::Finalize();
|
||||
KSynchronizationObject::Finalize();
|
||||
}
|
||||
|
||||
Result KProcess::Initialize(const ams::svc::CreateProcessParameter ¶ms) {
|
||||
|
@ -71,9 +71,6 @@ namespace ams::kern {
|
||||
/* Release the memory reservation. */
|
||||
m_resource_limit->Release(ams::svc::LimitableResource_PhysicalMemoryMax, size);
|
||||
m_resource_limit->Close();
|
||||
|
||||
/* Perform inherited finalization. */
|
||||
KAutoObjectWithSlabHeapAndContainer<KSharedMemory, KAutoObjectWithList>::Finalize();
|
||||
}
|
||||
|
||||
Result KSharedMemory::Map(KProcessPageTable *table, KProcessAddress address, size_t size, KProcess *process, ams::svc::MemoryPermission map_perm) {
|
||||
|
@ -84,7 +84,6 @@ namespace ams::kern {
|
||||
#endif
|
||||
|
||||
this->OnFinalizeSynchronizationObject();
|
||||
KAutoObject::Finalize();
|
||||
}
|
||||
|
||||
Result KSynchronizationObject::Wait(s32 *out_index, KSynchronizationObject **objects, const s32 num_objects, s64 timeout) {
|
||||
|
@ -338,7 +338,7 @@ namespace ams::kern {
|
||||
}
|
||||
|
||||
/* Perform inherited finalization. */
|
||||
KAutoObjectWithSlabHeapAndContainer<KThread, KSynchronizationObject>::Finalize();
|
||||
KSynchronizationObject::Finalize();
|
||||
}
|
||||
|
||||
bool KThread::IsSignaled() const {
|
||||
|
@ -56,9 +56,6 @@ namespace ams::kern {
|
||||
/* Close the page group. */
|
||||
GetReference(m_page_group).Close();
|
||||
GetReference(m_page_group).Finalize();
|
||||
|
||||
/* Perform inherited finalization. */
|
||||
KAutoObjectWithSlabHeapAndContainer<KTransferMemory, KAutoObjectWithList>::Finalize();
|
||||
}
|
||||
|
||||
void KTransferMemory::PostDestroy(uintptr_t arg) {
|
||||
|
Loading…
Reference in New Issue
Block a user