Parcourir la source

LibJS/JIT: Add fast path for JumpConditional where accumulator is Int32

Andreas Kling il y a 1 an
Parent
commit
b2a1f39400

+ 27 - 53
Userland/Libraries/LibJS/JIT/Compiler.cpp

@@ -176,72 +176,46 @@ void Compiler::compile_jump(Bytecode::Op::Jump const& op)
     m_assembler.jump(label_for(op.true_target()->block()));
 }
 
-static bool cxx_to_boolean(VM&, Value value)
+static u64 cxx_to_boolean(VM&, Value value)
 {
-    return value.to_boolean_slow_case();
+    return value.to_boolean();
 }
 
-void Compiler::compile_to_boolean(Assembler::Reg dst, Assembler::Reg src)
+void Compiler::compile_jump_conditional(Bytecode::Op::JumpConditional const& op)
 {
-    // dst = src;
-    m_assembler.mov(
-        Assembler::Operand::Register(dst),
-        Assembler::Operand::Register(src));
-
-    // dst >>= 48;
-    m_assembler.shift_right(
-        Assembler::Operand::Register(dst),
-        Assembler::Operand::Imm(48));
-
-    // if (dst != BOOLEAN_TAG) goto slow_case;
-    Assembler::Label slow_case {};
-    m_assembler.jump_if(
-        Assembler::Operand::Register(dst),
-        Assembler::Condition::NotEqualTo,
-        Assembler::Operand::Imm(BOOLEAN_TAG),
-        slow_case);
-
-    // Fast path for JS::Value booleans.
+    load_accumulator(ARG1);
 
-    // dst = src;
-    m_assembler.mov(
-        Assembler::Operand::Register(dst),
-        Assembler::Operand::Register(src));
+    branch_if_boolean(ARG1, [&] {
+        m_assembler.bitwise_and(
+            Assembler::Operand::Register(ARG1),
+            Assembler::Operand::Imm(1));
+        m_assembler.jump_if(
+            Assembler::Operand::Register(ARG1),
+            Assembler::Condition::EqualTo,
+            Assembler::Operand::Imm(0),
+            label_for(op.false_target()->block()));
+        m_assembler.jump(label_for(op.true_target()->block()));
+    });
 
-    // goto end;
-    auto end = m_assembler.jump();
+    branch_if_int32(ARG1, [&] {
+        m_assembler.mov32(
+            Assembler::Operand::Register(GPR0),
+            Assembler::Operand::Register(ARG1));
+        m_assembler.jump_if(
+            Assembler::Operand::Register(GPR0),
+            Assembler::Condition::EqualTo,
+            Assembler::Operand::Imm(0),
+            label_for(op.false_target()->block()));
+        m_assembler.jump(label_for(op.true_target()->block()));
+    });
 
-    // slow_case: // call C++ helper
-    slow_case.link(m_assembler);
-    m_assembler.mov(
-        Assembler::Operand::Register(ARG1),
-        Assembler::Operand::Register(src));
     native_call((void*)cxx_to_boolean);
-    m_assembler.mov(
-        Assembler::Operand::Register(dst),
-        Assembler::Operand::Register(RET));
-
-    // end:
-    end.link(m_assembler);
-
-    // dst &= 1;
-    m_assembler.bitwise_and(
-        Assembler::Operand::Register(dst),
-        Assembler::Operand::Imm(1));
-}
-
-void Compiler::compile_jump_conditional(Bytecode::Op::JumpConditional const& op)
-{
-    load_accumulator(GPR1);
-
-    compile_to_boolean(GPR0, GPR1);
 
     m_assembler.jump_if(
-        Assembler::Operand::Register(GPR0),
+        Assembler::Operand::Register(RET),
         Assembler::Condition::EqualTo,
         Assembler::Operand::Imm(0),
         label_for(op.false_target()->block()));
-
     m_assembler.jump(label_for(op.true_target()->block()));
 }
 

+ 6 - 1
Userland/Libraries/LibJS/JIT/Compiler.h

@@ -168,7 +168,6 @@ private:
     void load_accumulator(Assembler::Reg);
     void store_accumulator(Assembler::Reg);
 
-    void compile_to_boolean(Assembler::Reg dst, Assembler::Reg src);
     void compile_continuation(Optional<Bytecode::Label>, bool is_await);
 
     template<typename Codegen>
@@ -193,6 +192,12 @@ private:
         branch_if_type(reg, INT32_TAG, codegen);
     }
 
+    template<typename Codegen>
+    void branch_if_boolean(Assembler::Reg reg, Codegen codegen)
+    {
+        branch_if_type(reg, BOOLEAN_TAG, codegen);
+    }
+
     template<typename Codegen>
     void branch_if_object(Assembler::Reg reg, Codegen codegen)
     {