Source/JavaScriptCore/ChangeLog

 12013-09-07 Filip Pizlo <fpizlo@apple.com>
 2
 3 FTL should support typed array GetByVal and related ops
 4 https://bugs.webkit.org/show_bug.cgi?id=120965
 5
 6 Reviewed by NOBODY (OOPS!).
 7
 8 This adds support for the following typed array instantiations of the following
 9 DFG IR ops:
 10
 11 - GetByVal
 12
 13 - GetIndexedPropertyStorage
 14
 15 - CheckArray
 16
 17 - GetArrayLength
 18
 19 This also adds CheckArray for Int32/Double/Contiguous arrays.
 20
 21 * dfg/DFGArrayMode.cpp:
 22 (JSC::DFG::toIndexingShape):
 23 * dfg/DFGArrayMode.h:
 24 (JSC::DFG::ArrayMode::shapeMask):
 25 * ftl/FTLAbbreviations.h:
 26 (JSC::FTL::floatType):
 27 (JSC::FTL::buildSExt):
 28 * ftl/FTLAbstractHeapRepository.h:
 29 * ftl/FTLCapabilities.cpp:
 30 (JSC::FTL::canCompile):
 31 * ftl/FTLCommonValues.cpp:
 32 (JSC::FTL::CommonValues::CommonValues):
 33 * ftl/FTLCommonValues.h:
 34 * ftl/FTLLowerDFGToLLVM.cpp:
 35 (JSC::FTL::LowerDFGToLLVM::compileNode):
 36 (JSC::FTL::LowerDFGToLLVM::compileGetIndexedPropertyStorage):
 37 (JSC::FTL::LowerDFGToLLVM::compileCheckArray):
 38 (JSC::FTL::LowerDFGToLLVM::compileGetArrayLength):
 39 (JSC::FTL::LowerDFGToLLVM::compileGetByVal):
 40 (JSC::FTL::LowerDFGToLLVM::isArrayType):
 41 (JSC::FTL::LowerDFGToLLVM::hasClassInfo):
 42 * ftl/FTLOutput.h:
 43 (JSC::FTL::Output::constIntPtr):
 44 (JSC::FTL::Output::signExt):
 45 (JSC::FTL::Output::loadFloat):
 46
1472013-09-07 Anders Carlsson <andersca@apple.com>
248
349 VectorMover should use std::move
155259

Source/JavaScriptCore/dfg/DFGArrayMode.cpp

@@const char* arrayConversionToString(Arra
458458 }
459459}
460460
 461IndexingType toIndexingShape(Array::Type type)
 462{
 463 switch (type) {
 464 case Array::Int32:
 465 return Int32Shape;
 466 case Array::Double:
 467 return DoubleShape;
 468 case Array::Contiguous:
 469 return ContiguousShape;
 470 case Array::ArrayStorage:
 471 return ArrayStorageShape;
 472 case Array::SlowPutArrayStorage:
 473 return SlowPutArrayStorageShape;
 474 default:
 475 return NoIndexingShape;
 476 }
 477}
 478
