Title: [203361] trunk
Revision
203361
Author
[email protected]
Date
2016-07-18 12:12:57 -0700 (Mon, 18 Jul 2016)

Log Message

DFG should really support jneq_ptr
https://bugs.webkit.org/show_bug.cgi?id=159700

Reviewed by Keith Miller.
        
Source/_javascript_Core:

Prior to this change, DFG statically speculated that jneq_ptr would always fall through. This
meant that programs that called o.apply() or o.call() where apply or call weren't the
expected ones (i.e. the function.prototype.apply/call) would rage-recompile forever.
        
This adds profiling to jneq_ptr. We now know if it always falls through or sometimes doesn't.
If it sometimes doesn't, we now emit an actual control flow diamond. I decided to add a new
NodeType for "equal pointer", since none of the existing ones really captured that. For
example, there was no way to express "equal pointer" for strings or symbols. We don't use it
for that right now, but we might, and if we did, then it would be hugely surprising that the
DFG interpreted this as value equality. So, the DFG now has CompareEqPtr, which means exactly
what jneq_ptr means by "equal pointer".
        
This is an enormous speed-up on microbenchmarks. I would assume that it's a speed-up on some
real things, too, but I don't know that for a fact.

* bytecode/BytecodeList.json:
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::dumpBytecode):
* bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::emitJumpIfNotFunctionCall):
(JSC::BytecodeGenerator::emitJumpIfNotFunctionApply):
(JSC::BytecodeGenerator::emitExpectedFunctionSnippet):
* dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::parseBlock):
* dfg/DFGClobberize.h:
(JSC::DFG::clobberize):
* dfg/DFGDoesGC.cpp:
(JSC::DFG::doesGC):
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
* dfg/DFGNode.h:
(JSC::DFG::Node::hasCellOperand):
* dfg/DFGNodeType.h:
* dfg/DFGSafeToExecute.h:
(JSC::DFG::safeToExecute):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileRecordRegExpCachedResult):
(JSC::DFG::SpeculativeJIT::compileCompareEqPtr):
* dfg/DFGSpeculativeJIT.h:
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGValidate.cpp:
* ftl/FTLCapabilities.cpp:
(JSC::FTL::canCompile):
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileNode):
(JSC::FTL::DFG::LowerDFGToB3::compileCompareStrictEq):
(JSC::FTL::DFG::LowerDFGToB3::compileCompareEqPtr):
(JSC::FTL::DFG::LowerDFGToB3::compileCompareLess):
(JSC::FTL::DFG::LowerDFGToB3::compileCompareStrictEqConstant): Deleted.
* jit/JITOpcodes.cpp:
(JSC::JIT::emit_op_jneq_ptr):
(JSC::JIT::emit_op_eq):
* jit/JITOpcodes32_64.cpp:
(JSC::JIT::emit_op_jneq_ptr):
(JSC::JIT::emit_op_eq):
* llint/LowLevelInterpreter32_64.asm:
* llint/LowLevelInterpreter64.asm:

LayoutTests:

These tests now run super fast.

* js/regress/apply-not-apply-expected.txt: Added.
* js/regress/apply-not-apply.html: Added.
* js/regress/call-or-not-call-expected.txt: Added.
* js/regress/call-or-not-call.html: Added.
* js/regress/script-tests/apply-not-apply.js: Added.
(let.o.apply):
(foo):
* js/regress/script-tests/call-or-not-call.js: Added.
(let.o.call):
(foo):

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (203360 => 203361)


