Ignore:
Timestamp:
May 9, 2013, 12:38:23 PM (12 years ago)
Author:
[email protected]
Message:

DFGArrayMode::fromObserved is too liberal when it sees different Array and NonArray shapes
https://bugs.webkit.org/show_bug.cgi?id=115805

Source/JavaScriptCore:

Reviewed by Geoffrey Garen.

It checks the observed ArrayModes to see if we have seen any ArrayWith* first. If so, it assumes it's
an Array::Array, even if we've also observed any NonArrayWith* in the ArrayProfile. This leads to the
code generated by jumpSlowForUnwantedArrayMode to check the indexing type against (shape | IsArray)
instead of just shape, which can cause us to exit a lot in the case that we saw a NonArray.

To fix this we need to add a case that checks for both ArrayWith* and NonArrayWith* cases first, which
should then use Array::PossiblyArray, then do the checks we were already doing.

  • bytecode/ArrayProfile.h:

(JSC::hasSeenArray):
(JSC::hasSeenNonArray):

  • dfg/DFGArrayMode.cpp:

(JSC::DFG::ArrayMode::fromObserved):

LayoutTests:

Added regression test for array access over polymorphic array vs. non-array indexing types.
With the fix, we get 3.666x faster on this microbenchmark.

Reviewed by Geoffrey Garen.

  • fast/js/regress/array-nonarray-polymorphic-access-expected.txt: Added.
  • fast/js/regress/array-nonarray-polymorphic-access.html: Added.
  • fast/js/regress/script-tests/array-nonarray-polymorphic-access.js: Added.

(f):
(run):

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/dfg/DFGArrayMode.cpp

    r146887 r149834  
    113113            type = Array::Undecided;
    114114       
    115         if (observed & (asArrayModes(ArrayWithUndecided) | asArrayModes(ArrayWithInt32) | asArrayModes(ArrayWithDouble) | asArrayModes(ArrayWithContiguous) | asArrayModes(ArrayWithArrayStorage) | asArrayModes(ArrayWithSlowPutArrayStorage)))
     115        if (hasSeenArray(observed) && hasSeenNonArray(observed))
     116            arrayClass = Array::PossiblyArray;
     117        else if (hasSeenArray(observed))
    116118            arrayClass = Array::Array;
    117         else if (observed & (asArrayModes(NonArray) | asArrayModes(NonArrayWithInt32) | asArrayModes(NonArrayWithDouble) | asArrayModes(NonArrayWithContiguous) | asArrayModes(NonArrayWithArrayStorage) | asArrayModes(NonArrayWithSlowPutArrayStorage)))
     119        else if (hasSeenNonArray(observed))
    118120            arrayClass = Array::NonArray;
    119121        else
Note: See TracChangeset for help on using the changeset viewer.