Title: [239951] trunk
Revision
239951
Author
[email protected]
Date
2019-01-14 14:31:06 -0800 (Mon, 14 Jan 2019)

Log 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/_javascript_Core:

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):

Modified Paths

Added Paths

Diff

Modified: trunk/JSTests/ChangeLog (239950 => 239951)


--- trunk/JSTests/ChangeLog	2019-01-14 22:23:30 UTC (rev 239950)
+++ trunk/JSTests/ChangeLog	2019-01-14 22:31:06 UTC (rev 239951)
@@ -1,3 +1,13 @@
+2019-01-14  Yusuke Suzuki  <[email protected]>
+
+        [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.
+
+        * stress/typed-array-array-modes-profile.js: Added.
+        (foo):
+
 2019-01-14  Mark Lam  <[email protected]>
 
         Fix all CLoop JSC test failures (including some LLInt bugs due to recent bytecode format change).

Added: trunk/JSTests/stress/typed-array-array-modes-profile.js (0 => 239951)


--- trunk/JSTests/stress/typed-array-array-modes-profile.js	                        (rev 0)
+++ trunk/JSTests/stress/typed-array-array-modes-profile.js	2019-01-14 22:31:06 UTC (rev 239951)
@@ -0,0 +1,18 @@
+function foo(o) {
+    for (var i = 0; i < 100; ++i) {
+        o.f = o.f;
+    }
+}
+
+let typedArrays = [
+    Uint8Array,
+    Uint32Array,
+    Uint8Array,
+];
+
+for (let constructor of typedArrays) {
+    let a = new constructor(0);
+    for (let i = 0; i < 10000; i++) {
+        foo(a);
+    }
+}

Modified: trunk/Source/_javascript_Core/ChangeLog (239950 => 239951)


--- trunk/Source/_javascript_Core/ChangeLog	2019-01-14 22:23:30 UTC (rev 239950)
+++ trunk/Source/_javascript_Core/ChangeLog	2019-01-14 22:31:06 UTC (rev 239951)
@@ -1,3 +1,75 @@
+2019-01-14  Yusuke Suzuki  <[email protected]>
+
+        [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.
+
+        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):
+
 2019-01-14  Mark Lam  <[email protected]>
 
         Re-enable ability to build --cloop builds.

Modified: trunk/Source/_javascript_Core/bytecode/ArrayProfile.cpp (239950 => 239951)


--- trunk/Source/_javascript_Core/bytecode/ArrayProfile.cpp	2019-01-14 22:23:30 UTC (rev 239950)
+++ trunk/Source/_javascript_Core/bytecode/ArrayProfile.cpp	2019-01-14 22:31:06 UTC (rev 239951)
@@ -37,6 +37,19 @@
 const char* const ArrayProfile::s_typeName = "ArrayProfile";
 #endif
 
+// Keep in sync with the order of TypedArrayType.
+const ArrayModes typedArrayModes[NumberOfTypedArrayTypesExcludingDataView] = {
+    Int8ArrayMode,
+    Uint8ArrayMode,
+    Uint8ClampedArrayMode,
+    Int16ArrayMode,
+    Uint16ArrayMode,
+    Int32ArrayMode,
+    Uint32ArrayMode,
+    Float32ArrayMode,
+    Float64ArrayMode,
+};
+
 void dumpArrayModes(PrintStream& out, ArrayModes arrayModes)
 {
     if (!arrayModes) {
@@ -50,37 +63,37 @@
     }
     
     CommaPrinter comma("|");
-    if (arrayModes & asArrayModes(NonArray))
+    if (arrayModes & asArrayModesIgnoringTypedArrays(NonArray))
         out.print(comma, "NonArray");
-    if (arrayModes & asArrayModes(NonArrayWithInt32))
+    if (arrayModes & asArrayModesIgnoringTypedArrays(NonArrayWithInt32))
         out.print(comma, "NonArrayWithInt32");
-    if (arrayModes & asArrayModes(NonArrayWithDouble))
+    if (arrayModes & asArrayModesIgnoringTypedArrays(NonArrayWithDouble))
         out.print(comma, "NonArrayWithDouble");
-    if (arrayModes & asArrayModes(NonArrayWithContiguous))
+    if (arrayModes & asArrayModesIgnoringTypedArrays(NonArrayWithContiguous))
         out.print(comma, "NonArrayWithContiguous");
-    if (arrayModes & asArrayModes(NonArrayWithArrayStorage))
+    if (arrayModes & asArrayModesIgnoringTypedArrays(NonArrayWithArrayStorage))
         out.print(comma, "NonArrayWithArrayStorage");
-    if (arrayModes & asArrayModes(NonArrayWithSlowPutArrayStorage))
+    if (arrayModes & asArrayModesIgnoringTypedArrays(NonArrayWithSlowPutArrayStorage))
         out.print(comma, "NonArrayWithSlowPutArrayStorage");
-    if (arrayModes & asArrayModes(ArrayClass))
+    if (arrayModes & asArrayModesIgnoringTypedArrays(ArrayClass))
         out.print(comma, "ArrayClass");
-    if (arrayModes & asArrayModes(ArrayWithUndecided))
+    if (arrayModes & asArrayModesIgnoringTypedArrays(ArrayWithUndecided))
         out.print(comma, "ArrayWithUndecided");
-    if (arrayModes & asArrayModes(ArrayWithInt32))
+    if (arrayModes & asArrayModesIgnoringTypedArrays(ArrayWithInt32))
         out.print(comma, "ArrayWithInt32");
-    if (arrayModes & asArrayModes(ArrayWithDouble))
+    if (arrayModes & asArrayModesIgnoringTypedArrays(ArrayWithDouble))
         out.print(comma, "ArrayWithDouble");
-    if (arrayModes & asArrayModes(ArrayWithContiguous))
+    if (arrayModes & asArrayModesIgnoringTypedArrays(ArrayWithContiguous))
         out.print(comma, "ArrayWithContiguous");
-    if (arrayModes & asArrayModes(ArrayWithArrayStorage))
+    if (arrayModes & asArrayModesIgnoringTypedArrays(ArrayWithArrayStorage))
         out.print(comma, "ArrayWithArrayStorage");
-    if (arrayModes & asArrayModes(ArrayWithSlowPutArrayStorage))
+    if (arrayModes & asArrayModesIgnoringTypedArrays(ArrayWithSlowPutArrayStorage))
         out.print(comma, "ArrayWithSlowPutArrayStorage");
-    if (arrayModes & asArrayModes(CopyOnWriteArrayWithInt32))
+    if (arrayModes & asArrayModesIgnoringTypedArrays(CopyOnWriteArrayWithInt32))
         out.print(comma, "CopyOnWriteArrayWithInt32");
-    if (arrayModes & asArrayModes(CopyOnWriteArrayWithDouble))
+    if (arrayModes & asArrayModesIgnoringTypedArrays(CopyOnWriteArrayWithDouble))
         out.print(comma, "CopyOnWriteArrayWithDouble");
-    if (arrayModes & asArrayModes(CopyOnWriteArrayWithContiguous))
+    if (arrayModes & asArrayModesIgnoringTypedArrays(CopyOnWriteArrayWithContiguous))
         out.print(comma, "CopyOnWriteArrayWithContiguous");
 
     if (arrayModes & Int8ArrayMode)
@@ -115,11 +128,11 @@
 
 void ArrayProfile::computeUpdatedPrediction(const ConcurrentJSLocker&, CodeBlock* codeBlock, Structure* lastSeenStructure)
 {
-    m_observedArrayModes |= arrayModeFromStructure(lastSeenStructure);
+    m_observedArrayModes |= arrayModesFromStructure(lastSeenStructure);
     
     if (!m_didPerformFirstRunPruning
         && hasTwoOrMoreBitsSet(m_observedArrayModes)) {
-        m_observedArrayModes = arrayModeFromStructure(lastSeenStructure);
+        m_observedArrayModes = arrayModesFromStructure(lastSeenStructure);
         m_didPerformFirstRunPruning = true;
     }
     

Modified: trunk/Source/_javascript_Core/bytecode/ArrayProfile.h (239950 => 239951)


--- trunk/Source/_javascript_Core/bytecode/ArrayProfile.h	2019-01-14 22:23:30 UTC (rev 239950)
+++ trunk/Source/_javascript_Core/bytecode/ArrayProfile.h	2019-01-14 22:31:06 UTC (rev 239951)
@@ -58,7 +58,9 @@
 const ArrayModes Float32ArrayMode = 1 << 28;
 const ArrayModes Float64ArrayMode = 1 << 29;
 
-constexpr ArrayModes asArrayModes(IndexingType indexingMode)
+extern const ArrayModes typedArrayModes[NumberOfTypedArrayTypesExcludingDataView];
+
+constexpr ArrayModes asArrayModesIgnoringTypedArrays(IndexingType indexingMode)
 {
     return static_cast<unsigned>(1) << static_cast<unsigned>(indexingMode);
 }
@@ -76,12 +78,12 @@
     )
 
 #define ALL_NON_ARRAY_ARRAY_MODES                       \
-    (asArrayModes(NonArray)                             \
-    | asArrayModes(NonArrayWithInt32)                   \
-    | asArrayModes(NonArrayWithDouble)                  \
-    | asArrayModes(NonArrayWithContiguous)              \
-    | asArrayModes(NonArrayWithArrayStorage)            \
-    | asArrayModes(NonArrayWithSlowPutArrayStorage)     \
+    (asArrayModesIgnoringTypedArrays(NonArray)                             \
+    | asArrayModesIgnoringTypedArrays(NonArrayWithInt32)                   \
+    | asArrayModesIgnoringTypedArrays(NonArrayWithDouble)                  \
+    | asArrayModesIgnoringTypedArrays(NonArrayWithContiguous)              \
+    | asArrayModesIgnoringTypedArrays(NonArrayWithArrayStorage)            \
+    | asArrayModesIgnoringTypedArrays(NonArrayWithSlowPutArrayStorage)     \
     | ALL_TYPED_ARRAY_MODES)
 
 #define ALL_COPY_ON_WRITE_ARRAY_MODES                   \
@@ -90,13 +92,13 @@
     | CopyOnWriteArrayWithContiguousArrayMode)
 
 #define ALL_WRITABLE_ARRAY_ARRAY_MODES                  \
-    (asArrayModes(ArrayClass)                           \
-    | asArrayModes(ArrayWithUndecided)                  \
-    | asArrayModes(ArrayWithInt32)                      \
-    | asArrayModes(ArrayWithDouble)                     \
-    | asArrayModes(ArrayWithContiguous)                 \
-    | asArrayModes(ArrayWithArrayStorage)               \
-    | asArrayModes(ArrayWithSlowPutArrayStorage))
+    (asArrayModesIgnoringTypedArrays(ArrayClass)                           \
+    | asArrayModesIgnoringTypedArrays(ArrayWithUndecided)                  \
+    | asArrayModesIgnoringTypedArrays(ArrayWithInt32)                      \
+    | asArrayModesIgnoringTypedArrays(ArrayWithDouble)                     \
+    | asArrayModesIgnoringTypedArrays(ArrayWithContiguous)                 \
+    | asArrayModesIgnoringTypedArrays(ArrayWithArrayStorage)               \
+    | asArrayModesIgnoringTypedArrays(ArrayWithSlowPutArrayStorage))
 
 #define ALL_ARRAY_ARRAY_MODES                           \
     (ALL_WRITABLE_ARRAY_ARRAY_MODES                     \
@@ -104,33 +106,12 @@
 
 #define ALL_ARRAY_MODES (ALL_NON_ARRAY_ARRAY_MODES | ALL_ARRAY_ARRAY_MODES)
 
-inline ArrayModes arrayModeFromStructure(Structure* structure)
+inline ArrayModes arrayModesFromStructure(Structure* structure)
 {
-    switch (structure->classInfo()->typedArrayStorageType) {
-    case TypeInt8:
-        return Int8ArrayMode;
-    case TypeUint8:
-        return Uint8ArrayMode;
-    case TypeUint8Clamped:
-        return Uint8ClampedArrayMode;
-    case TypeInt16:
-        return Int16ArrayMode;
-    case TypeUint16:
-        return Uint16ArrayMode;
-    case TypeInt32:
-        return Int32ArrayMode;
-    case TypeUint32:
-        return Uint32ArrayMode;
-    case TypeFloat32:
-        return Float32ArrayMode;
-    case TypeFloat64:
-        return Float64ArrayMode;
-    case TypeDataView:
-    case NotTypedArray:
-        break;
-    }
-
-    return asArrayModes(structure->indexingMode());
+    JSType type = structure->typeInfo().type();
+    if (isTypedArrayType(type))
+        return typedArrayModes[type - FirstTypedArrayType];
+    return asArrayModesIgnoringTypedArrays(structure->indexingMode());
 }
 
 void dumpArrayModes(PrintStream&, ArrayModes);
@@ -156,37 +137,37 @@
     return (expected | proven) == expected;
 }
 
-inline bool arrayModesInclude(ArrayModes arrayModes, IndexingType shape)
+inline bool arrayModesIncludeIgnoringTypedArrays(ArrayModes arrayModes, IndexingType shape)
 {
-    ArrayModes modes = asArrayModes(NonArray | shape) | asArrayModes(ArrayClass | shape);
+    ArrayModes modes = asArrayModesIgnoringTypedArrays(NonArray | shape) | asArrayModesIgnoringTypedArrays(ArrayClass | shape);
     if (hasInt32(shape) || hasDouble(shape) || hasContiguous(shape))
-        modes |= asArrayModes(ArrayClass | shape | CopyOnWrite);
+        modes |= asArrayModesIgnoringTypedArrays(ArrayClass | shape | CopyOnWrite);
     return !!(arrayModes & modes);
 }
 
 inline bool shouldUseSlowPutArrayStorage(ArrayModes arrayModes)
 {
-    return arrayModesInclude(arrayModes, SlowPutArrayStorageShape);
+    return arrayModesIncludeIgnoringTypedArrays(arrayModes, SlowPutArrayStorageShape);
 }
 
 inline bool shouldUseFastArrayStorage(ArrayModes arrayModes)
 {
-    return arrayModesInclude(arrayModes, ArrayStorageShape);
+    return arrayModesIncludeIgnoringTypedArrays(arrayModes, ArrayStorageShape);
 }
 
 inline bool shouldUseContiguous(ArrayModes arrayModes)
 {
-    return arrayModesInclude(arrayModes, ContiguousShape);
+    return arrayModesIncludeIgnoringTypedArrays(arrayModes, ContiguousShape);
 }
 
 inline bool shouldUseDouble(ArrayModes arrayModes)
 {
-    return arrayModesInclude(arrayModes, DoubleShape);
+    return arrayModesIncludeIgnoringTypedArrays(arrayModes, DoubleShape);
 }
 
 inline bool shouldUseInt32(ArrayModes arrayModes)
 {
-    return arrayModesInclude(arrayModes, Int32Shape);
+    return arrayModesIncludeIgnoringTypedArrays(arrayModes, Int32Shape);
 }
 
 inline bool hasSeenArray(ArrayModes arrayModes)

Modified: trunk/Source/_javascript_Core/dfg/DFGAbstractValue.cpp (239950 => 239951)


--- trunk/Source/_javascript_Core/dfg/DFGAbstractValue.cpp	2019-01-14 22:23:30 UTC (rev 239950)
+++ trunk/Source/_javascript_Core/dfg/DFGAbstractValue.cpp	2019-01-14 22:31:06 UTC (rev 239951)
@@ -40,8 +40,8 @@
         m_structure.observeTransitions(vector);
         ArrayModes newModes = 0;
         for (unsigned i = vector.size(); i--;) {
-            if (m_arrayModes & asArrayModes(vector[i].previous->indexingType()))
-                newModes |= asArrayModes(vector[i].next->indexingType());
+            if (m_arrayModes & arrayModesFromStructure(vector[i].previous.get()))
+                newModes |= arrayModesFromStructure(vector[i].next.get());
         }
         m_arrayModes |= newModes;
     }
@@ -60,7 +60,7 @@
                 m_arrayModes = ALL_ARRAY_MODES;
                 m_structure.clobber();
             } else
-                m_arrayModes = asArrayModes(structure->indexingMode());
+                m_arrayModes = arrayModesFromStructure(structure);
         } else {
             m_structure.makeTop();
             m_arrayModes = ALL_ARRAY_MODES;
@@ -87,7 +87,7 @@
     RELEASE_ASSERT(structure);
     
     m_structure = structure;
-    m_arrayModes = asArrayModes(structure->indexingMode());
+    m_arrayModes = arrayModesFromStructure(structure.get());
     m_type = speculationFromStructure(structure.get());
     m_value = JSValue();
     
@@ -228,7 +228,7 @@
         FrozenValue* frozenValue = graph.freeze(value);
         if (frozenValue->pointsToHeap()) {
             m_structure = graph.registerStructure(frozenValue->structure());
-            m_arrayModes = asArrayModes(frozenValue->structure()->indexingMode());
+            m_arrayModes = arrayModesFromStructure(frozenValue->structure());
         } else {
             m_structure.clear();
             m_arrayModes = 0;
@@ -240,7 +240,7 @@
         mergeSpeculation(m_type, speculationFromValue(value));
         if (!!value && value.isCell()) {
             RegisteredStructure structure = graph.registerStructure(value.asCell()->structure(graph.m_vm));
-            mergeArrayModes(m_arrayModes, asArrayModes(structure->indexingMode()));
+            mergeArrayModes(m_arrayModes, arrayModesFromStructure(structure.get()));
             m_structure.merge(RegisteredStructureSet(structure));
         }
         if (m_value != value)
@@ -365,7 +365,7 @@
 bool AbstractValue::contains(RegisteredStructure structure) const
 {
     return couldBeType(speculationFromStructure(structure.get()))
-        && (m_arrayModes & arrayModeFromStructure(structure.get()))
+        && (m_arrayModes & arrayModesFromStructure(structure.get()))
         && m_structure.contains(structure);
 }
 

Modified: trunk/Source/_javascript_Core/dfg/DFGAbstractValue.h (239950 => 239951)


--- trunk/Source/_javascript_Core/dfg/DFGAbstractValue.h	2019-01-14 22:23:30 UTC (rev 239950)
+++ trunk/Source/_javascript_Core/dfg/DFGAbstractValue.h	2019-01-14 22:31:06 UTC (rev 239951)
@@ -137,7 +137,7 @@
     {
         if (m_type & SpecCell) {
             m_structure.observeTransition(from, to);
-            observeIndexingTypeTransition(from->indexingType(), to->indexingType());
+            observeIndexingTypeTransition(arrayModesFromStructure(from.get()), arrayModesFromStructure(to.get()));
         }
         checkConsistency();
     }
@@ -397,7 +397,7 @@
             ASSERT(m_type & SpecCell);
             Structure* structure = value.asCell()->structure();
             return m_structure.contains(structure)
-                && (m_arrayModes & asArrayModes(structure->indexingMode()));
+                && (m_arrayModes & arrayModesFromStructure(structure));
         }
         
         return true;
@@ -492,10 +492,10 @@
         m_arrayModes = ALL_ARRAY_MODES;
     }
     
-    void observeIndexingTypeTransition(IndexingType from, IndexingType to)
+    void observeIndexingTypeTransition(ArrayModes from, ArrayModes to)
     {
-        if (m_arrayModes & asArrayModes(from))
-            m_arrayModes |= asArrayModes(to);
+        if (m_arrayModes & from)
+            m_arrayModes |= to;
     }
     
     bool validateType(JSValue value) const

Modified: trunk/Source/_javascript_Core/dfg/DFGArrayMode.cpp (239950 => 239951)


--- trunk/Source/_javascript_Core/dfg/DFGArrayMode.cpp	2019-01-14 22:23:30 UTC (rev 239950)
+++ trunk/Source/_javascript_Core/dfg/DFGArrayMode.cpp	2019-01-14 22:31:06 UTC (rev 239951)
@@ -47,10 +47,10 @@
         Array::Class isArray;
         Array::Conversion converts;
 
-        RELEASE_ASSERT((observed & (asArrayModes(toIndexingShape(type)) | asArrayModes(toIndexingShape(type) | ArrayClass) | asArrayModes(toIndexingShape(type) | ArrayClass | CopyOnWrite))) == observed);
+        RELEASE_ASSERT((observed & (asArrayModesIgnoringTypedArrays(toIndexingShape(type)) | asArrayModesIgnoringTypedArrays(toIndexingShape(type) | ArrayClass) | asArrayModesIgnoringTypedArrays(toIndexingShape(type) | ArrayClass | CopyOnWrite))) == observed);
 
-        if (observed & asArrayModes(toIndexingShape(type))) {
-            if ((observed & asArrayModes(toIndexingShape(type))) == observed)
+        if (observed & asArrayModesIgnoringTypedArrays(toIndexingShape(type))) {
+            if ((observed & asArrayModesIgnoringTypedArrays(toIndexingShape(type))) == observed)
                 isArray = nonArray;
             else
                 isArray = Array::PossiblyArray;
@@ -57,7 +57,7 @@
         } else
             isArray = Array::Array;
 
-        if (action == Array::Write && (observed & asArrayModes(toIndexingShape(type) | ArrayClass | CopyOnWrite)))
+        if (action == Array::Write && (observed & asArrayModesIgnoringTypedArrays(toIndexingShape(type) | ArrayClass | CopyOnWrite)))
             converts = Array::Convert;
         else
             converts = Array::AsIs;
@@ -69,62 +69,62 @@
     switch (observed) {
     case 0:
         return ArrayMode(Array::Unprofiled);
-    case asArrayModes(NonArray):
+    case asArrayModesIgnoringTypedArrays(NonArray):
         if (action == Array::Write && !profile->mayInterceptIndexedAccesses(locker))
             return ArrayMode(Array::SelectUsingArguments, nonArray, Array::OutOfBounds, Array::Convert, action);
         return ArrayMode(Array::SelectUsingPredictions, nonArray, action).withSpeculationFromProfile(locker, profile, makeSafe);
 
-    case asArrayModes(ArrayWithUndecided):
+    case asArrayModesIgnoringTypedArrays(ArrayWithUndecided):
         if (action == Array::Write)
             return ArrayMode(Array::SelectUsingArguments, Array::Array, Array::OutOfBounds, Array::Convert, action);
         return ArrayMode(Array::Undecided, Array::Array, Array::OutOfBounds, Array::AsIs, action).withProfile(locker, profile, makeSafe);
         
-    case asArrayModes(NonArray) | asArrayModes(ArrayWithUndecided):
+    case asArrayModesIgnoringTypedArrays(NonArray) | asArrayModesIgnoringTypedArrays(ArrayWithUndecided):
         if (action == Array::Write && !profile->mayInterceptIndexedAccesses(locker))
             return ArrayMode(Array::SelectUsingArguments, Array::PossiblyArray, Array::OutOfBounds, Array::Convert, action);
         return ArrayMode(Array::SelectUsingPredictions, action).withSpeculationFromProfile(locker, profile, makeSafe);
 
-    case asArrayModes(NonArrayWithInt32):
-    case asArrayModes(ArrayWithInt32):
-    case asArrayModes(CopyOnWriteArrayWithInt32):
-    case asArrayModes(NonArrayWithInt32) | asArrayModes(ArrayWithInt32):
-    case asArrayModes(NonArrayWithInt32) | asArrayModes(CopyOnWriteArrayWithInt32):
-    case asArrayModes(ArrayWithInt32) | asArrayModes(CopyOnWriteArrayWithInt32):
-    case asArrayModes(NonArrayWithInt32) | asArrayModes(ArrayWithInt32) | asArrayModes(CopyOnWriteArrayWithInt32):
+    case asArrayModesIgnoringTypedArrays(NonArrayWithInt32):
+    case asArrayModesIgnoringTypedArrays(ArrayWithInt32):
+    case asArrayModesIgnoringTypedArrays(CopyOnWriteArrayWithInt32):
+    case asArrayModesIgnoringTypedArrays(NonArrayWithInt32) | asArrayModesIgnoringTypedArrays(ArrayWithInt32):
+    case asArrayModesIgnoringTypedArrays(NonArrayWithInt32) | asArrayModesIgnoringTypedArrays(CopyOnWriteArrayWithInt32):
+    case asArrayModesIgnoringTypedArrays(ArrayWithInt32) | asArrayModesIgnoringTypedArrays(CopyOnWriteArrayWithInt32):
+    case asArrayModesIgnoringTypedArrays(NonArrayWithInt32) | asArrayModesIgnoringTypedArrays(ArrayWithInt32) | asArrayModesIgnoringTypedArrays(CopyOnWriteArrayWithInt32):
         return handleContiguousModes(Array::Int32, observed);
 
-    case asArrayModes(NonArrayWithDouble):
-    case asArrayModes(ArrayWithDouble):
-    case asArrayModes(CopyOnWriteArrayWithDouble):
-    case asArrayModes(NonArrayWithDouble) | asArrayModes(ArrayWithDouble):
-    case asArrayModes(NonArrayWithDouble) | asArrayModes(CopyOnWriteArrayWithDouble):
-    case asArrayModes(ArrayWithDouble) | asArrayModes(CopyOnWriteArrayWithDouble):
-    case asArrayModes(NonArrayWithDouble) | asArrayModes(ArrayWithDouble) | asArrayModes(CopyOnWriteArrayWithDouble):
+    case asArrayModesIgnoringTypedArrays(NonArrayWithDouble):
+    case asArrayModesIgnoringTypedArrays(ArrayWithDouble):
+    case asArrayModesIgnoringTypedArrays(CopyOnWriteArrayWithDouble):
+    case asArrayModesIgnoringTypedArrays(NonArrayWithDouble) | asArrayModesIgnoringTypedArrays(ArrayWithDouble):
+    case asArrayModesIgnoringTypedArrays(NonArrayWithDouble) | asArrayModesIgnoringTypedArrays(CopyOnWriteArrayWithDouble):
+    case asArrayModesIgnoringTypedArrays(ArrayWithDouble) | asArrayModesIgnoringTypedArrays(CopyOnWriteArrayWithDouble):
+    case asArrayModesIgnoringTypedArrays(NonArrayWithDouble) | asArrayModesIgnoringTypedArrays(ArrayWithDouble) | asArrayModesIgnoringTypedArrays(CopyOnWriteArrayWithDouble):
         return handleContiguousModes(Array::Double, observed);
 
-    case asArrayModes(NonArrayWithContiguous):
-    case asArrayModes(ArrayWithContiguous):
-    case asArrayModes(CopyOnWriteArrayWithContiguous):
-    case asArrayModes(NonArrayWithContiguous) | asArrayModes(ArrayWithContiguous):
-    case asArrayModes(NonArrayWithContiguous) | asArrayModes(CopyOnWriteArrayWithContiguous):
-    case asArrayModes(ArrayWithContiguous) | asArrayModes(CopyOnWriteArrayWithContiguous):
-    case asArrayModes(NonArrayWithContiguous) | asArrayModes(ArrayWithContiguous) | asArrayModes(CopyOnWriteArrayWithContiguous):
+    case asArrayModesIgnoringTypedArrays(NonArrayWithContiguous):
+    case asArrayModesIgnoringTypedArrays(ArrayWithContiguous):
+    case asArrayModesIgnoringTypedArrays(CopyOnWriteArrayWithContiguous):
+    case asArrayModesIgnoringTypedArrays(NonArrayWithContiguous) | asArrayModesIgnoringTypedArrays(ArrayWithContiguous):
+    case asArrayModesIgnoringTypedArrays(NonArrayWithContiguous) | asArrayModesIgnoringTypedArrays(CopyOnWriteArrayWithContiguous):
+    case asArrayModesIgnoringTypedArrays(ArrayWithContiguous) | asArrayModesIgnoringTypedArrays(CopyOnWriteArrayWithContiguous):
+    case asArrayModesIgnoringTypedArrays(NonArrayWithContiguous) | asArrayModesIgnoringTypedArrays(ArrayWithContiguous) | asArrayModesIgnoringTypedArrays(CopyOnWriteArrayWithContiguous):
         return handleContiguousModes(Array::Contiguous, observed);
 
-    case asArrayModes(NonArrayWithArrayStorage):
+    case asArrayModesIgnoringTypedArrays(NonArrayWithArrayStorage):
         return ArrayMode(Array::ArrayStorage, nonArray, Array::AsIs, action).withProfile(locker, profile, makeSafe);
-    case asArrayModes(NonArrayWithSlowPutArrayStorage):
-    case asArrayModes(NonArrayWithArrayStorage) | asArrayModes(NonArrayWithSlowPutArrayStorage):
+    case asArrayModesIgnoringTypedArrays(NonArrayWithSlowPutArrayStorage):
+    case asArrayModesIgnoringTypedArrays(NonArrayWithArrayStorage) | asArrayModesIgnoringTypedArrays(NonArrayWithSlowPutArrayStorage):
         return ArrayMode(Array::SlowPutArrayStorage, nonArray, Array::AsIs, action).withProfile(locker, profile, makeSafe);
-    case asArrayModes(ArrayWithArrayStorage):
+    case asArrayModesIgnoringTypedArrays(ArrayWithArrayStorage):
         return ArrayMode(Array::ArrayStorage, Array::Array, Array::AsIs, action).withProfile(locker, profile, makeSafe);
-    case asArrayModes(ArrayWithSlowPutArrayStorage):
-    case asArrayModes(ArrayWithArrayStorage) | asArrayModes(ArrayWithSlowPutArrayStorage):
+    case asArrayModesIgnoringTypedArrays(ArrayWithSlowPutArrayStorage):
+    case asArrayModesIgnoringTypedArrays(ArrayWithArrayStorage) | asArrayModesIgnoringTypedArrays(ArrayWithSlowPutArrayStorage):
         return ArrayMode(Array::SlowPutArrayStorage, Array::Array, Array::AsIs, action).withProfile(locker, profile, makeSafe);
-    case asArrayModes(NonArrayWithArrayStorage) | asArrayModes(ArrayWithArrayStorage):
+    case asArrayModesIgnoringTypedArrays(NonArrayWithArrayStorage) | asArrayModesIgnoringTypedArrays(ArrayWithArrayStorage):
         return ArrayMode(Array::ArrayStorage, Array::PossiblyArray, Array::AsIs, action).withProfile(locker, profile, makeSafe);
-    case asArrayModes(NonArrayWithSlowPutArrayStorage) | asArrayModes(ArrayWithSlowPutArrayStorage):
-    case asArrayModes(NonArrayWithArrayStorage) | asArrayModes(ArrayWithArrayStorage) | asArrayModes(NonArrayWithSlowPutArrayStorage) | asArrayModes(ArrayWithSlowPutArrayStorage):
+    case asArrayModesIgnoringTypedArrays(NonArrayWithSlowPutArrayStorage) | asArrayModesIgnoringTypedArrays(ArrayWithSlowPutArrayStorage):
+    case asArrayModesIgnoringTypedArrays(NonArrayWithArrayStorage) | asArrayModesIgnoringTypedArrays(ArrayWithArrayStorage) | asArrayModesIgnoringTypedArrays(NonArrayWithSlowPutArrayStorage) | asArrayModesIgnoringTypedArrays(ArrayWithSlowPutArrayStorage):
         return ArrayMode(Array::SlowPutArrayStorage, Array::PossiblyArray, Array::AsIs, action).withProfile(locker, profile, makeSafe);
     case Int8ArrayMode:
         return ArrayMode(Array::Int8Array, nonArray, Array::AsIs, action).withProfile(locker, profile, makeSafe);
@@ -150,7 +150,7 @@
         if (observed & ALL_TYPED_ARRAY_MODES)
             return ArrayMode(Array::Generic, nonArray, Array::AsIs, action).withProfile(locker, profile, makeSafe);
 
-        if ((observed & asArrayModes(NonArray)) && profile->mayInterceptIndexedAccesses(locker))
+        if ((observed & asArrayModesIgnoringTypedArrays(NonArray)) && profile->mayInterceptIndexedAccesses(locker))
             return ArrayMode(Array::SelectUsingPredictions).withSpeculationFromProfile(locker, profile, makeSafe);
         
         Array::Type type;
@@ -438,7 +438,7 @@
     }
         
     case Array::Array: {
-        if (arrayModesAlreadyChecked(value.m_arrayModes, asArrayModes(shape | IsArray)))
+        if (arrayModesAlreadyChecked(value.m_arrayModes, asArrayModesIgnoringTypedArrays(shape | IsArray)))
             return true;
         if (value.m_structure.isTop())
             return false;
@@ -455,7 +455,7 @@
     }
         
     default: {
-        if (arrayModesAlreadyChecked(value.m_arrayModes, asArrayModes(shape) | asArrayModes(shape | IsArray)))
+        if (arrayModesAlreadyChecked(value.m_arrayModes, asArrayModesIgnoringTypedArrays(shape) | asArrayModesIgnoringTypedArrays(shape | IsArray)))
             return true;
         if (value.m_structure.isTop())
             return false;
@@ -505,7 +505,7 @@
         }
         
         case Array::Array: {
-            if (arrayModesAlreadyChecked(value.m_arrayModes, asArrayModes(ArrayWithArrayStorage) | asArrayModes(ArrayWithSlowPutArrayStorage)))
+            if (arrayModesAlreadyChecked(value.m_arrayModes, asArrayModesIgnoringTypedArrays(ArrayWithArrayStorage) | asArrayModesIgnoringTypedArrays(ArrayWithSlowPutArrayStorage)))
                 return true;
             if (value.m_structure.isTop())
                 return false;
@@ -520,7 +520,7 @@
         }
         
         default: {
-            if (arrayModesAlreadyChecked(value.m_arrayModes, asArrayModes(NonArrayWithArrayStorage) | asArrayModes(ArrayWithArrayStorage) | asArrayModes(NonArrayWithSlowPutArrayStorage) | asArrayModes(ArrayWithSlowPutArrayStorage)))
+            if (arrayModesAlreadyChecked(value.m_arrayModes, asArrayModesIgnoringTypedArrays(NonArrayWithArrayStorage) | asArrayModesIgnoringTypedArrays(ArrayWithArrayStorage) | asArrayModesIgnoringTypedArrays(NonArrayWithSlowPutArrayStorage) | asArrayModesIgnoringTypedArrays(ArrayWithSlowPutArrayStorage)))
                 return true;
             if (value.m_structure.isTop())
                 return false;

Modified: trunk/Source/_javascript_Core/dfg/DFGArrayMode.h (239950 => 239951)


--- trunk/Source/_javascript_Core/dfg/DFGArrayMode.h	2019-01-14 22:23:30 UTC (rev 239950)
+++ trunk/Source/_javascript_Core/dfg/DFGArrayMode.h	2019-01-14 22:31:06 UTC (rev 239951)
@@ -420,7 +420,7 @@
 
     bool structureWouldPassArrayModeFiltering(Structure* structure)
     {
-        return arrayModesAlreadyChecked(arrayModeFromStructure(structure), arrayModesThatPassFiltering());
+        return arrayModesAlreadyChecked(arrayModesFromStructure(structure), arrayModesThatPassFiltering());
     }
     
     ArrayModes arrayModesThatPassFiltering() const
@@ -445,8 +445,28 @@
         case Array::DirectArguments:
         case Array::ScopedArguments:
             return arrayModesWithIndexingShapes(ArrayStorageShape, NonArray);
+        case Array::Int8Array:
+            return Int8ArrayMode;
+        case Array::Int16Array:
+            return Int16ArrayMode;
+        case Array::Int32Array:
+            return Int32ArrayMode;
+        case Array::Uint8Array:
+            return Uint8ArrayMode;
+        case Array::Uint8ClampedArray:
+            return Uint8ClampedArrayMode;
+        case Array::Uint16Array:
+            return Uint16ArrayMode;
+        case Array::Uint32Array:
+            return Uint32ArrayMode;
+        case Array::Float32Array:
+            return Float32ArrayMode;
+        case Array::Float64Array:
+            return Float64ArrayMode;
+        case Array::AnyTypedArray:
+            return ALL_TYPED_ARRAY_MODES;
         default:
-            return asArrayModes(NonArray);
+            return asArrayModesIgnoringTypedArrays(NonArray);
         }
 
         if (action() == Array::Write)
@@ -497,20 +517,20 @@
         switch (arrayClass()) {
         case Array::NonArray:
         case Array::OriginalNonArray:
-            return asArrayModes(shape);
+            return asArrayModesIgnoringTypedArrays(shape);
         case Array::OriginalCopyOnWriteArray:
             ASSERT(hasInt32(shape) || hasDouble(shape) || hasContiguous(shape));
-            return asArrayModes(shape | IsArray) | asArrayModes(shape | IsArray | CopyOnWrite);
+            return asArrayModesIgnoringTypedArrays(shape | IsArray) | asArrayModesIgnoringTypedArrays(shape | IsArray | CopyOnWrite);
         case Array::Array:
             if (hasInt32(shape) || hasDouble(shape) || hasContiguous(shape))
-                return asArrayModes(shape | IsArray) | asArrayModes(shape | IsArray | CopyOnWrite);
+                return asArrayModesIgnoringTypedArrays(shape | IsArray) | asArrayModesIgnoringTypedArrays(shape | IsArray | CopyOnWrite);
             FALLTHROUGH;
         case Array::OriginalArray:
-            return asArrayModes(shape | IsArray);
+            return asArrayModesIgnoringTypedArrays(shape | IsArray);
         case Array::PossiblyArray:
             if (hasInt32(shape) || hasDouble(shape) || hasContiguous(shape))
-                return asArrayModes(shape) | asArrayModes(shape | IsArray) | asArrayModes(shape | IsArray | CopyOnWrite);
-            return asArrayModes(shape) | asArrayModes(shape | IsArray);
+                return asArrayModesIgnoringTypedArrays(shape) | asArrayModesIgnoringTypedArrays(shape | IsArray) | asArrayModesIgnoringTypedArrays(shape | IsArray | CopyOnWrite);
+            return asArrayModesIgnoringTypedArrays(shape) | asArrayModesIgnoringTypedArrays(shape | IsArray);
         default:
             // This is only necessary for C++ compilers that don't understand enums.
             return 0;

Modified: trunk/Source/_javascript_Core/dfg/DFGOSRExit.cpp (239950 => 239951)


--- trunk/Source/_javascript_Core/dfg/DFGOSRExit.cpp	2019-01-14 22:23:30 UTC (rev 239950)
+++ trunk/Source/_javascript_Core/dfg/DFGOSRExit.cpp	2019-01-14 22:31:06 UTC (rev 239951)
@@ -507,7 +507,7 @@
             ASSERT(exit.m_kind == BadCache || exit.m_kind == BadIndexingType);
             Structure* structure = profiledValue.asCell()->structure(vm);
             arrayProfile->observeStructure(structure);
-            arrayProfile->observeArrayMode(asArrayModes(structure->indexingMode()));
+            arrayProfile->observeArrayMode(arrayModesFromStructure(structure));
         }
         if (extraInitializationLevel <= ExtraInitializationLevel::ArrayProfileUpdate)
             break;
@@ -1185,6 +1185,15 @@
 
                 jit.load32(AssemblyHelpers::Address(value, JSCell::structureIDOffset()), scratch1);
                 jit.store32(scratch1, arrayProfile->addressOfLastSeenStructureID());
+
+                jit.load8(AssemblyHelpers::Address(value, JSCell::typeInfoTypeOffset()), scratch2);
+                jit.sub32(AssemblyHelpers::TrustedImm32(FirstTypedArrayType), scratch2);
+                auto notTypedArray = jit.branch32(MacroAssembler::AboveOrEqual, scratch2, AssemblyHelpers::TrustedImm32(NumberOfTypedArrayTypesExcludingDataView));
+                jit.move(AssemblyHelpers::TrustedImmPtr(typedArrayModes), scratch1);
+                jit.load32(AssemblyHelpers::BaseIndex(scratch1, scratch2, AssemblyHelpers::TimesFour), scratch2);
+                auto storeArrayModes = jit.jump();
+
+                notTypedArray.link(&jit);
 #if USE(JSVALUE64)
                 jit.load8(AssemblyHelpers::Address(value, JSCell::indexingTypeAndMiscOffset()), scratch1);
 #else
@@ -1193,6 +1202,7 @@
                 jit.and32(AssemblyHelpers::TrustedImm32(IndexingModeMask), scratch1);
                 jit.move(AssemblyHelpers::TrustedImm32(1), scratch2);
                 jit.lshift32(scratch1, scratch2);
+                storeArrayModes.link(&jit);
                 jit.or32(scratch2, AssemblyHelpers::AbsoluteAddress(arrayProfile->addressOfArrayModes()));
 
                 if (isARM64()) {

Modified: trunk/Source/_javascript_Core/dfg/DFGRegisteredStructureSet.cpp (239950 => 239951)


--- trunk/Source/_javascript_Core/dfg/DFGRegisteredStructureSet.cpp	2019-01-14 22:23:30 UTC (rev 239950)
+++ trunk/Source/_javascript_Core/dfg/DFGRegisteredStructureSet.cpp	2019-01-14 22:31:06 UTC (rev 239951)
@@ -53,7 +53,7 @@
 {
     genericFilter(
         [&] (RegisteredStructure structure) -> bool {
-            return arrayModes & arrayModeFromStructure(structure.get());
+            return arrayModes & arrayModesFromStructure(structure.get());
         });
 }
 
@@ -79,7 +79,7 @@
     ArrayModes result = 0;
     forEach(
         [&] (RegisteredStructure structure) {
-            mergeArrayModes(result, asArrayModes(structure->indexingMode()));
+            mergeArrayModes(result, arrayModesFromStructure(structure.get()));
         });
     return result;
 }

Modified: trunk/Source/_javascript_Core/ftl/FTLOSRExitCompiler.cpp (239950 => 239951)


--- trunk/Source/_javascript_Core/ftl/FTLOSRExitCompiler.cpp	2019-01-14 22:23:30 UTC (rev 239950)
+++ trunk/Source/_javascript_Core/ftl/FTLOSRExitCompiler.cpp	2019-01-14 22:31:06 UTC (rev 239951)
@@ -277,10 +277,20 @@
             if (ArrayProfile* arrayProfile = jit.baselineCodeBlockFor(codeOrigin)->getArrayProfile(codeOrigin.bytecodeIndex)) {
                 jit.load32(MacroAssembler::Address(GPRInfo::regT0, JSCell::structureIDOffset()), GPRInfo::regT1);
                 jit.store32(GPRInfo::regT1, arrayProfile->addressOfLastSeenStructureID());
+
+                jit.load8(MacroAssembler::Address(GPRInfo::regT0, JSCell::typeInfoTypeOffset()), GPRInfo::regT2);
+                jit.sub32(MacroAssembler::TrustedImm32(FirstTypedArrayType), GPRInfo::regT2);
+                auto notTypedArray = jit.branch32(MacroAssembler::AboveOrEqual, GPRInfo::regT2, MacroAssembler::TrustedImm32(NumberOfTypedArrayTypesExcludingDataView));
+                jit.move(MacroAssembler::TrustedImmPtr(typedArrayModes), GPRInfo::regT1);
+                jit.load32(MacroAssembler::BaseIndex(GPRInfo::regT1, GPRInfo::regT2, MacroAssembler::TimesFour), GPRInfo::regT2);
+                auto storeArrayModes = jit.jump();
+
+                notTypedArray.link(&jit);
                 jit.load8(MacroAssembler::Address(GPRInfo::regT0, JSCell::indexingTypeAndMiscOffset()), GPRInfo::regT1);
                 jit.and32(MacroAssembler::TrustedImm32(IndexingModeMask), GPRInfo::regT1);
                 jit.move(MacroAssembler::TrustedImm32(1), GPRInfo::regT2);
                 jit.lshift32(GPRInfo::regT1, GPRInfo::regT2);
+                storeArrayModes.link(&jit);
                 jit.or32(GPRInfo::regT2, MacroAssembler::AbsoluteAddress(arrayProfile->addressOfArrayModes()));
             }
         }

Modified: trunk/Source/_javascript_Core/jit/JITInlines.h (239950 => 239951)


--- trunk/Source/_javascript_Core/jit/JITInlines.h	2019-01-14 22:23:30 UTC (rev 239950)
+++ trunk/Source/_javascript_Core/jit/JITInlines.h	2019-01-14 22:31:06 UTC (rev 239951)
@@ -364,13 +364,12 @@
     store8(TrustedImm32(1), arrayProfile->addressOfOutOfBounds());
 }
 
-static inline bool arrayProfileSaw(ArrayModes arrayModes, IndexingType capability)
+inline JITArrayMode JIT::chooseArrayMode(ArrayProfile* profile)
 {
-    return arrayModesInclude(arrayModes, capability);
-}
+    auto arrayProfileSaw = [] (ArrayModes arrayModes, IndexingType capability) {
+        return arrayModesIncludeIgnoringTypedArrays(arrayModes, capability);
+    };
 
-inline JITArrayMode JIT::chooseArrayMode(ArrayProfile* profile)
-{
     ConcurrentJSLocker locker(m_codeBlock->m_lock);
     profile->computeUpdatedPrediction(locker, m_codeBlock);
     ArrayModes arrayModes = profile->observedArrayModes(locker);

Modified: trunk/Source/_javascript_Core/runtime/JSType.h (239950 => 239951)


--- trunk/Source/_javascript_Core/runtime/JSType.h	2019-01-14 22:23:30 UTC (rev 239950)
+++ trunk/Source/_javascript_Core/runtime/JSType.h	2019-01-14 22:31:06 UTC (rev 239951)
@@ -117,12 +117,12 @@
     MaxJSType = 0b11111111,
 };
 
