Changeset 223159 in webkit
- Timestamp:
- Oct 10, 2017 5:09:20 PM (7 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r223155 r223159 1 2017-10-10 Robin Morisset <rmorisset@apple.com> 2 3 Avoid allocating useless landingBlocks in DFGByteCodeParser::handleInlining() 4 https://bugs.webkit.org/show_bug.cgi?id=177926 5 6 Reviewed by Saam Barati. 7 8 When doing polyvariant inlining, there used to be a landing block for each callee, each of which was then linked to a continuation block. 9 With this change, we allocate the continuation block first, and pass it to the inlining routine so that op_ret in the callee link directly to it. 10 The only subtlety is that when inlining an intrinsic we must do the jump by hand, and also remember to call processSetLocalQueue with nextOffset before it. 11 12 * dfg/DFGByteCodeParser.cpp: 13 (JSC::DFG::ByteCodeParser::inlineCall): 14 (JSC::DFG::ByteCodeParser::attemptToInlineCall): 15 (JSC::DFG::ByteCodeParser::handleInlining): 16 (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry): 17 (JSC::DFG::ByteCodeParser::parse): 18 1 19 2017-10-10 Guillaume Emont <guijemont@igalia.com> 2 20 -
trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
r223112 r223159 229 229 bool handleInlining(Node* callTargetNode, int resultOperand, const CallLinkStatus&, int registerOffset, VirtualRegister thisArgument, VirtualRegister argumentsArgument, unsigned argumentsOffset, int argumentCountIncludingThis, unsigned nextOffset, NodeType callOp, InlineCallFrame::Kind, SpeculatedType prediction); 230 230 template<typename ChecksFunctor> 231 bool attemptToInlineCall(Node* callTargetNode, int resultOperand, CallVariant, int registerOffset, int argumentCountIncludingThis, unsigned nextOffset, InlineCallFrame::Kind, SpeculatedType prediction, unsigned& inliningBalance, const ChecksFunctor& insertChecks);231 bool attemptToInlineCall(Node* callTargetNode, int resultOperand, CallVariant, int registerOffset, int argumentCountIncludingThis, unsigned nextOffset, InlineCallFrame::Kind, SpeculatedType prediction, unsigned& inliningBalance, BasicBlock* continuationBlock, const ChecksFunctor& insertChecks); 232 232 template<typename ChecksFunctor> 233 void inlineCall(Node* callTargetNode, int resultOperand, CallVariant, int registerOffset, int argumentCountIncludingThis, unsigned nextOffset, InlineCallFrame::Kind, const ChecksFunctor& insertChecks);233 void inlineCall(Node* callTargetNode, int resultOperand, CallVariant, int registerOffset, int argumentCountIncludingThis, unsigned nextOffset, InlineCallFrame::Kind, BasicBlock* continuationBlock, const ChecksFunctor& insertChecks); 234 234 void cancelLinkingForBlock(InlineStackEntry*, BasicBlock*); // Only works when the given block is the last one to have been added for that inline stack entry. 235 235 // Handle intrinsic functions. Return true if it succeeded, false if we need to plant a call. … … 1158 1158 VirtualRegister inlineCallFrameStart, 1159 1159 int argumentCountIncludingThis, 1160 InlineCallFrame::Kind); 1160 InlineCallFrame::Kind, 1161 BasicBlock* continuationBlock); 1161 1162 1162 1163 ~InlineStackEntry() … … 1511 1512 1512 1513 template<typename ChecksFunctor> 1513 void ByteCodeParser::inlineCall(Node* callTargetNode, int resultOperand, CallVariant callee, int registerOffset, int argumentCountIncludingThis, unsigned nextOffset, InlineCallFrame::Kind kind, const ChecksFunctor& insertChecks)1514 void ByteCodeParser::inlineCall(Node* callTargetNode, int resultOperand, CallVariant callee, int registerOffset, int argumentCountIncludingThis, unsigned nextOffset, InlineCallFrame::Kind kind, BasicBlock* continuationBlock, const ChecksFunctor& insertChecks) 1514 1515 { 1515 1516 CodeSpecializationKind specializationKind = InlineCallFrame::specializationKindFor(kind); … … 1607 1608 1608 1609 InlineStackEntry inlineStackEntry(this, codeBlock, codeBlock, callee.function(), resultReg, 1609 (VirtualRegister)inlineCallFrameStart, argumentCountIncludingThis, kind );1610 (VirtualRegister)inlineCallFrameStart, argumentCountIncludingThis, kind, continuationBlock); 1610 1611 1611 1612 // This is where the actual inlining really happens. … … 1659 1660 1660 1661 template<typename ChecksFunctor> 1661 bool ByteCodeParser::attemptToInlineCall(Node* callTargetNode, int resultOperand, CallVariant callee, int registerOffset, int argumentCountIncludingThis, unsigned nextOffset, InlineCallFrame::Kind kind, SpeculatedType prediction, unsigned& inliningBalance, const ChecksFunctor& insertChecks)1662 bool ByteCodeParser::attemptToInlineCall(Node* callTargetNode, int resultOperand, CallVariant callee, int registerOffset, int argumentCountIncludingThis, unsigned nextOffset, InlineCallFrame::Kind kind, SpeculatedType prediction, unsigned& inliningBalance, BasicBlock* continuationBlock, const ChecksFunctor& insertChecks) 1662 1663 { 1663 1664 CodeSpecializationKind specializationKind = InlineCallFrame::specializationKindFor(kind); … … 1682 1683 didInsertChecks = true; 1683 1684 }; 1685 1686 auto endSpecialCase = [&] () { 1687 RELEASE_ASSERT(didInsertChecks); 1688 addToGraph(Phantom, callTargetNode); 1689 emitArgumentPhantoms(registerOffset, argumentCountIncludingThis); 1690 inliningBalance--; 1691 if (continuationBlock) { 1692 m_currentIndex = nextOffset; 1693 m_exitOK = true; 1694 processSetLocalQueue(); 1695 addJumpTo(continuationBlock); 1696 } 1697 }; 1684 1698 1685 1699 if (InternalFunction* function = callee.internalFunction()) { 1686 1700 if (handleConstantInternalFunction(callTargetNode, resultOperand, function, registerOffset, argumentCountIncludingThis, specializationKind, prediction, insertChecksWithAccounting)) { 1687 RELEASE_ASSERT(didInsertChecks); 1688 addToGraph(Phantom, callTargetNode); 1689 emitArgumentPhantoms(registerOffset, argumentCountIncludingThis); 1690 inliningBalance--; 1701 endSpecialCase(); 1691 1702 return true; 1692 1703 } … … 1698 1709 if (intrinsic != NoIntrinsic) { 1699 1710 if (handleIntrinsicCall(callTargetNode, resultOperand, intrinsic, registerOffset, argumentCountIncludingThis, prediction, insertChecksWithAccounting)) { 1700 RELEASE_ASSERT(didInsertChecks); 1701 addToGraph(Phantom, callTargetNode); 1702 emitArgumentPhantoms(registerOffset, argumentCountIncludingThis); 1703 inliningBalance--; 1711 endSpecialCase(); 1704 1712 return true; 1705 1713 } … … 1712 1720 if (const DOMJIT::Signature* signature = callee.signatureFor(specializationKind)) { 1713 1721 if (handleDOMJITCall(callTargetNode, resultOperand, signature, registerOffset, argumentCountIncludingThis, prediction, insertChecksWithAccounting)) { 1714 RELEASE_ASSERT(didInsertChecks); 1715 addToGraph(Phantom, callTargetNode); 1716 emitArgumentPhantoms(registerOffset, argumentCountIncludingThis); 1717 inliningBalance--; 1722 endSpecialCase(); 1718 1723 return true; 1719 1724 } … … 1728 1733 1729 1734 Instruction* savedCurrentInstruction = m_currentInstruction; 1730 inlineCall(callTargetNode, resultOperand, callee, registerOffset, argumentCountIncludingThis, nextOffset, kind, insertChecks);1735 inlineCall(callTargetNode, resultOperand, callee, registerOffset, argumentCountIncludingThis, nextOffset, kind, continuationBlock, insertChecks); 1731 1736 inliningBalance -= myInliningCost; 1732 1737 m_currentInstruction = savedCurrentInstruction; … … 1796 1801 callTargetNode, resultOperand, callLinkStatus[0], registerOffset, 1797 1802 argumentCountIncludingThis, nextOffset, kind, prediction, 1798 inliningBalance, [&] (CodeBlock* codeBlock) {1803 inliningBalance, nullptr, [&] (CodeBlock* codeBlock) { 1799 1804 emitFunctionChecks(callLinkStatus[0], callTargetNode, thisArgument); 1800 1805 … … 1940 1945 m_currentBlock->didLink(); 1941 1946 1942 // Each inlined callee will have a landing block that it returns at. They should all have jumps 1943 // to the continuation block, which we create last. 1944 Vector<BasicBlock*> landingBlocks; 1947 BasicBlock* continuationBlock = allocateUntargetableBlock(); 1948 VERBOSE_LOG("Adding untargetable block ", RawPointer(continuationBlock), " (continuation)\n"); 1945 1949 1946 1950 // We may force this true if we give up on inlining any of the edges. … … 1961 1965 myCallTargetNode, resultOperand, callLinkStatus[i], registerOffset, 1962 1966 argumentCountIncludingThis, nextOffset, kind, prediction, 1963 inliningBalance, [&] (CodeBlock*) { });1967 inliningBalance, continuationBlock, [&] (CodeBlock*) { }); 1964 1968 1965 1969 if (!inliningResult) { … … 1984 1988 } 1985 1989 data.cases.append(SwitchCase(m_graph.freeze(thingToCaseOn), calleeEntryBlock)); 1986 m_currentIndex = nextOffset;1987 m_exitOK = true;1988 processSetLocalQueue(); // This only comes into play for intrinsics, since normal inlined code will leave an empty queue.1989 if (Node* terminal = m_currentBlock->terminal())1990 ASSERT_UNUSED(terminal, terminal->op() == TailCall || terminal->op() == TailCallVarargs || terminal->op() == TailCallForwardVarargs);1991 else {1992 // FIXME: https://bugs.webkit.org/show_bug.cgi?id=177926 we can avoid this indirection in the case of normal inlined call1993 // by passing the continuation block all the way into inlineStackEntry->m_continuationBlock in inlineCall.1994 // It is not trivial because of the SetLocalQueue managed by intrinsics.1995 addToGraph(Jump);1996 landingBlocks.append(m_currentBlock);1997 }1998 VERBOSE_LOG("Marking ", RawPointer(m_currentBlock), " as linked (tail of poly inlinee)\n");1999 m_currentBlock->didLink();2000 2001 1990 VERBOSE_LOG("Finished inlining ", callLinkStatus[i], " at ", currentCodeOrigin(), ".\n"); 2002 1991 } 2003 2004 BasicBlock* slowPathBlock = allocateUntargetableBlock(); 1992 1993 // Slow path block 1994 m_currentBlock = allocateUntargetableBlock(); 2005 1995 m_currentIndex = oldOffset; 2006 1996 m_exitOK = true; 2007 data.fallThrough = BranchTarget(slowPathBlock); 2008 VERBOSE_LOG("Marking ", RawPointer(slowPathBlock), " as linked (slow path block)\n"); 2009 slowPathBlock->didLink(); 1997 data.fallThrough = BranchTarget(m_currentBlock); 2010 1998 prepareToParseBlock(); 2011 m_currentBlock = slowPathBlock;2012 1999 Node* myCallTargetNode = getDirect(calleeReg); 2013 2000 if (couldTakeSlowPath) { … … 2022 2009 2023 2010 set(VirtualRegister(resultOperand), addToGraph(BottomValue)); 2024 VERBOSE_LOG("coul tTakeSlowPath was wrong\n");2011 VERBOSE_LOG("couldTakeSlowPath was false\n"); 2025 2012 } 2026 2013 … … 2028 2015 m_exitOK = true; // Origin changed, so it's fine to exit again. 2029 2016 processSetLocalQueue(); 2017 2030 2018 if (Node* terminal = m_currentBlock->terminal()) 2031 2019 ASSERT_UNUSED(terminal, terminal->op() == TailCall || terminal->op() == TailCallVarargs || terminal->op() == TailCallForwardVarargs); 2032 2020 else { 2033 addToGraph(Jump); 2034 landingBlocks.append(m_currentBlock); 2035 } 2036 2037 // Continuation block 2038 m_currentBlock = allocateUntargetableBlock(); 2039 VERBOSE_LOG("Adding untargetable block ", RawPointer(m_currentBlock), " (continuation)\n"); 2021 addJumpTo(continuationBlock); 2022 } 2023 2040 2024 prepareToParseBlock(); 2041 2042 for (auto &landingBlock : landingBlocks) {2043 landingBlock->terminal()->targetBlock() = m_currentBlock;2044 landingBlock->didLink();2045 VERBOSE_LOG("We linked ", RawPointer(m_currentBlock), " (landing block) to the continuation block \n");2046 }2047 2025 2048 2026 m_currentIndex = oldOffset; 2027 m_currentBlock = continuationBlock; 2049 2028 m_exitOK = true; 2050 2029 … … 6152 6131 VirtualRegister inlineCallFrameStart, 6153 6132 int argumentCountIncludingThis, 6154 InlineCallFrame::Kind kind) 6133 InlineCallFrame::Kind kind, 6134 BasicBlock* continuationBlock) 6155 6135 : m_byteCodeParser(byteCodeParser) 6156 6136 , m_codeBlock(codeBlock) 6157 6137 , m_profiledBlock(profiledBlock) 6158 , m_continuationBlock( nullptr)6138 , m_continuationBlock(continuationBlock) 6159 6139 , m_returnValue(returnValueVR) 6160 6140 , m_caller(byteCodeParser->m_inlineStackTop) … … 6361 6341 InlineStackEntry inlineStackEntry( 6362 6342 this, m_codeBlock, m_profiledBlock, 0, VirtualRegister(), VirtualRegister(), 6363 m_codeBlock->numParameters(), InlineCallFrame::Call );6343 m_codeBlock->numParameters(), InlineCallFrame::Call, nullptr); 6364 6344 6365 6345 parseCodeBlock();
Note: See TracChangeset
for help on using the changeset viewer.