--- trunk/LayoutTests/ChangeLog	2016-07-18 19:12:24 UTC (rev 203360)
+++ trunk/LayoutTests/ChangeLog	2016-07-18 19:12:57 UTC (rev 203361)
@@ -1,3 +1,23 @@
+2016-07-12  Filip Pizlo  <[email protected]>
+
+        DFG should really support jneq_ptr
+        https://bugs.webkit.org/show_bug.cgi?id=159700
+
+        Reviewed by Keith Miller.
+        
+        These tests now run super fast.
+
+        * js/regress/apply-not-apply-expected.txt: Added.
+        * js/regress/apply-not-apply.html: Added.
+        * js/regress/call-or-not-call-expected.txt: Added.
+        * js/regress/call-or-not-call.html: Added.
+        * js/regress/script-tests/apply-not-apply.js: Added.
+        (let.o.apply):
+        (foo):
+        * js/regress/script-tests/call-or-not-call.js: Added.
+        (let.o.call):
+        (foo):
+
 2016-07-18  Ryan Haddad  <[email protected]>
 
         Marking fast/shapes/shape-outside-floats/shape-outside-big-box-border-radius-002.html as flaky on ios-sim

Added: trunk/LayoutTests/js/regress/apply-not-apply-expected.txt (0 => 203361)


--- trunk/LayoutTests/js/regress/apply-not-apply-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/js/regress/apply-not-apply-expected.txt	2016-07-18 19:12:57 UTC (rev 203361)
@@ -0,0 +1,10 @@
+JSRegress/apply-not-apply
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS no exception thrown
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/js/regress/apply-not-apply.html (0 => 203361)


--- trunk/LayoutTests/js/regress/apply-not-apply.html	                        (rev 0)
+++ trunk/LayoutTests/js/regress/apply-not-apply.html	2016-07-18 19:12:57 UTC (rev 203361)
@@ -0,0 +1,12 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<script src=""
+<script src=""
+<script src=""
+<script src=""
+</body>
+</html>

Added: trunk/LayoutTests/js/regress/call-or-not-call-expected.txt (0 => 203361)


--- trunk/LayoutTests/js/regress/call-or-not-call-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/js/regress/call-or-not-call-expected.txt	2016-07-18 19:12:57 UTC (rev 203361)
@@ -0,0 +1,10 @@
+JSRegress/call-or-not-call
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS no exception thrown
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/js/regress/call-or-not-call.html (0 => 203361)


--- trunk/LayoutTests/js/regress/call-or-not-call.html	                        (rev 0)
+++ trunk/LayoutTests/js/regress/call-or-not-call.html	2016-07-18 19:12:57 UTC (rev 203361)
@@ -0,0 +1,12 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<script src=""
+<script src=""
+<script src=""
+<script src=""
+</body>
+</html>

Added: trunk/LayoutTests/js/regress/script-tests/apply-not-apply.js (0 => 203361)


--- trunk/LayoutTests/js/regress/script-tests/apply-not-apply.js	                        (rev 0)
+++ trunk/LayoutTests/js/regress/script-tests/apply-not-apply.js	2016-07-18 19:12:57 UTC (rev 203361)
@@ -0,0 +1,26 @@
+"use strict";
+
+(function() {
+    let o = {
+        apply(a, b) {
+            return a + b;
+        }
+    };
+    
+    function foo() {
+        let result = 0;
+        for (let i = 0; i < 1000; ++i)
+            result = o.apply(result, 1);
+        return result;
+    }
+    
+    noInline(foo);
+    
+    let result = 0;
+    for (let i = 0; i < 10000; ++i)
+        result += foo();
+    
+    if (result != 10000000)
+        throw new "Bad result: " + result;
+})();
+

Added: trunk/LayoutTests/js/regress/script-tests/call-or-not-call.js (0 => 203361)


--- trunk/LayoutTests/js/regress/script-tests/call-or-not-call.js	                        (rev 0)
+++ trunk/LayoutTests/js/regress/script-tests/call-or-not-call.js	2016-07-18 19:12:57 UTC (rev 203361)
@@ -0,0 +1,28 @@
+"use strict";
+
+(function() {
+    let o = {
+        call(ignored, a, b) {
+            return a + b;
+        }
+    };
+    
+    let a = [o, (a, b) => a - 2 * b];
+    
+    function foo() {
+        let result = 0;
+        for (let i = 0; i < 1000; ++i)
+            result = a[((i % 5) == 0) | 0].call(null, result, 1);
+        return result;
+    }
+    
+    noInline(foo);
+    
+    let result = 0;
+    for (let i = 0; i < 10000; ++i)
+        result += foo();
+    
+    if (result != 4000000)
+        throw "Bad result: " + result;
+})();
+

