[SCM] WebKit Debian packaging branch, webkit-1.2, updated. upstream/1.1.90-6072-g9a69373

barraclough at apple.com barraclough at apple.com
Wed Apr 7 23:22:54 UTC 2010


The following commit has been merged in the webkit-1.2 branch:
commit 2ffca6f334fc92c5db45167cfe13b7ec53d04e0d
Author: barraclough at apple.com <barraclough at apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Wed Nov 4 23:59:14 2009 +0000

    https://bugs.webkit.org/show_bug.cgi?id=31104
    Refactor x86-specific behaviour out of the JIT.
    
    Patch by Gavin Barraclough <barraclough at apple.com> on 2009-11-04
    Reviewed by Oliver Hunt.
    
    - Add explicit double branch conditions for ordered and unordered comparisons (presently the brehaviour is a mix).
    - Refactor double to int conversion out into the MacroAssembler.
    - Remove broken double to int conversion for !JSVALUE32_64 builds - this code was broken and slowing us down, fixing it showed it not to be an improvement.
    - Remove exclusion of double to int conversion from (1 % X) cases in JSVALUE32_64 builds - if this was of benefit this is no longer the case; simplify.
    
    * assembler/MacroAssemblerARM.h:
    (JSC::MacroAssemblerARM::):
    * assembler/MacroAssemblerARMv7.h:
    (JSC::MacroAssemblerARMv7::):
    * assembler/MacroAssemblerX86Common.h:
    (JSC::MacroAssemblerX86Common::):
    (JSC::MacroAssemblerX86Common::convertInt32ToDouble):
    (JSC::MacroAssemblerX86Common::branchDouble):
    (JSC::MacroAssemblerX86Common::branchConvertDoubleToInt32):
    * jit/JITArithmetic.cpp:
    (JSC::JIT::emitBinaryDoubleOp):
    (JSC::JIT::emit_op_div):
    (JSC::JIT::emitSlow_op_jnless):
    (JSC::JIT::emitSlow_op_jnlesseq):
    * jit/JITOpcodes.cpp:
    (JSC::JIT::emit_op_jfalse):
    
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@50531 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/JavaScriptCore/ChangeLog b/JavaScriptCore/ChangeLog
index 6971551..fd30687 100644
--- a/JavaScriptCore/ChangeLog
+++ b/JavaScriptCore/ChangeLog
@@ -1,3 +1,32 @@
+2009-11-04  Gavin Barraclough  <barraclough at apple.com>
+
+        Reviewed by Oliver Hunt.
+
+        https://bugs.webkit.org/show_bug.cgi?id=31104
+        Refactor x86-specific behaviour out of the JIT.
+
+        - Add explicit double branch conditions for ordered and unordered comparisons (presently the brehaviour is a mix).
+        - Refactor double to int conversion out into the MacroAssembler.
+        - Remove broken double to int conversion for !JSVALUE32_64 builds - this code was broken and slowing us down, fixing it showed it not to be an improvement.
+        - Remove exclusion of double to int conversion from (1 % X) cases in JSVALUE32_64 builds - if this was of benefit this is no longer the case; simplify.
+
+        * assembler/MacroAssemblerARM.h:
+        (JSC::MacroAssemblerARM::):
+        * assembler/MacroAssemblerARMv7.h:
+        (JSC::MacroAssemblerARMv7::):
+        * assembler/MacroAssemblerX86Common.h:
+        (JSC::MacroAssemblerX86Common::):
+        (JSC::MacroAssemblerX86Common::convertInt32ToDouble):
+        (JSC::MacroAssemblerX86Common::branchDouble):
+        (JSC::MacroAssemblerX86Common::branchConvertDoubleToInt32):
+        * jit/JITArithmetic.cpp:
+        (JSC::JIT::emitBinaryDoubleOp):
+        (JSC::JIT::emit_op_div):
+        (JSC::JIT::emitSlow_op_jnless):
+        (JSC::JIT::emitSlow_op_jnlesseq):
+        * jit/JITOpcodes.cpp:
+        (JSC::JIT::emit_op_jfalse):
+
 2009-11-04  Mark Mentovai  <mark at chromium.org>
 
         Reviewed by Eric Seidel.
