Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (109039 => 109040)
--- trunk/Source/_javascript_Core/ChangeLog 2012-02-28 00:36:14 UTC (rev 109039)
+++ trunk/Source/_javascript_Core/ChangeLog 2012-02-28 00:37:58 UTC (rev 109040)
@@ -1,3 +1,26 @@
+2012-02-27 Filip Pizlo <fpi...@apple.com>
+
+ Old JIT's style of JSVALUE64 strict equality is subtly wrong
+ https://bugs.webkit.org/show_bug.cgi?id=79700
+
+ Reviewed by Oliver Hunt.
+
+ * assembler/MacroAssemblerX86_64.h:
+ (JSC::MacroAssemblerX86_64::comparePtr):
+ (MacroAssemblerX86_64):
+ * dfg/DFGOperations.cpp:
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::nonSpeculativeStrictEq):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeStrictEq):
+ (JSC::DFG::SpeculativeJIT::nonSpeculativeNonPeepholeStrictEq):
+ * jit/JITOpcodes.cpp:
+ (JSC::JIT::compileOpStrictEq):
+ (JSC::JIT::emitSlow_op_stricteq):
+ (JSC::JIT::emitSlow_op_nstricteq):
+ * jit/JITStubs.cpp:
+ (JSC::DEFINE_STUB_FUNCTION):
+
2012-02-27 Gavin Barraclough <barraclo...@apple.com>
Implement support for op_negate and op_bitnot in the DFG JIT
Modified: trunk/Source/_javascript_Core/assembler/MacroAssemblerX86_64.h (109039 => 109040)
--- trunk/Source/_javascript_Core/assembler/MacroAssemblerX86_64.h 2012-02-28 00:36:14 UTC (rev 109039)
+++ trunk/Source/_javascript_Core/assembler/MacroAssemblerX86_64.h 2012-02-28 00:37:58 UTC (rev 109040)
@@ -334,6 +334,13 @@
m_assembler.movzbl_rr(dest, dest);
}
+ void comparePtr(RelationalCondition cond, RegisterID left, RegisterID right, RegisterID dest)
+ {
+ m_assembler.cmpq_rr(right, left);
+ m_assembler.setCC_r(x86Condition(cond), dest);
+ m_assembler.movzbl_rr(dest, dest);
+ }
+
Jump branchAdd32(ResultCondition cond, TrustedImm32 src, AbsoluteAddress dest)
{
move(TrustedImmPtr(dest.m_ptr), scratchRegister);
Modified: trunk/Source/_javascript_Core/dfg/DFGOperations.cpp (109039 => 109040)
--- trunk/Source/_javascript_Core/dfg/DFGOperations.cpp 2012-02-28 00:36:14 UTC (rev 109039)
+++ trunk/Source/_javascript_Core/dfg/DFGOperations.cpp 2012-02-28 00:37:58 UTC (rev 109040)
@@ -736,8 +736,14 @@
{
JSGlobalData* globalData = &exec->globalData();
NativeCallFrameTracer tracer(globalData, exec);
+
+ JSValue src1 = JSValue::decode(encodedOp1);
+ JSValue src2 = JSValue::decode(encodedOp2);
- return JSValue::strictEqual(exec, JSValue::decode(encodedOp1), JSValue::decode(encodedOp2));
+ ASSERT((src1.isCell() && src2.isCell())
+ || src1.isDouble() || src2.isDouble());
+
+ return JSValue::strictEqual(exec, src1, src2);
}
static void* handleHostCall(ExecState* execCallee, JSValue callee, CodeSpecializationKind kind)
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (109039 => 109040)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2012-02-28 00:36:14 UTC (rev 109039)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2012-02-28 00:37:58 UTC (rev 109040)
@@ -383,9 +383,6 @@
bool SpeculativeJIT::nonSpeculativeStrictEq(Node& node, bool invert)
{
- if (!invert && (isKnownNumeric(node.child1().index()) || isKnownNumeric(node.child2().index())))
- return nonSpeculativeCompare(node, MacroAssembler::Equal, operationCompareStrictEq);
-
NodeIndex branchNodeIndex = detectPeepHoleBranch();
if (branchNodeIndex != NoNode) {
ASSERT(node.adjustedRefCount() == 1);
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp (109039 => 109040)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp 2012-02-28 00:36:14 UTC (rev 109039)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp 2012-02-28 00:37:58 UTC (rev 109040)
@@ -808,15 +808,21 @@
JITCompiler::Jump twoCellsCase = m_jit.branchTestPtr(JITCompiler::Zero, resultGPR, GPRInfo::tagMaskRegister);
- JITCompiler::Jump numberCase = m_jit.branchTestPtr(JITCompiler::NonZero, resultGPR, GPRInfo::tagTypeNumberRegister);
+ JITCompiler::Jump leftOK = m_jit.branchPtr(JITCompiler::AboveOrEqual, arg1GPR, GPRInfo::tagTypeNumberRegister);
+ JITCompiler::Jump leftDouble = m_jit.branchTestPtr(JITCompiler::NonZero, arg1GPR, GPRInfo::tagTypeNumberRegister);
+ leftOK.link(&m_jit);
+ JITCompiler::Jump rightOK = m_jit.branchPtr(JITCompiler::AboveOrEqual, arg2GPR, GPRInfo::tagTypeNumberRegister);
+ JITCompiler::Jump rightDouble = m_jit.branchTestPtr(JITCompiler::NonZero, arg2GPR, GPRInfo::tagTypeNumberRegister);
+ rightOK.link(&m_jit);
- branch32(invert ? JITCompiler::NotEqual : JITCompiler::Equal, arg1GPR, arg2GPR, taken);
+ branchPtr(invert ? JITCompiler::NotEqual : JITCompiler::Equal, arg1GPR, arg2GPR, taken);
jump(notTaken, ForceJump);
twoCellsCase.link(&m_jit);
branchPtr(JITCompiler::Equal, arg1GPR, arg2GPR, invert ? notTaken : taken);
- numberCase.link(&m_jit);
+ leftDouble.link(&m_jit);
+ rightDouble.link(&m_jit);
silentSpillAllRegisters(resultGPR);
callOperation(operationCompareStrictEq, resultGPR, arg1GPR, arg2GPR);
@@ -865,9 +871,14 @@
JITCompiler::Jump twoCellsCase = m_jit.branchTestPtr(JITCompiler::Zero, resultGPR, GPRInfo::tagMaskRegister);
- JITCompiler::Jump numberCase = m_jit.branchTestPtr(JITCompiler::NonZero, resultGPR, GPRInfo::tagTypeNumberRegister);
+ JITCompiler::Jump leftOK = m_jit.branchPtr(JITCompiler::AboveOrEqual, arg1GPR, GPRInfo::tagTypeNumberRegister);
+ JITCompiler::Jump leftDouble = m_jit.branchTestPtr(JITCompiler::NonZero, arg1GPR, GPRInfo::tagTypeNumberRegister);
+ leftOK.link(&m_jit);
+ JITCompiler::Jump rightOK = m_jit.branchPtr(JITCompiler::AboveOrEqual, arg2GPR, GPRInfo::tagTypeNumberRegister);
+ JITCompiler::Jump rightDouble = m_jit.branchTestPtr(JITCompiler::NonZero, arg2GPR, GPRInfo::tagTypeNumberRegister);
+ rightOK.link(&m_jit);
- m_jit.compare32(invert ? JITCompiler::NotEqual : JITCompiler::Equal, arg1GPR, arg2GPR, resultGPR);
+ m_jit.comparePtr(invert ? JITCompiler::NotEqual : JITCompiler::Equal, arg1GPR, arg2GPR, resultGPR);
JITCompiler::Jump done1 = m_jit.jump();
@@ -878,7 +889,8 @@
JITCompiler::Jump done2 = m_jit.jump();
- numberCase.link(&m_jit);
+ leftDouble.link(&m_jit);
+ rightDouble.link(&m_jit);
notEqualCase.link(&m_jit);
silentSpillAllRegisters(resultGPR);
Modified: trunk/Source/_javascript_Core/jit/JITOpcodes.cpp (109039 => 109040)
--- trunk/Source/_javascript_Core/jit/JITOpcodes.cpp 2012-02-28 00:36:14 UTC (rev 109039)
+++ trunk/Source/_javascript_Core/jit/JITOpcodes.cpp 2012-02-28 00:37:58 UTC (rev 109040)
@@ -963,17 +963,25 @@
unsigned src2 = currentInstruction[3].u.operand;
emitGetVirtualRegisters(src1, regT0, src2, regT1);
-
- // Jump to a slow case if either operand is a number, or if both are JSCell*s.
+
+ // Jump slow if both are cells (to cover strings).
move(regT0, regT2);
orPtr(regT1, regT2);
addSlowCase(emitJumpIfJSCell(regT2));
- addSlowCase(emitJumpIfImmediateNumber(regT2));
+
+ // Jump slow if either is a double. First test if it's an integer, which is fine, and then test
+ // if it's a double.
+ Jump leftOK = emitJumpIfImmediateInteger(regT0);
+ addSlowCase(emitJumpIfImmediateNumber(regT0));
+ leftOK.link(this);
+ Jump rightOK = emitJumpIfImmediateInteger(regT1);
+ addSlowCase(emitJumpIfImmediateNumber(regT1));
+ rightOK.link(this);
if (type == OpStrictEq)
- compare32(Equal, regT1, regT0, regT0);
+ comparePtr(Equal, regT1, regT0, regT0);
else
- compare32(NotEqual, regT1, regT0, regT0);
+ comparePtr(NotEqual, regT1, regT0, regT0);
emitTagAsBoolImmediate(regT0);
emitPutVirtualRegister(dst);
@@ -1364,6 +1372,7 @@
{
linkSlowCase(iter);
linkSlowCase(iter);
+ linkSlowCase(iter);
JITStubCall stubCall(this, cti_op_stricteq);
stubCall.addArgument(regT0);
stubCall.addArgument(regT1);
@@ -1374,6 +1383,7 @@
{
linkSlowCase(iter);
linkSlowCase(iter);
+ linkSlowCase(iter);
JITStubCall stubCall(this, cti_op_nstricteq);
stubCall.addArgument(regT0);
stubCall.addArgument(regT1);
Modified: trunk/Source/_javascript_Core/jit/JITStubs.cpp (109039 => 109040)
--- trunk/Source/_javascript_Core/jit/JITStubs.cpp 2012-02-28 00:36:14 UTC (rev 109039)
+++ trunk/Source/_javascript_Core/jit/JITStubs.cpp 2012-02-28 00:37:58 UTC (rev 109040)
@@ -3294,6 +3294,9 @@
JSValue src1 = stackFrame.args[0].jsValue();
JSValue src2 = stackFrame.args[1].jsValue();
+
+ ASSERT((src1.isCell() && src2.isCell())
+ || src1.isDouble() || src2.isDouble());
bool result = JSValue::strictEqual(stackFrame.callFrame, src1, src2);
CHECK_FOR_EXCEPTION_AT_END();
@@ -3323,6 +3326,9 @@
JSValue src1 = stackFrame.args[0].jsValue();
JSValue src2 = stackFrame.args[1].jsValue();
+ ASSERT((src1.isCell() && src2.isCell())
+ || src1.isDouble() || src2.isDouble());
+
bool result = !JSValue::strictEqual(stackFrame.callFrame, src1, src2);
CHECK_FOR_EXCEPTION_AT_END();
return JSValue::encode(jsBoolean(result));