Modified: trunk/Source/_javascript_Core/ChangeLog (203360 => 203361)


--- trunk/Source/_javascript_Core/ChangeLog	2016-07-18 19:12:24 UTC (rev 203360)
+++ trunk/Source/_javascript_Core/ChangeLog	2016-07-18 19:12:57 UTC (rev 203361)
@@ -1,5 +1,75 @@
 2016-07-12  Filip Pizlo  <[email protected]>
 
+        DFG should really support jneq_ptr
+        https://bugs.webkit.org/show_bug.cgi?id=159700
+
+        Reviewed by Keith Miller.
+        
+        Prior to this change, DFG statically speculated that jneq_ptr would always fall through. This
+        meant that programs that called o.apply() or o.call() where apply or call weren't the
+        expected ones (i.e. the function.prototype.apply/call) would rage-recompile forever.
+        
+        This adds profiling to jneq_ptr. We now know if it always falls through or sometimes doesn't.
+        If it sometimes doesn't, we now emit an actual control flow diamond. I decided to add a new
+        NodeType for "equal pointer", since none of the existing ones really captured that. For
+        example, there was no way to express "equal pointer" for strings or symbols. We don't use it
+        for that right now, but we might, and if we did, then it would be hugely surprising that the
+        DFG interpreted this as value equality. So, the DFG now has CompareEqPtr, which means exactly
+        what jneq_ptr means by "equal pointer".
+        
+        This is an enormous speed-up on microbenchmarks. I would assume that it's a speed-up on some
+        real things, too, but I don't know that for a fact.
+
+        * bytecode/BytecodeList.json:
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::dumpBytecode):
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::emitJumpIfNotFunctionCall):
+        (JSC::BytecodeGenerator::emitJumpIfNotFunctionApply):
+        (JSC::BytecodeGenerator::emitExpectedFunctionSnippet):
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::parseBlock):
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        * dfg/DFGDoesGC.cpp:
+        (JSC::DFG::doesGC):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        * dfg/DFGNode.h:
+        (JSC::DFG::Node::hasCellOperand):
+        * dfg/DFGNodeType.h:
+        * dfg/DFGSafeToExecute.h:
+        (JSC::DFG::safeToExecute):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileRecordRegExpCachedResult):
+        (JSC::DFG::SpeculativeJIT::compileCompareEqPtr):
+        * dfg/DFGSpeculativeJIT.h:
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGValidate.cpp:
+        * ftl/FTLCapabilities.cpp:
+        (JSC::FTL::canCompile):
+        * ftl/FTLLowerDFGToB3.cpp:
+        (JSC::FTL::DFG::LowerDFGToB3::compileNode):
+        (JSC::FTL::DFG::LowerDFGToB3::compileCompareStrictEq):
+        (JSC::FTL::DFG::LowerDFGToB3::compileCompareEqPtr):
+        (JSC::FTL::DFG::LowerDFGToB3::compileCompareLess):
+        (JSC::FTL::DFG::LowerDFGToB3::compileCompareStrictEqConstant): Deleted.
+        * jit/JITOpcodes.cpp:
+        (JSC::JIT::emit_op_jneq_ptr):
+        (JSC::JIT::emit_op_eq):
+        * jit/JITOpcodes32_64.cpp:
+        (JSC::JIT::emit_op_jneq_ptr):
+        (JSC::JIT::emit_op_eq):
+        * llint/LowLevelInterpreter32_64.asm:
+        * llint/LowLevelInterpreter64.asm:
+
+2016-07-12  Filip Pizlo  <[email protected]>
+
         OSR entry into DFG has problems with lexical scoping
         https://bugs.webkit.org/show_bug.cgi?id=159687
 

