Changeset 166276 in webkit


Ignore:
Timestamp:
Mar 25, 2014 7:14:40 PM (10 years ago)
Author:
fpizlo@apple.com
Message:

DFG::ByteCodeParser::SetMode should distinguish between setting immediately without a flush and setting immediately with a flush
https://bugs.webkit.org/show_bug.cgi?id=130760

Reviewed by Mark Hahnenberg.

  • dfg/DFGByteCodeParser.cpp:

(JSC::DFG::ByteCodeParser::setLocal):
(JSC::DFG::ByteCodeParser::setArgument):
(JSC::DFG::ByteCodeParser::handleInlining):
(JSC::DFG::ByteCodeParser::parseBlock):

  • tests/stress/assign-argument-in-inlined-call.js: Added.

(f1):
(getF2Arguments):
(f2):
(f3):

  • tests/stress/assign-captured-argument-in-inlined-call.js: Added.

(f1):
(f2):
(f3):

Location:
trunk/Source/JavaScriptCore
Files:
2 added
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r166266 r166276  
     12014-03-25  Filip Pizlo  <fpizlo@apple.com>
     2
     3        DFG::ByteCodeParser::SetMode should distinguish between setting immediately without a flush and setting immediately with a flush
     4        https://bugs.webkit.org/show_bug.cgi?id=130760
     5
     6        Reviewed by Mark Hahnenberg.
     7
     8        * dfg/DFGByteCodeParser.cpp:
     9        (JSC::DFG::ByteCodeParser::setLocal):
     10        (JSC::DFG::ByteCodeParser::setArgument):
     11        (JSC::DFG::ByteCodeParser::handleInlining):
     12        (JSC::DFG::ByteCodeParser::parseBlock):
     13        * tests/stress/assign-argument-in-inlined-call.js: Added.
     14        (f1):
     15        (getF2Arguments):
     16        (f2):
     17        (f3):
     18        * tests/stress/assign-captured-argument-in-inlined-call.js: Added.
     19        (f1):
     20        (f2):
     21        (f3):
     22
    1232014-03-25  Filip Pizlo  <fpizlo@apple.com>
    224
  • trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp

    r166142 r166276  
    250250    }
    251251   
    252     enum SetMode { NormalSet, ImmediateSet };
     252    enum SetMode {
     253        // A normal set which follows a two-phase commit that spans code origins. During
     254        // the current code origin it issues a MovHint, and at the start of the next
     255        // code origin there will be a SetLocal. If the local needs flushing, the second
     256        // SetLocal will be preceded with a Flush.
     257        NormalSet,
     258       
     259        // A set where the SetLocal happens immediately and there is still a Flush. This
     260        // is relevant when assigning to a local in tricky situations for the delayed
     261        // SetLocal logic but where we know that we have not performed any side effects
     262        // within this code origin. This is a safe replacement for NormalSet anytime we
     263        // know that we have not yet performed side effects in this code origin.
     264        ImmediateSetWithFlush,
     265       
     266        // A set where the SetLocal happens immediately and we do not Flush it even if
     267        // this is a local that is marked as needing it. This is relevant when
     268        // initializing locals at the top of a function.
     269        ImmediateNakedSet
     270    };
    253271    Node* setDirect(VirtualRegister operand, Node* value, SetMode setMode = NormalSet)
    254272    {
     
    341359        bool isCaptured = m_codeBlock->isCaptured(operand, inlineCallFrame());
    342360       
    343         if (setMode == NormalSet) {
     361        if (setMode != ImmediateNakedSet) {
    344362            ArgumentPosition* argumentPosition = findArgumentPositionForLocal(operand);
    345363            if (isCaptured || argumentPosition)
     
    400418        // then make sure that it's never unboxed.
    401419        if (argument) {
    402             if (setMode == NormalSet)
     420            if (setMode != ImmediateNakedSet)
    403421                flushDirect(operand);
    404422        } else if (m_codeBlock->specializationKind() == CodeForConstruct)
     
    14001418    if (callLinkStatus.isClosureCall()) {
    14011419        VariableAccessData* calleeVariable =
    1402             set(VirtualRegister(JSStack::Callee), callTargetNode, ImmediateSet)->variableAccessData();
     1420            set(VirtualRegister(JSStack::Callee), callTargetNode, ImmediateNakedSet)->variableAccessData();
    14031421        VariableAccessData* scopeVariable =
    1404             set(VirtualRegister(JSStack::ScopeChain), addToGraph(GetScope, callTargetNode), ImmediateSet)->variableAccessData();
     1422            set(VirtualRegister(JSStack::ScopeChain), addToGraph(GetScope, callTargetNode), ImmediateNakedSet)->variableAccessData();
    14051423       
    14061424        calleeVariable->mergeShouldNeverUnbox(true);
     
    21482166            // Initialize all locals to undefined.
    21492167            for (int i = 0; i < m_inlineStackTop->m_codeBlock->m_numVars; ++i)
    2150                 set(virtualRegisterForLocal(i), constantUndefined(), ImmediateSet);
     2168                set(virtualRegisterForLocal(i), constantUndefined(), ImmediateNakedSet);
    21512169            if (m_inlineStackTop->m_codeBlock->specializationKind() == CodeForConstruct)
    2152                 set(virtualRegisterForArgument(0), constantUndefined(), ImmediateSet);
     2170                set(virtualRegisterForArgument(0), constantUndefined(), ImmediateNakedSet);
    21532171            NEXT_OPCODE(op_enter);
    21542172           
     
    28462864            if (inlineCallFrame()) {
    28472865                ASSERT(m_inlineStackTop->m_returnValue.isValid());
    2848                 setDirect(m_inlineStackTop->m_returnValue, get(VirtualRegister(currentInstruction[1].u.operand)), ImmediateSet);
     2866                setDirect(m_inlineStackTop->m_returnValue, get(VirtualRegister(currentInstruction[1].u.operand)), ImmediateSetWithFlush);
    28492867                m_inlineStackTop->m_didReturn = true;
    28502868                if (m_inlineStackTop->m_unlinkedBlocks.isEmpty()) {
     
    29292947            // look like the bytecode had done it.
    29302948            int nextRegister = registerOffset + JSStack::CallFrameHeaderSize;
    2931             set(VirtualRegister(nextRegister++), get(VirtualRegister(thisReg)), ImmediateSet);
     2949            set(VirtualRegister(nextRegister++), get(VirtualRegister(thisReg)), ImmediateNakedSet);
    29322950            for (unsigned argument = 1; argument < argCount; ++argument)
    2933                 set(VirtualRegister(nextRegister++), get(virtualRegisterForArgument(argument)), ImmediateSet);
     2951                set(VirtualRegister(nextRegister++), get(virtualRegisterForArgument(argument)), ImmediateNakedSet);
    29342952           
    29352953            handleCall(
Note: See TracChangeset for help on using the changeset viewer.