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), ¤tInstruction[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), ¤tInstruction[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)