Modified: trunk/Source/_javascript_Core/bytecode/BytecodeList.json (203360 => 203361)


--- trunk/Source/_javascript_Core/bytecode/BytecodeList.json	2016-07-18 19:12:24 UTC (rev 203360)
+++ trunk/Source/_javascript_Core/bytecode/BytecodeList.json	2016-07-18 19:12:57 UTC (rev 203361)
@@ -86,7 +86,7 @@
             { "name" : "op_jfalse", "length" : 3 },
             { "name" : "op_jeq_null", "length" : 3 },
             { "name" : "op_jneq_null", "length" : 3 },
-            { "name" : "op_jneq_ptr", "length" : 4 },
+            { "name" : "op_jneq_ptr", "length" : 5 },
             { "name" : "op_jless", "length" : 4 },
             { "name" : "op_jlesseq", "length" : 4 },
             { "name" : "op_jgreater", "length" : 4 },

Modified: trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp (203360 => 203361)


--- trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp	2016-07-18 19:12:24 UTC (rev 203360)
+++ trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp	2016-07-18 19:12:57 UTC (rev 203361)
@@ -1311,6 +1311,7 @@
             int offset = (++it)->u.operand;
             printLocationAndOp(out, exec, location, it, "jneq_ptr");
             out.printf("%s, %d (%p), %d(->%d)", registerName(r0).data(), pointer, m_globalObject->actualPointerFor(pointer), offset, location + offset);
+            ++it;
             break;
         }
         case op_jless: {

Modified: trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp (203360 => 203361)


--- trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp	2016-07-18 19:12:24 UTC (rev 203360)
+++ trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp	2016-07-18 19:12:57 UTC (rev 203361)
@@ -1448,6 +1448,7 @@
     instructions().append(cond->index());
     instructions().append(Special::CallFunction);
     instructions().append(target->bind(begin, instructions().size()));
+    instructions().append(0);
     return target;
 }
 
@@ -1459,6 +1460,7 @@
     instructions().append(cond->index());
     instructions().append(Special::ApplyFunction);
     instructions().append(target->bind(begin, instructions().size()));
+    instructions().append(0);
     return target;
 }
 
@@ -3059,6 +3061,7 @@
         instructions().append(func->index());
         instructions().append(Special::ObjectConstructor);
         instructions().append(realCall->bind(begin, instructions().size()));
+        instructions().append(0);
         
         if (dst != ignoredResult())
             emitNewObject(dst);
@@ -3079,6 +3082,7 @@
         instructions().append(func->index());
         instructions().append(Special::ArrayConstructor);
         instructions().append(realCall->bind(begin, instructions().size()));
+        instructions().append(0);
         
         if (dst != ignoredResult()) {
             if (callArguments.argumentCountIncludingThis() == 2)

Modified: trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h (203360 => 203361)


--- trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h	2016-07-18 19:12:24 UTC (rev 203360)
+++ trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h	2016-07-18 19:12:57 UTC (rev 203361)
@@ -1522,6 +1522,18 @@
         break;
     }
         
+    case CompareEqPtr: {
+        Node* childNode = node->child1().node();
+        JSValue childValue = forNode(childNode).value();
+        if (childValue) {
+            setConstant(node, jsBoolean(childValue.isCell() && childValue.asCell() == node->cellOperand()->cell()));
+            break;
+        }
+        
+        forNode(node).setType(SpecBoolean);
+        break;
+    }
+        
     case StringCharCodeAt:
         forNode(node).setType(SpecInt32Only);
         break;

Modified: trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp (203360 => 203361)


--- trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp	2016-07-18 19:12:24 UTC (rev 203360)
+++ trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp	2016-07-18 19:12:57 UTC (rev 203361)
@@ -4564,17 +4564,23 @@
             NEXT_OPCODE(op_construct_varargs);
         }
             
-        case op_jneq_ptr:
-            // Statically speculate for now. It makes sense to let speculate-only jneq_ptr
-            // support simmer for a while before making it more general, since it's
-            // already gnarly enough as it is.
-            ASSERT(pointerIsFunction(currentInstruction[2].u.specialPointer));
-            addToGraph(
-                CheckCell,
-                OpInfo(m_graph.freeze(static_cast<JSCell*>(actualPointerFor(
-                    m_inlineStackTop->m_codeBlock, currentInstruction[2].u.specialPointer)))),
-                get(VirtualRegister(currentInstruction[1].u.operand)));
+        case op_jneq_ptr: {
+            Special::Pointer specialPointer = currentInstruction[2].u.specialPointer;
+            ASSERT(pointerIsCell(specialPointer));
+            JSCell* actualPointer = static_cast<JSCell*>(
+                actualPointerFor(m_inlineStackTop->m_codeBlock, specialPointer));
+            FrozenValue* frozenPointer = m_graph.freeze(actualPointer);
+            int operand = currentInstruction[1].u.operand;
+            unsigned relativeOffset = currentInstruction[3].u.operand;
+            Node* child = get(VirtualRegister(operand));
+            if (currentInstruction[4].u.operand) {
+                Node* condition = addToGraph(CompareEqPtr, OpInfo(frozenPointer), child);
+                addToGraph(Branch, OpInfo(branchData(m_currentIndex + OPCODE_LENGTH(op_jneq_ptr), m_currentIndex + relativeOffset)), condition);
+                LAST_OPCODE(op_jneq_ptr);
+            }
+            addToGraph(CheckCell, OpInfo(frozenPointer), child);
             NEXT_OPCODE(op_jneq_ptr);
+        }
 
         case op_resolve_scope: {
             int dst = currentInstruction[1].u.operand;

Modified: trunk/Source/_javascript_Core/dfg/DFGClobberize.h (203360 => 203361)


--- trunk/Source/_javascript_Core/dfg/DFGClobberize.h	2016-07-18 19:12:24 UTC (rev 203360)
+++ trunk/Source/_javascript_Core/dfg/DFGClobberize.h	2016-07-18 19:12:57 UTC (rev 203361)
@@ -164,6 +164,7 @@
     case GetGlobalObject:
     case StringCharCodeAt:
     case CompareStrictEq:
+    case CompareEqPtr:
     case IsJSArray:
     case IsEmpty:
     case IsUndefined:

Modified: trunk/Source/_javascript_Core/dfg/DFGDoesGC.cpp (203360 => 203361)


--- trunk/Source/_javascript_Core/dfg/DFGDoesGC.cpp	2016-07-18 19:12:24 UTC (rev 203360)
+++ trunk/Source/_javascript_Core/dfg/DFGDoesGC.cpp	2016-07-18 19:12:57 UTC (rev 203361)
@@ -139,6 +139,7 @@
     case CompareGreaterEq:
     case CompareEq:
     case CompareStrictEq:
+    case CompareEqPtr:
     case Call:
     case TailCallInlinedCaller:
     case Construct:

Modified: trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp (203360 => 203361)


--- trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp	2016-07-18 19:12:24 UTC (rev 203360)
+++ trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp	2016-07-18 19:12:57 UTC (rev 203361)
@@ -620,7 +620,7 @@
             }
             break;
         }
-
+            
         case StringFromCharCode:
             if (node->child1()->shouldSpeculateInt32())
                 fixEdge<Int32Use>(node->child1());
@@ -1589,6 +1589,7 @@
         case PutByIdWithThis:
         case PutByValWithThis:
         case GetByValWithThis:
+        case CompareEqPtr:
             break;
             
             break;