diff --git a/JavaScriptCore/assembler/MacroAssemblerARM.h b/JavaScriptCore/assembler/MacroAssemblerARM.h
index 7a72b06..a06797e 100644
--- a/JavaScriptCore/assembler/MacroAssemblerARM.h
+++ b/JavaScriptCore/assembler/MacroAssemblerARM.h
@@ -57,11 +57,11 @@ public:
     };
 
     enum DoubleCondition {
-        DoubleEqual = ARMAssembler::EQ,
+        DoubleEqualOrUnordered = ARMAssembler::EQ,
         DoubleGreaterThan = ARMAssembler::GT,
         DoubleGreaterThanOrEqual = ARMAssembler::GE,
-        DoubleLessThan = ARMAssembler::LT,
-        DoubleLessThanOrEqual = ARMAssembler::LE,
+        DoubleLessThanOrUnordered = ARMAssembler::LT,
+        DoubleLessThanOrEqualOrUnordered = ARMAssembler::LE,
     };
 
     static const RegisterID stackPointerRegister = ARMRegisters::sp;
diff --git a/JavaScriptCore/assembler/MacroAssemblerARMv7.h b/JavaScriptCore/assembler/MacroAssemblerARMv7.h
index c479517..26983bc 100644
--- a/JavaScriptCore/assembler/MacroAssemblerARMv7.h
+++ b/JavaScriptCore/assembler/MacroAssemblerARMv7.h
@@ -95,11 +95,11 @@ public:
     };
 
     enum DoubleCondition {
-        DoubleEqual = ARMv7Assembler::ConditionEQ,
+        DoubleEqualOrUnordered = ARMv7Assembler::ConditionEQ,
         DoubleGreaterThan = ARMv7Assembler::ConditionGT,
         DoubleGreaterThanOrEqual = ARMv7Assembler::ConditionGE,
-        DoubleLessThan = ARMv7Assembler::ConditionLO,
-        DoubleLessThanOrEqual = ARMv7Assembler::ConditionLS,
+        DoubleLessThanOrUnordered = ARMv7Assembler::ConditionLO,
+        DoubleLessThanOrEqualOrUnordered = ARMv7Assembler::ConditionLS,
     };
 
     static const RegisterID stackPointerRegister = ARMRegisters::sp;
