Inline store loop for CopyRest in DFG and FTL for certain array modes
https://bugs.webkit.org/show_bug.cgi?id=159612
Reviewed by Filip Pizlo.
JSTests:
- stress/rest-parameter-having-a-bad-time.js: Added.
- stress/rest-parameter-many-arguments.js: Added.
- stress/rest-parameter-various-types.js: Added.
Source/JavaScriptCore:
This patch changes the old copy_rest bytecode to actually allocate the rest array itself.
The bytecode is now called create_rest with an analogous CreateRest node in the DFG/FTL.
This allows the bytecode to be in control of what type of indexingType the array is allocated
with. We always allocate using ArrayWithContiguous storage unless we're havingABadTime().
This also makes allocating and writing into the array fast. On the fast path, the DFG/FTL
JIT will fast allocate the array and its storage, and we will do a memmove from the rest
region of arguments into the array's storage.
I'm seeing a 1-2% speedup on ES6SampleBench, and about a 2x speedup
on micro benchmarks that just test rest creation speed.
- bytecode/BytecodeList.json:
- bytecode/BytecodeUseDef.h:
(JSC::computeUsesForBytecodeOffset):
(JSC::computeDefsForBytecodeOffset):
(JSC::CodeBlock::dumpBytecode):
- bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::emitRestParameter):
- dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
- dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::parseBlock):
- dfg/DFGCallArrayAllocatorSlowPathGenerator.h:
(JSC::DFG::CallArrayAllocatorWithVariableSizeSlowPathGenerator::CallArrayAllocatorWithVariableSizeSlowPathGenerator):
(JSC::DFG::capabilityLevel):
(JSC::DFG::clobberize):
(JSC::DFG::doesGC):
(JSC::DFG::FixupPhase::fixupNode):
(JSC::DFG::Graph::uses):
(JSC::DFG::Graph::isWatchingHavingABadTimeWatchpoint):
(JSC::DFG::Graph::compilation):
(JSC::DFG::Node::numberOfArgumentsToSkip):
- dfg/DFGNodeType.h:
- dfg/DFGOperations.cpp:
- dfg/DFGOperations.h:
- dfg/DFGPredictionPropagationPhase.cpp:
- dfg/DFGSafeToExecute.h:
(JSC::DFG::safeToExecute):
- dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileCreateClonedArguments):
(JSC::DFG::SpeculativeJIT::compileCreateRest):
(JSC::DFG::SpeculativeJIT::compileGetRestLength):
(JSC::DFG::SpeculativeJIT::compileCopyRest): Deleted.
(JSC::DFG::SpeculativeJIT::callOperation):
- dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
(JSC::DFG::SpeculativeJIT::compileArithRandom):
(JSC::DFG::SpeculativeJIT::compileAllocateNewArrayWithSize):
- dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
(JSC::DFG::SpeculativeJIT::compileArithRandom):
(JSC::DFG::SpeculativeJIT::compileAllocateNewArrayWithSize):
(JSC::FTL::canCompile):
(JSC::FTL::DFG::LowerDFGToB3::compileNode):
(JSC::FTL::DFG::LowerDFGToB3::compileCreateClonedArguments):
(JSC::FTL::DFG::LowerDFGToB3::compileCreateRest):
(JSC::FTL::DFG::LowerDFGToB3::compileGetRestLength):
(JSC::FTL::DFG::LowerDFGToB3::compileNewArrayBuffer):
(JSC::FTL::DFG::LowerDFGToB3::compileAllocateArrayWithSize):
(JSC::FTL::DFG::LowerDFGToB3::compileNewArrayWithSize):
(JSC::FTL::DFG::LowerDFGToB3::compileCopyRest): Deleted.
(JSC::ExecState::addressOfArgumentsStart):
(JSC::ExecState::argument):
(JSC::JIT::privateCompileMainPass):
- jit/JIT.h:
- jit/JITOpcodes.cpp:
(JSC::JIT::emit_op_argument_count):
(JSC::JIT::emit_op_create_rest):
(JSC::JIT::emit_op_copy_rest): Deleted.
- jit/JITOperations.h:
- llint/LowLevelInterpreter.asm:
- runtime/CommonSlowPaths.cpp:
(JSC::SLOW_PATH_DECL):
- runtime/CommonSlowPaths.h:
LayoutTests:
- js/regress/rest-parameter-construction-performance-expected.txt: Added.
- js/regress/rest-parameter-construction-performance.html: Added.
- js/regress/script-tests/rest-parameter-construction-performance.js: Added.
(foo):
(test1):
(test2.foo):
(test2):