Modified: trunk/Source/_javascript_Core/dfg/DFGNode.h (203360 => 203361)


--- trunk/Source/_javascript_Core/dfg/DFGNode.h	2016-07-18 19:12:24 UTC (rev 203360)
+++ trunk/Source/_javascript_Core/dfg/DFGNode.h	2016-07-18 19:12:57 UTC (rev 203361)
@@ -1467,6 +1467,7 @@
         case NewGeneratorFunction:
         case CreateActivation:
         case MaterializeCreateActivation:
+        case CompareEqPtr:
             return true;
         default:
             return false;

Modified: trunk/Source/_javascript_Core/dfg/DFGNodeType.h (203360 => 203361)


--- trunk/Source/_javascript_Core/dfg/DFGNodeType.h	2016-07-18 19:12:24 UTC (rev 203360)
+++ trunk/Source/_javascript_Core/dfg/DFGNodeType.h	2016-07-18 19:12:57 UTC (rev 203361)
@@ -265,6 +265,7 @@
     macro(CompareGreaterEq, NodeResultBoolean | NodeMustGenerate) \
     macro(CompareEq, NodeResultBoolean | NodeMustGenerate) \
     macro(CompareStrictEq, NodeResultBoolean) \
+    macro(CompareEqPtr, NodeResultBoolean) \
     \
     /* Calls. */\
     macro(Call, NodeResultJS | NodeMustGenerate | NodeHasVarArgs) \

Modified: trunk/Source/_javascript_Core/dfg/DFGPredictionPropagationPhase.cpp (203360 => 203361)


--- trunk/Source/_javascript_Core/dfg/DFGPredictionPropagationPhase.cpp	2016-07-18 19:12:24 UTC (rev 203360)
+++ trunk/Source/_javascript_Core/dfg/DFGPredictionPropagationPhase.cpp	2016-07-18 19:12:57 UTC (rev 203361)
@@ -781,6 +781,7 @@
         case CompareGreaterEq:
         case CompareEq:
         case CompareStrictEq:
+        case CompareEqPtr:
         case OverridesHasInstance:
         case InstanceOf:
         case InstanceOfCustom:

Modified: trunk/Source/_javascript_Core/dfg/DFGSafeToExecute.h (203360 => 203361)


--- trunk/Source/_javascript_Core/dfg/DFGSafeToExecute.h	2016-07-18 19:12:24 UTC (rev 203360)
+++ trunk/Source/_javascript_Core/dfg/DFGSafeToExecute.h	2016-07-18 19:12:57 UTC (rev 203361)
@@ -235,6 +235,7 @@
     case CompareGreaterEq:
     case CompareEq:
     case CompareStrictEq:
+    case CompareEqPtr:
     case Call:
     case TailCallInlinedCaller:
     case Construct:

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (203360 => 203361)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2016-07-18 19:12:24 UTC (rev 203360)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2016-07-18 19:12:57 UTC (rev 203361)
@@ -8256,6 +8256,19 @@
     noResult(node);
 }
 
+void SpeculativeJIT::compileCompareEqPtr(Node* node)
+{
+    JSValueOperand operand(this, node->child1());
+    GPRTemporary result(this);
+    JSValueRegs regs = operand.jsValueRegs();
+    GPRReg resultGPR = result.gpr();
+    m_jit.boxBooleanPayload(false, resultGPR);
+    JITCompiler::JumpList notEqual = m_jit.branchIfNotEqual(regs, node->cellOperand()->value());
+    m_jit.boxBooleanPayload(true, resultGPR);
+    notEqual.link(&m_jit);
+    blessedBooleanResult(resultGPR, node);
+}
+
 } } // namespace JSC::DFG
 
 #endif

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h (203360 => 203361)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h	2016-07-18 19:12:24 UTC (rev 203360)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h	2016-07-18 19:12:57 UTC (rev 203361)
@@ -2559,6 +2559,7 @@
     void compileResolveScope(Node*);
     void compileGetDynamicVar(Node*);
     void compilePutDynamicVar(Node*);
