diff --git a/src/backend/x64/a32_emit_x64.h b/src/backend/x64/a32_emit_x64.h index 119b0517..e7068c4b 100644 --- a/src/backend/x64/a32_emit_x64.h +++ b/src/backend/x64/a32_emit_x64.h @@ -46,6 +46,7 @@ protected: const A32::UserConfig config; A32::Jit* jit_interface; BlockRangeInformation block_ranges; + ExceptionHandler exception_handler; struct FastDispatchEntry { u64 location_descriptor; diff --git a/src/backend/x64/block_of_code.cpp b/src/backend/x64/block_of_code.cpp index 103d8168..079a5cfa 100644 --- a/src/backend/x64/block_of_code.cpp +++ b/src/backend/x64/block_of_code.cpp @@ -83,7 +83,6 @@ BlockOfCode::BlockOfCode(RunCodeCallbacks cb, JitStateInfo jsi) { EnableWriting(); GenRunCode(); - exception_handler.Register(*this); } void BlockOfCode::PreludeComplete() { @@ -286,6 +285,10 @@ CodePtr BlockOfCode::GetCodeBegin() const { return near_code_begin; } +size_t BlockOfCode::GetTotalCodeSize() const { + return maxSize_; +} + void* BlockOfCode::AllocateFromCodeSpace(size_t alloc_size) { if (size_ + alloc_size >= maxSize_) { throw Xbyak::Error(Xbyak::ERR_CODE_IS_TOO_BIG); diff --git a/src/backend/x64/block_of_code.h b/src/backend/x64/block_of_code.h index ee405bbe..171efa68 100644 --- a/src/backend/x64/block_of_code.h +++ b/src/backend/x64/block_of_code.h @@ -98,6 +98,7 @@ public: void SwitchToNearCode(); CodePtr GetCodeBegin() const; + size_t GetTotalCodeSize() const; const void* GetReturnFromRunCodeAddress() const { return return_from_run_code[0]; @@ -163,18 +164,6 @@ private: std::array return_from_run_code; void GenRunCode(); - class ExceptionHandler final { - public: - ExceptionHandler(); - ~ExceptionHandler(); - - void Register(BlockOfCode& code); - private: - struct Impl; - std::unique_ptr impl; - }; - ExceptionHandler exception_handler; - Xbyak::util::Cpu cpu_info; }; diff --git a/src/backend/x64/emit_x64.cpp b/src/backend/x64/emit_x64.cpp index 1a50677b..2bc269c3 100644 --- a/src/backend/x64/emit_x64.cpp +++ b/src/backend/x64/emit_x64.cpp @@ -33,8 +33,9 @@ void EmitContext::EraseInstruction(IR::Inst* inst) { inst->ClearArgs(); } -EmitX64::EmitX64(BlockOfCode& code) - : code(code) {} +EmitX64::EmitX64(BlockOfCode& code) : code(code) { + exception_handler.Register(code); +} EmitX64::~EmitX64() = default; diff --git a/src/backend/x64/emit_x64.h b/src/backend/x64/emit_x64.h index 28a65ff1..dddf0ef4 100644 --- a/src/backend/x64/emit_x64.h +++ b/src/backend/x64/emit_x64.h @@ -16,6 +16,7 @@ #include +#include "backend/x64/exception_handler.h" #include "backend/x64/reg_alloc.h" #include "common/bit_util.h" #include "common/fp/fpcr.h" @@ -58,7 +59,7 @@ public: size_t size; // Length in bytes of emitted code }; - EmitX64(BlockOfCode& code); + explicit EmitX64(BlockOfCode& code); virtual ~EmitX64(); /// Looks up an emitted host block in the cache. @@ -114,6 +115,7 @@ protected: // State BlockOfCode& code; + ExceptionHandler exception_handler; std::unordered_map block_descriptors; std::unordered_map patch_information; }; diff --git a/src/backend/x64/exception_handler.h b/src/backend/x64/exception_handler.h new file mode 100644 index 00000000..c205949b --- /dev/null +++ b/src/backend/x64/exception_handler.h @@ -0,0 +1,26 @@ +/* This file is part of the dynarmic project. + * Copyright (c) 2020 MerryMage + * This software may be used and distributed according to the terms of the GNU + * General Public License version 2 or any later version. + */ + +#pragma once + +#include + +namespace Dynarmic::Backend::X64 { + +class BlockOfCode; + +class ExceptionHandler final { +public: + ExceptionHandler(); + ~ExceptionHandler(); + + void Register(BlockOfCode& code); +private: + struct Impl; + std::unique_ptr impl; +}; + +} // namespace Dynarmic::Backend::X64 diff --git a/src/backend/x64/exception_handler_generic.cpp b/src/backend/x64/exception_handler_generic.cpp index e801cf45..ae9986be 100644 --- a/src/backend/x64/exception_handler_generic.cpp +++ b/src/backend/x64/exception_handler_generic.cpp @@ -4,17 +4,17 @@ * General Public License version 2 or any later version. */ -#include "backend/x64/block_of_code.h" +#include "backend/x64/exception_handler.h" namespace Dynarmic::Backend::X64 { -struct BlockOfCode::ExceptionHandler::Impl final { +struct ExceptionHandler::Impl final { }; -BlockOfCode::ExceptionHandler::ExceptionHandler() = default; -BlockOfCode::ExceptionHandler::~ExceptionHandler() = default; +ExceptionHandler::ExceptionHandler() = default; +ExceptionHandler::~ExceptionHandler() = default; -void BlockOfCode::ExceptionHandler::Register(BlockOfCode&) { +void ExceptionHandler::Register(BlockOfCode&) { // Do nothing } diff --git a/src/backend/x64/exception_handler_windows.cpp b/src/backend/x64/exception_handler_windows.cpp index 15b1a087..1fed9f47 100644 --- a/src/backend/x64/exception_handler_windows.cpp +++ b/src/backend/x64/exception_handler_windows.cpp @@ -11,6 +11,7 @@ #include #include "backend/x64/block_of_code.h" +#include "backend/x64/exception_handler.h" #include "common/assert.h" #include "common/common_types.h" @@ -156,7 +157,7 @@ static PrologueInformation GetPrologueInformation() { return ret; } -struct BlockOfCode::ExceptionHandler::Impl final { +struct ExceptionHandler::Impl final { Impl(RUNTIME_FUNCTION* rfuncs_, const u8* base_ptr) : rfuncs(rfuncs_) { RtlAddFunctionTable(rfuncs, 1, reinterpret_cast(base_ptr)); } @@ -169,10 +170,10 @@ private: RUNTIME_FUNCTION* rfuncs = nullptr; }; -BlockOfCode::ExceptionHandler::ExceptionHandler() = default; -BlockOfCode::ExceptionHandler::~ExceptionHandler() = default; +ExceptionHandler::ExceptionHandler() = default; +ExceptionHandler::~ExceptionHandler() = default; -void BlockOfCode::ExceptionHandler::Register(BlockOfCode& code) { +void ExceptionHandler::Register(BlockOfCode& code) { const auto prolog_info = GetPrologueInformation(); code.align(16); @@ -190,8 +191,8 @@ void BlockOfCode::ExceptionHandler::Register(BlockOfCode& code) { code.align(16); RUNTIME_FUNCTION* rfuncs = static_cast(code.AllocateFromCodeSpace(sizeof(RUNTIME_FUNCTION))); - rfuncs->BeginAddress = static_cast(reinterpret_cast(code.run_code) - code.getCode()); - rfuncs->EndAddress = static_cast(code.maxSize_); + rfuncs->BeginAddress = static_cast(0); + rfuncs->EndAddress = static_cast(code.GetTotalCodeSize()); rfuncs->UnwindData = static_cast(reinterpret_cast(unwind_info) - code.getCode()); impl = std::make_unique(rfuncs, code.getCode());