Title: [109040] trunk/Source/_javascript_Core
Revision
109040
Author
fpi...@apple.com
Date
2012-02-27 16:37:58 -0800 (Mon, 27 Feb 2012)

Log Message

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):

Modified Paths

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));
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to