+    void compileCompareEqPtr(Node*);
 
     void moveTrueTo(GPRReg);
     void moveFalseTo(GPRReg);

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp (203360 => 203361)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp	2016-07-18 19:12:24 UTC (rev 203360)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp	2016-07-18 19:12:57 UTC (rev 203361)
@@ -2387,6 +2387,10 @@
         if (compileStrictEq(node))
             return;
         break;
+        
+    case CompareEqPtr:
+        compileCompareEqPtr(node);
+        break;
 
     case StringCharCodeAt: {
         compileGetCharCodeAt(node);

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp (203360 => 203361)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp	2016-07-18 19:12:24 UTC (rev 203360)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp	2016-07-18 19:12:57 UTC (rev 203361)
@@ -2522,6 +2522,10 @@
         if (compileStrictEq(node))
             return;
         break;
+        
+    case CompareEqPtr:
+        compileCompareEqPtr(node);
+        break;
 
     case StringCharCodeAt: {
         compileGetCharCodeAt(node);

Modified: trunk/Source/_javascript_Core/dfg/DFGValidate.cpp (203360 => 203361)


--- trunk/Source/_javascript_Core/dfg/DFGValidate.cpp	2016-07-18 19:12:24 UTC (rev 203360)
+++ trunk/Source/_javascript_Core/dfg/DFGValidate.cpp	2016-07-18 19:12:57 UTC (rev 203361)
@@ -266,6 +266,10 @@
                     VALIDATE((node), !!node->child1());
                     VALIDATE((node), !!node->child2());
                     break;
+                case CompareEqPtr:
+                    VALIDATE((node), !!node->child1());
+                    VALIDATE((node), !!node->cellOperand()->value() && node->cellOperand()->value().isCell());
+                    break;
                 case CheckStructure:
                 case StringFromCharCode:
                     VALIDATE((node), !!node->child1());

Modified: trunk/Source/_javascript_Core/ftl/FTLCapabilities.cpp (203360 => 203361)


--- trunk/Source/_javascript_Core/ftl/FTLCapabilities.cpp	2016-07-18 19:12:24 UTC (rev 203360)
+++ trunk/Source/_javascript_Core/ftl/FTLCapabilities.cpp	2016-07-18 19:12:57 UTC (rev 203361)
@@ -244,6 +244,7 @@
     case ResolveScope:
     case GetDynamicVar:
     case PutDynamicVar:
+    case CompareEqPtr:
         // These are OK.
         break;
 

Modified: trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp (203360 => 203361)


--- trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp	2016-07-18 19:12:24 UTC (rev 203360)
+++ trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp	2016-07-18 19:12:57 UTC (rev 203361)
@@ -819,6 +819,9 @@
         case CompareGreaterEq:
             compileCompareGreaterEq();
             break;
+        case CompareEqPtr:
+            compileCompareEqPtr();
+            break;
         case LogicalNot:
             compileLogicalNot();
             break;
@@ -4984,14 +4987,12 @@
         DFG_CRASH(m_graph, m_node, "Bad use kinds");
     }
     
-    void compileCompareStrictEqConstant()
+    void compileCompareEqPtr()
     {
-        JSValue constant = m_node->child2()->asJSValue();
-
         setBoolean(
             m_out.equal(
                 lowJSValue(m_node->child1()),
-                m_out.constInt64(JSValue::encode(constant))));
+                weakPointer(m_node->cellOperand()->cell())));
     }
     
     void compileCompareLess()

Modified: trunk/Source/_javascript_Core/jit/JITOpcodes.cpp (203360 => 203361)


