mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2025-05-19 09:25:08 -04:00
kern: devirtualize several KAutoObject functions
This commit is contained in:
parent
2490bbf4f9
commit
436613401a
30 changed files with 84 additions and 81 deletions
|
@ -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));
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue