Changeset 131982 in webkit
- Timestamp:
- Oct 19, 2012 11:53:04 PM (12 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r131977 r131982 1 2012-10-19 Filip Pizlo <fpizlo@apple.com> 2 3 DFG should have some facility for recognizing redundant CheckArrays and Arrayifies 4 https://bugs.webkit.org/show_bug.cgi?id=99287 5 6 Reviewed by Mark Hahnenberg. 7 8 Adds reasoning about indexing type sets (i.e. ArrayModes) to AbstractValue, which 9 then enables us to fold away CheckArray's and Arrayify's that are redundant. 10 11 * bytecode/ArrayProfile.cpp: 12 (JSC::arrayModesToString): 13 (JSC): 14 * bytecode/ArrayProfile.h: 15 (JSC): 16 (JSC::mergeArrayModes): 17 (JSC::arrayModesAlreadyChecked): 18 * bytecode/StructureSet.h: 19 (JSC::StructureSet::arrayModesFromStructures): 20 (StructureSet): 21 * dfg/DFGAbstractState.cpp: 22 (JSC::DFG::AbstractState::execute): 23 * dfg/DFGAbstractValue.h: 24 (JSC::DFG::AbstractValue::AbstractValue): 25 (JSC::DFG::AbstractValue::clear): 26 (JSC::DFG::AbstractValue::isClear): 27 (JSC::DFG::AbstractValue::makeTop): 28 (JSC::DFG::AbstractValue::clobberStructures): 29 (AbstractValue): 30 (JSC::DFG::AbstractValue::setMostSpecific): 31 (JSC::DFG::AbstractValue::set): 32 (JSC::DFG::AbstractValue::operator==): 33 (JSC::DFG::AbstractValue::merge): 34 (JSC::DFG::AbstractValue::filter): 35 (JSC::DFG::AbstractValue::filterArrayModes): 36 (JSC::DFG::AbstractValue::validate): 37 (JSC::DFG::AbstractValue::checkConsistency): 38 (JSC::DFG::AbstractValue::dump): 39 (JSC::DFG::AbstractValue::clobberArrayModes): 40 (JSC::DFG::AbstractValue::clobberArrayModesSlow): 41 (JSC::DFG::AbstractValue::setFuturePossibleStructure): 42 (JSC::DFG::AbstractValue::filterFuturePossibleStructure): 43 * dfg/DFGArrayMode.cpp: 44 (JSC::DFG::modeAlreadyChecked): 45 * dfg/DFGArrayMode.h: 46 (JSC::DFG::arrayModesFor): 47 (DFG): 48 * dfg/DFGConstantFoldingPhase.cpp: 49 (JSC::DFG::ConstantFoldingPhase::foldConstants): 50 * dfg/DFGSpeculativeJIT.cpp: 51 (JSC::DFG::SpeculativeJIT::arrayify): 52 1 53 2012-10-19 Filip Pizlo <fpizlo@apple.com> 2 54 -
trunk/Source/JavaScriptCore/bytecode/ArrayProfile.cpp
r128957 r131982 27 27 #include "ArrayProfile.h" 28 28 29 #include <wtf/StringExtras.h> 30 29 31 namespace JSC { 32 33 const char* arrayModesToString(ArrayModes arrayModes) 34 { 35 if (!arrayModes) 36 return "0:<empty>"; 37 38 if (arrayModes == ALL_ARRAY_MODES) 39 return "TOP"; 40 41 bool isNonArray = !!(arrayModes & NonArray); 42 bool isNonArrayWithContiguous = !!(arrayModes & NonArrayWithContiguous); 43 bool isNonArrayWithArrayStorage = !!(arrayModes & NonArrayWithArrayStorage); 44 bool isNonArrayWithSlowPutArrayStorage = !!(arrayModes & NonArrayWithSlowPutArrayStorage); 45 bool isArray = !!(arrayModes & ArrayClass); 46 bool isArrayWithContiguous = !!(arrayModes & ArrayWithContiguous); 47 bool isArrayWithArrayStorage = !!(arrayModes & ArrayWithArrayStorage); 48 bool isArrayWithSlowPutArrayStorage = !!(arrayModes & ArrayWithSlowPutArrayStorage); 49 50 static char result[256]; 51 snprintf( 52 result, sizeof(result), 53 "%u:%s%s%s%s%s%s%s%s", 54 arrayModes, 55 isNonArray ? "NonArray" : "", 56 isNonArrayWithContiguous ? "NonArrayWithContiguous" : "", 57 isNonArrayWithArrayStorage ? " NonArrayWithArrayStorage" : "", 58 isNonArrayWithSlowPutArrayStorage ? "NonArrayWithSlowPutArrayStorage" : "", 59 isArray ? "ArrayClass" : "", 60 isArrayWithContiguous ? "ArrayWithContiguous" : "", 61 isArrayWithArrayStorage ? " ArrayWithArrayStorage" : "", 62 isArrayWithSlowPutArrayStorage ? "ArrayWithSlowPutArrayStorage" : ""); 63 64 return result; 65 } 30 66 31 67 void ArrayProfile::computeUpdatedPrediction(OperationInProgress operation) -
trunk/Source/JavaScriptCore/bytecode/ArrayProfile.h
r129045 r131982 41 41 42 42 #define asArrayModes(type) \ 43 (1 << static_cast<unsigned>(type)) 43 (static_cast<unsigned>(1) << static_cast<unsigned>(type)) 44 45 #define ALL_NON_ARRAY_ARRAY_MODES \ 46 (asArrayModes(NonArray) \ 47 | asArrayModes(NonArrayWithContiguous) \ 48 | asArrayModes(NonArrayWithArrayStorage) \ 49 | asArrayModes(NonArrayWithSlowPutArrayStorage)) 50 51 #define ALL_ARRAY_ARRAY_MODES \ 52 (asArrayModes(ArrayClass) \ 53 | asArrayModes(ArrayWithContiguous) \ 54 | asArrayModes(ArrayWithArrayStorage) \ 55 | asArrayModes(ArrayWithSlowPutArrayStorage)) 56 57 #define ALL_ARRAY_MODES (ALL_NON_ARRAY_ARRAY_MODES | ALL_ARRAY_ARRAY_MODES) 44 58 45 59 inline ArrayModes arrayModeFromStructure(Structure* structure) 46 60 { 47 61 return asArrayModes(structure->indexingType()); 62 } 63 64 const char* arrayModesToString(ArrayModes); 65 66 inline bool mergeArrayModes(ArrayModes& left, ArrayModes right) 67 { 68 ArrayModes newModes = left | right; 69 if (newModes == left) 70 return false; 71 left = newModes; 72 return true; 73 } 74 75 // Checks if proven is a subset of expected. 76 inline bool arrayModesAlreadyChecked(ArrayModes proven, ArrayModes expected) 77 { 78 return (expected | proven) == expected; 48 79 } 49 80 -
trunk/Source/JavaScriptCore/bytecode/StructureSet.h
r121925 r131982 27 27 #define StructureSet_h 28 28 29 #include "ArrayProfile.h" 29 30 #include "SpeculatedType.h" 30 31 #include "Structure.h" … … 138 139 } 139 140 141 ArrayModes arrayModesFromStructures() const 142 { 143 ArrayModes result = 0; 144 145 for (size_t i = 0; i < m_structures.size(); ++i) 146 mergeArrayModes(result, asArrayModes(m_structures[i]->indexingType())); 147 148 return result; 149 } 150 140 151 bool operator==(const StructureSet& other) const 141 152 { -
trunk/Source/JavaScriptCore/dfg/DFGAbstractState.cpp
r131822 r131982 1421 1421 break; 1422 1422 } 1423 forNode(node.child1()).filterArrayModes(arrayModesFor(node.arrayMode())); 1423 1424 break; 1424 1425 } 1425 1426 case Arrayify: { 1427 if (modeAlreadyChecked(forNode(node.child1()), node.arrayMode())) { 1428 m_foundConstants = true; 1429 node.setCanExit(false); 1430 break; 1431 } 1426 1432 switch (node.arrayMode()) { 1427 1433 case ALL_EFFECTFUL_MODES: … … 1432 1438 forNode(nodeIndex).clear(); 1433 1439 clobberStructures(indexInBlock); 1440 forNode(node.child1()).filterArrayModes(arrayModesFor(node.arrayMode())); 1434 1441 break; 1435 1442 default: 1436 ASSERT_NOT_REACHED();1443 CRASH(); 1437 1444 break; 1438 1445 } -
trunk/Source/JavaScriptCore/dfg/DFGAbstractValue.h
r125999 r131982 31 31 #if ENABLE(DFG_JIT) 32 32 33 #include "ArrayProfile.h" 33 34 #include "DFGStructureAbstractValue.h" 34 35 #include "JSCell.h" … … 41 42 AbstractValue() 42 43 : m_type(SpecNone) 44 , m_arrayModes(0) 43 45 { 44 46 } … … 47 49 { 48 50 m_type = SpecNone; 51 m_arrayModes = 0; 49 52 m_currentKnownStructure.clear(); 50 53 m_futurePossibleStructure.clear(); … … 55 58 bool isClear() const 56 59 { 57 bool result = m_type == SpecNone && m_currentKnownStructure.isClear() && m_futurePossibleStructure.isClear();60 bool result = m_type == SpecNone && !m_arrayModes && m_currentKnownStructure.isClear() && m_futurePossibleStructure.isClear(); 58 61 if (result) 59 62 ASSERT(!m_value); … … 64 67 { 65 68 m_type = SpecTop; 69 m_arrayModes = ALL_ARRAY_MODES; 66 70 m_currentKnownStructure.makeTop(); 67 71 m_futurePossibleStructure.makeTop(); … … 72 76 void clobberStructures() 73 77 { 74 if (m_type & SpecCell) 78 if (m_type & SpecCell) { 75 79 m_currentKnownStructure.makeTop(); 76 else 80 clobberArrayModes(); 81 } else { 77 82 ASSERT(m_currentKnownStructure.isClear()); 78 checkConsistency(); 79 } 80 83 ASSERT(!m_arrayModes); 84 } 85 checkConsistency(); 86 } 87 81 88 void clobberValue() 82 89 { … … 104 111 result.makeTop(); 105 112 return result; 106 }107 108 void setFuturePossibleStructure(Structure* structure)109 {110 if (structure->transitionWatchpointSetIsStillValid())111 m_futurePossibleStructure = structure;112 else113 m_futurePossibleStructure.makeTop();114 }115 116 void filterFuturePossibleStructure(Structure* structure)117 {118 if (structure->transitionWatchpointSetIsStillValid())119 m_futurePossibleStructure.filter(StructureAbstractValue(structure));120 113 } 121 114 … … 126 119 m_currentKnownStructure = structure; 127 120 setFuturePossibleStructure(structure); 121 m_arrayModes = asArrayModes(structure->indexingType()); 128 122 } else { 129 123 m_currentKnownStructure.clear(); 130 124 m_futurePossibleStructure.clear(); 125 m_arrayModes = 0; 131 126 } 132 127 … … 141 136 if (!!value && value.isCell()) { 142 137 m_currentKnownStructure.makeTop(); 143 setFuturePossibleStructure(value.asCell()->structure()); 138 Structure* structure = value.asCell()->structure(); 139 setFuturePossibleStructure(structure); 140 m_arrayModes = asArrayModes(structure->indexingType()); 141 clobberArrayModes(); 144 142 } else { 145 143 m_currentKnownStructure.clear(); 146 144 m_futurePossibleStructure.clear(); 145 m_arrayModes = 0; 147 146 } 148 147 … … 157 156 m_currentKnownStructure = structure; 158 157 setFuturePossibleStructure(structure); 158 m_arrayModes = asArrayModes(structure->indexingType()); 159 159 m_type = speculationFromStructure(structure); 160 160 m_value = JSValue(); … … 168 168 m_currentKnownStructure.makeTop(); 169 169 m_futurePossibleStructure.makeTop(); 170 m_arrayModes = ALL_ARRAY_MODES; 170 171 } else { 171 172 m_currentKnownStructure.clear(); 172 173 m_futurePossibleStructure.clear(); 174 m_arrayModes = 0; 173 175 } 174 176 m_type = type; … … 180 182 { 181 183 return m_type == other.m_type 184 && m_arrayModes == other.m_arrayModes 182 185 && m_currentKnownStructure == other.m_currentKnownStructure 183 186 && m_futurePossibleStructure == other.m_futurePossibleStructure … … 200 203 } else { 201 204 result |= mergeSpeculation(m_type, other.m_type); 205 result |= mergeArrayModes(m_arrayModes, other.m_arrayModes); 202 206 result |= m_currentKnownStructure.addAll(other.m_currentKnownStructure); 203 207 result |= m_futurePossibleStructure.addAll(other.m_futurePossibleStructure); … … 219 223 m_currentKnownStructure.makeTop(); 220 224 m_futurePossibleStructure.makeTop(); 225 m_arrayModes = ALL_ARRAY_MODES; 221 226 } 222 227 m_value = JSValue(); … … 228 233 { 229 234 m_type &= other.speculationFromStructures(); 235 m_arrayModes &= other.arrayModesFromStructures(); 230 236 m_currentKnownStructure.filter(other); 231 237 if (m_currentKnownStructure.isClear()) … … 242 248 m_futurePossibleStructure.filter(m_type); 243 249 250 filterArrayModesByType(); 244 251 filterValueByType(); 252 253 checkConsistency(); 254 } 255 256 void filterArrayModes(ArrayModes arrayModes) 257 { 258 ASSERT(arrayModes); 259 260 m_type &= SpecCell; 261 m_arrayModes &= arrayModes; 262 263 // I could do more fancy filtering here. But it probably won't make any difference. 245 264 246 265 checkConsistency(); … … 259 278 m_currentKnownStructure.filter(m_type); 260 279 m_futurePossibleStructure.filter(m_type); 261 280 281 filterArrayModesByType(); 262 282 filterValueByType(); 263 283 264 284 checkConsistency(); 265 }266 267 // We could go further, and ensure that if the futurePossibleStructure contravenes268 // the value, then we could clear both of those things. But that's unlikely to help269 // in any realistic scenario, so we don't do it. Simpler is better.270 void filterValueByType()271 {272 if (!!m_type) {273 // The type is still non-empty. This implies that regardless of what filtering274 // was done, we either didn't have a value to begin with, or that value is still275 // valid.276 ASSERT(!m_value || validateType(m_value));277 return;278 }279 280 // The type has been rendered empty. That means that the value must now be invalid,281 // as well.282 ASSERT(!m_value || !validateType(m_value));283 m_value = JSValue();284 285 } 285 286 … … 320 321 Structure* structure = value.asCell()->structure(); 321 322 return m_currentKnownStructure.contains(structure) 322 && m_futurePossibleStructure.contains(structure); 323 && m_futurePossibleStructure.contains(structure) 324 && (m_arrayModes & asArrayModes(structure->indexingType())); 323 325 } 324 326 … … 331 333 ASSERT(m_currentKnownStructure.isClear()); 332 334 ASSERT(m_futurePossibleStructure.isClear()); 335 ASSERT(!m_arrayModes); 333 336 } 334 337 … … 347 350 void dump(FILE* out) const 348 351 { 349 fprintf(out, "(%s, ", speculationToString(m_type));352 fprintf(out, "(%s, %s, ", speculationToString(m_type), arrayModesToString(m_arrayModes)); 350 353 m_currentKnownStructure.dump(out); 351 354 dataLog(", "); … … 438 441 SpeculatedType m_type; 439 442 443 // This is a proven constraint on the possible indexing types that this value 444 // can have right now. It also implicitly constraints the set of structures 445 // that the value may have right now, since a structure has an immutable 446 // indexing type. This is subject to change upon reassignment, or any side 447 // effect that makes non-obvious changes to the heap. 448 ArrayModes m_arrayModes; 449 440 450 // This is a proven constraint on the possible values that this value can 441 451 // have now or any time in the future, unless it is reassigned. Note that this … … 445 455 // means TOP. 446 456 JSValue m_value; 457 458 private: 459 void clobberArrayModes() 460 { 461 if (m_arrayModes == ALL_ARRAY_MODES) 462 return; 463 464 if (LIKELY(m_arrayModes & asArrayModes(NonArray))) 465 m_arrayModes = ALL_ARRAY_MODES; 466 else 467 clobberArrayModesSlow(); 468 } 469 470 void clobberArrayModesSlow() 471 { 472 if (m_arrayModes & asArrayModes(ArrayClass)) 473 m_arrayModes = ALL_ARRAY_MODES; 474 else if (m_arrayModes & asArrayModes(NonArrayWithContiguous)) 475 m_arrayModes |= asArrayModes(NonArrayWithArrayStorage) | asArrayModes(NonArrayWithSlowPutArrayStorage); 476 else if (m_arrayModes & asArrayModes(ArrayWithContiguous)) 477 m_arrayModes |= asArrayModes(ArrayWithArrayStorage) | asArrayModes(ArrayWithSlowPutArrayStorage); 478 else if (m_arrayModes & asArrayModes(NonArrayWithArrayStorage)) 479 m_arrayModes |= asArrayModes(NonArrayWithSlowPutArrayStorage); 480 else if (m_arrayModes & asArrayModes(ArrayWithArrayStorage)) 481 m_arrayModes |= asArrayModes(ArrayWithArrayStorage); 482 } 483 484 void setFuturePossibleStructure(Structure* structure) 485 { 486 if (structure->transitionWatchpointSetIsStillValid()) 487 m_futurePossibleStructure = structure; 488 else 489 m_futurePossibleStructure.makeTop(); 490 } 491 492 void filterFuturePossibleStructure(Structure* structure) 493 { 494 if (structure->transitionWatchpointSetIsStillValid()) 495 m_futurePossibleStructure.filter(StructureAbstractValue(structure)); 496 } 497 498 // We could go further, and ensure that if the futurePossibleStructure contravenes 499 // the value, then we could clear both of those things. But that's unlikely to help 500 // in any realistic scenario, so we don't do it. Simpler is better. 501 void filterValueByType() 502 { 503 if (!!m_type) { 504 // The type is still non-empty. This implies that regardless of what filtering 505 // was done, we either didn't have a value to begin with, or that value is still 506 // valid. 507 ASSERT(!m_value || validateType(m_value)); 508 return; 509 } 510 511 // The type has been rendered empty. That means that the value must now be invalid, 512 // as well. 513 ASSERT(!m_value || !validateType(m_value)); 514 m_value = JSValue(); 515 } 516 517 void filterArrayModesByType() 518 { 519 if (!(m_type & SpecCell)) 520 m_arrayModes = 0; 521 else if (!(m_type & ~SpecArray)) 522 m_arrayModes &= ALL_ARRAY_ARRAY_MODES; 523 else if (!(m_type & SpecArray)) 524 m_arrayModes &= ALL_NON_ARRAY_ARRAY_MODES; 525 } 447 526 }; 448 527 -
trunk/Source/JavaScriptCore/dfg/DFGArrayMode.cpp
r131289 r131982 168 168 case Array::PossiblyArrayWithContiguousToTail: 169 169 case Array::PossiblyArrayWithContiguousOutOfBounds: 170 case Array::ToContiguous: 171 if (arrayModesAlreadyChecked(value.m_arrayModes, asArrayModes(NonArrayWithContiguous) | asArrayModes(ArrayWithContiguous))) 172 return true; 170 173 return value.m_currentKnownStructure.hasSingleton() 171 174 && hasContiguous(value.m_currentKnownStructure.singleton()->indexingType()); … … 174 177 case Array::ArrayWithContiguousToTail: 175 178 case Array::ArrayWithContiguousOutOfBounds: 179 if (arrayModesAlreadyChecked(value.m_arrayModes, asArrayModes(ArrayWithContiguous))) 180 return true; 176 181 return value.m_currentKnownStructure.hasSingleton() 177 182 && hasContiguous(value.m_currentKnownStructure.singleton()->indexingType()) … … 184 189 case Array::PossiblyArrayWithArrayStorageToHole: 185 190 case Array::PossiblyArrayWithArrayStorageOutOfBounds: 191 case Array::ToArrayStorage: 192 case Array::PossiblyArrayToArrayStorage: 193 if (arrayModesAlreadyChecked(value.m_arrayModes, asArrayModes(NonArrayWithArrayStorage) | asArrayModes(ArrayWithArrayStorage))) 194 return true; 186 195 return value.m_currentKnownStructure.hasSingleton() 187 196 && hasFastArrayStorage(value.m_currentKnownStructure.singleton()->indexingType()); … … 189 198 case Array::SlowPutArrayStorage: 190 199 case Array::PossiblyArrayWithSlowPutArrayStorage: 200 case Array::ToSlowPutArrayStorage: 201 if (arrayModesAlreadyChecked(value.m_arrayModes, asArrayModes(NonArrayWithArrayStorage) | asArrayModes(ArrayWithArrayStorage) | asArrayModes(NonArrayWithSlowPutArrayStorage) | asArrayModes(ArrayWithSlowPutArrayStorage))) 202 return true; 191 203 return value.m_currentKnownStructure.hasSingleton() 192 204 && hasArrayStorage(value.m_currentKnownStructure.singleton()->indexingType()); … … 195 207 case Array::ArrayWithArrayStorageToHole: 196 208 case Array::ArrayWithArrayStorageOutOfBounds: 209 case Array::ArrayToArrayStorage: 210 if (arrayModesAlreadyChecked(value.m_arrayModes, asArrayModes(ArrayWithArrayStorage))) 211 return true; 197 212 return value.m_currentKnownStructure.hasSingleton() 198 213 && hasFastArrayStorage(value.m_currentKnownStructure.singleton()->indexingType()) … … 200 215 201 216 case Array::ArrayWithSlowPutArrayStorage: 217 if (arrayModesAlreadyChecked(value.m_arrayModes, asArrayModes(ArrayWithArrayStorage) | asArrayModes(ArrayWithSlowPutArrayStorage))) 218 return true; 202 219 return value.m_currentKnownStructure.hasSingleton() 203 220 && hasArrayStorage(value.m_currentKnownStructure.singleton()->indexingType()) 204 221 && (value.m_currentKnownStructure.singleton()->indexingType() & IsArray); 205 206 case ALL_EFFECTFUL_MODES:207 return false;208 222 209 223 case Array::Arguments: -
trunk/Source/JavaScriptCore/dfg/DFGArrayMode.h
r131289 r131982 350 350 } 351 351 352 // This returns the set of array modes that will pass filtering of a CheckArray or 353 // Arrayify with the given mode. 354 inline ArrayModes arrayModesFor(Array::Mode arrayMode) 355 { 356 switch (arrayMode) { 357 case Array::Generic: 358 return ALL_ARRAY_MODES; 359 case Array::Contiguous: 360 case Array::ContiguousToTail: 361 case Array::ContiguousOutOfBounds: 362 case Array::ToContiguous: 363 return asArrayModes(NonArrayWithContiguous); 364 case Array::PossiblyArrayWithContiguous: 365 case Array::PossiblyArrayWithContiguousToTail: 366 case Array::PossiblyArrayWithContiguousOutOfBounds: 367 return asArrayModes(NonArrayWithContiguous) | asArrayModes(ArrayWithContiguous); 368 case ARRAY_WITH_CONTIGUOUS_MODES: 369 return asArrayModes(ArrayWithContiguous); 370 case Array::ArrayStorage: 371 case Array::ArrayStorageToHole: 372 case Array::ArrayStorageOutOfBounds: 373 case Array::ToArrayStorage: 374 return asArrayModes(NonArrayWithArrayStorage); 375 case Array::ToSlowPutArrayStorage: 376 case Array::SlowPutArrayStorage: 377 return asArrayModes(NonArrayWithArrayStorage) | asArrayModes(NonArrayWithSlowPutArrayStorage); 378 case Array::PossiblyArrayWithArrayStorage: 379 case Array::PossiblyArrayWithArrayStorageToHole: 380 case Array::PossiblyArrayWithArrayStorageOutOfBounds: 381 case Array::PossiblyArrayToArrayStorage: 382 return asArrayModes(NonArrayWithArrayStorage) | asArrayModes(ArrayWithArrayStorage); 383 case Array::PossiblyArrayWithSlowPutArrayStorage: 384 return asArrayModes(NonArrayWithArrayStorage) | asArrayModes(ArrayWithArrayStorage) | asArrayModes(NonArrayWithSlowPutArrayStorage) | asArrayModes(ArrayWithSlowPutArrayStorage); 385 case Array::ArrayWithArrayStorage: 386 case Array::ArrayWithArrayStorageToHole: 387 case Array::ArrayWithArrayStorageOutOfBounds: 388 case Array::ArrayToArrayStorage: 389 return asArrayModes(ArrayWithArrayStorage); 390 case Array::ArrayWithSlowPutArrayStorage: 391 return asArrayModes(ArrayWithArrayStorage) | asArrayModes(ArrayWithSlowPutArrayStorage); 392 default: 393 return asArrayModes(NonArray); 394 } 395 } 396 352 397 } } // namespace JSC::DFG 353 398 -
trunk/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp
r129948 r131982 103 103 } 104 104 105 case CheckArray: { 105 case CheckArray: 106 case Arrayify: { 106 107 if (!modeAlreadyChecked(m_state.forNode(node.child1()), node.arrayMode())) 107 108 break; -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
r131868 r131982 580 580 { 581 581 ASSERT(modeIsSpecific(node.arrayMode())); 582 ASSERT(!modeAlreadyChecked(m_state.forNode(node.child1()), node.arrayMode()));583 582 584 583 SpeculateCellOperand base(this, node.child1()); 584 585 if (modeAlreadyChecked(m_state.forNode(node.child1()), node.arrayMode())) { 586 GPRTemporary temp(this); 587 m_jit.loadPtr( 588 MacroAssembler::Address(base.gpr(), JSObject::butterflyOffset()), temp.gpr()); 589 storageResult(temp.gpr(), m_compileIndex); 590 return; 591 } 585 592 586 593 if (!node.child2()) {
Note: See TracChangeset
for help on using the changeset viewer.