diff --git a/JavaScriptCore/assembler/MacroAssemblerX86Common.h b/JavaScriptCore/assembler/MacroAssemblerX86Common.h
index 5ebefa7..c415f24 100644
--- a/JavaScriptCore/assembler/MacroAssemblerX86Common.h
+++ b/JavaScriptCore/assembler/MacroAssemblerX86Common.h
@@ -36,6 +36,10 @@
 namespace JSC {
 
 class MacroAssemblerX86Common : public AbstractMacroAssembler<X86Assembler> {
+    static const int DoubleConditionBitInvert = 0x10;
+    static const int DoubleConditionBitSpecial = 0x20;
+    static const int DoubleConditionBits = DoubleConditionBitInvert | DoubleConditionBitSpecial;
+
 public:
 
     enum Condition {
@@ -56,13 +60,24 @@ public:
     };
 
     enum DoubleCondition {
-        DoubleEqual = X86Assembler::ConditionE,
+        // These conditions will only evaluate to true if the comparison is ordered - i.e. neither operand is NaN.
+        DoubleEqual = X86Assembler::ConditionE | DoubleConditionBitSpecial,
         DoubleNotEqual = X86Assembler::ConditionNE,
         DoubleGreaterThan = X86Assembler::ConditionA,
         DoubleGreaterThanOrEqual = X86Assembler::ConditionAE,
-        DoubleLessThan = X86Assembler::ConditionB,
-        DoubleLessThanOrEqual = X86Assembler::ConditionBE,
+        DoubleLessThan = X86Assembler::ConditionA | DoubleConditionBitInvert,
+        DoubleLessThanOrEqual = X86Assembler::ConditionAE | DoubleConditionBitInvert,
+        // If either operand is NaN, these conditions always evaluate to true.
+        DoubleEqualOrUnordered = X86Assembler::ConditionE,
+        DoubleNotEqualOrUnordered = X86Assembler::ConditionNE | DoubleConditionBitSpecial,
+        DoubleGreaterThanOrUnordered = X86Assembler::ConditionB | DoubleConditionBitInvert,
+        DoubleGreaterThanOrEqualOrUnordered = X86Assembler::ConditionBE | DoubleConditionBitInvert,
+        DoubleLessThanOrUnordered = X86Assembler::ConditionB,
+        DoubleLessThanOrEqualOrUnordered = X86Assembler::ConditionBE,
     };
+    COMPILE_ASSERT(
+        !((X86Assembler::ConditionE | X86Assembler::ConditionNE | X86Assembler::ConditionA | X86Assembler::ConditionAE | X86Assembler::ConditionB | X86Assembler::ConditionBE) & DoubleConditionBits),
+        DoubleConditionBits_should_not_interfere_with_X86Assembler_Condition_codes);
 
     static const RegisterID stackPointerRegister = X86Registers::esp;
 
@@ -416,20 +431,35 @@ public:
 
     void convertInt32ToDouble(Address src, FPRegisterID dest)
     {
+        ASSERT(isSSE2Present());
         m_assembler.cvtsi2sd_mr(src.offset, src.base, dest);
     }
 
     Jump branchDouble(DoubleCondition cond, FPRegisterID left, FPRegisterID right)
     {
         ASSERT(isSSE2Present());
-        m_assembler.ucomisd_rr(right, left);
-        return Jump(m_assembler.jCC(x86Condition(cond)));
-    }
 
-    Jump branchDouble(DoubleCondition cond, FPRegisterID left, Address right)
-    {
-        m_assembler.ucomisd_mr(right.offset, right.base, left);
-        return Jump(m_assembler.jCC(x86Condition(cond)));
+        if (cond & DoubleConditionBitInvert)
+            m_assembler.ucomisd_rr(left, right);
+        else
+            m_assembler.ucomisd_rr(right, left);
+
+        if (cond == DoubleEqual) {
+            Jump isUnordered(m_assembler.jp());
+            Jump result = Jump(m_assembler.je());
+            isUnordered.link(this);
+            return result;
+        } else if (cond == DoubleNotEqualOrUnordered) {
+            Jump isUnordered(m_assembler.jp());
+            Jump isEqual(m_assembler.je());
+            isUnordered.link(this);
+            Jump result = jump();
+            isEqual.link(this);
+            return result;
+        }
+
+        ASSERT(!(cond & DoubleConditionBitSpecial));
+        return Jump(m_assembler.jCC(static_cast<X86Assembler::Condition>(cond & ~DoubleConditionBits)));
     }
 
     // Truncates 'src' to an integer, and places the resulting 'dest'.
@@ -443,6 +473,25 @@ public:
         return branch32(Equal, dest, Imm32(0x80000000));
     }
 
+    // Convert 'src' to an integer, and places the resulting 'dest'.
+    // If the result is not representable as a 32 bit value, branch.
+    // May also branch for some values that are representable in 32 bits
+    // (specifically, in this case, 0).
+    void branchConvertDoubleToInt32(FPRegisterID src, RegisterID dest, JumpList& failureCases, FPRegisterID fpTemp)
+    {
+        ASSERT(isSSE2Present());
+        m_assembler.cvttsd2si_rr(src, dest);
+
+        // If the result is zero, it might have been -0.0, and the double comparison won't catch this!
+        failureCases.append(branchTest32(Zero, dest));
+
+        // Convert the integer result back to float & compare to the original value - if not equal or unordered (NaN) then jump.
+        convertInt32ToDouble(dest, fpTemp);
+        m_assembler.ucomisd_rr(fpTemp, src);
+        failureCases.append(m_assembler.jp());
+        failureCases.append(m_assembler.jne());
+    }
+
     void zeroDouble(FPRegisterID srcDest)
     {
         ASSERT(isSSE2Present());
@@ -889,11 +938,6 @@ protected:
         return static_cast<X86Assembler::Condition>(cond);
     }
 
-    X86Assembler::Condition x86Condition(DoubleCondition cond)
-    {
-        return static_cast<X86Assembler::Condition>(cond);
-    }
-
 private:
     // Only MacroAssemblerX86 should be using the following method; SSE2 is always available on
     // x86_64, and clients & subclasses of MacroAssembler should be using 'supportsFloatingPoint()'.
diff --git a/JavaScriptCore/jit/JITArithmetic.cpp b/JavaScriptCore/jit/JITArithmetic.cpp
index 8cda482..e6df334 100644
--- a/JavaScriptCore/jit/JITArithmetic.cpp
+++ b/JavaScriptCore/jit/JITArithmetic.cpp
@@ -829,11 +829,11 @@ void JIT::emitBinaryDoubleOp(OpcodeID opcodeID, unsigned dst, unsigned op1, unsi
                 break;
             case op_jnless:
                 emitLoadDouble(op1, fpRegT2);
-                addJump(branchDouble(DoubleLessThanOrEqual, fpRegT0, fpRegT2), dst);
+                addJump(branchDouble(DoubleLessThanOrEqualOrUnordered, fpRegT0, fpRegT2), dst);
                 break;
             case op_jnlesseq:
                 emitLoadDouble(op1, fpRegT2);
-                addJump(branchDouble(DoubleLessThan, fpRegT0, fpRegT2), dst);
+                addJump(branchDouble(DoubleLessThanOrUnordered, fpRegT0, fpRegT2), dst);
                 break;
             default:
                 ASSERT_NOT_REACHED();
@@ -882,11 +882,11 @@ void JIT::emitBinaryDoubleOp(OpcodeID opcodeID, unsigned dst, unsigned op1, unsi
                 break;
             case op_jnless:
                 emitLoadDouble(op2, fpRegT1);
-                addJump(branchDouble(DoubleLessThanOrEqual, fpRegT1, fpRegT0), dst);
+                addJump(branchDouble(DoubleLessThanOrEqualOrUnordered, fpRegT1, fpRegT0), dst);
                 break;
             case op_jnlesseq:
                 emitLoadDouble(op2, fpRegT1);
-                addJump(branchDouble(DoubleLessThan, fpRegT1, fpRegT0), dst);
+                addJump(branchDouble(DoubleLessThanOrUnordered, fpRegT1, fpRegT0), dst);
                 break;
             default:
                 ASSERT_NOT_REACHED();
@@ -1000,20 +1000,11 @@ void JIT::emit_op_div(Instruction* currentInstruction)
     divDouble(fpRegT1, fpRegT0);
 
     JumpList doubleResult;
-    if (!isOperandConstantImmediateInt(op1) || getConstantOperand(op1).asInt32() > 1) {
-        m_assembler.cvttsd2si_rr(fpRegT0, regT0);
-        convertInt32ToDouble(regT0, fpRegT1);
-        m_assembler.ucomisd_rr(fpRegT1, fpRegT0);
-
-        doubleResult.append(m_assembler.jne());
-        doubleResult.append(m_assembler.jp());
-        
-        doubleResult.append(branchTest32(Zero, regT0));
+    branchConvertDoubleToInt32(fpRegT0, regT0, doubleResult, fpRegT1);
 
-        // Int32 result.
-        emitStoreInt32(dst, regT0, (op1 == dst || op2 == dst));
-        end.append(jump());
-    }
+    // Int32 result.
+    emitStoreInt32(dst, regT0, (op1 == dst || op2 == dst));
+    end.append(jump());
 
     // Double result.
     doubleResult.link(this);
@@ -1365,7 +1356,7 @@ void JIT::emitSlow_op_jnless(Instruction* currentInstruction, Vector<SlowCaseEnt
             move(Imm32(op2imm), regT1);
             convertInt32ToDouble(regT1, fpRegT1);
 
-            emitJumpSlowToHot(branchDouble(DoubleLessThanOrEqual, fpRegT1, fpRegT0), target);
+            emitJumpSlowToHot(branchDouble(DoubleLessThanOrEqualOrUnordered, fpRegT1, fpRegT0), target);
 
             emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jnless));
 
@@ -1406,7 +1397,7 @@ void JIT::emitSlow_op_jnless(Instruction* currentInstruction, Vector<SlowCaseEnt
             move(Imm32(op1imm), regT0);
             convertInt32ToDouble(regT0, fpRegT0);
 
-            emitJumpSlowToHot(branchDouble(DoubleLessThanOrEqual, fpRegT1, fpRegT0), target);
+            emitJumpSlowToHot(branchDouble(DoubleLessThanOrEqualOrUnordered, fpRegT1, fpRegT0), target);
 
             emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jnless));
 
@@ -1452,7 +1443,7 @@ void JIT::emitSlow_op_jnless(Instruction* currentInstruction, Vector<SlowCaseEnt
             loadDouble(Address(regT1, OBJECT_OFFSETOF(JSNumberCell, m_value)), fpRegT1);
 #endif
 
-            emitJumpSlowToHot(branchDouble(DoubleLessThanOrEqual, fpRegT1, fpRegT0), target);
+            emitJumpSlowToHot(branchDouble(DoubleLessThanOrEqualOrUnordered, fpRegT1, fpRegT0), target);
 
             emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jnless));
 
