DFG should really support jneq_ptr
authorfpizlo@apple.com <fpizlo@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 18 Jul 2016 19:12:57 +0000 (19:12 +0000)
committerfpizlo@apple.com <fpizlo@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 18 Jul 2016 19:12:57 +0000 (19:12 +0000)
commit5dbe1cc388f0b6ca8750e8434cf85118ae2492ef
tree460229aff8645496193be319ecfed34536ebde5e
parent7f2911bf1a4146256d6f37db0a55f1d633782e08
DFG should really support jneq_ptr
https://bugs.webkit.org/show_bug.cgi?id=159700

Reviewed by Keith Miller.

Source/JavaScriptCore:

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

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@203361 268f45cc-cd09-0410-ab3c-d52691b4dbfc
31 files changed:
LayoutTests/ChangeLog
LayoutTests/js/regress/apply-not-apply-expected.txt [new file with mode: 0644]
LayoutTests/js/regress/apply-not-apply.html [new file with mode: 0644]
LayoutTests/js/regress/call-or-not-call-expected.txt [new file with mode: 0644]
LayoutTests/js/regress/call-or-not-call.html [new file with mode: 0644]
LayoutTests/js/regress/script-tests/apply-not-apply.js [new file with mode: 0644]
LayoutTests/js/regress/script-tests/call-or-not-call.js [new file with mode: 0644]
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/bytecode/BytecodeList.json
Source/JavaScriptCore/bytecode/CodeBlock.cpp
Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h
Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
Source/JavaScriptCore/dfg/DFGClobberize.h
Source/JavaScriptCore/dfg/DFGDoesGC.cpp
Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
Source/JavaScriptCore/dfg/DFGNode.h
Source/JavaScriptCore/dfg/DFGNodeType.h
Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp
Source/JavaScriptCore/dfg/DFGSafeToExecute.h
Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
Source/JavaScriptCore/dfg/DFGValidate.cpp
Source/JavaScriptCore/ftl/FTLCapabilities.cpp
Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp
Source/JavaScriptCore/jit/JITOpcodes.cpp
Source/JavaScriptCore/jit/JITOpcodes32_64.cpp
Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm
Source/JavaScriptCore/llint/LowLevelInterpreter64.asm