461479TypedArrayType toTypedArrayType(Array::Type type)
462480{
463481 switch (type) {
155253

Source/JavaScriptCore/dfg/DFGArrayMode.h

@@const char* arrayClassToString(Array::Cl
104104const char* arraySpeculationToString(Array::Speculation);
105105const char* arrayConversionToString(Array::Conversion);
106106
 107IndexingType toIndexingShape(Array::Type);
 108
107109TypedArrayType toTypedArrayType(Array::Type);
108110Array::Type toArrayType(TypedArrayType);
109111

@@public:
383385 return type() == Array::String;
384386 }
385387
 388 IndexingType shapeMask() const
 389 {
 390 return toIndexingShape(type());
 391 }
 392
386393 TypedArrayType typedArrayType() const
387394 {
388395 return toTypedArrayType(type());
155253

Source/JavaScriptCore/ftl/FTLAbbreviations.h

@@static inline LType int16Type(LContext c
5353static inline LType int32Type(LContext context) { return LLVMInt32TypeInContext(context); }
5454static inline LType int64Type(LContext context) { return LLVMInt64TypeInContext(context); }
5555static inline LType intPtrType(LContext context) { return LLVMInt64TypeInContext(context); }
 56static inline LType floatType(LContext context) { return LLVMFloatTypeInContext(context); }
5657static inline LType doubleType(LContext context) { return LLVMDoubleTypeInContext(context); }
5758
5859static inline LType pointerType(LType type) { return LLVMPointerType(type, 0); }

@@static inline LValue buildLShr(LBuilder
201202static inline LValue buildNot(LBuilder builder, LValue value) { return LLVMBuildNot(builder, value, ""); }
202203static inline LValue buildLoad(LBuilder builder, LValue pointer) { return LLVMBuildLoad(builder, pointer, ""); }
203204static inline LValue buildStore(LBuilder builder, LValue value, LValue pointer) { return LLVMBuildStore(builder, value, pointer); }
 205static inline LValue buildSExt(LBuilder builder, LValue value, LType type) { return LLVMBuildSExt(builder, value, type, ""); }
204206static inline LValue buildZExt(LBuilder builder, LValue value, LType type) { return LLVMBuildZExt(builder, value, type, ""); }
205207static inline LValue buildFPToSI(LBuilder builder, LValue value, LType type) { return LLVMBuildFPToSI(builder, value, type, ""); }
206208static inline LValue buildSIToFP(LBuilder builder, LValue value, LType type) { return LLVMBuildSIToFP(builder, value, type, ""); }
155253

Source/JavaScriptCore/ftl/FTLAbstractHeapRepository.h

@@namespace JSC { namespace FTL {
4141#define FOR_EACH_ABSTRACT_FIELD(macro) \
4242 macro(Butterfly_publicLength, Butterfly::offsetOfPublicLength()) \
4343 macro(Butterfly_vectorLength, Butterfly::offsetOfVectorLength()) \
 44 macro(JSArrayBufferView_length, JSArrayBufferView::offsetOfLength()) \
 45 macro(JSArrayBufferView_mode, JSArrayBufferView::offsetOfMode()) \
 46 macro(JSArrayBufferView_vector, JSArrayBufferView::offsetOfVector()) \
4447 macro(JSCell_structure, JSCell::structureOffset()) \
4548 macro(JSObject_butterfly, JSObject::butterflyOffset()) \
4649 macro(JSString_length, JSString::offsetOfLength()) \
4750 macro(JSString_value, JSString::offsetOfValue()) \
4851 macro(StringImpl_data, StringImpl::dataOffset()) \
4952 macro(StringImpl_hashAndFlags, StringImpl::flagsOffset()) \
 53 macro(Structure_classInfo, Structure::classInfoOffset()) \
5054 macro(Structure_globalObject, Structure::globalObjectOffset()) \
 55 macro(Structure_indexingType, Structure::indexingTypeOffset()) \
5156 macro(Structure_typeInfoFlags, Structure::typeInfoFlagsOffset())
5257
5358#define FOR_EACH_INDEXED_ABSTRACT_HEAP(macro) \
155253

Source/JavaScriptCore/ftl/FTLCapabilities.cpp

@@inline CapabilityLevel canCompile(Node*
9191 case GlobalVarWatchpoint:
9292 // These are OK.
9393 break;
 94 case GetIndexedPropertyStorage:
 95 if (isTypedView(node->arrayMode().typedArrayType()))
 96 break;
 97 return CannotCompile;
 98 case CheckArray:
 99 switch (node->arrayMode().type()) {
 100 case Array::Int32:
 101 case Array::Double:
 102 case Array::Contiguous:
 103 break;
 104 default:
 105 if (isTypedView(node->arrayMode().typedArrayType()))
 106 break;
 107 return CannotCompile;
 108 }
 109 break;
94110 case GetArrayLength:
95111 switch (node->arrayMode().type()) {
96112 case Array::Int32:

@@inline CapabilityLevel canCompile(Node*
98114 case Array::Contiguous:
99115 break;
100116 default:
 117 if (isTypedView(node->arrayMode().typedArrayType()))
 118 break;
101119 return CannotCompile;
102120 }
103121 break;

@@inline CapabilityLevel canCompile(Node*
110128 case Array::Contiguous:
111129 break;
112130 default:
 131 if (isTypedView(node->arrayMode().typedArrayType()))
 132 return CanCompileAndOSREnter;
113133 return CannotCompile;
114134 }
115135 switch (node->arrayMode().speculation()) {
155253

Source/JavaScriptCore/ftl/FTLCommonValues.cpp

@@CommonValues::CommonValues(LContext cont
3838 , int32(int32Type(context))
3939 , int64(int64Type(context))
4040 , intPtr(intPtrType(context))
 41 , floatType(FTL::floatType(context))
4142 , doubleType(FTL::doubleType(context))
4243 , ref8(pointerType(int8))
4344 , ref16(pointerType(int16))
4445 , ref32(pointerType(int32))
4546 , ref64(pointerType(int64))
4647 , refPtr(pointerType(intPtr))
 48 , refFloat(pointerType(floatType))
4749 , refDouble(pointerType(doubleType))
4850 , booleanTrue(constInt(boolean, true, ZeroExtend))
4951 , booleanFalse(constInt(boolean, false, ZeroExtend))
155253

Source/JavaScriptCore/ftl/FTLCommonValues.h

@@public:
5050 const LType int32;
5151 const LType int64;
5252 const LType intPtr;
 53 const LType floatType;
5354 const LType doubleType;
5455 const LType ref8;
5556 const LType ref16;
5657 const LType ref32;
5758 const LType ref64;
5859 const LType refPtr;
 60 const LType refFloat;
5961 const LType refDouble;
6062 const LValue booleanTrue;
6163 const LValue booleanFalse;
155253

Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp

@@private:
341341 case GetButterfly:
342342 compileGetButterfly();
343343 break;
 344 case GetIndexedPropertyStorage:
 345 compileGetIndexedPropertyStorage();
 346 break;
 347 case CheckArray:
 348 compileCheckArray();
 349 break;
344350 case GetArrayLength:
345351 compileGetArrayLength();
346352 break;

@@private:
12031209 setStorage(m_out.loadPtr(lowCell(m_node->child1()), m_heaps.JSObject_butterfly));
12041210 }
12051211
 1212 void compileGetIndexedPropertyStorage()
 1213 {
 1214 setStorage(m_out.loadPtr(lowCell(m_node->child1()), m_heaps.JSArrayBufferView_vector));
 1215 }
 1216
 1217 void compileCheckArray()
 1218 {
 1219 Edge edge = m_node->child1();
 1220 LValue cell = lowCell(edge);
 1221
 1222 if (m_node->arrayMode().alreadyChecked(m_graph, m_node, m_state.forNode(edge)))
 1223 return;
 1224
 1225 speculate(
 1226 BadIndexingType, jsValueValue(cell), 0,
 1227 m_out.bitNot(isArrayType(cell, m_node->arrayMode())));
 1228 }
 1229
12061230 void compileGetArrayLength()
12071231 {
12081232 switch (m_node->arrayMode().type()) {

@@private:
12101234 case Array::Double:
12111235 case Array::Contiguous: {
12121236 setInt32(m_out.load32(lowStorage(m_node->child2()), m_heaps.Butterfly_publicLength));
1213  break;
 1237 return;
12141238 }
12151239
12161240 default:
 1241 if (isTypedView(m_node->arrayMode().typedArrayType())) {
 1242 setInt32(
 1243 m_out.load32(lowCell(m_node->child1()), m_heaps.JSArrayBufferView_length));
 1244 return;
 1245 }
 1246
12171247 RELEASE_ASSERT_NOT_REACHED();
1218  break;
 1248 return;
12191249 }
12201250 }
12211251

@@private:
12811311 return;
12821312 }
12831313
1284  default:
 1314 default: {
 1315 TypedArrayType type = m_node->arrayMode().typedArrayType();
 1316
 1317 if (isTypedView(type)) {
 1318 LValue array = lowCell(m_node->child1());
 1319
 1320 speculate(
 1321 OutOfBounds, noValue(), 0,
 1322 m_out.aboveOrEqual(
 1323 index, m_out.load32(array, m_heaps.JSArrayBufferView_length)));
 1324
 1325 TypedPointer pointer = TypedPointer(
 1326 m_heaps.typedArrayProperties,
 1327 m_out.add(
 1328 storage,
 1329 m_out.shl(
 1330 m_out.zeroExt(index, m_out.intPtr),
 1331 m_out.constIntPtr(logElementSize(type)))));
 1332
 1333 if (isInt(type)) {
 1334 LValue result;
 1335 switch (elementSize(type)) {
 1336 case 1:
 1337 result = m_out.load8(pointer);
 1338 break;
 1339 case 2:
 1340 result = m_out.load16(pointer);
 1341 break;
 1342 case 4:
 1343 result = m_out.load32(pointer);
 1344 break;
 1345 default:
 1346 RELEASE_ASSERT_NOT_REACHED();
 1347 }
 1348
 1349 if (elementSize(type) < 4) {
 1350 if (isSigned(type))
 1351 result = m_out.signExt(result, m_out.int32);
 1352 else
 1353 result = m_out.zeroExt(result, m_out.int32);
 1354 setInt32(result);
 1355 return;
 1356 }
 1357
 1358 if (isSigned(type)) {
 1359 setInt32(result);
 1360 return;
 1361 }
 1362
 1363 if (m_node->shouldSpeculateInteger()) {
 1364 speculateForward(
 1365 Overflow, noValue(), 0, m_out.lessThan(result, m_out.int32Zero),
 1366 uInt32Value(result));
 1367 setInt32(result);
 1368 return;
 1369 }
 1370
 1371 setDouble(m_out.unsignedToFP(result, m_out.doubleType));
 1372 return;
 1373 }
 1374
 1375 ASSERT(isFloat(type));
 1376
 1377 LValue result;
 1378 switch (type) {
 1379 case TypeFloat32:
 1380 result = m_out.loadFloat(pointer);
 1381 break;
 1382 case TypeFloat64:
 1383 result = m_out.loadDouble(pointer);
 1384 break;
 1385 default:
 1386 RELEASE_ASSERT_NOT_REACHED();
 1387 }
 1388
 1389 result = m_out.select(
 1390 m_out.doubleEqual(result, result), result, m_out.constDouble(QNaN));
 1391 setDouble(result);
 1392 return;
 1393 }
 1394
12851395 RELEASE_ASSERT_NOT_REACHED();
12861396 return;
1287  }
 1397 } }
12881398 }
12891399
12901400 void compilePutByVal()

@@private:
23192429 return isString(cell);
23202430 }
23212431
 2432 LValue isArrayType(LValue cell, ArrayMode arrayMode)
 2433 {
 2434 switch (arrayMode.type()) {
 2435 case Array::Int32:
 2436 case Array::Double:
 2437 case Array::Contiguous: {
 2438 LValue indexingType = m_out.load8(
 2439 m_out.loadPtr(cell, m_heaps.JSCell_structure),
 2440 m_heaps.Structure_indexingType);
 2441
 2442 switch (arrayMode.arrayClass()) {
 2443 case Array::OriginalArray:
 2444 RELEASE_ASSERT_NOT_REACHED();
 2445 return 0;
 2446
 2447 case Array::Array:
 2448 return m_out.equal(
 2449 m_out.bitAnd(indexingType, m_out.constInt8(IsArray | IndexingShapeMask)),
 2450 m_out.constInt8(IsArray | arrayMode.shapeMask()));
 2451
 2452 default:
 2453 return m_out.equal(
 2454 m_out.bitAnd(indexingType, m_out.constInt8(IndexingShapeMask)),
 2455 m_out.constInt8(arrayMode.shapeMask()));
 2456 }
 2457 }
 2458
 2459 default:
 2460 return hasClassInfo(cell, classInfoForType(arrayMode.typedArrayType()));
 2461 }
 2462 }
 2463
 2464 LValue hasClassInfo(LValue cell, const ClassInfo* classInfo)
 2465 {
 2466 return m_out.equal(
 2467 m_out.loadPtr(
 2468 m_out.loadPtr(cell, m_heaps.JSCell_structure),
 2469 m_heaps.Structure_classInfo),
 2470 m_out.constIntPtr(classInfo));
 2471 }
 2472
23222473 void speculateObject(Edge edge, LValue cell)
23232474 {
23242475 FTL_TYPE_CHECK(jsValueValue(cell), edge, SpecObject, isNotObject(cell));
155253

Source/JavaScriptCore/ftl/FTLOutput.h

@@public:
108108 LValue constInt8(int8_t value) { return constInt(int8, value); }
109109 LValue constInt32(int32_t value) { return constInt(int32, value); }
110110 template<typename T>
111  LValue constIntPtr(T value) { return constInt(intPtr, bitwise_cast<intptr_t>(value)); }
 111 LValue constIntPtr(T* value) { return constInt(intPtr, bitwise_cast<intptr_t>(value)); }
 112 template<typename T>
 113 LValue constIntPtr(T value) { return constInt(intPtr, static_cast<intptr_t>(value)); }
112114 LValue constInt64(int64_t value) { return constInt(int64, value); }
113115 LValue constDouble(double value) { return constReal(doubleType, value); }
114116

@@public:
169171 return call(doubleAbsIntrinsic(), value);
170172 }
171173
 174 LValue signExt(LValue value, LType type) { return buildSExt(m_builder, value, type); }
172175 LValue zeroExt(LValue value, LType type) { return buildZExt(m_builder, value, type); }
173176 LValue fpToInt(LValue value, LType type) { return buildFPToSI(m_builder, value, type); }
174177 LValue fpToInt32(LValue value) { return fpToInt(value, int32); }

@@public:
201204 LValue load32(TypedPointer pointer) { return load(pointer, ref32); }
202205 LValue load64(TypedPointer pointer) { return load(pointer, ref64); }
203206 LValue loadPtr(TypedPointer pointer) { return load(pointer, refPtr); }
 207 LValue loadFloat(TypedPointer pointer) { return load(pointer, refFloat); }
204208 LValue loadDouble(TypedPointer pointer) { return load(pointer, refDouble); }
205209 void store32(LValue value, TypedPointer pointer) { store(value, pointer, ref32); }
206210 void store64(LValue value, TypedPointer pointer) { store(value, pointer, ref64); }
155253