Changeset 239951 in webkit


Ignore:
Timestamp:
Jan 14, 2019 2:31:06 PM (5 years ago)
Author:
yusukesuzuki@slowstart.org
Message:

[JSC] Do not use asArrayModes() with Structures because it discards TypedArray information
https://bugs.webkit.org/show_bug.cgi?id=193372

Reviewed by Saam Barati.

JSTests:

  • stress/typed-array-array-modes-profile.js: Added.

(foo):

Source/JavaScriptCore:

When RegisteredStructureSet is filtered with AbstractValue, we use structure, SpeculationType, and ArrayModes.
However, we use asArrayModes() function with IndexingMode to compute the ArrayModes in AbstractValue. This is
wrong since this discards TypedArray ArrayModes. As a result, if RegisteredStructureSet with TypedArrays is
filtered with ArrayModes of AbstractValue populated from TypedArrays, we filter all the structures out since
AbstractValue's ArrayModes become NonArray, which is wrong with the TypedArrays' ArrayModes. This leads to
incorrect FTL code generation with MultiGetByOffset etc. nodes because,

  1. AI think that this MultiGetByOffset never succeeds since all the values of RegisteredStructureSet are filtered out by the AbstractValue.
  2. AI says the state of MultiGetByOffset is invalid since AI think it never succeeds.
  3. So subsequent code becomes FTL crash code since AI think the execution should do OSR exit.
  4. Then, FTL emits the code for MultiGetByOffset, and emits crash after that.
  5. But in reality, the incoming value can match to the one of the RegisteredStructureSet value since (1)'s structures are incorrectly filtered by the incorrect ArrayModes.
  6. Then, the execution goes on, and falls into the FTL crash.

This patch fixes the incorrect ArrayModes calculation by the following changes

  1. Rename asArrayModes to asArrayModesIgnoringTypedArrays.
  2. Fix incorrect asArrayModesIgnoringTypedArrays use in our code. Use arrayModesFromStructure instead.
  3. Fix OSR exit code which stores incorrect ArrayModes to the profiles.
  • bytecode/ArrayProfile.cpp:

(JSC::dumpArrayModes):
(JSC::ArrayProfile::computeUpdatedPrediction):

  • bytecode/ArrayProfile.h:

(JSC::asArrayModesIgnoringTypedArrays):
(JSC::arrayModesFromStructure):
(JSC::arrayModesIncludeIgnoringTypedArrays):
(JSC::shouldUseSlowPutArrayStorage):
(JSC::shouldUseFastArrayStorage):
(JSC::shouldUseContiguous):
(JSC::shouldUseDouble):
(JSC::shouldUseInt32):
(JSC::asArrayModes): Deleted.
(JSC::arrayModeFromStructure): Deleted.
(JSC::arrayModesInclude): Deleted.

  • dfg/DFGAbstractValue.cpp:

(JSC::DFG::AbstractValue::observeTransitions):
(JSC::DFG::AbstractValue::set):
(JSC::DFG::AbstractValue::mergeOSREntryValue):
(JSC::DFG::AbstractValue::contains const):

  • dfg/DFGAbstractValue.h:

(JSC::DFG::AbstractValue::observeTransition):
(JSC::DFG::AbstractValue::validate const):
(JSC::DFG::AbstractValue::observeIndexingTypeTransition):

  • dfg/DFGArrayMode.cpp:

(JSC::DFG::ArrayMode::fromObserved):
(JSC::DFG::ArrayMode::alreadyChecked const):

  • dfg/DFGArrayMode.h:

(JSC::DFG::ArrayMode::structureWouldPassArrayModeFiltering):
(JSC::DFG::ArrayMode::arrayModesThatPassFiltering const):
(JSC::DFG::ArrayMode::arrayModesWithIndexingShape const):

  • dfg/DFGOSRExit.cpp:

(JSC::DFG::OSRExit::executeOSRExit):
(JSC::DFG::OSRExit::compileExit):

  • dfg/DFGRegisteredStructureSet.cpp:

(JSC::DFG::RegisteredStructureSet::filterArrayModes):
(JSC::DFG::RegisteredStructureSet::arrayModesFromStructures const):

  • ftl/FTLOSRExitCompiler.cpp:

(JSC::FTL::compileStub):

  • jit/JITInlines.h:

(JSC::JIT::chooseArrayMode):
(JSC::arrayProfileSaw): Deleted.

  • runtime/JSType.h:

(JSC::isTypedArrayType):

Location:
trunk
Files:
1 added
13 edited

Legend:

