We should have a more concise way of determining when we're varargs calling a functio...
authorsbarati@apple.com <sbarati@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 11 Nov 2016 08:33:34 +0000 (08:33 +0000)
committersbarati@apple.com <sbarati@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 11 Nov 2016 08:33:34 +0000 (08:33 +0000)
commit86f76f7ceec1b10d15c43735aee7cbce088ad717
treec9eab94c14270d45b868aafc03664174920c964e
parent7f181a6300eaa51214271ff76b1233e9f7181328
We should have a more concise way of determining when we're varargs calling a function using rest parameters
https://bugs.webkit.org/show_bug.cgi?id=164258

Reviewed by Yusuke Suzuki.

JSTests:

* microbenchmarks/call-using-spread.js: Added.
(bar):
(foo):
* microbenchmarks/spread-large-array.js: Added.
(foo):
(arrays.push):
* microbenchmarks/spread-small-array.js: Added.
(foo):
* stress/spread-array-iterator-watchpoint-2.js: Added.
(foo):
(arrayIterator.next):
* stress/spread-array-iterator-watchpoint.js: Added.
(foo):
(Array.prototype.Symbol.iterator):
* stress/spread-non-array.js: Added.
(assert):
(foo):
(let.customIterator.Symbol.iterator):
(bar):

Source/JavaScriptCore:

This patch adds two new bytecodes and DFG nodes for the following code patterns:

```
foo(a, b, ...c)
let x = [a, b, ...c];
```

To do this, I've introduced two new bytecode operations (and their
corresponding DFG nodes):

op_spread and op_new_array_with_spread.

op_spread takes a single input and performs the ES6 iteration protocol on it.
It returns the result of doing the spread inside a new class I've
made called JSFixedArray. JSFixedArray is a cell with a single 'size'
field and a buffer of values allocated inline in the cell. Abstracting
the protocol into a single node is good because it will make IR analysis
in the future much simpler. For now, it's also good because it allows
us to create fast paths for array iteration (which is quite common).
This fast path allows us to emit really good code for array iteration
inside the DFG/FTL.

op_new_array_with_spread is a variable argument bytecode that also
has a bit vector associated with it. The bit vector indicates if
any particular argument is to be spread or not. Arguments that
are spread are known to be JSFixedArray because we must emit an
op_spread before op_new_array_with_spread consumes the value.
For example, for this array:
[a, b, ...c, d, ...e]
we will have this bit vector:
[0, 0, 1, 0, 1]

The reason I've chosen this IR is that it will make eliminating
a rest allocation for this type of code much easier:

```
function foo(...args) {
    return bar(a, b, ...args);
}
```

It will be easier to analyze the IR now that the operations
will be described at a high level.

This patch is an ~8% speedup on ES6SampleBench on my MBP.

