From 6917eaf53b0260cf9ef0d1311a59d460f6329715 Mon Sep 17 00:00:00 2001
From: Hamish Milne <hamishmilne83@gmail.com>
Date: Fri, 27 Dec 2019 18:52:33 +0000
Subject: [PATCH] Use load_construct_data for kernel objects

---
 TODO                                    |  5 ++--
 src/audio_core/dsp_interface.h          |  1 -
 src/common/CMakeLists.txt               |  4 +++
 src/common/archives.h                   | 12 ++++-----
 src/common/construct.h                  | 30 ++++++++++-----------
 src/common/serialization/atomic.h       | 36 ++++++++++++-------------
 src/core/core.cpp                       |  2 +-
 src/core/hle/kernel/address_arbiter.cpp |  5 ++--
 src/core/hle/kernel/address_arbiter.h   |  3 ++-
 src/core/hle/kernel/client_port.cpp     |  5 +++-
 src/core/hle/kernel/client_port.h       |  4 +++
 src/core/hle/kernel/client_session.cpp  |  2 +-
 src/core/hle/kernel/client_session.h    |  3 ++-
 src/core/hle/kernel/event.cpp           |  4 +--
 src/core/hle/kernel/event.h             |  3 ++-
 src/core/hle/kernel/mutex.cpp           |  5 ++--
 src/core/hle/kernel/mutex.h             |  3 ++-
 src/core/hle/kernel/object.cpp          | 12 +--------
 src/core/hle/kernel/object.h            | 17 +++++++++---
 src/core/hle/kernel/process.cpp         | 20 +++++++-------
 src/core/hle/kernel/process.h           | 11 ++++++--
 src/core/hle/kernel/resource_limit.cpp  |  9 +++++--
 src/core/hle/kernel/resource_limit.h    |  5 ++++
 src/core/hle/kernel/semaphore.cpp       |  4 +--
 src/core/hle/kernel/semaphore.h         |  3 ++-
 src/core/hle/kernel/server_port.cpp     |  9 ++++---
 src/core/hle/kernel/server_port.h       |  3 +++
 src/core/hle/kernel/server_session.cpp  |  8 +++---
 src/core/hle/kernel/server_session.h    |  3 ++-
 src/core/hle/kernel/shared_memory.cpp   |  9 ++++---
 src/core/hle/kernel/shared_memory.h     |  5 +++-
 src/core/hle/kernel/thread.cpp          |  9 +++----
 src/core/hle/kernel/thread.h            |  3 ++-
 src/core/hle/kernel/timer.cpp           |  9 ++++---
 src/core/hle/kernel/timer.h             |  5 +++-
 35 files changed, 158 insertions(+), 113 deletions(-)

diff --git a/TODO b/TODO
index 5a483dc84..be118365d 100644
--- a/TODO
+++ b/TODO
@@ -3,7 +3,7 @@
 ✔ Memory @done(19-08-13 15:41)
     ☐ Page tables
     ☐ Skip N3DS RAM if unused
-✔ DSP @done(19-08-13 15:41)
+☐ DSP
 ✔ Service manager @started(19-12-23 00:36) @done(19-12-23 11:38) @lasted(11h2m3s)
     ✔ Fix or ignore inverse map @done(19-12-23 12:46)
 ☐ App loader
@@ -16,6 +16,7 @@
 ☐ Telemetry session
 ☐ Replace SERIALIZE_AS_POD with BOOST_IS_BITWISE_SERIALIZABLE
 ☐ Review constructor/initialization code
+☐ Fix CI
 ✔ HW @done(19-08-13 15:41)
     ✔ GPU regs @done(19-08-13 15:41)
     ✔ LCD regs @done(19-08-13 15:41)
@@ -78,7 +79,7 @@
         ✔ DSP @done(19-12-26 18:10)
         ✔ ERR @done(19-12-26 18:14)
         ✔ FRD @done(19-12-26 19:09)
-        ☐ FS
+        ✔ FS @done(19-12-27 11:46)
         ☐ GSP
         ☐ HID
         ☐ HTTP
diff --git a/src/audio_core/dsp_interface.h b/src/audio_core/dsp_interface.h
index 29ec13d61..fc3d7cab2 100644
--- a/src/audio_core/dsp_interface.h
+++ b/src/audio_core/dsp_interface.h
@@ -6,7 +6,6 @@
 
 #include <memory>
 #include <vector>
