Changeset 238511 in webkit


Ignore:
Timestamp:
Nov 26, 2018 12:29:33 PM (5 years ago)
Author:
sbarati@apple.com
Message:

InPlaceAbstractState::endBasicBlock rule for SetLocal should filter the value based on the flush format
https://bugs.webkit.org/show_bug.cgi?id=191956
<rdar://problem/45665806>

Reviewed by Yusuke Suzuki.

JSTests:

  • stress/end-basic-block-set-local-should-filter-type.js: Added.

(bar):
(foo):

Source/JavaScriptCore:

This is a similar bug to what Keith fixed in r232134. The issue is if we have
a program like this:

a: JSConstant(jsNumber(0))
b: SetLocal(Int32:@a, loc1, FlushedInt32)
c: ArrayifyToStructure(Cell:@a)
d: Jump(...)

At the point in the program right after the Jump, a GetLocal for loc1
would return whatever the ArrayifyToStructure resulting type is. This breaks
the invariant that a GetLocal must return a value that is a subtype of its
FlushFormat. InPlaceAbstractState::endBasicBlock will know if a SetLocal is
the final node touching a local slot. If so, it'll see if any nodes later
in the block may have refined the type of the value stored in that slot. If
so, endBasicBlock() further refines the type to ensure that any GetLocals
loading from the same slot will result in having this more refined type.
However, we must ensure that this logic only considers types within the
hierarchy of the variable access data's FlushFormat, otherwise, we may
break the invariant that a GetLocal's type is a subtype of its FlushFormat.

  • dfg/DFGInPlaceAbstractState.cpp:

(JSC::DFG::InPlaceAbstractState::endBasicBlock):

Location:
trunk
Files:
1 added
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/JSTests/ChangeLog

    r238510 r238511  
     12018-11-26  Saam barati  <sbarati@apple.com>
     2
     3        InPlaceAbstractState::endBasicBlock rule for SetLocal should filter the value based on the flush format
     4        https://bugs.webkit.org/show_bug.cgi?id=191956
     5        <rdar://problem/45665806>
     6
     7        Reviewed by Yusuke Suzuki.
     8
     9        * stress/end-basic-block-set-local-should-filter-type.js: Added.
     10        (bar):
     11        (foo):
     12
    1132018-11-26  Saam barati  <sbarati@apple.com>
    214
  • trunk/Source/JavaScriptCore/ChangeLog

    r238510 r238511  
     12018-11-26  Saam barati  <sbarati@apple.com>
     2
     3        InPlaceAbstractState::endBasicBlock rule for SetLocal should filter the value based on the flush format
     4        https://bugs.webkit.org/show_bug.cgi?id=191956
     5        <rdar://problem/45665806>
     6
     7        Reviewed by Yusuke Suzuki.
     8
     9        This is a similar bug to what Keith fixed in r232134. The issue is if we have
     10        a program like this:
     11       
     12        a: JSConstant(jsNumber(0))
     13        b: SetLocal(Int32:@a, loc1, FlushedInt32)
     14        c: ArrayifyToStructure(Cell:@a)
     15        d: Jump(...)
     16       
     17        At the point in the program right after the Jump, a GetLocal for loc1
     18        would return whatever the ArrayifyToStructure resulting type is. This breaks
     19        the invariant that a GetLocal must return a value that is a subtype of its
     20        FlushFormat. InPlaceAbstractState::endBasicBlock will know if a SetLocal is
     21        the final node touching a local slot. If so, it'll see if any nodes later
     22        in the block may have refined the type of the value stored in that slot. If
     23        so, endBasicBlock() further refines the type to ensure that any GetLocals
     24        loading from the same slot will result in having this more refined type.
     25        However, we must ensure that this logic only considers types within the
     26        hierarchy of the variable access data's FlushFormat, otherwise, we may
     27        break the invariant that a GetLocal's type is a subtype of its FlushFormat.
     28
     29        * dfg/DFGInPlaceAbstractState.cpp:
     30        (JSC::DFG::InPlaceAbstractState::endBasicBlock):
     31
    1322018-11-26  Saam barati  <sbarati@apple.com>
    233
  • trunk/Source/JavaScriptCore/dfg/DFGInPlaceAbstractState.cpp

    r232134 r238511  
    266266            case SetLocal: {
    267267                // The block sets the variable, and potentially refines it, both
    268                 // before and after setting it.
    269                 destination = forNode(node->child1());
     268                // before and after setting it. Since the SetLocal already did
     269                // a type check based on the flush format's type, we're only interested
     270                // in refinements within that type hierarchy. Otherwise, we may end up
     271                // saying that any GetLocals reachable from this basic block load something
     272                // outside of that hierarchy, e.g:
     273                //
     274                // a: JSConstant(jsNumber(0))
     275                // b: SetLocal(Int32:@a, loc1, FlushedInt32)
     276                // c: ArrayifyToStructure(Cell:@a)
     277                // d: Jump(...)
     278                //
     279                // In this example, we can't trust whatever type ArrayifyToStructure sets
     280                // @a to. We're only interested in the subset of that type that intersects
     281                // with Int32.
     282                AbstractValue value = forNode(node->child1());
     283                value.filter(typeFilterFor(node->variableAccessData()->flushFormat()));
     284                destination = value;
    270285                break;
    271286            }
Note: See TracChangeset for help on using the changeset viewer.