Changeset 34867 in webkit for trunk/JavaScriptCore/kjs
- Timestamp:
- Jun 28, 2008, 8:56:04 PM (17 years ago)
- Location:
- trunk/JavaScriptCore/kjs
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/kjs/JSArray.cpp
r34843 r34867 38 38 39 39 struct ArrayStorage { 40 unsigned m_vectorLength; 40 41 unsigned m_numValuesInVector; 41 42 SparseArrayValueMap* m_sparseValueMap; … … 87 88 88 89 m_length = initialLength; 89 m_ vectorLength = initialCapacity;90 m_fastAccessCutoff = 0; 90 91 m_storage = static_cast<ArrayStorage*>(fastZeroedMalloc(storageSize(initialCapacity))); 92 m_storage->m_vectorLength = initialCapacity; 91 93 92 94 Heap::heap(this)->reportExtraMemoryCost(initialCapacity * sizeof(JSValue*)); … … 101 103 102 104 m_length = length; 103 m_ vectorLength= length;105 m_fastAccessCutoff = length; 104 106 105 107 ArrayStorage* storage = static_cast<ArrayStorage*>(fastMalloc(storageSize(length))); 106 108 109 storage->m_vectorLength = length; 107 110 storage->m_numValuesInVector = length; 108 111 storage->m_sparseValueMap = 0; … … 135 138 ArrayStorage* storage = m_storage; 136 139 137 if (i < m_vectorLength) {140 if (i < storage->m_vectorLength) { 138 141 JSValue* value = storage->m_vector[i]; 139 142 return value ? value : jsUndefined(); … … 153 156 } 154 157 155 ALWAYS_INLINE bool JSArray::inlineGetOwnPropertySlot(ExecState* exec, unsigned i, PropertySlot& slot)158 NEVER_INLINE bool JSArray::getOwnPropertySlotSlowCase(ExecState* exec, unsigned i, PropertySlot& slot) 156 159 { 157 160 ArrayStorage* storage = m_storage; 158 161 159 if ( UNLIKELY(i >= m_length)) {162 if (i >= m_length) { 160 163 if (i > maxArrayIndex) 161 164 return getOwnPropertySlot(exec, Identifier::from(exec, i), slot); … … 163 166 } 164 167 165 if (i < m_vectorLength) {168 if (i < storage->m_vectorLength) { 166 169 JSValue*& valueSlot = storage->m_vector[i]; 167 170 if (valueSlot) { … … 192 195 unsigned i = propertyName.toArrayIndex(&isArrayIndex); 193 196 if (isArrayIndex) 194 return inlineGetOwnPropertySlot(exec, i, slot);197 return JSArray::getOwnPropertySlot(exec, i, slot); 195 198 196 199 return JSObject::getOwnPropertySlot(exec, propertyName, slot); … … 199 202 bool JSArray::getOwnPropertySlot(ExecState* exec, unsigned i, PropertySlot& slot) 200 203 { 201 return inlineGetOwnPropertySlot(exec, i, slot); 204 if (i < m_fastAccessCutoff) { 205 slot.setValueSlot(&m_storage->m_vector[i]); 206 return true; 207 } 208 209 return getOwnPropertySlotSlowCase(exec, i, slot); 202 210 } 203 211 … … 229 237 checkConsistency(); 230 238 239 if (i < m_fastAccessCutoff) { 240 m_storage->m_vector[i] = value; 241 checkConsistency(); 242 return; 243 } 244 231 245 unsigned length = m_length; 232 if (i >= length) { 246 if (i >= length && i <= maxArrayIndex) { 247 length = i + 1; 248 m_length = length; 249 } 250 251 if (i < m_storage->m_vectorLength) { 252 JSValue*& valueSlot = m_storage->m_vector[i]; 253 if (valueSlot) { 254 valueSlot = value; 255 checkConsistency(); 256 return; 257 } 258 valueSlot = value; 259 if (++m_storage->m_numValuesInVector == m_length) 260 m_fastAccessCutoff = m_length; 261 checkConsistency(); 262 return; 263 } 264 265 putSlowCase(exec, i, value); 266 } 267 268 NEVER_INLINE void JSArray::putSlowCase(ExecState* exec, unsigned i, JSValue* value) 269 { 270 ArrayStorage* storage = m_storage; 271 SparseArrayValueMap* map = storage->m_sparseValueMap; 272 273 if (i >= sparseArrayCutoff) { 233 274 if (i > maxArrayIndex) { 234 275 put(exec, Identifier::from(exec, i), value); 235 276 return; 236 277 } 237 length = i + 1; 238 m_length = length; 239 } 240 241 ArrayStorage* storage = m_storage; 242 243 if (i < m_vectorLength) { 244 JSValue*& valueSlot = storage->m_vector[i]; 245 storage->m_numValuesInVector += !valueSlot; 246 valueSlot = value; 247 checkConsistency(); 248 return; 249 } 250 251 SparseArrayValueMap* map = storage->m_sparseValueMap; 252 253 if (i >= sparseArrayCutoff) { 278 254 279 // We miss some cases where we could compact the storage, such as a large array that is being filled from the end 255 280 // (which will only be compacted as we reach indices that are less than cutoff) - but this makes the check much faster. … … 278 303 unsigned newNumValuesInVector = storage->m_numValuesInVector + 1; 279 304 unsigned newVectorLength = increasedVectorLength(i + 1); 280 for (unsigned j = max( m_vectorLength, sparseArrayCutoff); j < newVectorLength; ++j)305 for (unsigned j = max(storage->m_vectorLength, sparseArrayCutoff); j < newVectorLength; ++j) 281 306 newNumValuesInVector += map->contains(j); 282 307 if (i >= sparseArrayCutoff) … … 297 322 storage = static_cast<ArrayStorage*>(fastRealloc(storage, storageSize(newVectorLength))); 298 323 299 unsigned vectorLength = m_vectorLength;324 unsigned vectorLength = storage->m_vectorLength; 300 325 if (newNumValuesInVector == storage->m_numValuesInVector + 1) { 301 326 for (unsigned j = vectorLength; j < newVectorLength; ++j) … … 312 337 storage->m_vector[i] = value; 313 338 314 m_vectorLength = newVectorLength;339 storage->m_vectorLength = newVectorLength; 315 340 storage->m_numValuesInVector = newNumValuesInVector; 316 341 … … 339 364 ArrayStorage* storage = m_storage; 340 365 341 if (i < m_vectorLength) {366 if (i < storage->m_vectorLength) { 342 367 JSValue*& valueSlot = storage->m_vector[i]; 343 bool hadValue = valueSlot; 368 if (!valueSlot) { 369 checkConsistency(); 370 return false; 371 } 344 372 valueSlot = 0; 345 storage->m_numValuesInVector -= hadValue; 373 --storage->m_numValuesInVector; 374 if (m_fastAccessCutoff > i) 375 m_fastAccessCutoff = i; 346 376 checkConsistency(); 347 return hadValue;377 return true; 348 378 } 349 379 … … 375 405 ArrayStorage* storage = m_storage; 376 406 377 unsigned usedVectorLength = min(m_length, m_vectorLength);407 unsigned usedVectorLength = min(m_length, storage->m_vectorLength); 378 408 for (unsigned i = 0; i < usedVectorLength; ++i) { 379 409 if (storage->m_vector[i]) … … 397 427 ArrayStorage* storage = m_storage; 398 428 399 unsigned vectorLength = m_vectorLength;429 unsigned vectorLength = storage->m_vectorLength; 400 430 ASSERT(newLength > vectorLength); 401 431 unsigned newVectorLength = increasedVectorLength(newLength); … … 405 435 return false; 406 436 407 m_vectorLength = newVectorLength;437 storage->m_vectorLength = newVectorLength; 408 438 409 439 for (unsigned i = vectorLength; i < newVectorLength; ++i) … … 423 453 424 454 if (newLength < length) { 425 unsigned usedVectorLength = min(length, m_vectorLength); 455 if (m_fastAccessCutoff > newLength) 456 m_fastAccessCutoff = newLength; 457 458 unsigned usedVectorLength = min(length, storage->m_vectorLength); 426 459 for (unsigned i = newLength; i < usedVectorLength; ++i) { 427 460 JSValue*& valueSlot = storage->m_vector[i]; … … 456 489 ArrayStorage* storage = m_storage; 457 490 458 unsigned usedVectorLength = min(m_length, m_vectorLength);491 unsigned usedVectorLength = min(m_length, storage->m_vectorLength); 459 492 for (unsigned i = 0; i < usedVectorLength; ++i) { 460 493 JSValue* value = storage->m_vector[i]; … … 626 659 return; 627 660 628 unsigned usedVectorLength = min(m_length, m_ vectorLength);661 unsigned usedVectorLength = min(m_length, m_storage->m_vectorLength); 629 662 630 663 AVLTree<AVLTreeAbstractorForArrayCompare, 44> tree; // Depth 44 is enough for 2^31 items … … 671 704 if (SparseArrayValueMap* map = m_storage->m_sparseValueMap) { 672 705 newUsedVectorLength += map->size(); 673 if (newUsedVectorLength > m_ vectorLength) {706 if (newUsedVectorLength > m_storage->m_vectorLength) { 674 707 if (!increaseVectorLength(newUsedVectorLength)) { 675 708 exec->setException(Error::create(exec, GeneralError, "Out of memory")); … … 710 743 m_storage->m_vector[i] = 0; 711 744 745 m_fastAccessCutoff = newUsedVectorLength; 712 746 m_storage->m_numValuesInVector = newUsedVectorLength; 713 747 … … 721 755 ArrayStorage* storage = m_storage; 722 756 723 unsigned usedVectorLength = min(m_length, m_vectorLength);757 unsigned usedVectorLength = min(m_length, storage->m_vectorLength); 724 758 725 759 unsigned numDefined = 0; … … 744 778 if (SparseArrayValueMap* map = storage->m_sparseValueMap) { 745 779 newUsedVectorLength += map->size(); 746 if (newUsedVectorLength > m_vectorLength) {780 if (newUsedVectorLength > storage->m_vectorLength) { 747 781 if (!increaseVectorLength(newUsedVectorLength)) 748 782 return 0; … … 763 797 storage->m_vector[i] = 0; 764 798 799 m_fastAccessCutoff = newUsedVectorLength; 765 800 storage->m_numValuesInVector = newUsedVectorLength; 766 801 … … 788 823 ASSERT(!m_storage->m_sparseValueMap); 789 824 825 ASSERT(m_fastAccessCutoff <= m_length); 826 ASSERT(m_fastAccessCutoff <= m_storage->m_numValuesInVector); 827 790 828 unsigned numValuesInVector = 0; 791 for (unsigned i = 0; i < m_ vectorLength; ++i) {829 for (unsigned i = 0; i < m_storage->m_vectorLength; ++i) { 792 830 if (JSValue* value = m_storage->m_vector[i]) { 793 831 ASSERT(i < m_length); … … 796 834 ++numValuesInVector; 797 835 } else { 836 ASSERT(i >= m_fastAccessCutoff); 798 837 if (type == SortConsistencyCheck) 799 838 ASSERT(i >= m_storage->m_numValuesInVector); … … 807 846 unsigned index = it->first; 808 847 ASSERT(index < m_length); 809 ASSERT(index >= m_ vectorLength);848 ASSERT(index >= m_storage->m_vectorLength); 810 849 ASSERT(index <= maxArrayIndex); 811 850 ASSERT(it->second); -
trunk/JavaScriptCore/kjs/JSArray.h
r34754 r34867 64 64 65 65 static JSValue* lengthGetter(ExecState*, const Identifier&, const PropertySlot&); 66 bool inlineGetOwnPropertySlot(ExecState*, unsigned propertyName, PropertySlot&); 66 67 bool getOwnPropertySlotSlowCase(ExecState*, unsigned propertyName, PropertySlot&); 68 void putSlowCase(ExecState*, unsigned propertyName, JSValue*); 67 69 68 70 bool increaseVectorLength(unsigned newLength); … … 74 76 75 77 unsigned m_length; 76 unsigned m_ vectorLength;78 unsigned m_fastAccessCutoff; 77 79 ArrayStorage* m_storage; 78 80 };
Note:
See TracChangeset
for help on using the changeset viewer.