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 {