@@ -1550,7 +1541,7 @@ void JIT::emitSlow_op_jnlesseq(Instruction* currentInstruction, Vector<SlowCaseE
             move(Imm32(op2imm), regT1);
             convertInt32ToDouble(regT1, fpRegT1);
 
-            emitJumpSlowToHot(branchDouble(DoubleLessThan, fpRegT1, fpRegT0), target);
+            emitJumpSlowToHot(branchDouble(DoubleLessThanOrUnordered, fpRegT1, fpRegT0), target);
 
             emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jnlesseq));
 
@@ -1591,7 +1582,7 @@ void JIT::emitSlow_op_jnlesseq(Instruction* currentInstruction, Vector<SlowCaseE
             move(Imm32(op1imm), regT0);
             convertInt32ToDouble(regT0, fpRegT0);
 
-            emitJumpSlowToHot(branchDouble(DoubleLessThan, fpRegT1, fpRegT0), target);
+            emitJumpSlowToHot(branchDouble(DoubleLessThanOrUnordered, fpRegT1, fpRegT0), target);
 
             emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jnlesseq));
 
@@ -1637,7 +1628,7 @@ void JIT::emitSlow_op_jnlesseq(Instruction* currentInstruction, Vector<SlowCaseE
             loadDouble(Address(regT1, OBJECT_OFFSETOF(JSNumberCell, m_value)), fpRegT1);
 #endif
 
-            emitJumpSlowToHot(branchDouble(DoubleLessThan, fpRegT1, fpRegT0), target);
+            emitJumpSlowToHot(branchDouble(DoubleLessThanOrUnordered, fpRegT1, fpRegT0), target);
 
             emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jnlesseq));
 
