From 52dae41d7f5774fb7efbfcfaf355ac5a747612f2 Mon Sep 17 00:00:00 2001
From: MerryMage <MerryMage@users.noreply.github.com>
Date: Wed, 24 Mar 2021 11:08:41 +0000
Subject: [PATCH] arm_dynarmic: Always have a 'valid' jit instance

---
 src/core/arm/dynarmic/arm_dynarmic_32.cpp | 31 +++++-------------
 src/core/arm/dynarmic/arm_dynarmic_32.h   |  5 ++-
 src/core/arm/dynarmic/arm_dynarmic_64.cpp | 38 ++++++++---------------
 src/core/arm/dynarmic/arm_dynarmic_64.h   |  5 +--
 4 files changed, 26 insertions(+), 53 deletions(-)

diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.cpp b/src/core/arm/dynarmic/arm_dynarmic_32.cpp
index 53d78de32..4b2a62b4f 100644
--- a/src/core/arm/dynarmic/arm_dynarmic_32.cpp
+++ b/src/core/arm/dynarmic/arm_dynarmic_32.cpp
@@ -114,18 +114,17 @@ public:
     static constexpr u64 minimum_run_cycles = 1000U;
 };
 
-std::shared_ptr<Dynarmic::A32::Jit> ARM_Dynarmic_32::MakeJit(Common::PageTable& page_table,
-                                                             std::size_t address_space_bits) const {
+std::shared_ptr<Dynarmic::A32::Jit> ARM_Dynarmic_32::MakeJit(Common::PageTable* page_table) const {
     Dynarmic::A32::UserConfig config;
     config.callbacks = cb.get();
-    // TODO(bunnei): Implement page table for 32-bit
-    // config.page_table = &page_table.pointers;
     config.coprocessors[15] = cp15;
     config.define_unpredictable_behaviour = true;
     static constexpr std::size_t PAGE_BITS = 12;
     static constexpr std::size_t NUM_PAGE_TABLE_ENTRIES = 1 << (32 - PAGE_BITS);
-    config.page_table = reinterpret_cast<std::array<std::uint8_t*, NUM_PAGE_TABLE_ENTRIES>*>(
-        page_table.pointers.data());
+    if (page_table) {
+        config.page_table = reinterpret_cast<std::array<std::uint8_t*, NUM_PAGE_TABLE_ENTRIES>*>(
+            page_table->pointers.data());
+    }
     config.absolute_offset_page_table = true;
     config.page_table_pointer_mask_bits = Common::PageTable::ATTRIBUTE_BITS;
     config.detect_misaligned_access_via_page_table = 16 | 32 | 64 | 128;
@@ -201,7 +200,8 @@ ARM_Dynarmic_32::ARM_Dynarmic_32(System& system, CPUInterrupts& interrupt_handle
     : ARM_Interface{system, interrupt_handlers, uses_wall_clock},
       cb(std::make_unique<DynarmicCallbacks32>(*this)),
       cp15(std::make_shared<DynarmicCP15>(*this)), core_index{core_index},
-      exclusive_monitor{dynamic_cast<DynarmicExclusiveMonitor&>(exclusive_monitor)} {}
+      exclusive_monitor{dynamic_cast<DynarmicExclusiveMonitor&>(exclusive_monitor)},
+      jit(MakeJit(nullptr)) {}
 
 ARM_Dynarmic_32::~ARM_Dynarmic_32() = default;
 
@@ -256,9 +256,6 @@ void ARM_Dynarmic_32::ChangeProcessorID(std::size_t new_core_id) {
 }
 
 void ARM_Dynarmic_32::SaveContext(ThreadContext32& ctx) {
-    if (!jit) {
-        return;
-    }
     Dynarmic::A32::Context context;
     jit->SaveContext(context);
     ctx.cpu_registers = context.Regs();
@@ -268,9 +265,6 @@ void ARM_Dynarmic_32::SaveContext(ThreadContext32& ctx) {
 }
 
 void ARM_Dynarmic_32::LoadContext(const ThreadContext32& ctx) {
-    if (!jit) {
-        return;
-    }
     Dynarmic::A32::Context context;
     context.Regs() = ctx.cpu_registers;
     context.ExtRegs() = ctx.extension_registers;
@@ -284,23 +278,14 @@ void ARM_Dynarmic_32::PrepareReschedule() {
 }
 
 void ARM_Dynarmic_32::ClearInstructionCache() {
-    if (!jit) {
-        return;
-    }
     jit->ClearCache();
 }
 
 void ARM_Dynarmic_32::InvalidateCacheRange(VAddr addr, std::size_t size) {
-    if (!jit) {
-        return;
-    }
     jit->InvalidateCacheRange(static_cast<u32>(addr), size);
 }
 
 void ARM_Dynarmic_32::ClearExclusiveState() {
-    if (!jit) {
-        return;
-    }
     jit->ClearExclusiveState();
 }
 
@@ -316,7 +301,7 @@ void ARM_Dynarmic_32::PageTableChanged(Common::PageTable& page_table,
         LoadContext(ctx);
         return;
     }
-    jit = MakeJit(page_table, new_address_space_size_in_bits);
+    jit = MakeJit(&page_table);
     LoadContext(ctx);
     jit_cache.emplace(key, jit);
 }
diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.h b/src/core/arm/dynarmic/arm_dynarmic_32.h
index f6c4d4db9..d40aef7a9 100644
--- a/src/core/arm/dynarmic/arm_dynarmic_32.h
+++ b/src/core/arm/dynarmic/arm_dynarmic_32.h
@@ -68,8 +68,7 @@ public:
                           std::size_t new_address_space_size_in_bits) override;
 
 private:
-    std::shared_ptr<Dynarmic::A32::Jit> MakeJit(Common::PageTable& page_table,
-                                                std::size_t address_space_bits) const;
+    std::shared_ptr<Dynarmic::A32::Jit> MakeJit(Common::PageTable* page_table) const;
 
     using JitCacheKey = std::pair<Common::PageTable*, std::size_t>;
     using JitCacheType =
@@ -80,10 +79,10 @@ private:
 
     std::unique_ptr<DynarmicCallbacks32> cb;
     JitCacheType jit_cache;
-    std::shared_ptr<Dynarmic::A32::Jit> jit;
     std::shared_ptr<DynarmicCP15> cp15;
     std::size_t core_index;
     DynarmicExclusiveMonitor& exclusive_monitor;
+    std::shared_ptr<Dynarmic::A32::Jit> jit;
 };
 
 } // namespace Core
diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.cpp b/src/core/arm/dynarmic/arm_dynarmic_64.cpp
index b36b7d918..083c2bdee 100644
--- a/src/core/arm/dynarmic/arm_dynarmic_64.cpp
+++ b/src/core/arm/dynarmic/arm_dynarmic_64.cpp
@@ -142,7 +142,7 @@ public:
     static constexpr u64 minimum_run_cycles = 1000U;
 };
 