-static const uint32_t FirstTypedArrayType = Int8ArrayType;
-static const uint32_t LastTypedArrayType = DataViewType;
+static constexpr uint32_t FirstTypedArrayType = Int8ArrayType;
+static constexpr uint32_t LastTypedArrayType = DataViewType;
 
 // LastObjectType should be MaxJSType (not LastJSCObjectType) since embedders can add their extended object types after the enums listed in JSType.
-static const uint32_t FirstObjectType = ObjectType;
-static const uint32_t LastObjectType = MaxJSType;
+static constexpr uint32_t FirstObjectType = ObjectType;
+static constexpr uint32_t LastObjectType = MaxJSType;
 
 static constexpr uint32_t NumberOfTypedArrayTypes = LastTypedArrayType - FirstTypedArrayType + 1;
 static constexpr uint32_t NumberOfTypedArrayTypesExcludingDataView = NumberOfTypedArrayTypes - 1;
@@ -130,6 +130,11 @@
 static_assert(sizeof(JSType) == sizeof(uint8_t), "sizeof(JSType) is one byte.");
 static_assert(LastJSCObjectType < 128, "The highest bit is reserved for embedder's extension.");
 
+inline constexpr bool isTypedArrayType(JSType type)
+{
+    return (static_cast<uint32_t>(type) - FirstTypedArrayType) < NumberOfTypedArrayTypesExcludingDataView;
+}
+
 } // namespace JSC
 
 namespace WTF {
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to