-#include "boost/serialization/array.hpp"
 #include "audio_core/audio_types.h"
 #include "audio_core/time_stretch.h"
 #include "common/common_types.h"
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt
index c0182ed48..ac745d868 100644
--- a/src/common/CMakeLists.txt
+++ b/src/common/CMakeLists.txt
@@ -54,6 +54,7 @@ add_custom_command(OUTPUT scm_rev.cpp
 add_library(common STATIC
     alignment.h
     announce_multiplayer_room.h
+    archives.h
     assert.h
     detached_tasks.cpp
     detached_tasks.h
@@ -66,6 +67,7 @@ add_library(common STATIC
     common_funcs.h
     common_paths.h
     common_types.h
+    construct.h
     file_util.cpp
     file_util.h
     hash.h
@@ -91,8 +93,10 @@ add_library(common STATIC
     scm_rev.h
     scope_exit.h
     serialization/atomic.h
+    serialization/boost_discrete_interval.hpp
     serialization/boost_flat_set.h
     serialization/boost_vector.hpp
+    serialization/optional.h
     string_util.cpp
     string_util.h
     swap.h
diff --git a/src/common/archives.h b/src/common/archives.h
index a27afe80c..74cd9e08f 100644
--- a/src/common/archives.h
+++ b/src/common/archives.h
@@ -6,12 +6,12 @@ using iarchive = boost::archive::binary_iarchive;
 using oarchive = boost::archive::binary_oarchive;
 
 #define SERIALIZE_IMPL(A) template void A::serialize<iarchive>( \
-    iarchive & ar, \
-    const unsigned int file_version \
-); \
-template void A::serialize<oarchive>( \
-    oarchive & ar, \
-    const unsigned int file_version \
+    iarchive & ar,                                              \
+    const unsigned int file_version                             \
+);                                                              \
+template void A::serialize<oarchive>(                           \
+    oarchive & ar,                                              \
+    const unsigned int file_version                             \
 );
 
 #define SERIALIZE_EXPORT_IMPL(A) \
diff --git a/src/common/construct.h b/src/common/construct.h
index 6ef9af1ef..4e230ca43 100644
--- a/src/common/construct.h
+++ b/src/common/construct.h
@@ -12,20 +12,18 @@ public:
     }
 };
 
-#define BOOST_SERIALIZATION_CONSTRUCT(T) \
-namespace boost { namespace serialization { \
-\
-    template<class Archive> \
-    inline void save_construct_data( \
-        Archive & ar, const T * t, const unsigned int file_version \
-    ){ \
-        construct_access::save_construct(ar, t, file_version); \
-    } \
-\
-    template<class Archive> \
-    inline void load_construct_data( \
-        Archive & ar, T * t, const unsigned int file_version \
-    ){ \
-        construct_access::load_construct(ar, t, file_version); \
-    } \
+#define BOOST_SERIALIZATION_CONSTRUCT(T)                          \
+namespace boost { namespace serialization {                       \
+template<class Archive>                                           \
+inline void save_construct_data(                                  \
+    Archive & ar, const T * t, const unsigned int file_version    \
+){                                                                \
+    construct_access::save_construct(ar, t, file_version);        \
+}                                                                 \
+template<class Archive>                                           \
+inline void load_construct_data(                                  \
+    Archive & ar, T * t, const unsigned int file_version          \
+){                                                                \
+    construct_access::load_construct(ar, t, file_version);        \
+}                                                                 \
 }}
diff --git a/src/common/serialization/atomic.h b/src/common/serialization/atomic.h
index ef33202ff..665914df3 100644
--- a/src/common/serialization/atomic.h
+++ b/src/common/serialization/atomic.h
@@ -3,26 +3,26 @@
 #include <atomic>
 #include <boost/serialization/split_free.hpp>
 
-namespace boost::serialization
+namespace boost::serialization {
+
+template <class Archive, class T>
+void serialize(Archive& ar, std::atomic<T>& value, const unsigned int file_version)
 {
-    template <class Archive, class T>
-    void serialize(Archive& ar, std::atomic<T>& value, const unsigned int file_version)
-    {
-        boost::serialization::split_free(ar, value, file_version);
-    }
+    boost::serialization::split_free(ar, value, file_version);
+}
 
-    template <class Archive, class T>
-    void save(Archive& ar, const std::atomic<T>& value, const unsigned int file_version)
-    {
-        ar << value.load();
-    }
+template <class Archive, class T>
+void save(Archive& ar, const std::atomic<T>& value, const unsigned int file_version)
+{
+    ar << value.load();
+}
 
-    template <class Archive, class T>
-    void load(Archive& ar, std::atomic<T>& value, const unsigned int file_version)
-    {
-        T tmp;
-        ar >> tmp;
-        value.store(tmp);
-    }
+template <class Archive, class T>
+void load(Archive& ar, std::atomic<T>& value, const unsigned int file_version)
+{
+    T tmp;
+    ar >> tmp;
+    value.store(tmp);
+}
 
 } // namespace boost::serialization
diff --git a/src/core/core.cpp b/src/core/core.cpp
index 055eadae2..2df38f3ed 100644
--- a/src/core/core.cpp
+++ b/src/core/core.cpp
@@ -4,7 +4,7 @@
 
 #include <memory>
 #include <utility>
-#include "boost/serialization/array.hpp"
+#include <boost/serialization/array.hpp>
 #include "audio_core/dsp_interface.h"
 #include "audio_core/hle/hle.h"
 #include "audio_core/lle/lle.h"
diff --git a/src/core/hle/kernel/address_arbiter.cpp b/src/core/hle/kernel/address_arbiter.cpp
index ca120e6f9..e5e017daa 100644
--- a/src/core/hle/kernel/address_arbiter.cpp
+++ b/src/core/hle/kernel/address_arbiter.cpp
@@ -69,12 +69,11 @@ std::shared_ptr<Thread> AddressArbiter::ResumeHighestPriorityThread(VAddr addres
     return thread;
 }
 
-AddressArbiter::AddressArbiter() : kernel(Core::Global<KernelSystem>()) {}
+AddressArbiter::AddressArbiter(KernelSystem& kernel) : Object(kernel), kernel(kernel) {}
 AddressArbiter::~AddressArbiter() {}
 
 std::shared_ptr<AddressArbiter> KernelSystem::CreateAddressArbiter(std::string name) {
-    auto address_arbiter{std::make_shared<AddressArbiter>()};
-    address_arbiter->Init(*this);
+    auto address_arbiter{std::make_shared<AddressArbiter>(*this)};
 
     address_arbiter->name = std::move(name);
 
diff --git a/src/core/hle/kernel/address_arbiter.h b/src/core/hle/kernel/address_arbiter.h
index 3b29a84a4..793d274ca 100644
--- a/src/core/hle/kernel/address_arbiter.h
+++ b/src/core/hle/kernel/address_arbiter.h
@@ -36,7 +36,7 @@ enum class ArbitrationType : u32 {
 
 class AddressArbiter final : public Object {
 public:
-    explicit AddressArbiter();
+    explicit AddressArbiter(KernelSystem& kernel);
     ~AddressArbiter() override;
 
     std::string GetTypeName() const override {
@@ -85,3 +85,4 @@ private:
 } // namespace Kernel
 
 BOOST_CLASS_EXPORT_KEY(Kernel::AddressArbiter)
+CONSTRUCT_KERNEL_OBJECT(Kernel::AddressArbiter)
diff --git a/src/core/hle/kernel/client_port.cpp b/src/core/hle/kernel/client_port.cpp
index f9202035c..618c7d0d7 100644
--- a/src/core/hle/kernel/client_port.cpp
+++ b/src/core/hle/kernel/client_port.cpp
@@ -17,6 +17,9 @@ SERIALIZE_EXPORT_IMPL(Kernel::ClientPort)
 
 namespace Kernel {
 
+ClientPort::ClientPort(KernelSystem& kernel) : Object(kernel), kernel(kernel) {}
+ClientPort::~ClientPort() = default;
+
 ResultVal<std::shared_ptr<ClientSession>> ClientPort::Connect() {
     // Note: Threads do not wait for the server endpoint to call
     // AcceptSession before returning from this call.
@@ -27,7 +30,7 @@ ResultVal<std::shared_ptr<ClientSession>> ClientPort::Connect() {
     active_sessions++;
 
     // Create a new session pair, let the created sessions inherit the parent port's HLE handler.
-    auto [server, client] = Core::Global<KernelSystem>().CreateSessionPair(server_port->GetName(), SharedFrom(this));
+    auto [server, client] = kernel.CreateSessionPair(server_port->GetName(), SharedFrom(this));
 
     if (server_port->hle_handler)
         server_port->hle_handler->ClientConnected(server);
diff --git a/src/core/hle/kernel/client_port.h b/src/core/hle/kernel/client_port.h
index 72cae85c3..c5b032f1f 100644
--- a/src/core/hle/kernel/client_port.h
+++ b/src/core/hle/kernel/client_port.h
@@ -18,6 +18,8 @@ class ClientSession;
 
 class ClientPort final : public Object {
 public:
+    explicit ClientPort(KernelSystem& kernel);
+    ~ClientPort() override;
 
     friend class ServerPort;
     std::string GetTypeName() const override {
@@ -51,6 +53,7 @@ public:
     void ConnectionClosed();
 
 private:
+    KernelSystem& kernel;
     std::shared_ptr<ServerPort> server_port; ///< ServerPort associated with this client port.
     u32 max_sessions = 0;    ///< Maximum number of simultaneous sessions the port can have
     u32 active_sessions = 0; ///< Number of currently open sessions to this port
@@ -75,3 +78,4 @@ private:
 } // namespace Kernel
 
 BOOST_CLASS_EXPORT_KEY(Kernel::ClientPort)
+CONSTRUCT_KERNEL_OBJECT(Kernel::ClientPort)
diff --git a/src/core/hle/kernel/client_session.cpp b/src/core/hle/kernel/client_session.cpp
index ba9c2ec50..0b00576d3 100644
--- a/src/core/hle/kernel/client_session.cpp
+++ b/src/core/hle/kernel/client_session.cpp
@@ -15,7 +15,7 @@ SERIALIZE_EXPORT_IMPL(Kernel::ClientSession)
 
 namespace Kernel {
 
-ClientSession::ClientSession() = default;
+ClientSession::ClientSession(KernelSystem& kernel) : Object(kernel) {}
 ClientSession::~ClientSession() {
     // This destructor will be called automatically when the last ClientSession handle is closed by
     // the emulated application.
diff --git a/src/core/hle/kernel/client_session.h b/src/core/hle/kernel/client_session.h
index 2ffe68f8b..1ddbfb348 100644
--- a/src/core/hle/kernel/client_session.h
+++ b/src/core/hle/kernel/client_session.h
@@ -20,7 +20,7 @@ class Thread;
 
 class ClientSession final : public Object {
 public:
-    explicit ClientSession();
+    explicit ClientSession(KernelSystem& kernel);
     ~ClientSession() override;
 
     friend class KernelSystem;
@@ -64,3 +64,4 @@ private:
 } // namespace Kernel
 
 BOOST_CLASS_EXPORT_KEY(Kernel::ClientSession)
+CONSTRUCT_KERNEL_OBJECT(Kernel::ClientSession)
diff --git a/src/core/hle/kernel/event.cpp b/src/core/hle/kernel/event.cpp
index 7af667739..2375d6733 100644
--- a/src/core/hle/kernel/event.cpp
+++ b/src/core/hle/kernel/event.cpp
@@ -15,11 +15,11 @@ SERIALIZE_EXPORT_IMPL(Kernel::Event)
 
 namespace Kernel {
 
-Event::Event() : WaitObject() {}
+Event::Event(KernelSystem& kernel) : WaitObject(kernel) {}
 Event::~Event() {}
 
 std::shared_ptr<Event> KernelSystem::CreateEvent(ResetType reset_type, std::string name) {
-    auto evt{std::make_shared<Event>()};
+    auto evt{std::make_shared<Event>(*this)};
 
     evt->signaled = false;
     evt->reset_type = reset_type;
diff --git a/src/core/hle/kernel/event.h b/src/core/hle/kernel/event.h
index bb97f6eb1..509ab5c6c 100644
--- a/src/core/hle/kernel/event.h
+++ b/src/core/hle/kernel/event.h
@@ -13,7 +13,7 @@ namespace Kernel {
 
 class Event final : public WaitObject {
 public:
-    explicit Event();
+    explicit Event(KernelSystem& kernel);
     ~Event() override;
 
     std::string GetTypeName() const override {
@@ -65,3 +65,4 @@ private:
 } // namespace Kernel
 
 BOOST_CLASS_EXPORT_KEY(Kernel::Event)
+CONSTRUCT_KERNEL_OBJECT(Kernel::Event)
diff --git a/src/core/hle/kernel/mutex.cpp b/src/core/hle/kernel/mutex.cpp
index 16bcd3af2..4badd88ce 100644
--- a/src/core/hle/kernel/mutex.cpp
+++ b/src/core/hle/kernel/mutex.cpp
@@ -27,12 +27,11 @@ void ReleaseThreadMutexes(Thread* thread) {
     thread->held_mutexes.clear();
 }
 
-Mutex::Mutex() : kernel(Core::Global<KernelSystem>()) {}
+Mutex::Mutex(KernelSystem& kernel) : WaitObject(kernel), kernel(kernel) {}
 Mutex::~Mutex() {}
 
 std::shared_ptr<Mutex> KernelSystem::CreateMutex(bool initial_locked, std::string name) {
-    auto mutex{std::make_shared<Mutex>()};
-    mutex->Init(*this);
+    auto mutex{std::make_shared<Mutex>(*this)};
 
     mutex->lock_count = 0;
     mutex->name = std::move(name);
diff --git a/src/core/hle/kernel/mutex.h b/src/core/hle/kernel/mutex.h
index f4449c0f2..a164b70da 100644
--- a/src/core/hle/kernel/mutex.h
+++ b/src/core/hle/kernel/mutex.h
@@ -18,7 +18,7 @@ class Thread;
 
 class Mutex final : public WaitObject {
 public:
-    explicit Mutex();
+    explicit Mutex(KernelSystem& kernel);
     ~Mutex() override;
 
     std::string GetTypeName() const override {
@@ -81,3 +81,4 @@ void ReleaseThreadMutexes(Thread* thread);
 } // namespace Kernel
 
 BOOST_CLASS_EXPORT_KEY(Kernel::Mutex)
+CONSTRUCT_KERNEL_OBJECT(Kernel::Mutex)
diff --git a/src/core/hle/kernel/object.cpp b/src/core/hle/kernel/object.cpp
index 6ab1b1769..f9ca68218 100644
--- a/src/core/hle/kernel/object.cpp
+++ b/src/core/hle/kernel/object.cpp
@@ -8,17 +8,7 @@
 
 namespace Kernel {
 
-// TODO: Remove this
-Object::Object(KernelSystem& kernel)
-{
-}
-
-Object::Object() = default;
-
-void Object::Init(KernelSystem& kernel)
-{
-    object_id = kernel.GenerateObjectID();
-}
+Object::Object(KernelSystem& kernel) : object_id{kernel.GenerateObjectID()} {}
 
 Object::~Object() = default;
 
diff --git a/src/core/hle/kernel/object.h b/src/core/hle/kernel/object.h
index 6adba034e..a61e47c17 100644
--- a/src/core/hle/kernel/object.h
+++ b/src/core/hle/kernel/object.h
@@ -8,9 +8,12 @@
 #include <memory>
 #include <string>
 #include <boost/serialization/access.hpp>
+#include <boost/serialization/assume_abstract.hpp>
+#include <boost/serialization/export.hpp>
 #include "common/serialization/atomic.h"
 #include "common/common_types.h"
 #include "core/hle/kernel/kernel.h"
+#include "core/global.h"
 
 namespace Kernel {
 
@@ -43,11 +46,8 @@ enum {
 class Object : NonCopyable, public std::enable_shared_from_this<Object> {
 public:
     explicit Object(KernelSystem& kernel);
-    Object();
     virtual ~Object();
 
-    virtual void Init(KernelSystem& kernel);
-
     /// Returns a unique identifier for the object. For debugging purposes only.
     u32 GetObjectId() const {
         return object_id.load(std::memory_order_relaxed);
@@ -99,3 +99,14 @@ inline std::shared_ptr<T> DynamicObjectCast(std::shared_ptr<Object> object) {
 }
 
 } // namespace Kernel
+
+BOOST_SERIALIZATION_ASSUME_ABSTRACT(Kernel::Object)
+
+#define CONSTRUCT_KERNEL_OBJECT(T)                                \
+namespace boost::serialization {                                  \
+template<class Archive>                                           \
+inline void load_construct_data(                                  \
+    Archive & ar, T * t, const unsigned int file_version          \
+){                                                                \
+    ::new(t)T(Core::Global<Kernel::KernelSystem>());              \
+}}
diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp
index 72f882c56..12afe1f89 100644
--- a/src/core/hle/kernel/process.cpp
+++ b/src/core/hle/kernel/process.cpp
@@ -20,6 +20,9 @@
 #include "core/memory.h"
 #include "core/global.h"
 
+SERIALIZE_EXPORT_IMPL(Kernel::Process)
+SERIALIZE_EXPORT_IMPL(Kernel::CodeSet)
+
 namespace Kernel {
 
 template <class Archive>
@@ -46,8 +49,7 @@ void Process::serialize(Archive& ar, const unsigned int file_version)
 SERIALIZE_IMPL(Process)
 
 std::shared_ptr<CodeSet> KernelSystem::CreateCodeSet(std::string name, u64 program_id) {
-    auto codeset{std::make_shared<CodeSet>()};
-    codeset->Init(*this);
+    auto codeset{std::make_shared<CodeSet>(*this)};
 
     codeset->name = std::move(name);
     codeset->program_id = program_id;
@@ -55,9 +57,11 @@ std::shared_ptr<CodeSet> KernelSystem::CreateCodeSet(std::string name, u64 progr
     return codeset;
 }
 
+CodeSet::CodeSet(KernelSystem& kernel) : Object(kernel) {}
+CodeSet::~CodeSet() {}
+
 std::shared_ptr<Process> KernelSystem::CreateProcess(std::shared_ptr<CodeSet> code_set) {
-    auto process{std::make_shared<Process>()};
-    process->Init(*this);
+    auto process{std::make_shared<Process>(*this)};
 
     process->codeset = std::move(code_set);
     process->flags.raw = 0;
@@ -428,12 +432,8 @@ ResultCode Process::Unmap(VAddr target, VAddr source, u32 size, VMAPermission pe
     return RESULT_SUCCESS;
 }
 
-Kernel::Process::Process() : Kernel::Process::Process(Core::Global<KernelSystem>())
-{
-}
-
-Kernel::Process::Process(KernelSystem& kernel) : kernel(kernel), handle_table(kernel), vm_manager(kernel.memory)
-{
+Kernel::Process::Process(KernelSystem& kernel)
+    : Object(kernel), handle_table(kernel), vm_manager(kernel.memory), kernel(kernel) {
     kernel.memory.RegisterPageTable(&vm_manager.page_table);
 }
 Kernel::Process::~Process() {
diff --git a/src/core/hle/kernel/process.h b/src/core/hle/kernel/process.h
index 70a5f212b..5746a1c6a 100644
--- a/src/core/hle/kernel/process.h
+++ b/src/core/hle/kernel/process.h
@@ -65,6 +65,9 @@ struct MemoryRegionInfo;
 
 class CodeSet final : public Object {
 public:
+    explicit CodeSet(KernelSystem& kernel);
+    ~CodeSet() override;
+
     struct Segment {
         std::size_t offset = 0;
         VAddr addr = 0;
@@ -143,8 +146,7 @@ private:
 
 class Process final : public Object {
 public:
-    Process();
-    explicit Process(KernelSystem& kernel);
+    explicit Process(Kernel::KernelSystem& kernel);
     ~Process() override;
 
     std::string GetTypeName() const override {
@@ -235,3 +237,8 @@ private:
     void serialize(Archive& ar, const unsigned int file_version);
 };
 } // namespace Kernel
+
+BOOST_CLASS_EXPORT_KEY(Kernel::CodeSet)
+BOOST_CLASS_EXPORT_KEY(Kernel::Process)
+CONSTRUCT_KERNEL_OBJECT(Kernel::CodeSet)
+CONSTRUCT_KERNEL_OBJECT(Kernel::Process)
diff --git a/src/core/hle/kernel/resource_limit.cpp b/src/core/hle/kernel/resource_limit.cpp
index fe19caff9..9affa685a 100644
--- a/src/core/hle/kernel/resource_limit.cpp
+++ b/src/core/hle/kernel/resource_limit.cpp
@@ -3,15 +3,20 @@
 // Refer to the license.txt file included.
 
 #include <cstring>
+#include "common/archives.h"
 #include "common/assert.h"
 #include "common/logging/log.h"
 #include "core/hle/kernel/resource_limit.h"
 
+SERIALIZE_EXPORT_IMPL(Kernel::ResourceLimit)
+
 namespace Kernel {
 
+ResourceLimit::ResourceLimit(KernelSystem& kernel) : Object(kernel) {}
+ResourceLimit::~ResourceLimit() {}
+
 std::shared_ptr<ResourceLimit> ResourceLimit::Create(KernelSystem& kernel, std::string name) {
-    auto resource_limit{std::make_shared<ResourceLimit>()};
-    resource_limit->Init(kernel);
+    auto resource_limit{std::make_shared<ResourceLimit>(kernel)};
 
     resource_limit->name = std::move(name);
     return resource_limit;
diff --git a/src/core/hle/kernel/resource_limit.h b/src/core/hle/kernel/resource_limit.h
index 06fe71587..0d64f1216 100644
--- a/src/core/hle/kernel/resource_limit.h
+++ b/src/core/hle/kernel/resource_limit.h
@@ -35,6 +35,8 @@ enum ResourceTypes {
 
 class ResourceLimit final : public Object {
 public:
+    explicit ResourceLimit(KernelSystem& kernel);
+    ~ResourceLimit() override;
 
     /**
      * Creates a resource limit object.
@@ -165,3 +167,6 @@ private:
 };
 
 } // namespace Kernel
+
+BOOST_CLASS_EXPORT_KEY(Kernel::ResourceLimit)
+CONSTRUCT_KERNEL_OBJECT(Kernel::ResourceLimit)
diff --git a/src/core/hle/kernel/semaphore.cpp b/src/core/hle/kernel/semaphore.cpp
index f60a653e5..c637f5f4d 100644
--- a/src/core/hle/kernel/semaphore.cpp
+++ b/src/core/hle/kernel/semaphore.cpp
@@ -13,7 +13,7 @@ SERIALIZE_EXPORT_IMPL(Kernel::Semaphore)
 
 namespace Kernel {
 
-Semaphore::Semaphore() : WaitObject() {}
+Semaphore::Semaphore(KernelSystem& kernel) : WaitObject(kernel) {}
 Semaphore::~Semaphore() {}
 
 ResultVal<std::shared_ptr<Semaphore>> KernelSystem::CreateSemaphore(s32 initial_count,
@@ -23,7 +23,7 @@ ResultVal<std::shared_ptr<Semaphore>> KernelSystem::CreateSemaphore(s32 initial_
     if (initial_count > max_count)
         return ERR_INVALID_COMBINATION_KERNEL;
 
-    auto semaphore{std::make_shared<Semaphore>()};
+    auto semaphore{std::make_shared<Semaphore>(*this)};
 
     // When the semaphore is created, some slots are reserved for other threads,
     // and the rest is reserved for the caller thread
diff --git a/src/core/hle/kernel/semaphore.h b/src/core/hle/kernel/semaphore.h
index ff6a4434a..f28c30ec7 100644
--- a/src/core/hle/kernel/semaphore.h
+++ b/src/core/hle/kernel/semaphore.h
@@ -16,7 +16,7 @@ namespace Kernel {
 
 class Semaphore final : public WaitObject {
 public:
-    explicit Semaphore();
+    explicit Semaphore(KernelSystem& kernel);
     ~Semaphore() override;
 
     std::string GetTypeName() const override {
@@ -60,3 +60,4 @@ private:
 } // namespace Kernel
 
 BOOST_CLASS_EXPORT_KEY(Kernel::Semaphore)
+CONSTRUCT_KERNEL_OBJECT(Kernel::Semaphore)
diff --git a/src/core/hle/kernel/server_port.cpp b/src/core/hle/kernel/server_port.cpp
index 0aeb86a78..46aa8f758 100644
--- a/src/core/hle/kernel/server_port.cpp
+++ b/src/core/hle/kernel/server_port.cpp
@@ -17,6 +17,9 @@ SERIALIZE_EXPORT_IMPL(Kernel::ServerPort)
 
 namespace Kernel {
 
+ServerPort::ServerPort(KernelSystem& kernel) : WaitObject(kernel) {}
+ServerPort::~ServerPort() {}
+
 ResultVal<std::shared_ptr<ServerSession>> ServerPort::Accept() {
     if (pending_sessions.empty()) {
         return ERR_NO_PENDING_SESSIONS;
@@ -37,10 +40,8 @@ void ServerPort::Acquire(Thread* thread) {
 }
 
 KernelSystem::PortPair KernelSystem::CreatePortPair(u32 max_sessions, std::string name) {
-    auto server_port{std::make_shared<ServerPort>()};
-    server_port->Init(*this);
-    auto client_port{std::make_shared<ClientPort>()};
-    client_port->Init(*this);
+    auto server_port{std::make_shared<ServerPort>(*this)};
+    auto client_port{std::make_shared<ClientPort>(*this)};
 
     server_port->name = name + "_Server";
     client_port->name = name + "_Client";
diff --git a/src/core/hle/kernel/server_port.h b/src/core/hle/kernel/server_port.h
index f055cd267..2f00e586e 100644
--- a/src/core/hle/kernel/server_port.h
+++ b/src/core/hle/kernel/server_port.h
@@ -25,6 +25,8 @@ class SessionRequestHandler;
 
 class ServerPort final : public WaitObject {
 public:
+    explicit ServerPort(KernelSystem& kernel);
+    ~ServerPort() override;
 
     std::string GetTypeName() const override {
         return "ServerPort";
@@ -73,3 +75,4 @@ private:
 } // namespace Kernel
 
 BOOST_CLASS_EXPORT_KEY(Kernel::ServerPort)
+CONSTRUCT_KERNEL_OBJECT(Kernel::ServerPort)
diff --git a/src/core/hle/kernel/server_session.cpp b/src/core/hle/kernel/server_session.cpp
index 146142f08..e0c4087f1 100644
--- a/src/core/hle/kernel/server_session.cpp
+++ b/src/core/hle/kernel/server_session.cpp
@@ -16,7 +16,7 @@ SERIALIZE_EXPORT_IMPL(Kernel::ServerSession)
 
 namespace Kernel {
 
-ServerSession::ServerSession() : kernel(Core::Global<KernelSystem>()) {}
+ServerSession::ServerSession(KernelSystem& kernel) : WaitObject(kernel), kernel(kernel) {}
 ServerSession::~ServerSession() {
     // This destructor will be called automatically when the last ServerSession handle is closed by
     // the emulated application.
@@ -33,8 +33,7 @@ ServerSession::~ServerSession() {
 
 ResultVal<std::shared_ptr<ServerSession>> ServerSession::Create(KernelSystem& kernel,
                                                                 std::string name) {
-    auto server_session{std::make_shared<ServerSession>()};
-    server_session->Init(kernel);
+    auto server_session{std::make_shared<ServerSession>(kernel)};
 
     server_session->name = std::move(name);
     server_session->parent = nullptr;
@@ -127,8 +126,7 @@ ResultCode ServerSession::HandleSyncRequest(std::shared_ptr<Thread> thread) {
 KernelSystem::SessionPair KernelSystem::CreateSessionPair(const std::string& name,
                                                           std::shared_ptr<ClientPort> port) {
     auto server_session = ServerSession::Create(*this, name + "_Server").Unwrap();
-    auto client_session{std::make_shared<ClientSession>()};
-    client_session->Init(*this);
+    auto client_session{std::make_shared<ClientSession>(*this)};
     client_session->name = name + "_Client";
 
     std::shared_ptr<Session> parent(new Session);
diff --git a/src/core/hle/kernel/server_session.h b/src/core/hle/kernel/server_session.h
index 05b469c38..6eb5673f6 100644
--- a/src/core/hle/kernel/server_session.h
+++ b/src/core/hle/kernel/server_session.h
@@ -42,7 +42,7 @@ class Thread;
 class ServerSession final : public WaitObject {
 public:
     ~ServerSession() override;
-    explicit ServerSession();
+    explicit ServerSession(KernelSystem& kernel);
 
     std::string GetName() const override {
         return name;
@@ -125,3 +125,4 @@ private:
 } // namespace Kernel
 
 BOOST_CLASS_EXPORT_KEY(Kernel::ServerSession)
+CONSTRUCT_KERNEL_OBJECT(Kernel::ServerSession)
diff --git a/src/core/hle/kernel/shared_memory.cpp b/src/core/hle/kernel/shared_memory.cpp
index c76cdfa19..14c9751e8 100644
--- a/src/core/hle/kernel/shared_memory.cpp
+++ b/src/core/hle/kernel/shared_memory.cpp
@@ -3,6 +3,7 @@
 // Refer to the license.txt file included.
 
 #include <cstring>
+#include "common/archives.h"
 #include "common/logging/log.h"
 #include "core/hle/kernel/errors.h"
 #include "core/hle/kernel/memory.h"
@@ -10,9 +11,11 @@
 #include "core/memory.h"
 #include "core/global.h"
 
+SERIALIZE_EXPORT_IMPL(Kernel::SharedMemory)
+
 namespace Kernel {
 
-SharedMemory::SharedMemory() : Object(Core::Global<KernelSystem>()), kernel(Core::Global<KernelSystem>()) {}
+SharedMemory::SharedMemory(KernelSystem& kernel) : Object(kernel), kernel(kernel) {}
 SharedMemory::~SharedMemory() {
     for (const auto& interval : holding_memory) {
         kernel.GetMemoryRegion(MemoryRegion::SYSTEM)
@@ -28,7 +31,7 @@ SharedMemory::~SharedMemory() {
 ResultVal<std::shared_ptr<SharedMemory>> KernelSystem::CreateSharedMemory(
     Process* owner_process, u32 size, MemoryPermission permissions,
     MemoryPermission other_permissions, VAddr address, MemoryRegion region, std::string name) {
-    auto shared_memory{std::make_shared<SharedMemory>()};
+    auto shared_memory{std::make_shared<SharedMemory>(*this)};
 
     shared_memory->owner_process = owner_process;
     shared_memory->name = std::move(name);
@@ -73,7 +76,7 @@ ResultVal<std::shared_ptr<SharedMemory>> KernelSystem::CreateSharedMemory(
 std::shared_ptr<SharedMemory> KernelSystem::CreateSharedMemoryForApplet(
     u32 offset, u32 size, MemoryPermission permissions, MemoryPermission other_permissions,
     std::string name) {
-    auto shared_memory{std::make_shared<SharedMemory>()};
+    auto shared_memory{std::make_shared<SharedMemory>(*this)};
 
     // Allocate memory in heap
     MemoryRegionInfo* memory_region = GetMemoryRegion(MemoryRegion::SYSTEM);
diff --git a/src/core/hle/kernel/shared_memory.h b/src/core/hle/kernel/shared_memory.h
index 925f7783c..88727be6d 100644
--- a/src/core/hle/kernel/shared_memory.h
+++ b/src/core/hle/kernel/shared_memory.h
@@ -16,7 +16,7 @@ namespace Kernel {
 
 class SharedMemory final : public Object {
 public:
-    explicit SharedMemory();
+    explicit SharedMemory(KernelSystem& kernel);
     ~SharedMemory() override;
 
     std::string GetTypeName() const override {
@@ -123,3 +123,6 @@ private:
 };
 
 } // namespace Kernel
+
+BOOST_CLASS_EXPORT_KEY(Kernel::SharedMemory)
+CONSTRUCT_KERNEL_OBJECT(Kernel::SharedMemory)
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp
index 98fe85175..c824b58a6 100644
--- a/src/core/hle/kernel/thread.cpp
+++ b/src/core/hle/kernel/thread.cpp
@@ -66,9 +66,9 @@ u32 ThreadManager::NewThreadId() {
     return next_thread_id++;
 }
 
-Thread::Thread()
-    : context(Core::Global<KernelSystem>().GetThreadManager().NewContext()),
-      thread_manager(Core::Global<KernelSystem>().GetThreadManager()) {}
+Thread::Thread(KernelSystem& kernel)
+    : WaitObject(kernel), context(kernel.GetThreadManager().NewContext()),
+      thread_manager(kernel.GetThreadManager()) {}
 Thread::~Thread() {}
 
 Thread* ThreadManager::GetCurrentThread() const {
@@ -338,8 +338,7 @@ ResultVal<std::shared_ptr<Thread>> KernelSystem::CreateThread(std::string name,
                           ErrorSummary::InvalidArgument, ErrorLevel::Permanent);
     }
 
-    auto thread{std::make_shared<Thread>()};
-    thread->Init(*this);
+    auto thread{std::make_shared<Thread>(*this)};
 
     thread_manager->thread_list.push_back(thread);
     thread_manager->ready_queue.prepare(priority);
diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h
index b423392e3..09341560a 100644
--- a/src/core/hle/kernel/thread.h
+++ b/src/core/hle/kernel/thread.h
@@ -164,7 +164,7 @@ private:
 
 class Thread final : public WaitObject {
 public:
-    explicit Thread();
+    explicit Thread(KernelSystem&);
     ~Thread() override;
 
     std::string GetName() const override {
@@ -340,3 +340,4 @@ std::shared_ptr<Thread> SetupMainThread(KernelSystem& kernel, u32 entry_point, u
 } // namespace Kernel
 
 BOOST_CLASS_EXPORT_KEY(Kernel::Thread)
+CONSTRUCT_KERNEL_OBJECT(Kernel::Thread)
diff --git a/src/core/hle/kernel/timer.cpp b/src/core/hle/kernel/timer.cpp
index 422cf990c..f1a31cdf9 100644
--- a/src/core/hle/kernel/timer.cpp
+++ b/src/core/hle/kernel/timer.cpp
@@ -4,6 +4,7 @@
 
 #include <cinttypes>
 #include <unordered_map>
+#include "common/archives.h"
 #include "common/assert.h"
 #include "common/logging/log.h"
 #include "core/core.h"
@@ -13,17 +14,19 @@
 #include "core/hle/kernel/timer.h"
 #include "core/global.h"
 
+SERIALIZE_EXPORT_IMPL(Kernel::Timer)
+
 namespace Kernel {
 
-Timer::Timer() : kernel(Core::Global<KernelSystem>()), timer_manager(Core::Global<KernelSystem>().GetTimerManager()) {}
+Timer::Timer(KernelSystem& kernel)
+    : WaitObject(kernel), kernel(kernel), timer_manager(kernel.GetTimerManager()) {}
 Timer::~Timer() {
     Cancel();
     timer_manager.timer_callback_table.erase(callback_id);
 }
 
 std::shared_ptr<Timer> KernelSystem::CreateTimer(ResetType reset_type, std::string name) {
-    auto timer{std::make_shared<Timer>()};
-    timer->Init(*this);
+    auto timer{std::make_shared<Timer>(*this)};
 
     timer->reset_type = reset_type;
     timer->signaled = false;
diff --git a/src/core/hle/kernel/timer.h b/src/core/hle/kernel/timer.h
index 690350611..f61ec1c11 100644
--- a/src/core/hle/kernel/timer.h
+++ b/src/core/hle/kernel/timer.h
@@ -46,7 +46,7 @@ private:
 
 class Timer final : public WaitObject {
 public:
-    explicit Timer();
+    explicit Timer(KernelSystem& kernel);
     ~Timer() override;
 
     std::string GetTypeName() const override {
@@ -127,3 +127,6 @@ private:
 };
 
 } // namespace Kernel
+
+BOOST_CLASS_EXPORT_KEY(Kernel::Timer)
+CONSTRUCT_KERNEL_OBJECT(Kernel::Timer)