Changeset 194135 in webkit
- Timestamp:
- Dec 16, 2015 1:10:09 AM (8 years ago)
- Location:
- trunk
- Files:
-
- 7 added
- 23 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r194134 r194135 1 2015-12-16 Yusuke Suzuki <utatane.tea@gmail.com> 2 3 [ES6] Handle new_generator_func / new_generator_func_exp in DFG / FTL 4 https://bugs.webkit.org/show_bug.cgi?id=152227 5 6 Reviewed by Saam Barati. 7 8 Make the test taking longer time. 9 10 * js/regress/script-tests/generator-function-create.js: 11 (test): 12 1 13 2015-12-16 Tomas Popela <tpopela@redhat.com> 2 14 -
trunk/LayoutTests/js/regress/script-tests/generator-function-create.js
r193907 r194135 8 8 return gen; 9 9 } 10 noInline(createGeneratorFunction); 10 function test() 11 { 12 for (var i = 0; i < 500; ++i) 13 createGeneratorFunction(); 14 } 15 noInline(test); 16 11 17 for (var i = 0; i < 1e4; ++i) 12 createGeneratorFunction();18 test(); -
trunk/Source/JavaScriptCore/ChangeLog
r194131 r194135 1 2015-12-16 Yusuke Suzuki <utatane.tea@gmail.com> 2 3 [ES6] Handle new_generator_func / new_generator_func_exp in DFG / FTL 4 https://bugs.webkit.org/show_bug.cgi?id=152227 5 6 Reviewed by Saam Barati. 7 8 This patch introduces new_generator_func / new_generator_func_exp into DFG and FTL. 9 We add a new DFG Node, NewGeneratorFunction. It will construct a function with GeneratorFunction's structure. 10 The structure of GeneratorFunction is different from one of Function because GeneratorFunction has the different __proto__. 11 12 * dfg/DFGAbstractInterpreterInlines.h: 13 (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects): 14 * dfg/DFGByteCodeParser.cpp: 15 (JSC::DFG::ByteCodeParser::parseBlock): 16 * dfg/DFGCapabilities.cpp: 17 (JSC::DFG::capabilityLevel): 18 * dfg/DFGClobberize.h: 19 (JSC::DFG::clobberize): 20 * dfg/DFGClobbersExitState.cpp: 21 (JSC::DFG::clobbersExitState): 22 * dfg/DFGDoesGC.cpp: 23 (JSC::DFG::doesGC): 24 * dfg/DFGFixupPhase.cpp: 25 (JSC::DFG::FixupPhase::fixupNode): 26 * dfg/DFGMayExit.cpp: 27 (JSC::DFG::mayExit): 28 * dfg/DFGNode.h: 29 (JSC::DFG::Node::convertToPhantomNewFunction): 30 (JSC::DFG::Node::hasCellOperand): 31 (JSC::DFG::Node::isFunctionAllocation): 32 * dfg/DFGNodeType.h: 33 * dfg/DFGObjectAllocationSinkingPhase.cpp: 34 * dfg/DFGPredictionPropagationPhase.cpp: 35 (JSC::DFG::PredictionPropagationPhase::propagate): 36 * dfg/DFGSafeToExecute.h: 37 (JSC::DFG::safeToExecute): 38 * dfg/DFGSpeculativeJIT.cpp: 39 (JSC::DFG::SpeculativeJIT::compileNewFunction): 40 * dfg/DFGSpeculativeJIT32_64.cpp: 41 (JSC::DFG::SpeculativeJIT::compile): 42 * dfg/DFGSpeculativeJIT64.cpp: 43 (JSC::DFG::SpeculativeJIT::compile): 44 * dfg/DFGStoreBarrierInsertionPhase.cpp: 45 * dfg/DFGStructureRegistrationPhase.cpp: 46 (JSC::DFG::StructureRegistrationPhase::run): 47 * ftl/FTLCapabilities.cpp: 48 (JSC::FTL::canCompile): 49 * ftl/FTLLowerDFGToLLVM.cpp: 50 (JSC::FTL::DFG::LowerDFGToLLVM::compileNode): 51 (JSC::FTL::DFG::LowerDFGToLLVM::compileNewFunction): 52 * tests/stress/generator-function-create-optimized.js: Added. 53 (shouldBe): 54 (g): 55 (test.return.gen): 56 (test): 57 (test2.gen): 58 (test2): 59 * tests/stress/generator-function-declaration-sinking-no-double-allocate.js: Added. 60 (shouldBe): 61 (GeneratorFunctionPrototype): 62 (call): 63 (f): 64 (sink): 65 * tests/stress/generator-function-declaration-sinking-osrexit.js: Added. 66 (shouldBe): 67 (GeneratorFunctionPrototype): 68 (g): 69 (f): 70 (sink): 71 * tests/stress/generator-function-declaration-sinking-put.js: Added. 72 (shouldBe): 73 (GeneratorFunctionPrototype): 74 (g): 75 (f): 76 (sink): 77 * tests/stress/generator-function-expression-sinking-no-double-allocate.js: Added. 78 (shouldBe): 79 (GeneratorFunctionPrototype): 80 (call): 81 (f): 82 (sink): 83 * tests/stress/generator-function-expression-sinking-osrexit.js: Added. 84 (shouldBe): 85 (GeneratorFunctionPrototype): 86 (g): 87 (sink): 88 * tests/stress/generator-function-expression-sinking-put.js: Added. 89 (shouldBe): 90 (GeneratorFunctionPrototype): 91 (g): 92 (sink): 93 1 94 2015-12-15 Mark Lam <mark.lam@apple.com> 2 95 -
trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h
r194113 r194135 1761 1761 m_graph, m_codeBlock->globalObjectFor(node->origin.semantic)->arrowFunctionStructure()); 1762 1762 break; 1763 1763 1764 case NewGeneratorFunction: 1765 forNode(node).set( 1766 m_graph, m_codeBlock->globalObjectFor(node->origin.semantic)->generatorFunctionStructure()); 1767 break; 1768 1764 1769 case NewFunction: 1765 1770 forNode(node).set( -
trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
r194087 r194135 4558 4558 } 4559 4559 4560 case op_new_func: { 4560 case op_new_func: 4561 case op_new_generator_func: { 4561 4562 FunctionExecutable* decl = m_inlineStackTop->m_profiledBlock->functionDecl(currentInstruction[3].u.operand); 4562 4563 FrozenValue* frozen = m_graph.freezeStrong(decl); 4563 set(VirtualRegister(currentInstruction[1].u.operand), 4564 addToGraph(NewFunction, OpInfo(frozen), get(VirtualRegister(currentInstruction[2].u.operand)))); 4564 NodeType op = (opcodeID == op_new_generator_func) ? NewGeneratorFunction : NewFunction; 4565 set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(op, OpInfo(frozen), get(VirtualRegister(currentInstruction[2].u.operand)))); 4566 static_assert(OPCODE_LENGTH(op_new_func) == OPCODE_LENGTH(op_new_generator_func), "The length of op_new_func should eqaual to one of op_new_generator_func"); 4565 4567 NEXT_OPCODE(op_new_func); 4566 4568 } 4567 4569 4568 4570 case op_new_func_exp: 4571 case op_new_generator_func_exp: 4569 4572 case op_new_arrow_func_exp: { 4570 4573 FunctionExecutable* expr = m_inlineStackTop->m_profiledBlock->functionExpr(currentInstruction[3].u.operand); 4571 4574 FrozenValue* frozen = m_graph.freezeStrong(expr); 4572 set(VirtualRegister(currentInstruction[1].u.operand),4573 addToGraph(NewFunction, OpInfo(frozen), get(VirtualRegister(currentInstruction[2].u.operand))));4574 4575 if (opcodeID == op_new_func_exp ) {4575 NodeType op = (opcodeID == op_new_generator_func_exp) ? NewGeneratorFunction : NewFunction; 4576 set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(op, OpInfo(frozen), get(VirtualRegister(currentInstruction[2].u.operand)))); 4577 4578 if (opcodeID == op_new_func_exp || opcodeID == op_new_generator_func_exp) { 4576 4579 // Curly braces are necessary 4580 static_assert(OPCODE_LENGTH(op_new_func_exp) == OPCODE_LENGTH(op_new_generator_func_exp), "The length of op_new_func_exp should eqaual to one of op_new_generator_func_exp"); 4577 4581 NEXT_OPCODE(op_new_func_exp); 4578 4582 } else { -
trunk/Source/JavaScriptCore/dfg/DFGCapabilities.cpp
r194036 r194135 216 216 case op_new_func: 217 217 case op_new_func_exp: 218 case op_new_generator_func: 219 case op_new_generator_func_exp: 218 220 case op_new_arrow_func_exp: 219 221 case op_create_lexical_environment: -
trunk/Source/JavaScriptCore/dfg/DFGClobberize.h
r194113 r194135 1034 1034 case NewArrowFunction: 1035 1035 case NewFunction: 1036 case NewGeneratorFunction: 1036 1037 if (node->castOperand<FunctionExecutable*>()->singletonFunction()->isStillValid()) 1037 1038 write(Watchpoint_fire); -
trunk/Source/JavaScriptCore/dfg/DFGClobbersExitState.cpp
r190076 r194135 78 78 case NewArrowFunction: 79 79 case NewFunction: 80 case NewGeneratorFunction: 80 81 // Like above, but with the JSFunction allocation caveat. 81 82 return node->castOperand<FunctionExecutable*>()->singletonFunction()->isStillValid(); -
trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp
r194087 r194135 248 248 case NewArrowFunction: 249 249 case NewFunction: 250 case NewGeneratorFunction: 250 251 case NewTypedArray: 251 252 case ThrowReferenceError: -
trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
r194113 r194135 1388 1388 case CreateScopedArguments: 1389 1389 case CreateActivation: 1390 case NewFunction: { 1390 case NewFunction: 1391 case NewGeneratorFunction: { 1391 1392 fixEdge<CellUse>(node->child1()); 1392 1393 break; -
trunk/Source/JavaScriptCore/dfg/DFGMayExit.cpp
r192814 r194135 144 144 case NewFunction: 145 145 case NewArrowFunction: 146 case NewGeneratorFunction: 146 147 case NewStringObject: 147 148 case CreateActivation: -
trunk/Source/JavaScriptCore/dfg/DFGNode.h
r194113 r194135 586 586 void convertToPhantomNewFunction() 587 587 { 588 ASSERT(m_op == NewFunction || m_op == NewArrowFunction );588 ASSERT(m_op == NewFunction || m_op == NewArrowFunction || m_op == NewGeneratorFunction); 589 589 m_op = PhantomNewFunction; 590 590 m_flags |= NodeMustGenerate; … … 1357 1357 case NewFunction: 1358 1358 case NewArrowFunction: 1359 case NewGeneratorFunction: 1359 1360 case CreateActivation: 1360 1361 case MaterializeCreateActivation: … … 1575 1576 case NewArrowFunction: 1576 1577 case NewFunction: 1578 case NewGeneratorFunction: 1577 1579 return true; 1578 1580 default: -
trunk/Source/JavaScriptCore/dfg/DFGNodeType.h
r194087 r194135 313 313 \ 314 314 macro(NewArrowFunction, NodeResultJS) \ 315 macro(NewGeneratorFunction, NodeResultJS) \ 315 316 \ 316 317 /* These aren't terminals but always exit */ \ -
trunk/Source/JavaScriptCore/dfg/DFGObjectAllocationSinkingPhase.cpp
r193766 r194135 140 140 // replace any use of those pointers by the corresponding 141 141 // materialization 142 enum class Kind { Escaped, Object, Activation, Function, NewArrowFunction };142 enum class Kind { Escaped, Object, Activation, Function, ArrowFunction, GeneratorFunction }; 143 143 144 144 explicit Allocation(Node* identifier = nullptr, Kind kind = Kind::Escaped) … … 234 234 bool isFunctionAllocation() const 235 235 { 236 return m_kind == Kind::Function || m_kind == Kind::NewArrowFunction; 237 } 238 239 bool isArrowFunctionAllocation() const 240 { 241 return m_kind == Kind::NewArrowFunction; 236 return m_kind == Kind::Function || m_kind == Kind::ArrowFunction || m_kind == Kind::GeneratorFunction; 242 237 } 243 238 … … 275 270 break; 276 271 277 case Kind::NewArrowFunction: 278 out.print("NewArrowFunction"); 272 case Kind::ArrowFunction: 273 out.print("ArrowFunction"); 274 break; 275 276 case Kind::GeneratorFunction: 277 out.print("GeneratorFunction"); 279 278 break; 280 279 … … 838 837 839 838 case NewFunction: 840 case NewArrowFunction: { 839 case NewArrowFunction: 840 case NewGeneratorFunction: { 841 841 if (node->castOperand<FunctionExecutable*>()->singletonFunction()->isStillValid()) { 842 842 m_heap.escape(node->child1().node()); … … 844 844 } 845 845 846 target = &m_heap.newAllocation(node, Allocation::Kind::Function); 846 if (node->op() == NewGeneratorFunction) 847 target = &m_heap.newAllocation(node, Allocation::Kind::GeneratorFunction); 848 else if (node->op() == NewArrowFunction) 849 target = &m_heap.newAllocation(node, Allocation::Kind::ArrowFunction); 850 else 851 target = &m_heap.newAllocation(node, Allocation::Kind::Function); 847 852 writes.add(FunctionExecutablePLoc, LazyNode(node->cellOperand())); 848 853 writes.add(FunctionActivationPLoc, LazyNode(node->child1().node())); … … 1447 1452 } 1448 1453 1449 case Allocation::Kind::NewArrowFunction: 1454 case Allocation::Kind::ArrowFunction: 1455 case Allocation::Kind::GeneratorFunction: 1450 1456 case Allocation::Kind::Function: { 1451 1457 FrozenValue* executable = allocation.identifier()->cellOperand(); 1452 1458 1453 NodeType nodeType = allocation.kind() == Allocation::Kind::NewArrowFunction ? NewArrowFunction : NewFunction; 1459 NodeType nodeType = 1460 allocation.kind() == Allocation::Kind::ArrowFunction ? NewArrowFunction : 1461 allocation.kind() == Allocation::Kind::GeneratorFunction ? NewGeneratorFunction : NewFunction; 1454 1462 1455 1463 return m_graph.addNode( … … 1783 1791 case NewArrowFunction: 1784 1792 case NewFunction: 1793 case NewGeneratorFunction: 1785 1794 node->convertToPhantomNewFunction(); 1786 1795 break; … … 2034 2043 2035 2044 case NewFunction: 2036 case NewArrowFunction: { 2045 case NewArrowFunction: 2046 case NewGeneratorFunction: { 2037 2047 Vector<PromotedHeapLocation> locations = m_locationsForAllocation.get(escapee); 2038 2048 ASSERT(locations.size() == 2); -
trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp
r194087 r194135 210 210 case GetCallee: 211 211 case NewArrowFunction: 212 case NewFunction: { 212 case NewFunction: 213 case NewGeneratorFunction: { 213 214 changed |= setPrediction(SpecFunction); 214 215 break; -
trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h
r194087 r194135 269 269 case NewArrowFunction: 270 270 case NewFunction: 271 case NewGeneratorFunction: 271 272 case Jump: 272 273 case Branch: -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
r194113 r194135 51 51 #include "JSCInlines.h" 52 52 #include "JSEnvironmentRecord.h" 53 #include "JSGeneratorFunction.h" 53 54 #include "JSLexicalEnvironment.h" 54 55 #include "LinkBuffer.h" … … 5373 5374 { 5374 5375 NodeType nodeType = node->op(); 5375 ASSERT(nodeType == NewFunction || nodeType == NewArrowFunction );5376 ASSERT(nodeType == NewFunction || nodeType == NewArrowFunction || nodeType == NewGeneratorFunction); 5376 5377 5377 5378 SpeculateCellOperand scope(this, node->child1()); … … 5411 5412 callOperation(operationNewArrowFunction, resultGPR, scopeGPR, executable, thisValueTagGPR, thisValuePayloadGPR); 5412 5413 #endif 5414 else if (nodeType == NewGeneratorFunction) 5415 callOperation(operationNewGeneratorFunction, resultGPR, scopeGPR, executable); 5413 5416 else 5414 5417 callOperation(operationNewFunction, resultGPR, scopeGPR, executable); … … 5418 5421 } 5419 5422 5420 Structure* structure = nodeType == NewArrowFunction 5421 ? m_jit.graph().globalObjectFor(node->origin.semantic)->arrowFunctionStructure() 5422 : m_jit.graph().globalObjectFor(node->origin.semantic)->functionStructure(); 5423 Structure* structure = 5424 nodeType == NewArrowFunction ? m_jit.graph().globalObjectFor(node->origin.semantic)->arrowFunctionStructure() : 5425 nodeType == NewGeneratorFunction ? m_jit.graph().globalObjectFor(node->origin.semantic)->generatorFunctionStructure() : 5426 m_jit.graph().globalObjectFor(node->origin.semantic)->functionStructure(); 5423 5427 5424 5428 GPRTemporary result(this); … … 5436 5440 5437 5441 addSlowPathGenerator(slowPathCall(slowPath, this, operationNewFunctionWithInvalidatedReallocationWatchpoint, resultGPR, scopeGPR, executable)); 5442 } 5443 5444 if (nodeType == NewGeneratorFunction) { 5445 compileNewFunctionCommon<JSGeneratorFunction>(resultGPR, structure, scratch1GPR, scratch2GPR, scopeGPR, slowPath, JSGeneratorFunction::allocationSize(0), executable, JSGeneratorFunction::offsetOfScopeChain(), JSGeneratorFunction::offsetOfExecutable(), JSGeneratorFunction::offsetOfRareData()); 5446 5447 addSlowPathGenerator(slowPathCall(slowPath, this, operationNewGeneratorFunctionWithInvalidatedReallocationWatchpoint, resultGPR, scopeGPR, executable)); 5438 5448 } 5439 5449 -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
r194087 r194135 4409 4409 case NewFunction: 4410 4410 case NewArrowFunction: 4411 case NewGeneratorFunction: 4411 4412 compileNewFunction(node); 4412 4413 break; -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
r194087 r194135 4398 4398 case NewFunction: 4399 4399 case NewArrowFunction: 4400 case NewGeneratorFunction: 4400 4401 compileNewFunction(node); 4401 4402 break; -
trunk/Source/JavaScriptCore/dfg/DFGStoreBarrierInsertionPhase.cpp
r190076 r194135 307 307 case NewArrowFunction: 308 308 case NewFunction: 309 case NewGeneratorFunction: 309 310 // Nodes that allocate get to set their epoch because for those nodes we know 310 311 // that they will be the newest object in the heap. -
trunk/Source/JavaScriptCore/dfg/DFGStructureRegistrationPhase.cpp
r193653 r194135 147 147 registerStructure(m_graph.globalObjectFor(node->origin.semantic)->functionStructure()); 148 148 break; 149 case NewGeneratorFunction: 150 registerStructure(m_graph.globalObjectFor(node->origin.semantic)->generatorFunctionStructure()); 151 break; 149 152 150 153 default: -
trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp
r194087 r194135 112 112 case NewArrowFunction: 113 113 case NewFunction: 114 case NewGeneratorFunction: 114 115 case GetClosureVar: 115 116 case PutClosureVar: -
trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp
r194126 r194135 53 53 #include "JSArrowFunction.h" 54 54 #include "JSCInlines.h" 55 #include "JSGeneratorFunction.h" 55 56 #include "JSLexicalEnvironment.h" 56 57 #include "OperandsInlines.h" … … 755 756 case NewFunction: 756 757 case NewArrowFunction: 758 case NewGeneratorFunction: 757 759 compileNewFunction(); 758 760 break; … … 3561 3563 void compileNewFunction() 3562 3564 { 3563 ASSERT(m_node->op() == NewFunction || m_node->op() == NewArrowFunction); 3564 3565 ASSERT(m_node->op() == NewFunction || m_node->op() == NewArrowFunction || m_node->op() == NewGeneratorFunction); 3565 3566 bool isArrowFunction = m_node->op() == NewArrowFunction; 3567 bool isGeneratorFunction = m_node->op() == NewGeneratorFunction; 3566 3568 3567 3569 LValue scope = lowCell(m_node->child1()); … … 3570 3572 FunctionExecutable* executable = m_node->castOperand<FunctionExecutable*>(); 3571 3573 if (executable->singletonFunction()->isStillValid()) { 3572 LValue callResult = isArrowFunction 3573 ? vmCall(m_out.int64, m_out.operation(operationNewArrowFunction), m_callFrame, scope, weakPointer(executable), thisValue) 3574 : vmCall(m_out.int64, m_out.operation(operationNewFunction), m_callFrame, scope, weakPointer(executable)); 3574 LValue callResult = 3575 isArrowFunction ? vmCall(m_out.int64, m_out.operation(operationNewArrowFunction), m_callFrame, scope, weakPointer(executable), thisValue) : 3576 isGeneratorFunction ? vmCall(m_out.int64, m_out.operation(operationNewGeneratorFunction), m_callFrame, scope, weakPointer(executable)) : 3577 vmCall(m_out.int64, m_out.operation(operationNewFunction), m_callFrame, scope, weakPointer(executable)); 3575 3578 setJSValue(callResult); 3576 3579 return; 3577 3580 } 3578 3581 3579 Structure* structure = isArrowFunction 3580 ? m_graph.globalObjectFor(m_node->origin.semantic)->arrowFunctionStructure() 3581 : m_graph.globalObjectFor(m_node->origin.semantic)->functionStructure(); 3582 Structure* structure = 3583 isArrowFunction ? m_graph.globalObjectFor(m_node->origin.semantic)->arrowFunctionStructure() : 3584 isGeneratorFunction ? m_graph.globalObjectFor(m_node->origin.semantic)->generatorFunctionStructure() : 3585 m_graph.globalObjectFor(m_node->origin.semantic)->functionStructure(); 3582 3586 3583 3587 LBasicBlock slowPath = FTL_NEW_BLOCK(m_out, ("NewFunction slow path")); … … 3586 3590 LBasicBlock lastNext = m_out.insertNewBlocksBefore(slowPath); 3587 3591 3588 LValue fastObject = isArrowFunction 3589 ? allocateObject<JSArrowFunction>(structure, m_out.intPtrZero, slowPath) 3590 : allocateObject<JSFunction>(structure, m_out.intPtrZero, slowPath); 3592 LValue fastObject = 3593 isArrowFunction ? allocateObject<JSArrowFunction>(structure, m_out.intPtrZero, slowPath) : 3594 isGeneratorFunction ? allocateObject<JSGeneratorFunction>(structure, m_out.intPtrZero, slowPath) : 3595 allocateObject<JSFunction>(structure, m_out.intPtrZero, slowPath); 3591 3596 3592 3597 … … 3617 3622 locations[0].directGPR(), locations[1].directGPR(), 3618 3623 CCallHelpers::TrustedImmPtr(executable), locations[2].directGPR()); 3624 } 3625 if (isGeneratorFunction) { 3626 return createLazyCallGenerator( 3627 operationNewGeneratorFunctionWithInvalidatedReallocationWatchpoint, 3628 locations[0].directGPR(), locations[1].directGPR(), 3629 CCallHelpers::TrustedImmPtr(executable)); 3619 3630 } 3620 3631 return createLazyCallGenerator(
Note: See TracChangeset
for help on using the changeset viewer.