Changeset 244864 in webkit for trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
- Timestamp:
- May 1, 2019, 7:40:44 PM (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
r244811 r244864 1609 1609 } 1610 1610 1611 InlineStackEntry* callerStackTop = m_inlineStackTop; 1612 InlineStackEntry inlineStackEntry(this, codeBlock, codeBlock, callee.function(), result, 1613 (VirtualRegister)inlineCallFrameStart, argumentCountIncludingThis, kind, continuationBlock); 1614 1615 // This is where the actual inlining really happens. 1616 unsigned oldIndex = m_currentIndex; 1617 m_currentIndex = 0; 1618 1619 switch (kind) { 1620 case InlineCallFrame::GetterCall: 1621 case InlineCallFrame::SetterCall: { 1622 // When inlining getter and setter calls, we setup a stack frame which does not appear in the bytecode. 1623 // Because Inlining can switch on executable, we could have a graph like this. 1624 // 1625 // BB#0 1626 // ... 1627 // 30: GetSetter 1628 // 31: MovHint(loc10) 1629 // 32: SetLocal(loc10) 1630 // 33: MovHint(loc9) 1631 // 34: SetLocal(loc9) 1632 // ... 1633 // 37: GetExecutable(@30) 1634 // ... 1635 // 41: Switch(@37) 1636 // 1637 // BB#2 1638 // 42: GetLocal(loc12, bc#7 of caller) 1639 // ... 1640 // --> callee: loc9 and loc10 are arguments of callee. 1641 // ... 1642 // <HERE, exit to callee, loc9 and loc10 are required in the bytecode> 1643 // 1644 // When we prune OSR availability at the beginning of BB#2 (bc#7 in the caller), we prune loc9 and loc10's liveness because the caller does not actually have loc9 and loc10. 1645 // However, when we begin executing the callee, we need OSR exit to be aware of where it can recover the arguments to the setter, loc9 and loc10. The MovHints in the inlined 1646 // callee make it so that if we exit at <HERE>, we can recover loc9 and loc10. 1647 for (int index = 0; index < argumentCountIncludingThis; ++index) { 1648 VirtualRegister argumentToGet = callerStackTop->remapOperand(virtualRegisterForArgument(index, registerOffset)); 1649 addToGraph(MovHint, OpInfo(argumentToGet.offset()), getDirect(argumentToGet)); 1650 } 1651 break; 1652 } 1653 default: 1654 break; 1655 } 1656 1611 1657 if (arityFixupCount) { 1612 1658 // Note: we do arity fixup in two phases: 1613 1659 // 1. We get all the values we need and MovHint them to the expected locals. 1614 // 2. We SetLocal them inside the callee's CodeOrigin. This way, if we exit, the callee's1660 // 2. We SetLocal them after that. This way, if we exit, the callee's 1615 1661 // frame is already set up. If any SetLocal exits, we have a valid exit state. 1616 1662 // This is required because if we didn't do this in two phases, we may exit in 1617 // the middle of arity fixup from the calle r's CodeOrigin. This is unsound because if1618 // we did the SetLocals in the caller's frame, the memcpy may clobber needed parts1619 // of the frame right before exiting.For example, consider if we need to pad two args:1663 // the middle of arity fixup from the callee's CodeOrigin. This is unsound because exited 1664 // code does not have arity fixup so that remaining necessary fixups are not executed. 1665 // For example, consider if we need to pad two args: 1620 1666 // [arg3][arg2][arg1][arg0] 1621 1667 // [fix ][fix ][arg3][arg2][arg1][arg0] 1622 1668 // We memcpy starting from arg0 in the direction of arg3. If we were to exit at a type check 1623 // for arg3's SetLocal in the calle r's CodeOrigin, we'd exit with a frame like so:1669 // for arg3's SetLocal in the callee's CodeOrigin, we'd exit with a frame like so: 1624 1670 // [arg3][arg2][arg1][arg2][arg1][arg0] 1625 // And the caller would then just end up thinking its argument are: 1626 // [arg3][arg2][arg1][arg2] 1671 // Since we do not perform arity fixup in the callee, this is the frame used by the callee. 1672 // And the callee would then just end up thinking its argument are: 1673 // [fix ][fix ][arg3][arg2][arg1][arg0] 1627 1674 // which is incorrect. 1628 1675 … … 1643 1690 if (registerOffsetAfterFixup != registerOffset) { 1644 1691 for (int index = 0; index < argumentCountIncludingThis; ++index) { 1645 Node* value = get(virtualRegisterForArgument(index, registerOffset)); 1646 VirtualRegister argumentToSet = m_inlineStackTop->remapOperand(virtualRegisterForArgument(index, registerOffsetAfterFixup)); 1692 VirtualRegister argumentToGet = callerStackTop->remapOperand(virtualRegisterForArgument(index, registerOffset)); 1693 Node* value = getDirect(argumentToGet); 1694 VirtualRegister argumentToSet = m_inlineStackTop->remapOperand(virtualRegisterForArgument(index)); 1647 1695 addToGraph(MovHint, OpInfo(argumentToSet.offset()), value); 1648 1696 m_setLocalQueue.append(DelayedSetLocal { currentCodeOrigin(), argumentToSet, value, ImmediateNakedSet }); … … 1650 1698 } 1651 1699 for (int index = 0; index < arityFixupCount; ++index) { 1652 VirtualRegister argumentToSet = m_inlineStackTop->remapOperand(virtualRegisterForArgument(argumentCountIncludingThis + index , registerOffsetAfterFixup));1700 VirtualRegister argumentToSet = m_inlineStackTop->remapOperand(virtualRegisterForArgument(argumentCountIncludingThis + index)); 1653 1701 addToGraph(MovHint, OpInfo(argumentToSet.offset()), undefined); 1654 1702 m_setLocalQueue.append(DelayedSetLocal { currentCodeOrigin(), argumentToSet, undefined, ImmediateNakedSet }); … … 1656 1704 1657 1705 // At this point, it's OK to OSR exit because we finished setting up 1658 // our callee's frame. We emit an ExitOK below from the callee's CodeOrigin. 1659 } 1660 1661 InlineStackEntry inlineStackEntry(this, codeBlock, codeBlock, callee.function(), result, 1662 (VirtualRegister)inlineCallFrameStart, argumentCountIncludingThis, kind, continuationBlock); 1663 1664 // This is where the actual inlining really happens. 1665 unsigned oldIndex = m_currentIndex; 1666 m_currentIndex = 0; 1706 // our callee's frame. We emit an ExitOK below. 1707 } 1667 1708 1668 1709 // At this point, it's again OK to OSR exit. … … 4372 4413 // since we only really care about 'this' in this case. But we're not going to take that 4373 4414 // shortcut. 4374 int nextRegister = registerOffset + CallFrame::headerSizeInRegisters; 4375 set(VirtualRegister(nextRegister++), base, ImmediateNakedSet); 4415 set(virtualRegisterForArgument(0, registerOffset), base, ImmediateNakedSet); 4376 4416 4377 4417 // We've set some locals, but they are not user-visible. It's still OK to exit from here. … … 4556 4596 VirtualRegister(registerOffset)).toLocal()); 4557 4597 4558 int nextRegister = registerOffset + CallFrame::headerSizeInRegisters; 4559 set(VirtualRegister(nextRegister++), base, ImmediateNakedSet); 4560 set(VirtualRegister(nextRegister++), value, ImmediateNakedSet); 4598 set(virtualRegisterForArgument(0, registerOffset), base, ImmediateNakedSet); 4599 set(virtualRegisterForArgument(1, registerOffset), value, ImmediateNakedSet); 4561 4600 4562 4601 // We've set some locals, but they are not user-visible. It's still OK to exit from here.
Note:
See TracChangeset
for help on using the changeset viewer.