mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-22 10:42:36 +01:00
Reimplement ASMJIT runtime
Try to emplace generated code in lower address area. Protect generated code from writing.
This commit is contained in:
parent
a0d95a823e
commit
3d980a9f66
@ -194,10 +194,75 @@ void jit_runtime::finalize() noexcept
|
|||||||
std::memcpy(alloc(s_data_init.size(), 1, false), s_data_init.data(), s_data_init.size());
|
std::memcpy(alloc(s_data_init.size(), 1, false), s_data_init.data(), s_data_init.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
asmjit::JitRuntime& asmjit::get_global_runtime()
|
asmjit::Runtime& asmjit::get_global_runtime()
|
||||||
{
|
{
|
||||||
|
// 16 MiB for internal needs
|
||||||
|
static constexpr u64 size = 1024 * 1024 * 16;
|
||||||
|
|
||||||
|
struct custom_runtime final : asmjit::HostRuntime
|
||||||
|
{
|
||||||
|
custom_runtime() noexcept
|
||||||
|
{
|
||||||
|
// Search starting in first 2 GiB of memory
|
||||||
|
for (u64 addr = size;; addr += size)
|
||||||
|
{
|
||||||
|
if (auto ptr = utils::memory_reserve(size, reinterpret_cast<void*>(addr)))
|
||||||
|
{
|
||||||
|
m_pos.raw() = static_cast<std::byte*>(ptr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize "end" pointer
|
||||||
|
m_max = m_pos + size;
|
||||||
|
|
||||||
|
// Make memory writable + executable
|
||||||
|
utils::memory_commit(m_pos, size, utils::protection::wx);
|
||||||
|
}
|
||||||
|
|
||||||
|
asmjit::Error _add(void** dst, asmjit::CodeHolder* code) noexcept override
|
||||||
|
{
|
||||||
|
std::size_t codeSize = code->getCodeSize();
|
||||||
|
if (!codeSize) [[unlikely]]
|
||||||
|
{
|
||||||
|
*dst = nullptr;
|
||||||
|
return asmjit::kErrorNoCodeGenerated;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* p = m_pos.fetch_add(::align(codeSize, 4096));
|
||||||
|
if (!p || m_pos > m_max) [[unlikely]]
|
||||||
|
{
|
||||||
|
*dst = nullptr;
|
||||||
|
return asmjit::kErrorNoVirtualMemory;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t relocSize = code->relocate(p);
|
||||||
|
if (!relocSize) [[unlikely]]
|
||||||
|
{
|
||||||
|
*dst = nullptr;
|
||||||
|
return asmjit::kErrorInvalidState;
|
||||||
|
}
|
||||||
|
|
||||||
|
utils::memory_protect(p, ::align(codeSize, 4096), utils::protection::rx);
|
||||||
|
flush(p, relocSize);
|
||||||
|
*dst = p;
|
||||||
|
|
||||||
|
return asmjit::kErrorOk;
|
||||||
|
}
|
||||||
|
|
||||||
|
asmjit::Error _release(void* ptr) noexcept override
|
||||||
|
{
|
||||||
|
return asmjit::kErrorOk;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
atomic_t<std::byte*> m_pos{};
|
||||||
|
|
||||||
|
std::byte* m_max{};
|
||||||
|
};
|
||||||
|
|
||||||
// Magic static
|
// Magic static
|
||||||
static asmjit::JitRuntime g_rt;
|
static custom_runtime g_rt;
|
||||||
return g_rt;
|
return g_rt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@ struct jit_runtime final : asmjit::HostRuntime
|
|||||||
namespace asmjit
|
namespace asmjit
|
||||||
{
|
{
|
||||||
// Should only be used to build global functions
|
// Should only be used to build global functions
|
||||||
asmjit::JitRuntime& get_global_runtime();
|
asmjit::Runtime& get_global_runtime();
|
||||||
|
|
||||||
// Emit xbegin and adjacent loop, return label at xbegin
|
// Emit xbegin and adjacent loop, return label at xbegin
|
||||||
[[nodiscard]] asmjit::Label build_transaction_enter(X86Assembler& c, Label fallback, const X86Gp& ctr, uint less_than);
|
[[nodiscard]] asmjit::Label build_transaction_enter(X86Assembler& c, Label fallback, const X86Gp& ctr, uint less_than);
|
||||||
@ -64,7 +64,7 @@ namespace asmjit
|
|||||||
|
|
||||||
// Build runtime function with asmjit::X86Assembler
|
// Build runtime function with asmjit::X86Assembler
|
||||||
template <typename FT, typename F>
|
template <typename FT, typename F>
|
||||||
FT build_function_asm(F&& builder)
|
inline FT build_function_asm(F&& builder)
|
||||||
{
|
{
|
||||||
using namespace asmjit;
|
using namespace asmjit;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user