⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 232134 in webkit


Ignore:
Timestamp:
May 23, 2018, 4:04:58 PM (8 years ago)
Author:
keith_miller@apple.com
Message:

InPlaceAbstractState should filter variables at the tail from a GetLocal by their flush format
https://bugs.webkit.org/show_bug.cgi?id=185923

Reviewed by Saam Barati.

Previously, we could confuse AI by overly broadening a type. This happens when a block in a
loop has a local mutated following a GetLocal but never SetLocaled to the stack. For example,

Block 1:
@1: GetLocal(loc42, FlushedInt32);
@2: PutStructure(Check: Cell: @1);
@3: Jump(Block 1);

Would cause us to claim that loc42 could be either an int32 or a some cell. However,
the type of an local cannot change without writing to it.

This fixes a crash in destructuring-rest-element.js

  • dfg/DFGInPlaceAbstractState.cpp:

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

Location:
trunk/Source/JavaScriptCore
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r232132 r232134  
     12018-05-23  Keith Miller  <keith_miller@apple.com>
     2
     3        InPlaceAbstractState should filter variables at the tail from a GetLocal by their flush format
     4        https://bugs.webkit.org/show_bug.cgi?id=185923
     5
     6        Reviewed by Saam Barati.
     7
     8        Previously, we could confuse AI by overly broadening a type. This happens when a block in a
     9        loop has a local mutated following a GetLocal but never SetLocaled to the stack. For example,
     10
     11        Block 1:
     12        @1: GetLocal(loc42, FlushedInt32);
     13        @2: PutStructure(Check: Cell: @1);
     14        @3: Jump(Block 1);
     15
     16        Would cause us to claim that loc42 could be either an int32 or a some cell. However,
     17        the type of an local cannot change without writing to it.
     18
     19        This fixes a crash in destructuring-rest-element.js
     20
     21        * dfg/DFGInPlaceAbstractState.cpp:
     22        (JSC::DFG::InPlaceAbstractState::endBasicBlock):
     23
    1242018-05-23  Filip Pizlo  <fpizlo@apple.com>
    225
  • trunk/Source/JavaScriptCore/dfg/DFGInPlaceAbstractState.cpp

    r231660 r232134  
    237237            case SetArgument:
    238238            case PhantomLocal:
    239             case Flush:
     239            case Flush: {
    240240                // The block transfers the value from head to tail.
    241241                destination = variableAt(index);
    242242                break;
     243            }
    243244               
    244             case GetLocal:
     245            case GetLocal: {
    245246                // The block refines the value with additional speculations.
    246247                destination = forNode(node);
     248
     249                // We need to make sure that we don't broaden the type beyond what the flush
     250                // format says it will be. The value may claim to have changed abstract state
     251                // but it's type cannot change without a store. For example:
     252                //
     253                // Block #1:
     254                // 0: GetLocal(loc42, FlushFormatInt32)
     255                // 1: PutStructure(Check: Cell: @0, ArrayStructure)
     256                // ...
     257                // 2: Branch(T: #1, F: #2)
     258                //
     259                // In this case the AbstractState of @0 will say it's an SpecArray but the only
     260                // reason that would have happened is because we would have exited the cell check.
     261
     262                FlushFormat flushFormat = node->variableAccessData()->flushFormat();
     263                destination.filter(typeFilterFor(flushFormat));
    247264                break;
    248                
    249             case SetLocal:
     265            }
     266            case SetLocal: {
    250267                // The block sets the variable, and potentially refines it, both
    251268                // before and after setting it.
    252269                destination = forNode(node->child1());
    253270                break;
     271            }
    254272               
    255273            default:
Note: See TracChangeset for help on using the changeset viewer.