[SCM] WebKit Debian packaging branch, webkit-1.1, updated. upstream/1.1.15.1-1414-gc69ee75

oliver at apple.com oliver at apple.com
Thu Oct 29 20:34:04 UTC 2009


The following commit has been merged in the webkit-1.1 branch:
commit 8d181633c2b199cad12e890530788f8e14b6c897
Author: oliver at apple.com <oliver at apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Fri Sep 25 02:40:59 2009 +0000

    Division is needlessly slow in 64-bit
    https://bugs.webkit.org/show_bug.cgi?id=29723
    
    Reviewed by Gavin Barraclough.
    
    Add codegen for op_div on x86-64
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@48744 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/JavaScriptCore/ChangeLog b/JavaScriptCore/ChangeLog
index 338d00a..94f0cf1 100644
--- a/JavaScriptCore/ChangeLog
+++ b/JavaScriptCore/ChangeLog
@@ -1,3 +1,27 @@
+2009-09-24  Oliver Hunt  <oliver at apple.com>
+
+        Reviewed by Gavin Barraclough.
+
+        Division is needlessly slow in 64-bit
+        https://bugs.webkit.org/show_bug.cgi?id=29723
+
+        Add codegen for op_div on x86-64
+
+        * jit/JIT.cpp:
+        (JSC::JIT::privateCompileMainPass):
+        (JSC::JIT::privateCompileSlowCases):
+        * jit/JIT.h:
+        * jit/JITArithmetic.cpp:
+        (JSC::JIT::compileBinaryArithOpSlowCase):
+        (JSC::JIT::emit_op_div):
+        (JSC::JIT::emitSlow_op_div):
+        * jit/JITInlineMethods.h:
+        (JSC::JIT::isOperandConstantImmediateDouble):
+        (JSC::JIT::addressFor):
+        (JSC::JIT::emitLoadDouble):
+        (JSC::JIT::emitLoadInt32ToDouble):
+        (JSC::JIT::emitJumpSlowCaseIfNotImmediateNumber):
+
 2009-09-24  Jeremy Orlow  <jorlow at chromium.org>
 
         Reviewed by Dimitri Glazkov.