@@ -2160,27 +2151,10 @@ void JIT::emit_op_div(Instruction* currentInstruction)
     }
     divDouble(fpRegT1, fpRegT0);
 
-    JumpList doubleResult;
-    Jump end;
-    bool attemptIntConversion = (!isOperandConstantImmediateInt(op1) || getConstantOperand(op1).asInt32() > 1) && isOperandConstantImmediateInt(op2);
-    if (attemptIntConversion) {
-        m_assembler.cvttsd2si_rr(fpRegT0, regT0);
-        doubleResult.append(branchTest32(Zero, regT0));
-        m_assembler.ucomisd_rr(fpRegT1, fpRegT0);
-        
-        doubleResult.append(m_assembler.jne());
-        doubleResult.append(m_assembler.jp());
-        emitFastArithIntToImmNoCheck(regT0, regT0);
-        end = jump();
-    }
-
     // Double result.
-    doubleResult.link(this);
     moveDoubleToPtr(fpRegT0, regT0);
     subPtr(tagTypeNumberRegister, regT0);
 
-    if (attemptIntConversion)
-        end.link(this);
     emitPutVirtualRegister(dst, regT0);
 }
 
diff --git a/JavaScriptCore/jit/JITOpcodes.cpp b/JavaScriptCore/jit/JITOpcodes.cpp
index 14736cf..3dfae75 100644
--- a/JavaScriptCore/jit/JITOpcodes.cpp
+++ b/JavaScriptCore/jit/JITOpcodes.cpp
@@ -786,7 +786,7 @@ void JIT::emit_op_jfalse(Instruction* currentInstruction)
 
         zeroDouble(fpRegT0);
         emitLoadDouble(cond, fpRegT1);
-        addJump(branchDouble(DoubleEqual, fpRegT0, fpRegT1), target);
+        addJump(branchDouble(DoubleEqualOrUnordered, fpRegT0, fpRegT1), target);
     } else
         addSlowCase(isNotInteger);
 

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list