-std::shared_ptr<Dynarmic::A64::Jit> ARM_Dynarmic_64::MakeJit(Common::PageTable& page_table,
+std::shared_ptr<Dynarmic::A64::Jit> ARM_Dynarmic_64::MakeJit(Common::PageTable* page_table,
                                                              std::size_t address_space_bits) const {
     Dynarmic::A64::UserConfig config;
 
@@ -150,13 +150,15 @@ std::shared_ptr<Dynarmic::A64::Jit> ARM_Dynarmic_64::MakeJit(Common::PageTable&
     config.callbacks = cb.get();
 
     // Memory
-    config.page_table = reinterpret_cast<void**>(page_table.pointers.data());
-    config.page_table_address_space_bits = address_space_bits;
-    config.page_table_pointer_mask_bits = Common::PageTable::ATTRIBUTE_BITS;
-    config.silently_mirror_page_table = false;
-    config.absolute_offset_page_table = true;
-    config.detect_misaligned_access_via_page_table = 16 | 32 | 64 | 128;
-    config.only_detect_misalignment_via_page_table_on_page_boundary = true;
+    if (page_table) {
+        config.page_table = reinterpret_cast<void**>(page_table->pointers.data());
+        config.page_table_address_space_bits = address_space_bits;
+        config.page_table_pointer_mask_bits = Common::PageTable::ATTRIBUTE_BITS;
+        config.silently_mirror_page_table = false;
+        config.absolute_offset_page_table = true;
+        config.detect_misaligned_access_via_page_table = 16 | 32 | 64 | 128;
+        config.only_detect_misalignment_via_page_table_on_page_boundary = true;
+    }
 
     // Multi-process state
     config.processor_id = core_index;
@@ -237,7 +239,8 @@ ARM_Dynarmic_64::ARM_Dynarmic_64(System& system, CPUInterrupts& interrupt_handle
                                  std::size_t core_index)
     : ARM_Interface{system, interrupt_handlers, uses_wall_clock},
       cb(std::make_unique<DynarmicCallbacks64>(*this)), core_index{core_index},
-      exclusive_monitor{dynamic_cast<DynarmicExclusiveMonitor&>(exclusive_monitor)} {}
+      exclusive_monitor{dynamic_cast<DynarmicExclusiveMonitor&>(exclusive_monitor)},
+      jit(MakeJit(nullptr, 48)) {}
 
 ARM_Dynarmic_64::~ARM_Dynarmic_64() = default;
 
@@ -294,9 +297,6 @@ void ARM_Dynarmic_64::ChangeProcessorID(std::size_t new_core_id) {
 }
 
 void ARM_Dynarmic_64::SaveContext(ThreadContext64& ctx) {
-    if (!jit) {
-        return;
-    }
     ctx.cpu_registers = jit->GetRegisters();
     ctx.sp = jit->GetSP();
     ctx.pc = jit->GetPC();
@@ -308,9 +308,6 @@ void ARM_Dynarmic_64::SaveContext(ThreadContext64& ctx) {
 }
 
 void ARM_Dynarmic_64::LoadContext(const ThreadContext64& ctx) {
-    if (!jit) {
-        return;
-    }
     jit->SetRegisters(ctx.cpu_registers);
     jit->SetSP(ctx.sp);
     jit->SetPC(ctx.pc);
@@ -326,23 +323,14 @@ void ARM_Dynarmic_64::PrepareReschedule() {
 }
 
 void ARM_Dynarmic_64::ClearInstructionCache() {
-    if (!jit) {
-        return;
-    }
     jit->ClearCache();
 }
 
 void ARM_Dynarmic_64::InvalidateCacheRange(VAddr addr, std::size_t size) {
-    if (!jit) {
-        return;
-    }
     jit->InvalidateCacheRange(addr, size);
 }
 
 void ARM_Dynarmic_64::ClearExclusiveState() {
-    if (!jit) {
-        return;
-    }
     jit->ClearExclusiveState();
 }
 
@@ -358,7 +346,7 @@ void ARM_Dynarmic_64::PageTableChanged(Common::PageTable& page_table,
         LoadContext(ctx);
         return;
     }
-    jit = MakeJit(page_table, new_address_space_size_in_bits);
+    jit = MakeJit(&page_table, new_address_space_size_in_bits);
     LoadContext(ctx);
     jit_cache.emplace(key, jit);
 }
diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.h b/src/core/arm/dynarmic/arm_dynarmic_64.h
index 329b59a32..edef04376 100644
--- a/src/core/arm/dynarmic/arm_dynarmic_64.h
+++ b/src/core/arm/dynarmic/arm_dynarmic_64.h
@@ -61,7 +61,7 @@ public:
                           std::size_t new_address_space_size_in_bits) override;
 
 private:
-    std::shared_ptr<Dynarmic::A64::Jit> MakeJit(Common::PageTable& page_table,
+    std::shared_ptr<Dynarmic::A64::Jit> MakeJit(Common::PageTable* page_table,
                                                 std::size_t address_space_bits) const;
 
     using JitCacheKey = std::pair<Common::PageTable*, std::size_t>;
@@ -71,10 +71,11 @@ private:
     friend class DynarmicCallbacks64;
     std::unique_ptr<DynarmicCallbacks64> cb;
     JitCacheType jit_cache;
-    std::shared_ptr<Dynarmic::A64::Jit> jit;
 
     std::size_t core_index;
     DynarmicExclusiveMonitor& exclusive_monitor;
+
+    std::shared_ptr<Dynarmic::A64::Jit> jit;
 };
 
 } // namespace Core