diff --git a/JavaScriptCore/jit/JIT.cpp b/JavaScriptCore/jit/JIT.cpp
index bf3a418..ea8434e 100644
--- a/JavaScriptCore/jit/JIT.cpp
+++ b/JavaScriptCore/jit/JIT.cpp
@@ -195,7 +195,7 @@ void JIT::privateCompileMainPass()
 
         switch (m_interpreter->getOpcodeID(currentInstruction->u.opcode)) {
         DEFINE_BINARY_OP(op_del_by_val)
-#if !USE(JSVALUE32_64)
+#if USE(JSVALUE32)
         DEFINE_BINARY_OP(op_div)
 #endif
         DEFINE_BINARY_OP(op_in)
@@ -230,7 +230,7 @@ void JIT::privateCompileMainPass()
         DEFINE_OP(op_create_arguments)
         DEFINE_OP(op_debug)
         DEFINE_OP(op_del_by_id)
-#if USE(JSVALUE32_64)
+#if !USE(JSVALUE32)
         DEFINE_OP(op_div)
 #endif
         DEFINE_OP(op_end)
@@ -379,7 +379,7 @@ void JIT::privateCompileSlowCases()
         DEFINE_SLOWCASE_OP(op_construct)
         DEFINE_SLOWCASE_OP(op_construct_verify)
         DEFINE_SLOWCASE_OP(op_convert_this)
-#if USE(JSVALUE32_64)
+#if !USE(JSVALUE32)
         DEFINE_SLOWCASE_OP(op_div)
 #endif
         DEFINE_SLOWCASE_OP(op_eq)
diff --git a/JavaScriptCore/jit/JIT.h b/JavaScriptCore/jit/JIT.h
index 5c58e9d..3b35935 100644
--- a/JavaScriptCore/jit/JIT.h
+++ b/JavaScriptCore/jit/JIT.h
@@ -379,14 +379,18 @@ namespace JSC {
 
         enum CompileOpStrictEqType { OpStrictEq, OpNStrictEq };
         void compileOpStrictEq(Instruction* instruction, CompileOpStrictEqType type);
+        bool isOperandConstantImmediateDouble(unsigned src);
+        
+        void emitLoadDouble(unsigned index, FPRegisterID value);
+        void emitLoadInt32ToDouble(unsigned index, FPRegisterID value);
+
+        Address addressFor(unsigned index, RegisterID base = callFrameRegister);
 
 #if USE(JSVALUE32_64)
         Address tagFor(unsigned index, RegisterID base = callFrameRegister);
         Address payloadFor(unsigned index, RegisterID base = callFrameRegister);
-        Address addressFor(unsigned index, RegisterID base = callFrameRegister);
 
         bool getOperandConstantImmediateInt(unsigned op1, unsigned op2, unsigned& op, int32_t& constant);
-        bool isOperandConstantImmediateDouble(unsigned src);
 
         void emitLoadTag(unsigned index, RegisterID tag);
         void emitLoadPayload(unsigned index, RegisterID payload);
@@ -394,8 +398,6 @@ namespace JSC {
         void emitLoad(const JSValue& v, RegisterID tag, RegisterID payload);
         void emitLoad(unsigned index, RegisterID tag, RegisterID payload, RegisterID base = callFrameRegister);
         void emitLoad2(unsigned index1, RegisterID tag1, RegisterID payload1, unsigned index2, RegisterID tag2, RegisterID payload2);
-        void emitLoadDouble(unsigned index, FPRegisterID value);
-        void emitLoadInt32ToDouble(unsigned index, FPRegisterID value);
 
         void emitStore(unsigned index, RegisterID tag, RegisterID payload, RegisterID base = callFrameRegister);
         void emitStore(unsigned index, const JSValue constant, RegisterID base = callFrameRegister);
@@ -499,6 +501,7 @@ namespace JSC {
         JIT::Jump emitJumpIfNotImmediateInteger(RegisterID);
         JIT::Jump emitJumpIfNotImmediateIntegers(RegisterID, RegisterID, RegisterID);
         void emitJumpSlowCaseIfNotImmediateInteger(RegisterID);
+        void emitJumpSlowCaseIfNotImmediateNumber(RegisterID);
         void emitJumpSlowCaseIfNotImmediateIntegers(RegisterID, RegisterID, RegisterID);
 
 #if !USE(JSVALUE64)
diff --git a/JavaScriptCore/jit/JITArithmetic.cpp b/JavaScriptCore/jit/JITArithmetic.cpp
index 3be13cb..fb44386 100644
--- a/JavaScriptCore/jit/JITArithmetic.cpp
+++ b/JavaScriptCore/jit/JITArithmetic.cpp
@@ -1978,9 +1978,11 @@ void JIT::compileBinaryArithOpSlowCase(OpcodeID opcodeID, Vector<SlowCaseEntry>:
         addDouble(fpRegT2, fpRegT1);
     else if (opcodeID == op_sub)
         subDouble(fpRegT2, fpRegT1);
-    else {
-        ASSERT(opcodeID == op_mul);
+    else if (opcodeID == op_mul)
         mulDouble(fpRegT2, fpRegT1);
+    else {
+        ASSERT(opcodeID == op_div);
+        divDouble(fpRegT2, fpRegT1);
     }
     moveDoubleToPtr(fpRegT1, regT0);
     subPtr(tagTypeNumberRegister, regT0);
@@ -2082,6 +2084,103 @@ void JIT::emitSlow_op_mul(Instruction* currentInstruction, Vector<SlowCaseEntry>
         compileBinaryArithOpSlowCase(op_mul, iter, result, op1, op2, types);
 }
 
+void JIT::emit_op_div(Instruction* currentInstruction)
+{
+    unsigned dst = currentInstruction[1].u.operand;
+    unsigned op1 = currentInstruction[2].u.operand;
+    unsigned op2 = currentInstruction[3].u.operand;
+    OperandTypes types = OperandTypes::fromInt(currentInstruction[4].u.operand);
+
+    if (isOperandConstantImmediateDouble(op1)) {
+        emitGetVirtualRegister(op1, regT0);
+        addPtr(tagTypeNumberRegister, regT0);
+        movePtrToDouble(regT0, fpRegT0);
+    } else if (isOperandConstantImmediateInt(op1)) {
+        emitLoadInt32ToDouble(op1, fpRegT0);
+    } else {
+        emitGetVirtualRegister(op1, regT0);
+        if (!types.first().definitelyIsNumber())
+            emitJumpSlowCaseIfNotImmediateNumber(regT0);
+        Jump notInt = emitJumpIfNotImmediateInteger(regT0);
+        convertInt32ToDouble(regT0, fpRegT0);
+        Jump skipDoubleLoad = jump();
+        notInt.link(this);
+        addPtr(tagTypeNumberRegister, regT0);
+        movePtrToDouble(regT0, fpRegT0);
+        skipDoubleLoad.link(this);
+    }
+    
+    if (isOperandConstantImmediateDouble(op2)) {
+        emitGetVirtualRegister(op2, regT1);
+        addPtr(tagTypeNumberRegister, regT1);
+        movePtrToDouble(regT1, fpRegT1);
+    } else if (isOperandConstantImmediateInt(op2)) {
+        emitLoadInt32ToDouble(op2, fpRegT1);
+    } else {
+        emitGetVirtualRegister(op2, regT1);
+        if (!types.second().definitelyIsNumber())
+            emitJumpSlowCaseIfNotImmediateNumber(regT1);
+        Jump notInt = emitJumpIfNotImmediateInteger(regT1);
+        convertInt32ToDouble(regT1, fpRegT1);
+        Jump skipDoubleLoad = jump();
+        notInt.link(this);
+        addPtr(tagTypeNumberRegister, regT1);
+        movePtrToDouble(regT1, fpRegT1);
+        skipDoubleLoad.link(this);
+    }
+    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);
+}
+
+void JIT::emitSlow_op_div(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+    unsigned result = currentInstruction[1].u.operand;
+    unsigned op1 = currentInstruction[2].u.operand;
+    unsigned op2 = currentInstruction[3].u.operand;
+    OperandTypes types = OperandTypes::fromInt(currentInstruction[4].u.operand);
+    if (types.first().definitelyIsNumber() && types.second().definitelyIsNumber()) {
+#ifndef NDEBUG
+        breakpoint();
+#endif
+        return;
+    }
+    if (!isOperandConstantImmediateDouble(op1) && !isOperandConstantImmediateInt(op1)) {
+        if (!types.first().definitelyIsNumber())
+            linkSlowCase(iter);
+    }
+    if (!isOperandConstantImmediateDouble(op2) && !isOperandConstantImmediateInt(op2)) {
+        if (!types.second().definitelyIsNumber())
+            linkSlowCase(iter);
+    }
+    // There is an extra slow case for (op1 * -N) or (-N * op2), to check for 0 since this should produce a result of -0.
+    JITStubCall stubCall(this, cti_op_div);
+    stubCall.addArgument(op1, regT2);
+    stubCall.addArgument(op2, regT2);
+    stubCall.call(result);
+}
+
 void JIT::emit_op_sub(Instruction* currentInstruction)
 {
     unsigned result = currentInstruction[1].u.operand;
diff --git a/JavaScriptCore/jit/JITInlineMethods.h b/JavaScriptCore/jit/JITInlineMethods.h
index e69e273..f26457a 100644
--- a/JavaScriptCore/jit/JITInlineMethods.h
+++ b/JavaScriptCore/jit/JITInlineMethods.h
@@ -65,6 +65,11 @@ ALWAYS_INLINE void JIT::emitGetJITStubArg(unsigned argumentNumber, RegisterID ds
     peek(dst, argumentStackOffset);
 }
 
+ALWAYS_INLINE bool JIT::isOperandConstantImmediateDouble(unsigned src)
+{
+    return m_codeBlock->isConstantRegisterIndex(src) && getConstantOperand(src).isDouble();
+}
+
 ALWAYS_INLINE JSValue JIT::getConstantOperand(unsigned src)
 {
     ASSERT(m_codeBlock->isConstantRegisterIndex(src));
@@ -305,6 +310,11 @@ ALWAYS_INLINE void JIT::sampleCodeBlock(CodeBlock* codeBlock)
 #endif
 #endif
 
+inline JIT::Address JIT::addressFor(unsigned index, RegisterID base)
+{
+    return Address(base, (index * sizeof(Register)));
+}
+
 #if USE(JSVALUE32_64)
 
 inline JIT::Address JIT::tagFor(unsigned index, RegisterID base)
@@ -317,11 +327,6 @@ inline JIT::Address JIT::payloadFor(unsigned index, RegisterID base)
     return Address(base, (index * sizeof(Register)) + OBJECT_OFFSETOF(JSValue, u.asBits.payload));
 }
 
-inline JIT::Address JIT::addressFor(unsigned index, RegisterID base)
-{
-    return Address(base, (index * sizeof(Register)));
-}
-
 inline void JIT::emitLoadTag(unsigned index, RegisterID tag)
 {
     RegisterID mappedTag;
@@ -579,11 +584,6 @@ ALWAYS_INLINE bool JIT::getOperandConstantImmediateInt(unsigned op1, unsigned op
     return false;
 }
 
-ALWAYS_INLINE bool JIT::isOperandConstantImmediateDouble(unsigned src)
-{
-    return m_codeBlock->isConstantRegisterIndex(src) && getConstantOperand(src).isDouble();
-}
-
 /* Deprecated: Please use JITStubCall instead. */
 
 ALWAYS_INLINE void JIT::emitPutJITStubArg(RegisterID tag, RegisterID payload, unsigned argumentNumber)
@@ -732,6 +732,24 @@ ALWAYS_INLINE JIT::Jump JIT::emitJumpIfNotImmediateNumber(RegisterID reg)
 {
     return branchTestPtr(Zero, reg, tagTypeNumberRegister);
 }
+
+inline void JIT::emitLoadDouble(unsigned index, FPRegisterID value)
+{
+    if (m_codeBlock->isConstantRegisterIndex(index)) {
+        Register& inConstantPool = m_codeBlock->constantRegister(index);
+        loadDouble(&inConstantPool, value);
+    } else
+        loadDouble(addressFor(index), value);
+}
+
+inline void JIT::emitLoadInt32ToDouble(unsigned index, FPRegisterID value)
+{
+    if (m_codeBlock->isConstantRegisterIndex(index)) {
+        Register& inConstantPool = m_codeBlock->constantRegister(index);
+        convertInt32ToDouble(AbsoluteAddress(&inConstantPool), value);
+    } else
+        convertInt32ToDouble(addressFor(index), value);
+}
 #endif
 
 ALWAYS_INLINE JIT::Jump JIT::emitJumpIfImmediateInteger(RegisterID reg)
@@ -769,6 +787,11 @@ ALWAYS_INLINE void JIT::emitJumpSlowCaseIfNotImmediateIntegers(RegisterID reg1,
     addSlowCase(emitJumpIfNotImmediateIntegers(reg1, reg2, scratch));
 }
 
+ALWAYS_INLINE void JIT::emitJumpSlowCaseIfNotImmediateNumber(RegisterID reg)
+{
+    addSlowCase(emitJumpIfNotImmediateNumber(reg));
+}
+
 #if !USE(JSVALUE64)
 ALWAYS_INLINE void JIT::emitFastArithDeTagImmediate(RegisterID reg)
 {

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list