Browse Source

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.
Andreas Kling 1 year ago
parent
commit
5b198ccf32
2 changed files with 12 additions and 5 deletions
  1. 8 3
      Userland/Libraries/LibJIT/Assembler.h
  2. 4 2
      Userland/Libraries/LibJS/JIT/Compiler.cpp

+ 8 - 3
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;

+ 4 - 2
Userland/Libraries/LibJS/JIT/Compiler.cpp

@@ -357,7 +357,8 @@ void Compiler::push_unwind_context(bool valid, Optional<Bytecode::Label> 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<Bytecode::Label> 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));