* CMakeLists.txt:
* DerivedSources.make:
* JavaScriptCore.xcodeproj/project.pbxproj:
* builtins/IteratorHelpers.js: Added.
(performIteration):
* bytecode/BytecodeList.json:
* bytecode/BytecodeUseDef.h:
(JSC::computeUsesForBytecodeOffset):
(JSC::computeDefsForBytecodeOffset):
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::dumpBytecode):
* bytecode/ObjectPropertyConditionSet.cpp:
(JSC::generateConditionForSelfEquivalence):
* bytecode/ObjectPropertyConditionSet.h:
* bytecode/TrackedReferences.cpp:
(JSC::TrackedReferences::check):
* bytecode/UnlinkedCodeBlock.h:
(JSC::UnlinkedCodeBlock::bitVectors):
(JSC::UnlinkedCodeBlock::bitVector):
(JSC::UnlinkedCodeBlock::addBitVector):
(JSC::UnlinkedCodeBlock::shrinkToFit):
* bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::emitNewArrayWithSpread):
* bytecompiler/BytecodeGenerator.h:
* bytecompiler/NodesCodegen.cpp:
(JSC::ArrayNode::emitBytecode):
* dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::addToGraph):
(JSC::DFG::ByteCodeParser::parseBlock):
* dfg/DFGCapabilities.cpp:
(JSC::DFG::capabilityLevel):
* dfg/DFGClobberize.h:
(JSC::DFG::clobberize):
* dfg/DFGDoesGC.cpp:
(JSC::DFG::doesGC):
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
(JSC::DFG::FixupPhase::watchHavingABadTime):
* dfg/DFGGraph.h:
(JSC::DFG::Graph::isWatchingArrayIteratorProtocolWatchpoint):
* dfg/DFGNode.h:
(JSC::DFG::Node::bitVector):
* dfg/DFGNodeType.h:
* dfg/DFGOperations.cpp:
* dfg/DFGOperations.h:
* dfg/DFGPredictionPropagationPhase.cpp:
* dfg/DFGSafeToExecute.h:
(JSC::DFG::safeToExecute):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileSpread):
(JSC::DFG::SpeculativeJIT::compileNewArrayWithSpread):
* dfg/DFGSpeculativeJIT.h:
(JSC::DFG::SpeculativeJIT::callOperation):
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGStructureRegistrationPhase.cpp:
(JSC::DFG::StructureRegistrationPhase::run):
* ftl/FTLAbstractHeapRepository.h:
* ftl/FTLCapabilities.cpp:
(JSC::FTL::canCompile):
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileNode):
(JSC::FTL::DFG::LowerDFGToB3::compileNewArrayWithSpread):
(JSC::FTL::DFG::LowerDFGToB3::compileSpread):
(JSC::FTL::DFG::LowerDFGToB3::allocateVariableSizedCell):
* jit/AssemblyHelpers.h:
(JSC::AssemblyHelpers::emitAllocateVariableSizedCell):
(JSC::AssemblyHelpers::emitAllocateVariableSizedJSObject):
* jit/JIT.cpp:
(JSC::JIT::privateCompileMainPass):
* jit/JIT.h:
* jit/JITOpcodes.cpp:
(JSC::JIT::emit_op_new_array_with_spread):
(JSC::JIT::emit_op_spread):
* jit/JITOperations.h:
* llint/LLIntData.cpp:
(JSC::LLInt::Data::performAssertions):
* llint/LLIntSlowPaths.cpp:
* llint/LowLevelInterpreter.asm:
* runtime/ArrayIteratorAdaptiveWatchpoint.cpp: Added.
(JSC::ArrayIteratorAdaptiveWatchpoint::ArrayIteratorAdaptiveWatchpoint):
(JSC::ArrayIteratorAdaptiveWatchpoint::handleFire):
* runtime/ArrayIteratorAdaptiveWatchpoint.h: Added.
* runtime/CommonSlowPaths.cpp:
(JSC::SLOW_PATH_DECL):
* runtime/CommonSlowPaths.h:
* runtime/IteratorOperations.h:
(JSC::forEachInIterable):
* runtime/JSCInlines.h:
* runtime/JSFixedArray.cpp: Added.
(JSC::JSFixedArray::visitChildren):
* runtime/JSFixedArray.h: Added.
(JSC::JSFixedArray::createStructure):
(JSC::JSFixedArray::createFromArray):
(JSC::JSFixedArray::get):
(JSC::JSFixedArray::buffer):
(JSC::JSFixedArray::size):
(JSC::JSFixedArray::offsetOfSize):
(JSC::JSFixedArray::offsetOfData):
(JSC::JSFixedArray::create):
(JSC::JSFixedArray::JSFixedArray):
(JSC::JSFixedArray::allocationSize):
* runtime/JSGlobalObject.cpp:
(JSC::JSGlobalObject::JSGlobalObject):
(JSC::JSGlobalObject::init):
(JSC::JSGlobalObject::visitChildren):
(JSC::JSGlobalObject::objectPrototypeIsSane): Deleted.
(JSC::JSGlobalObject::arrayPrototypeChainIsSane): Deleted.
(JSC::JSGlobalObject::stringPrototypeChainIsSane): Deleted.
* runtime/JSGlobalObject.h:
(JSC::JSGlobalObject::arrayIteratorProtocolWatchpoint):
(JSC::JSGlobalObject::iteratorProtocolFunction):
* runtime/JSGlobalObjectInlines.h: Added.
(JSC::JSGlobalObject::objectPrototypeIsSane):
(JSC::JSGlobalObject::arrayPrototypeChainIsSane):
(JSC::JSGlobalObject::stringPrototypeChainIsSane):
(JSC::JSGlobalObject::isArrayIteratorProtocolFastAndNonObservable):
* runtime/JSType.h:
* runtime/VM.cpp:
(JSC::VM::VM):
* runtime/VM.h:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@208584 268f45cc-cd09-0410-ab3c-d52691b4dbfc
65 files changed:
JSTests/ChangeLog
JSTests/microbenchmarks/call-using-spread.js [new file with mode: 0644]
JSTests/microbenchmarks/spread-large-array.js [new file with mode: 0644]
JSTests/microbenchmarks/spread-small-array.js [new file with mode: 0644]
JSTests/stress/spread-array-iterator-watchpoint-2.js [new file with mode: 0644]
JSTests/stress/spread-array-iterator-watchpoint.js [new file with mode: 0644]
JSTests/stress/spread-non-array.js [new file with mode: 0644]
Source/JavaScriptCore/CMakeLists.txt
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/DerivedSources.make
Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
Source/JavaScriptCore/builtins/IteratorHelpers.js [new file with mode: 0644]
Source/JavaScriptCore/bytecode/BytecodeList.json
Source/JavaScriptCore/bytecode/BytecodeUseDef.h
Source/JavaScriptCore/bytecode/CodeBlock.cpp
Source/JavaScriptCore/bytecode/ObjectPropertyConditionSet.cpp
Source/JavaScriptCore/bytecode/ObjectPropertyConditionSet.h
Source/JavaScriptCore/bytecode/TrackedReferences.cpp
Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h
Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h
Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h
Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
Source/JavaScriptCore/dfg/DFGCapabilities.cpp
Source/JavaScriptCore/dfg/DFGClobberize.h
Source/JavaScriptCore/dfg/DFGDoesGC.cpp
Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
Source/JavaScriptCore/dfg/DFGGraph.h
Source/JavaScriptCore/dfg/DFGNode.h
Source/JavaScriptCore/dfg/DFGNodeType.h
Source/JavaScriptCore/dfg/DFGOperations.cpp
Source/JavaScriptCore/dfg/DFGOperations.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/DFGStructureRegistrationPhase.cpp
Source/JavaScriptCore/ftl/FTLAbstractHeapRepository.h
Source/JavaScriptCore/ftl/FTLCapabilities.cpp
Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp
Source/JavaScriptCore/jit/AssemblyHelpers.h
Source/JavaScriptCore/jit/JIT.cpp
Source/JavaScriptCore/jit/JIT.h
Source/JavaScriptCore/jit/JITOpcodes.cpp
Source/JavaScriptCore/jit/JITOperations.h
Source/JavaScriptCore/llint/LLIntData.cpp
Source/JavaScriptCore/llint/LLIntSlowPaths.cpp
Source/JavaScriptCore/llint/LowLevelInterpreter.asm
Source/JavaScriptCore/runtime/ArrayIteratorAdaptiveWatchpoint.cpp [new file with mode: 0644]
Source/JavaScriptCore/runtime/ArrayIteratorAdaptiveWatchpoint.h [new file with mode: 0644]
Source/JavaScriptCore/runtime/CommonSlowPaths.cpp
Source/JavaScriptCore/runtime/CommonSlowPaths.h
Source/JavaScriptCore/runtime/IteratorOperations.h
Source/JavaScriptCore/runtime/JSCInlines.h
Source/JavaScriptCore/runtime/JSFixedArray.cpp [new file with mode: 0644]
Source/JavaScriptCore/runtime/JSFixedArray.h [new file with mode: 0644]
Source/JavaScriptCore/runtime/JSGlobalObject.cpp
Source/JavaScriptCore/runtime/JSGlobalObject.h
Source/JavaScriptCore/runtime/JSGlobalObjectInlines.h [new file with mode: 0644]
Source/JavaScriptCore/runtime/JSType.h
Source/JavaScriptCore/runtime/VM.cpp
Source/JavaScriptCore/runtime/VM.h