[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