From 5b198ccf32409fcfd313460bca0789503bdae89c Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Thu, 26 Oct 2023 19:48:37 +0200 Subject: [PATCH] LibJS+LibJIT: Don't turn patchable movs into xors with self If a mov instruction is meant to be patchable, we don't want to rewrite it as a xor, since that removes the slot where we'd patch in the right value later. Also, make sure to set both size bits in the REX prefix for xoring a register with itself. --- Userland/Libraries/LibJIT/Assembler.h | 11 ++++++++--- Userland/Libraries/LibJS/JIT/Compiler.cpp | 6 ++++-- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/Userland/Libraries/LibJIT/Assembler.h b/Userland/Libraries/LibJIT/Assembler.h index 25f2565a112..54f9acd581e 100644 --- a/Userland/Libraries/LibJIT/Assembler.h +++ b/Userland/Libraries/LibJIT/Assembler.h @@ -108,7 +108,12 @@ struct Assembler { emit8(count.offset_or_immediate); } - void mov(Operand dst, Operand src) + enum class Patchable { + Yes, + No, + }; + + void mov(Operand dst, Operand src, Patchable patchable = Patchable::No) { if (dst.type == Operand::Type::Reg && src.type == Operand::Type::Reg) { if (src.reg == dst.reg) @@ -122,9 +127,9 @@ struct Assembler { } if (dst.type == Operand::Type::Reg && src.type == Operand::Type::Imm64) { - if (src.offset_or_immediate == 0) { + if (patchable == Patchable::No && src.offset_or_immediate == 0) { // xor dst, dst - emit8(0x48 | ((to_underlying(dst.reg) >= 8) ? 1 << 0 : 0)); + emit8(0x48 | ((to_underlying(dst.reg) >= 8) ? (1 << 0 | 1 << 2) : 0)); emit8(0x31); emit8(0xc0 | (encode_reg(dst.reg) << 3) | encode_reg(dst.reg)); return; diff --git a/Userland/Libraries/LibJS/JIT/Compiler.cpp b/Userland/Libraries/LibJS/JIT/Compiler.cpp index 40d666878d9..e374f35d494 100644 --- a/Userland/Libraries/LibJS/JIT/Compiler.cpp +++ b/Userland/Libraries/LibJS/JIT/Compiler.cpp @@ -357,7 +357,8 @@ void Compiler::push_unwind_context(bool valid, Optional const& // push finalizer (patched later) m_assembler.mov( Assembler::Operand::Register(GPR0), - Assembler::Operand::Imm64(0)); + Assembler::Operand::Imm64(0), + Assembler::Patchable::Yes); if (finalizer.has_value()) block_data_for(finalizer.value().block()).absolute_references_to_here.append(m_assembler.m_output.size() - 8); m_assembler.push(Assembler::Operand::Register(GPR0)); @@ -365,7 +366,8 @@ void Compiler::push_unwind_context(bool valid, Optional const& // push handler (patched later) m_assembler.mov( Assembler::Operand::Register(GPR0), - Assembler::Operand::Imm64(0)); + Assembler::Operand::Imm64(0), + Assembler::Patchable::Yes); if (handler.has_value()) block_data_for(handler.value().block()).absolute_references_to_here.append(m_assembler.m_output.size() - 8); m_assembler.push(Assembler::Operand::Register(GPR0));