Unmodified
Added
Removed
  • trunk/JSTests/ChangeLog

    r239940 r239951  
     12019-01-14  Yusuke Suzuki  <yusukesuzuki@slowstart.org>
     2
     3        [JSC] Do not use asArrayModes() with Structures because it discards TypedArray information
     4        https://bugs.webkit.org/show_bug.cgi?id=193372
     5
     6        Reviewed by Saam Barati.
     7
     8        * stress/typed-array-array-modes-profile.js: Added.
     9        (foo):
     10
    1112019-01-14  Mark Lam  <mark.lam@apple.com>
    212
  • trunk/Source/JavaScriptCore/ChangeLog

    r239947 r239951  
     12019-01-14  Yusuke Suzuki  <yusukesuzuki@slowstart.org>
     2
     3        [JSC] Do not use asArrayModes() with Structures because it discards TypedArray information
     4        https://bugs.webkit.org/show_bug.cgi?id=193372
     5
     6        Reviewed by Saam Barati.
     7
     8        When RegisteredStructureSet is filtered with AbstractValue, we use structure, SpeculationType, and ArrayModes.
     9        However, we use asArrayModes() function with IndexingMode to compute the ArrayModes in AbstractValue. This is
     10        wrong since this discards TypedArray ArrayModes. As a result, if RegisteredStructureSet with TypedArrays is
     11        filtered with ArrayModes of AbstractValue populated from TypedArrays, we filter all the structures out since
     12        AbstractValue's ArrayModes become NonArray, which is wrong with the TypedArrays' ArrayModes. This leads to
     13        incorrect FTL code generation with MultiGetByOffset etc. nodes because,
     14
     15        1. AI think that this MultiGetByOffset never succeeds since all the values of RegisteredStructureSet are filtered out by the AbstractValue.
     16        2. AI says the state of MultiGetByOffset is invalid since AI think it never succeeds.
     17        3. So subsequent code becomes FTL crash code since AI think the execution should do OSR exit.
     18        4. Then, FTL emits the code for MultiGetByOffset, and emits crash after that.
     19        5. But in reality, the incoming value can match to the one of the RegisteredStructureSet value since (1)'s structures are incorrectly filtered by the incorrect ArrayModes.
     20        6. Then, the execution goes on, and falls into the FTL crash.
     21
     22        This patch fixes the incorrect ArrayModes calculation by the following changes
     23
     24        1. Rename asArrayModes to asArrayModesIgnoringTypedArrays.
     25        2. Fix incorrect asArrayModesIgnoringTypedArrays use in our code. Use arrayModesFromStructure instead.
     26        3. Fix OSR exit code which stores incorrect ArrayModes to the profiles.
     27
     28        * bytecode/ArrayProfile.cpp:
     29        (JSC::dumpArrayModes):
     30        (JSC::ArrayProfile::computeUpdatedPrediction):
     31        * bytecode/ArrayProfile.h:
     32        (JSC::asArrayModesIgnoringTypedArrays):
     33        (JSC::arrayModesFromStructure):
     34        (JSC::arrayModesIncludeIgnoringTypedArrays):
     35        (JSC::shouldUseSlowPutArrayStorage):
     36        (JSC::shouldUseFastArrayStorage):
     37        (JSC::shouldUseContiguous):
     38        (JSC::shouldUseDouble):
     39        (JSC::shouldUseInt32):
     40        (JSC::asArrayModes): Deleted.
     41        (JSC::arrayModeFromStructure): Deleted.
     42        (JSC::arrayModesInclude): Deleted.
     43        * dfg/DFGAbstractValue.cpp:
     44        (JSC::DFG::AbstractValue::observeTransitions):
     45        (JSC::DFG::AbstractValue::set):
     46        (JSC::DFG::AbstractValue::mergeOSREntryValue):
     47        (JSC::DFG::AbstractValue::contains const):
     48        * dfg/DFGAbstractValue.h:
     49        (JSC::DFG::AbstractValue::observeTransition):
     50        (JSC::DFG::AbstractValue::validate const):
     51        (JSC::DFG::AbstractValue::observeIndexingTypeTransition):
     52        * dfg/DFGArrayMode.cpp:
     53        (JSC::DFG::ArrayMode::fromObserved):
     54        (JSC::DFG::ArrayMode::alreadyChecked const):
     55        * dfg/DFGArrayMode.h:
     56        (JSC::DFG::ArrayMode::structureWouldPassArrayModeFiltering):
     57        (JSC::DFG::ArrayMode::arrayModesThatPassFiltering const):
     58        (JSC::DFG::ArrayMode::arrayModesWithIndexingShape const):
     59        * dfg/DFGOSRExit.cpp:
     60        (JSC::DFG::OSRExit::executeOSRExit):
     61        (JSC::DFG::OSRExit::compileExit):
     62        * dfg/DFGRegisteredStructureSet.cpp:
     63        (JSC::DFG::RegisteredStructureSet::filterArrayModes):
     64        (JSC::DFG::RegisteredStructureSet::arrayModesFromStructures const):
     65        * ftl/FTLOSRExitCompiler.cpp:
     66        (JSC::FTL::compileStub):
     67        * jit/JITInlines.h:
     68        (JSC::JIT::chooseArrayMode):
     69        (JSC::arrayProfileSaw): Deleted.
     70        * runtime/JSType.h:
     71        (JSC::isTypedArrayType):
     72
    1732019-01-14  Mark Lam  <mark.lam@apple.com>
    274
  • trunk/Source/JavaScriptCore/bytecode/ArrayProfile.cpp

    r235827 r239951  
    3838#endif
    3939
     40// Keep in sync with the order of TypedArrayType.
     41const ArrayModes typedArrayModes[NumberOfTypedArrayTypesExcludingDataView] = {
     42    Int8ArrayMode,
     43    Uint8ArrayMode,
     44    Uint8ClampedArrayMode,
     45    Int16ArrayMode,
     46    Uint16ArrayMode,
     47    Int32ArrayMode,
     48    Uint32ArrayMode,
     49    Float32ArrayMode,
     50    Float64ArrayMode,
     51};
     52
    4053void dumpArrayModes(PrintStream& out, ArrayModes arrayModes)
    4154{
     
    5164   
    5265    CommaPrinter comma("|");
    53     if (arrayModes & asArrayModes(NonArray))
     66    if (arrayModes & asArrayModesIgnoringTypedArrays(NonArray))
    5467        out.print(comma, "NonArray");
    55     if (arrayModes & asArrayModes(NonArrayWithInt32))
     68    if (arrayModes & asArrayModesIgnoringTypedArrays(NonArrayWithInt32))
    5669        out.print(comma, "NonArrayWithInt32");
    57     if (arrayModes & asArrayModes(NonArrayWithDouble))
     70    if (arrayModes & asArrayModesIgnoringTypedArrays(NonArrayWithDouble))
    5871        out.print(comma, "NonArrayWithDouble");
    59     if (arrayModes & asArrayModes(NonArrayWithContiguous))
     72    if (arrayModes & asArrayModesIgnoringTypedArrays(NonArrayWithContiguous))
    6073        out.print(comma, "NonArrayWithContiguous");
    61     if (arrayModes & asArrayModes(NonArrayWithArrayStorage))
     74    if (arrayModes & asArrayModesIgnoringTypedArrays(NonArrayWithArrayStorage))
    6275        out.print(comma, "NonArrayWithArrayStorage");
    63     if (arrayModes & asArrayModes(NonArrayWithSlowPutArrayStorage))
     76    if (arrayModes & asArrayModesIgnoringTypedArrays(NonArrayWithSlowPutArrayStorage))
    6477        out.print(comma, "NonArrayWithSlowPutArrayStorage");
    65     if (arrayModes & asArrayModes(ArrayClass))
     78    if (arrayModes & asArrayModesIgnoringTypedArrays(ArrayClass))
    6679        out.print(comma, "ArrayClass");
    67     if (arrayModes & asArrayModes(ArrayWithUndecided))
     80    if (arrayModes & asArrayModesIgnoringTypedArrays(ArrayWithUndecided))
    6881        out.print(comma, "ArrayWithUndecided");
    69     if (arrayModes & asArrayModes(ArrayWithInt32))
     82    if (arrayModes & asArrayModesIgnoringTypedArrays(ArrayWithInt32))
    7083        out.print(comma, "ArrayWithInt32");
    71     if (arrayModes & asArrayModes(ArrayWithDouble))
     84    if (arrayModes & asArrayModesIgnoringTypedArrays(ArrayWithDouble))
    7285        out.print(comma, "ArrayWithDouble");
    73     if (arrayModes & asArrayModes(ArrayWithContiguous))
     86    if (arrayModes & asArrayModesIgnoringTypedArrays(ArrayWithContiguous))
    7487        out.print(comma, "ArrayWithContiguous");
    75     if (arrayModes & asArrayModes(ArrayWithArrayStorage))
     88    if (arrayModes & asArrayModesIgnoringTypedArrays(ArrayWithArrayStorage))
    7689        out.print(comma, "ArrayWithArrayStorage");
    77     if (arrayModes & asArrayModes(ArrayWithSlowPutArrayStorage))
     90    if (arrayModes & asArrayModesIgnoringTypedArrays(ArrayWithSlowPutArrayStorage))
    7891        out.print(comma, "ArrayWithSlowPutArrayStorage");
    79     if (arrayModes & asArrayModes(CopyOnWriteArrayWithInt32))
     92    if (arrayModes & asArrayModesIgnoringTypedArrays(CopyOnWriteArrayWithInt32))
    8093        out.print(comma, "CopyOnWriteArrayWithInt32");
    81     if (arrayModes & asArrayModes(CopyOnWriteArrayWithDouble))
     94    if (arrayModes & asArrayModesIgnoringTypedArrays(CopyOnWriteArrayWithDouble))
    8295        out.print(comma, "CopyOnWriteArrayWithDouble");
    83     if (arrayModes & asArrayModes(CopyOnWriteArrayWithContiguous))
     96    if (arrayModes & asArrayModesIgnoringTypedArrays(CopyOnWriteArrayWithContiguous))
    8497        out.print(comma, "CopyOnWriteArrayWithContiguous");
    8598
     
    116129void ArrayProfile::computeUpdatedPrediction(const ConcurrentJSLocker&, CodeBlock* codeBlock, Structure* lastSeenStructure)
    117130{
    118     m_observedArrayModes |= arrayModeFromStructure(lastSeenStructure);
     131    m_observedArrayModes |= arrayModesFromStructure(lastSeenStructure);
    119132   
    120133    if (!m_didPerformFirstRunPruning
    121134        && hasTwoOrMoreBitsSet(m_observedArrayModes)) {
    122         m_observedArrayModes = arrayModeFromStructure(lastSeenStructure);
     135        m_observedArrayModes = arrayModesFromStructure(lastSeenStructure);
    123136        m_didPerformFirstRunPruning = true;
    124137    }
  • trunk/Source/JavaScriptCore/bytecode/ArrayProfile.h

    r237547 r239951  
    5959const ArrayModes Float64ArrayMode = 1 << 29;
    6060
    61 constexpr ArrayModes asArrayModes(IndexingType indexingMode)
     61extern const ArrayModes typedArrayModes[NumberOfTypedArrayTypesExcludingDataView];
     62
     63constexpr ArrayModes asArrayModesIgnoringTypedArrays(IndexingType indexingMode)
    6264{
    6365    return static_cast<unsigned>(1) << static_cast<unsigned>(indexingMode);
     
    7779
    7880#define ALL_NON_ARRAY_ARRAY_MODES                       \
    79     (asArrayModes(NonArray)                             \
    80     | asArrayModes(NonArrayWithInt32)                   \
    81     | asArrayModes(NonArrayWithDouble)                  \
    82     | asArrayModes(NonArrayWithContiguous)              \
    83     | asArrayModes(NonArrayWithArrayStorage)            \
    84     | asArrayModes(NonArrayWithSlowPutArrayStorage)     \
     81    (asArrayModesIgnoringTypedArrays(NonArray)                             \
     82    | asArrayModesIgnoringTypedArrays(NonArrayWithInt32)                   \
     83    | asArrayModesIgnoringTypedArrays(NonArrayWithDouble)                  \
     84    | asArrayModesIgnoringTypedArrays(NonArrayWithContiguous)              \
     85    | asArrayModesIgnoringTypedArrays(NonArrayWithArrayStorage)            \
     86    | asArrayModesIgnoringTypedArrays(NonArrayWithSlowPutArrayStorage)     \
    8587    | ALL_TYPED_ARRAY_MODES)
    8688
     
    9193
    9294#define ALL_WRITABLE_ARRAY_ARRAY_MODES                  \
    93     (asArrayModes(ArrayClass)                           \
    94     | asArrayModes(ArrayWithUndecided)                  \
    95     | asArrayModes(ArrayWithInt32)                      \
    96     | asArrayModes(ArrayWithDouble)                     \
    97     | asArrayModes(ArrayWithContiguous)                 \
    98     | asArrayModes(ArrayWithArrayStorage)               \
    99     | asArrayModes(ArrayWithSlowPutArrayStorage))
     95    (asArrayModesIgnoringTypedArrays(ArrayClass)                           \
     96    | asArrayModesIgnoringTypedArrays(ArrayWithUndecided)                  \
     97    | asArrayModesIgnoringTypedArrays(ArrayWithInt32)                      \
     98    | asArrayModesIgnoringTypedArrays(ArrayWithDouble)                     \
     99    | asArrayModesIgnoringTypedArrays(ArrayWithContiguous)                 \
     100    | asArrayModesIgnoringTypedArrays(ArrayWithArrayStorage)               \
     101    | asArrayModesIgnoringTypedArrays(ArrayWithSlowPutArrayStorage))
    100102
    101103#define ALL_ARRAY_ARRAY_MODES                           \
     
    105107#define ALL_ARRAY_MODES (ALL_NON_ARRAY_ARRAY_MODES | ALL_ARRAY_ARRAY_MODES)
    106108
    107 inline ArrayModes arrayModeFromStructure(Structure* structure)
    108 {
    109     switch (structure->classInfo()->typedArrayStorageType) {
    110     case TypeInt8:
    111         return Int8ArrayMode;
    112     case TypeUint8:
    113         return Uint8ArrayMode;
    114     case TypeUint8Clamped:
    115         return Uint8ClampedArrayMode;
    116     case TypeInt16:
    117         return Int16ArrayMode;
    118     case TypeUint16:
    119         return Uint16ArrayMode;
    120     case TypeInt32:
    121         return Int32ArrayMode;
    122     case TypeUint32:
    123         return Uint32ArrayMode;
    124     case TypeFloat32:
    125         return Float32ArrayMode;
    126     case TypeFloat64:
    127         return Float64ArrayMode;
    128     case TypeDataView:
    129     case NotTypedArray:
    130         break;
    131     }
    132 
    133     return asArrayModes(structure->indexingMode());
     109inline ArrayModes arrayModesFromStructure(Structure* structure)
     110{
     111    JSType type = structure->typeInfo().type();
     112    if (isTypedArrayType(type))
     113        return typedArrayModes[type - FirstTypedArrayType];
     114    return asArrayModesIgnoringTypedArrays(structure->indexingMode());
    134115}
    135116
     
    157138}
    158139
    159 inline bool arrayModesInclude(ArrayModes arrayModes, IndexingType shape)
    160 {
    161     ArrayModes modes = asArrayModes(NonArray | shape) | asArrayModes(ArrayClass | shape);
     140inline bool arrayModesIncludeIgnoringTypedArrays(ArrayModes arrayModes, IndexingType shape)
     141{
     142    ArrayModes modes = asArrayModesIgnoringTypedArrays(NonArray | shape) | asArrayModesIgnoringTypedArrays(ArrayClass | shape);
    162143    if (hasInt32(shape) || hasDouble(shape) || hasContiguous(shape))
    163         modes |= asArrayModes(ArrayClass | shape | CopyOnWrite);
     144        modes |= asArrayModesIgnoringTypedArrays(ArrayClass | shape | CopyOnWrite);
    164145    return !!(arrayModes & modes);
    165146}
     
    167148inline bool shouldUseSlowPutArrayStorage(ArrayModes arrayModes)
    168149{
    169     return arrayModesInclude(arrayModes, SlowPutArrayStorageShape);
     150    return arrayModesIncludeIgnoringTypedArrays(arrayModes, SlowPutArrayStorageShape);
    170151}
    171152
    172153inline bool shouldUseFastArrayStorage(ArrayModes arrayModes)
    173154{
    174     return arrayModesInclude(arrayModes, ArrayStorageShape);
     155    return arrayModesIncludeIgnoringTypedArrays(arrayModes, ArrayStorageShape);
    175156}
    176157
    177158inline bool shouldUseContiguous(ArrayModes arrayModes)
    178159{
    179     return arrayModesInclude(arrayModes, ContiguousShape);
     160    return arrayModesIncludeIgnoringTypedArrays(arrayModes, ContiguousShape);
    180161}
    181162
    182163inline bool shouldUseDouble(ArrayModes arrayModes)
    183164{
    184     return arrayModesInclude(arrayModes, DoubleShape);
     165    return arrayModesIncludeIgnoringTypedArrays(arrayModes, DoubleShape);
    185166}
    186167
    187168inline bool shouldUseInt32(ArrayModes arrayModes)
    188169{
    189     return arrayModesInclude(arrayModes, Int32Shape);
     170    return arrayModesIncludeIgnoringTypedArrays(arrayModes, Int32Shape);
    190171}
    191172
  • trunk/Source/JavaScriptCore/dfg/DFGAbstractValue.cpp

    r237325 r239951  
    4141        ArrayModes newModes = 0;
    4242        for (unsigned i = vector.size(); i--;) {
    43             if (m_arrayModes & asArrayModes(vector[i].previous->indexingType()))
    44                 newModes |= asArrayModes(vector[i].next->indexingType());
     43            if (m_arrayModes & arrayModesFromStructure(vector[i].previous.get()))
     44                newModes |= arrayModesFromStructure(vector[i].next.get());
    4545        }
    4646        m_arrayModes |= newModes;
     
    6161                m_structure.clobber();
    6262            } else
    63                 m_arrayModes = asArrayModes(structure->indexingMode());
     63                m_arrayModes = arrayModesFromStructure(structure);
    6464        } else {
    6565            m_structure.makeTop();
     
    8888   
    8989    m_structure = structure;
    90     m_arrayModes = asArrayModes(structure->indexingMode());
     90    m_arrayModes = arrayModesFromStructure(structure.get());
    9191    m_type = speculationFromStructure(structure.get());
    9292    m_value = JSValue();
     
    229229        if (frozenValue->pointsToHeap()) {
    230230            m_structure = graph.registerStructure(frozenValue->structure());
    231             m_arrayModes = asArrayModes(frozenValue->structure()->indexingMode());
     231            m_arrayModes = arrayModesFromStructure(frozenValue->structure());
    232232        } else {
    233233            m_structure.clear();
     
    241241        if (!!value && value.isCell()) {
    242242            RegisteredStructure structure = graph.registerStructure(value.asCell()->structure(graph.m_vm));
    243             mergeArrayModes(m_arrayModes, asArrayModes(structure->indexingMode()));
     243            mergeArrayModes(m_arrayModes, arrayModesFromStructure(structure.get()));
    244244            m_structure.merge(RegisteredStructureSet(structure));
    245245        }
     
    366366{
    367367    return couldBeType(speculationFromStructure(structure.get()))
    368         && (m_arrayModes & arrayModeFromStructure(structure.get()))
     368        && (m_arrayModes & arrayModesFromStructure(structure.get()))
    369369        && m_structure.contains(structure);
    370370}
  • trunk/Source/JavaScriptCore/dfg/DFGAbstractValue.h

    r237325 r239951  
    138138        if (m_type & SpecCell) {
    139139            m_structure.observeTransition(from, to);
    140             observeIndexingTypeTransition(from->indexingType(), to->indexingType());
     140            observeIndexingTypeTransition(arrayModesFromStructure(from.get()), arrayModesFromStructure(to.get()));
    141141        }
    142142        checkConsistency();
     
    398398            Structure* structure = value.asCell()->structure();
    399399            return m_structure.contains(structure)
    400                 && (m_arrayModes & asArrayModes(structure->indexingMode()));
     400                && (m_arrayModes & arrayModesFromStructure(structure));
    401401        }
    402402       
     
    493493    }
    494494   
    495     void observeIndexingTypeTransition(IndexingType from, IndexingType to)
    496     {
    497         if (m_arrayModes & asArrayModes(from))
    498             m_arrayModes |= asArrayModes(to);
     495    void observeIndexingTypeTransition(ArrayModes from, ArrayModes to)
     496    {
     497        if (m_arrayModes & from)
     498            m_arrayModes |= to;
    499499    }
    500500   
  • trunk/Source/JavaScriptCore/dfg/DFGArrayMode.cpp

    r234184 r239951  
    4848        Array::Conversion converts;
    4949
    50         RELEASE_ASSERT((observed & (asArrayModes(toIndexingShape(type)) | asArrayModes(toIndexingShape(type) | ArrayClass) | asArrayModes(toIndexingShape(type) | ArrayClass | CopyOnWrite))) == observed);
    51 
    52         if (observed & asArrayModes(toIndexingShape(type))) {
    53             if ((observed & asArrayModes(toIndexingShape(type))) == observed)
     50        RELEASE_ASSERT((observed & (asArrayModesIgnoringTypedArrays(toIndexingShape(type)) | asArrayModesIgnoringTypedArrays(toIndexingShape(type) | ArrayClass) | asArrayModesIgnoringTypedArrays(toIndexingShape(type) | ArrayClass | CopyOnWrite))) == observed);
     51
     52        if (observed & asArrayModesIgnoringTypedArrays(toIndexingShape(type))) {
     53            if ((observed & asArrayModesIgnoringTypedArrays(toIndexingShape(type))) == observed)
    5454                isArray = nonArray;
    5555            else
     
    5858            isArray = Array::Array;
    5959
    60         if (action == Array::Write && (observed & asArrayModes(toIndexingShape(type) | ArrayClass | CopyOnWrite)))
     60        if (action == Array::Write && (observed & asArrayModesIgnoringTypedArrays(toIndexingShape(type) | ArrayClass | CopyOnWrite)))
    6161            converts = Array::Convert;
    6262        else
     
    7070    case 0:
    7171        return ArrayMode(Array::Unprofiled);
    72     case asArrayModes(NonArray):
     72    case asArrayModesIgnoringTypedArrays(NonArray):
    7373        if (action == Array::Write && !profile->mayInterceptIndexedAccesses(locker))
    7474            return ArrayMode(Array::SelectUsingArguments, nonArray, Array::OutOfBounds, Array::Convert, action);
    7575        return ArrayMode(Array::SelectUsingPredictions, nonArray, action).withSpeculationFromProfile(locker, profile, makeSafe);
    7676
    77     case asArrayModes(ArrayWithUndecided):
     77    case asArrayModesIgnoringTypedArrays(ArrayWithUndecided):
    7878        if (action == Array::Write)
    7979            return ArrayMode(Array::SelectUsingArguments, Array::Array, Array::OutOfBounds, Array::Convert, action);
    8080        return ArrayMode(Array::Undecided, Array::Array, Array::OutOfBounds, Array::AsIs, action).withProfile(locker, profile, makeSafe);
    8181       
    82     case asArrayModes(NonArray) | asArrayModes(ArrayWithUndecided):
     82    case asArrayModesIgnoringTypedArrays(NonArray) | asArrayModesIgnoringTypedArrays(ArrayWithUndecided):
    8383        if (action == Array::Write && !profile->mayInterceptIndexedAccesses(locker))
    8484            return ArrayMode(Array::SelectUsingArguments, Array::PossiblyArray, Array::OutOfBounds, Array::Convert, action);
    8585        return ArrayMode(Array::SelectUsingPredictions, action).withSpeculationFromProfile(locker, profile, makeSafe);
    8686
    87     case asArrayModes(NonArrayWithInt32):
    88     case asArrayModes(ArrayWithInt32):
    89     case asArrayModes(CopyOnWriteArrayWithInt32):
    90     case asArrayModes(NonArrayWithInt32) | asArrayModes(ArrayWithInt32):
    91     case asArrayModes(NonArrayWithInt32) | asArrayModes(CopyOnWriteArrayWithInt32):
    92     case asArrayModes(ArrayWithInt32) | asArrayModes(CopyOnWriteArrayWithInt32):
    93     case asArrayModes(NonArrayWithInt32) | asArrayModes(ArrayWithInt32) | asArrayModes(CopyOnWriteArrayWithInt32):
     87    case asArrayModesIgnoringTypedArrays(NonArrayWithInt32):
     88    case asArrayModesIgnoringTypedArrays(ArrayWithInt32):
     89    case asArrayModesIgnoringTypedArrays(CopyOnWriteArrayWithInt32):
     90    case asArrayModesIgnoringTypedArrays(NonArrayWithInt32) | asArrayModesIgnoringTypedArrays(ArrayWithInt32):
     91    case asArrayModesIgnoringTypedArrays(NonArrayWithInt32) | asArrayModesIgnoringTypedArrays(CopyOnWriteArrayWithInt32):
     92    case asArrayModesIgnoringTypedArrays(ArrayWithInt32) | asArrayModesIgnoringTypedArrays(CopyOnWriteArrayWithInt32):
     93    case asArrayModesIgnoringTypedArrays(NonArrayWithInt32) | asArrayModesIgnoringTypedArrays(ArrayWithInt32) | asArrayModesIgnoringTypedArrays(CopyOnWriteArrayWithInt32):
    9494        return handleContiguousModes(Array::Int32, observed);
    9595
    96     case asArrayModes(NonArrayWithDouble):
    97     case asArrayModes(ArrayWithDouble):
    98     case asArrayModes(CopyOnWriteArrayWithDouble):
    99     case asArrayModes(NonArrayWithDouble) | asArrayModes(ArrayWithDouble):
    100     case asArrayModes(NonArrayWithDouble) | asArrayModes(CopyOnWriteArrayWithDouble):
    101     case asArrayModes(ArrayWithDouble) | asArrayModes(CopyOnWriteArrayWithDouble):
    102     case asArrayModes(NonArrayWithDouble) | asArrayModes(ArrayWithDouble) | asArrayModes(CopyOnWriteArrayWithDouble):
     96    case asArrayModesIgnoringTypedArrays(NonArrayWithDouble):
     97    case asArrayModesIgnoringTypedArrays(ArrayWithDouble):
     98    case asArrayModesIgnoringTypedArrays(CopyOnWriteArrayWithDouble):
     99    case asArrayModesIgnoringTypedArrays(NonArrayWithDouble) | asArrayModesIgnoringTypedArrays(ArrayWithDouble):
     100    case asArrayModesIgnoringTypedArrays(NonArrayWithDouble) | asArrayModesIgnoringTypedArrays(CopyOnWriteArrayWithDouble):
     101    case asArrayModesIgnoringTypedArrays(ArrayWithDouble) | asArrayModesIgnoringTypedArrays(CopyOnWriteArrayWithDouble):
     102    case asArrayModesIgnoringTypedArrays(NonArrayWithDouble) | asArrayModesIgnoringTypedArrays(ArrayWithDouble) | asArrayModesIgnoringTypedArrays(CopyOnWriteArrayWithDouble):
    103103        return handleContiguousModes(Array::Double, observed);
    104104
    105     case asArrayModes(NonArrayWithContiguous):
    106     case asArrayModes(ArrayWithContiguous):
    107     case asArrayModes(CopyOnWriteArrayWithContiguous):
    108     case asArrayModes(NonArrayWithContiguous) | asArrayModes(ArrayWithContiguous):
    109     case asArrayModes(NonArrayWithContiguous) | asArrayModes(CopyOnWriteArrayWithContiguous):
    110     case asArrayModes(ArrayWithContiguous) | asArrayModes(CopyOnWriteArrayWithContiguous):
    111     case asArrayModes(NonArrayWithContiguous) | asArrayModes(ArrayWithContiguous) | asArrayModes(CopyOnWriteArrayWithContiguous):
     105    case asArrayModesIgnoringTypedArrays(NonArrayWithContiguous):
     106    case asArrayModesIgnoringTypedArrays(ArrayWithContiguous):
     107    case asArrayModesIgnoringTypedArrays(CopyOnWriteArrayWithContiguous):
     108    case asArrayModesIgnoringTypedArrays(NonArrayWithContiguous) | asArrayModesIgnoringTypedArrays(ArrayWithContiguous):
     109    case asArrayModesIgnoringTypedArrays(NonArrayWithContiguous) | asArrayModesIgnoringTypedArrays(CopyOnWriteArrayWithContiguous):
     110    case asArrayModesIgnoringTypedArrays(ArrayWithContiguous) | asArrayModesIgnoringTypedArrays(CopyOnWriteArrayWithContiguous):
     111    case asArrayModesIgnoringTypedArrays(NonArrayWithContiguous) | asArrayModesIgnoringTypedArrays(ArrayWithContiguous) | asArrayModesIgnoringTypedArrays(CopyOnWriteArrayWithContiguous):
    112112        return handleContiguousModes(Array::Contiguous, observed);
    113113
    114     case asArrayModes(NonArrayWithArrayStorage):
     114    case asArrayModesIgnoringTypedArrays(NonArrayWithArrayStorage):
    115115        return ArrayMode(Array::ArrayStorage, nonArray, Array::AsIs, action).withProfile(locker, profile, makeSafe);
    116     case asArrayModes(NonArrayWithSlowPutArrayStorage):
    117     case asArrayModes(NonArrayWithArrayStorage) | asArrayModes(NonArrayWithSlowPutArrayStorage):
     116    case asArrayModesIgnoringTypedArrays(NonArrayWithSlowPutArrayStorage):
     117    case asArrayModesIgnoringTypedArrays(NonArrayWithArrayStorage) | asArrayModesIgnoringTypedArrays(NonArrayWithSlowPutArrayStorage):
    118118        return ArrayMode(Array::SlowPutArrayStorage, nonArray, Array::AsIs, action).withProfile(locker, profile, makeSafe);
    119     case asArrayModes(ArrayWithArrayStorage):
     119    case asArrayModesIgnoringTypedArrays(ArrayWithArrayStorage):
    120120        return ArrayMode(Array::ArrayStorage, Array::Array, Array::AsIs, action).withProfile(locker, profile, makeSafe);
    121     case asArrayModes(ArrayWithSlowPutArrayStorage):
    122     case asArrayModes(ArrayWithArrayStorage) | asArrayModes(ArrayWithSlowPutArrayStorage):
     121    case asArrayModesIgnoringTypedArrays(ArrayWithSlowPutArrayStorage):
     122    case asArrayModesIgnoringTypedArrays(ArrayWithArrayStorage) | asArrayModesIgnoringTypedArrays(ArrayWithSlowPutArrayStorage):
    123123        return ArrayMode(Array::SlowPutArrayStorage, Array::Array, Array::AsIs, action).withProfile(locker, profile, makeSafe);
    124     case asArrayModes(NonArrayWithArrayStorage) | asArrayModes(ArrayWithArrayStorage):
     124    case asArrayModesIgnoringTypedArrays(NonArrayWithArrayStorage) | asArrayModesIgnoringTypedArrays(ArrayWithArrayStorage):
    125125        return ArrayMode(Array::ArrayStorage, Array::PossiblyArray, Array::AsIs, action).withProfile(locker, profile, makeSafe);
    126     case asArrayModes(NonArrayWithSlowPutArrayStorage) | asArrayModes(ArrayWithSlowPutArrayStorage):
    127     case asArrayModes(NonArrayWithArrayStorage) | asArrayModes(ArrayWithArrayStorage) | asArrayModes(NonArrayWithSlowPutArrayStorage) | asArrayModes(ArrayWithSlowPutArrayStorage):
     126    case asArrayModesIgnoringTypedArrays(NonArrayWithSlowPutArrayStorage) | asArrayModesIgnoringTypedArrays(ArrayWithSlowPutArrayStorage):
     127    case asArrayModesIgnoringTypedArrays(NonArrayWithArrayStorage) | asArrayModesIgnoringTypedArrays(ArrayWithArrayStorage) | asArrayModesIgnoringTypedArrays(NonArrayWithSlowPutArrayStorage) | asArrayModesIgnoringTypedArrays(ArrayWithSlowPutArrayStorage):
    128128        return ArrayMode(Array::SlowPutArrayStorage, Array::PossiblyArray, Array::AsIs, action).withProfile(locker, profile, makeSafe);
    129129    case Int8ArrayMode:
     
    151151            return ArrayMode(Array::Generic, nonArray, Array::AsIs, action).withProfile(locker, profile, makeSafe);
    152152
    153         if ((observed & asArrayModes(NonArray)) && profile->mayInterceptIndexedAccesses(locker))
     153        if ((observed & asArrayModesIgnoringTypedArrays(NonArray)) && profile->mayInterceptIndexedAccesses(locker))
    154154            return ArrayMode(Array::SelectUsingPredictions).withSpeculationFromProfile(locker, profile, makeSafe);
    155155       
     
    439439       
    440440    case Array::Array: {
    441         if (arrayModesAlreadyChecked(value.m_arrayModes, asArrayModes(shape | IsArray)))
     441        if (arrayModesAlreadyChecked(value.m_arrayModes, asArrayModesIgnoringTypedArrays(shape | IsArray)))
    442442            return true;
    443443        if (value.m_structure.isTop())
     
    456456       
    457457    default: {
    458         if (arrayModesAlreadyChecked(value.m_arrayModes, asArrayModes(shape) | asArrayModes(shape | IsArray)))
     458        if (arrayModesAlreadyChecked(value.m_arrayModes, asArrayModesIgnoringTypedArrays(shape) | asArrayModesIgnoringTypedArrays(shape | IsArray)))
    459459            return true;
    460460        if (value.m_structure.isTop())
     
    506506       
    507507        case Array::Array: {
    508             if (arrayModesAlreadyChecked(value.m_arrayModes, asArrayModes(ArrayWithArrayStorage) | asArrayModes(ArrayWithSlowPutArrayStorage)))
     508            if (arrayModesAlreadyChecked(value.m_arrayModes, asArrayModesIgnoringTypedArrays(ArrayWithArrayStorage) | asArrayModesIgnoringTypedArrays(ArrayWithSlowPutArrayStorage)))
    509509                return true;
    510510            if (value.m_structure.isTop())
     
    521521       
    522522        default: {
    523             if (arrayModesAlreadyChecked(value.m_arrayModes, asArrayModes(NonArrayWithArrayStorage) | asArrayModes(ArrayWithArrayStorage) | asArrayModes(NonArrayWithSlowPutArrayStorage) | asArrayModes(ArrayWithSlowPutArrayStorage)))
     523            if (arrayModesAlreadyChecked(value.m_arrayModes, asArrayModesIgnoringTypedArrays(NonArrayWithArrayStorage) | asArrayModesIgnoringTypedArrays(ArrayWithArrayStorage) | asArrayModesIgnoringTypedArrays(NonArrayWithSlowPutArrayStorage) | asArrayModesIgnoringTypedArrays(ArrayWithSlowPutArrayStorage)))
    524524                return true;
    525525            if (value.m_structure.isTop())
  • trunk/Source/JavaScriptCore/dfg/DFGArrayMode.h

    r234184 r239951  
    421421    bool structureWouldPassArrayModeFiltering(Structure* structure)
    422422    {
    423         return arrayModesAlreadyChecked(arrayModeFromStructure(structure), arrayModesThatPassFiltering());
     423        return arrayModesAlreadyChecked(arrayModesFromStructure(structure), arrayModesThatPassFiltering());
    424424    }
    425425   
     
    446446        case Array::ScopedArguments:
    447447            return arrayModesWithIndexingShapes(ArrayStorageShape, NonArray);
    448         default:
    449             return asArrayModes(NonArray);
     448        case Array::Int8Array:
     449            return Int8ArrayMode;
     450        case Array::Int16Array:
     451            return Int16ArrayMode;
     452        case Array::Int32Array:
     453            return Int32ArrayMode;
     454        case Array::Uint8Array:
     455            return Uint8ArrayMode;
     456        case Array::Uint8ClampedArray:
     457            return Uint8ClampedArrayMode;
     458        case Array::Uint16Array:
     459            return Uint16ArrayMode;
     460        case Array::Uint32Array:
     461            return Uint32ArrayMode;
     462        case Array::Float32Array:
     463            return Float32ArrayMode;
     464        case Array::Float64Array:
     465            return Float64ArrayMode;
     466        case Array::AnyTypedArray:
     467            return ALL_TYPED_ARRAY_MODES;
     468        default:
     469            return asArrayModesIgnoringTypedArrays(NonArray);
    450470        }
    451471
     
    498518        case Array::NonArray:
    499519        case Array::OriginalNonArray:
    500             return asArrayModes(shape);
     520            return asArrayModesIgnoringTypedArrays(shape);
    501521        case Array::OriginalCopyOnWriteArray:
    502522            ASSERT(hasInt32(shape) || hasDouble(shape) || hasContiguous(shape));
    503             return asArrayModes(shape | IsArray) | asArrayModes(shape | IsArray | CopyOnWrite);
     523            return asArrayModesIgnoringTypedArrays(shape | IsArray) | asArrayModesIgnoringTypedArrays(shape | IsArray | CopyOnWrite);
    504524        case Array::Array:
    505525            if (hasInt32(shape) || hasDouble(shape) || hasContiguous(shape))
    506                 return asArrayModes(shape | IsArray) | asArrayModes(shape | IsArray | CopyOnWrite);
     526                return asArrayModesIgnoringTypedArrays(shape | IsArray) | asArrayModesIgnoringTypedArrays(shape | IsArray | CopyOnWrite);
    507527            FALLTHROUGH;
    508528        case Array::OriginalArray:
    509             return asArrayModes(shape | IsArray);
     529            return asArrayModesIgnoringTypedArrays(shape | IsArray);
    510530        case Array::PossiblyArray:
    511531            if (hasInt32(shape) || hasDouble(shape) || hasContiguous(shape))
    512                 return asArrayModes(shape) | asArrayModes(shape | IsArray) | asArrayModes(shape | IsArray | CopyOnWrite);
    513             return asArrayModes(shape) | asArrayModes(shape | IsArray);
     532                return asArrayModesIgnoringTypedArrays(shape) | asArrayModesIgnoringTypedArrays(shape | IsArray) | asArrayModesIgnoringTypedArrays(shape | IsArray | CopyOnWrite);
     533            return asArrayModesIgnoringTypedArrays(shape) | asArrayModesIgnoringTypedArrays(shape | IsArray);
    514534        default:
    515535            // This is only necessary for C++ compilers that don't understand enums.
  • trunk/Source/JavaScriptCore/dfg/DFGOSRExit.cpp

    r239867 r239951  
    508508            Structure* structure = profiledValue.asCell()->structure(vm);
    509509            arrayProfile->observeStructure(structure);
    510             arrayProfile->observeArrayMode(asArrayModes(structure->indexingMode()));
     510            arrayProfile->observeArrayMode(arrayModesFromStructure(structure));
    511511        }
    512512        if (extraInitializationLevel <= ExtraInitializationLevel::ArrayProfileUpdate)
     
    11861186                jit.load32(AssemblyHelpers::Address(value, JSCell::structureIDOffset()), scratch1);
    11871187                jit.store32(scratch1, arrayProfile->addressOfLastSeenStructureID());
     1188
     1189                jit.load8(AssemblyHelpers::Address(value, JSCell::typeInfoTypeOffset()), scratch2);
     1190                jit.sub32(AssemblyHelpers::TrustedImm32(FirstTypedArrayType), scratch2);
     1191                auto notTypedArray = jit.branch32(MacroAssembler::AboveOrEqual, scratch2, AssemblyHelpers::TrustedImm32(NumberOfTypedArrayTypesExcludingDataView));
     1192                jit.move(AssemblyHelpers::TrustedImmPtr(typedArrayModes), scratch1);
     1193                jit.load32(AssemblyHelpers::BaseIndex(scratch1, scratch2, AssemblyHelpers::TimesFour), scratch2);
     1194                auto storeArrayModes = jit.jump();
     1195
     1196                notTypedArray.link(&jit);
    11881197#if USE(JSVALUE64)
    11891198                jit.load8(AssemblyHelpers::Address(value, JSCell::indexingTypeAndMiscOffset()), scratch1);
     
    11941203                jit.move(AssemblyHelpers::TrustedImm32(1), scratch2);
    11951204                jit.lshift32(scratch1, scratch2);
     1205                storeArrayModes.link(&jit);
    11961206                jit.or32(scratch2, AssemblyHelpers::AbsoluteAddress(arrayProfile->addressOfArrayModes()));
    11971207
  • trunk/Source/JavaScriptCore/dfg/DFGRegisteredStructureSet.cpp

    r237325 r239951  
    5454    genericFilter(
    5555        [&] (RegisteredStructure structure) -> bool {
    56             return arrayModes & arrayModeFromStructure(structure.get());
     56            return arrayModes & arrayModesFromStructure(structure.get());
    5757        });
    5858}
     
    8080    forEach(
    8181        [&] (RegisteredStructure structure) {
    82             mergeArrayModes(result, asArrayModes(structure->indexingMode()));
     82            mergeArrayModes(result, arrayModesFromStructure(structure.get()));
    8383        });
    8484    return result;
  • trunk/Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp

    r234331 r239951  
    278278                jit.load32(MacroAssembler::Address(GPRInfo::regT0, JSCell::structureIDOffset()), GPRInfo::regT1);
    279279                jit.store32(GPRInfo::regT1, arrayProfile->addressOfLastSeenStructureID());
     280
     281                jit.load8(MacroAssembler::Address(GPRInfo::regT0, JSCell::typeInfoTypeOffset()), GPRInfo::regT2);
     282                jit.sub32(MacroAssembler::TrustedImm32(FirstTypedArrayType), GPRInfo::regT2);
     283                auto notTypedArray = jit.branch32(MacroAssembler::AboveOrEqual, GPRInfo::regT2, MacroAssembler::TrustedImm32(NumberOfTypedArrayTypesExcludingDataView));
     284                jit.move(MacroAssembler::TrustedImmPtr(typedArrayModes), GPRInfo::regT1);
     285                jit.load32(MacroAssembler::BaseIndex(GPRInfo::regT1, GPRInfo::regT2, MacroAssembler::TimesFour), GPRInfo::regT2);
     286                auto storeArrayModes = jit.jump();
     287
     288                notTypedArray.link(&jit);
    280289                jit.load8(MacroAssembler::Address(GPRInfo::regT0, JSCell::indexingTypeAndMiscOffset()), GPRInfo::regT1);
    281290                jit.and32(MacroAssembler::TrustedImm32(IndexingModeMask), GPRInfo::regT1);
    282291                jit.move(MacroAssembler::TrustedImm32(1), GPRInfo::regT2);
    283292                jit.lshift32(GPRInfo::regT1, GPRInfo::regT2);
     293                storeArrayModes.link(&jit);
    284294                jit.or32(GPRInfo::regT2, MacroAssembler::AbsoluteAddress(arrayProfile->addressOfArrayModes()));
    285295            }
  • trunk/Source/JavaScriptCore/jit/JITInlines.h

    r239626 r239951  
    365365}
    366366
    367 static inline bool arrayProfileSaw(ArrayModes arrayModes, IndexingType capability)
    368 {
    369     return arrayModesInclude(arrayModes, capability);
    370 }
    371 
    372367inline JITArrayMode JIT::chooseArrayMode(ArrayProfile* profile)
    373368{
     369    auto arrayProfileSaw = [] (ArrayModes arrayModes, IndexingType capability) {
     370        return arrayModesIncludeIgnoringTypedArrays(arrayModes, capability);
     371    };
     372
    374373    ConcurrentJSLocker locker(m_codeBlock->m_lock);
    375374    profile->computeUpdatedPrediction(locker, m_codeBlock);
  • trunk/Source/JavaScriptCore/runtime/JSType.h

    r237547 r239951  
    118118};
    119119
    120 static const uint32_t FirstTypedArrayType = Int8ArrayType;
    121 static const uint32_t LastTypedArrayType = DataViewType;
     120static constexpr uint32_t FirstTypedArrayType = Int8ArrayType;
     121static constexpr uint32_t LastTypedArrayType = DataViewType;
    122122
    123123// LastObjectType should be MaxJSType (not LastJSCObjectType) since embedders can add their extended object types after the enums listed in JSType.
    124 static const uint32_t FirstObjectType = ObjectType;
    125 static const uint32_t LastObjectType = MaxJSType;
     124static constexpr uint32_t FirstObjectType = ObjectType;
     125static constexpr uint32_t LastObjectType = MaxJSType;
    126126
    127127static constexpr uint32_t NumberOfTypedArrayTypes = LastTypedArrayType - FirstTypedArrayType + 1;
     
    130130static_assert(sizeof(JSType) == sizeof(uint8_t), "sizeof(JSType) is one byte.");
    131131static_assert(LastJSCObjectType < 128, "The highest bit is reserved for embedder's extension.");
     132
     133inline constexpr bool isTypedArrayType(JSType type)
     134{
     135    return (static_cast<uint32_t>(type) - FirstTypedArrayType) < NumberOfTypedArrayTypesExcludingDataView;
     136}
    132137
    133138} // namespace JSC
Note: See TracChangeset for help on using the changeset viewer.