--- trunk/Source/_javascript_Core/jit/JITOpcodes.cpp	2016-07-18 19:12:24 UTC (rev 203360)
+++ trunk/Source/_javascript_Core/jit/JITOpcodes.cpp	2016-07-18 19:12:57 UTC (rev 203361)
@@ -421,7 +421,10 @@
     unsigned target = currentInstruction[3].u.operand;
     
     emitGetVirtualRegister(src, regT0);
-    addJump(branchPtr(NotEqual, regT0, TrustedImmPtr(actualPointerFor(m_codeBlock, ptr))), target);
+    CCallHelpers::Jump equal = branchPtr(Equal, regT0, TrustedImmPtr(actualPointerFor(m_codeBlock, ptr)));
+    store32(TrustedImm32(1), &currentInstruction[4].u.operand);
+    addJump(jump(), target);
+    equal.link(this);
 }
 
 void JIT::emit_op_eq(Instruction* currentInstruction)

Modified: trunk/Source/_javascript_Core/jit/JITOpcodes32_64.cpp (203360 => 203361)


--- trunk/Source/_javascript_Core/jit/JITOpcodes32_64.cpp	2016-07-18 19:12:24 UTC (rev 203360)
+++ trunk/Source/_javascript_Core/jit/JITOpcodes32_64.cpp	2016-07-18 19:12:57 UTC (rev 203361)
@@ -589,8 +589,12 @@
     unsigned target = currentInstruction[3].u.operand;
 
     emitLoad(src, regT1, regT0);
-    addJump(branch32(NotEqual, regT1, TrustedImm32(JSValue::CellTag)), target);
-    addJump(branchPtr(NotEqual, regT0, TrustedImmPtr(actualPointerFor(m_codeBlock, ptr))), target);
+    CCallHelpers::Jump notCell = branch32(NotEqual, regT1, TrustedImm32(JSValue::CellTag));
+    CCallHelpers::Jump equal = branchPtr(Equal, regT0, TrustedImmPtr(actualPointerFor(m_codeBlock, ptr)));
+    notCell.link(this);
+    store32(TrustedImm32(1), &currentInstruction[4].u.operand);
+    addJump(jump(), target);
+    equal.link(this);
 }
 
 void JIT::emit_op_eq(Instruction* currentInstruction)

Modified: trunk/Source/_javascript_Core/llint/LowLevelInterpreter32_64.asm (203360 => 203361)


--- trunk/Source/_javascript_Core/llint/LowLevelInterpreter32_64.asm	2016-07-18 19:12:24 UTC (rev 203360)
+++ trunk/Source/_javascript_Core/llint/LowLevelInterpreter32_64.asm	2016-07-18 19:12:57 UTC (rev 203361)
@@ -1808,9 +1808,10 @@
     loadp JSGlobalObject::m_specialPointers[t2, t1, 4], t1
     bpeq PayloadOffset[cfr, t0, 8], t1, .opJneqPtrFallThrough
 .opJneqPtrBranch:
+    storei 1, 16[PC]
     dispatchBranch(12[PC])
 .opJneqPtrFallThrough:
-    dispatch(4)
+    dispatch(5)
 
 
 macro compare(integerCompare, doubleCompare, slowPath)

Modified: trunk/Source/_javascript_Core/llint/LowLevelInterpreter64.asm (203360 => 203361)


--- trunk/Source/_javascript_Core/llint/LowLevelInterpreter64.asm	2016-07-18 19:12:24 UTC (rev 203360)
+++ trunk/Source/_javascript_Core/llint/LowLevelInterpreter64.asm	2016-07-18 19:12:57 UTC (rev 203361)
@@ -1767,9 +1767,10 @@
     loadp CodeBlock::m_globalObject[t2], t2
     loadp JSGlobalObject::m_specialPointers[t2, t1, 8], t1
     bpneq t1, [cfr, t0, 8], .opJneqPtrTarget
-    dispatch(4)
+    dispatch(5)
 
 .opJneqPtrTarget:
+    storei 1, 32[PB, PC, 8]
     dispatchIntIndirect(3)
 
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to