Changeset 34204 in webkit
- Timestamp:
- May 29, 2008 10:14:02 AM (16 years ago)
- Location:
- trunk
- Files:
-
- 3 added
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/ChangeLog
r34198 r34204 1 2008-05-29 Alexey Proskuryakov <ap@webkit.org> 2 3 Reviewed by Darin. 4 5 https://bugs.webkit.org/show_bug.cgi?id=19294 6 <rdar://problem/5969062> A crash when iterating over a sparse array backwards. 7 8 * kjs/array_instance.cpp: Turned sparseArrayCutoff into a macro, so that using max() on it 9 doesn't cause a PIC branch. 10 (KJS::ArrayInstance::increaseVectorLength): Added a comment about this function not 11 preserving class invariants. 12 (KJS::ArrayInstance::put): Update m_storage after reallocation. Move values that fit to 13 the vector from the map in all code paths. 14 1 15 2008-05-29 Thiago Macieira <tjmaciei@trolltech.com> 2 16 -
trunk/JavaScriptCore/kjs/array_instance.cpp
r34118 r34204 48 48 // When indices greater than sparseArrayCutoff are involved, we use a vector 49 49 // as long as it is 1/8 full. If more sparse than that, we use a map. 50 static const unsigned sparseArrayCutoff = 10000; 50 // This value has to be a macro to be used in max() and min() without introducing 51 // a PIC branch in Mach-O binaries, see <rdar://problem/5971391>. 52 #define sparseArrayCutoff 10000U 51 53 static const unsigned minDensityMultiplier = 8; 52 54 … … 227 229 } 228 230 229 if (i < sparseArrayCutoff) { 231 SparseArrayValueMap* map = storage->m_sparseValueMap; 232 233 if (i >= sparseArrayCutoff) { 234 // We miss some cases where we could compact the storage, such as a large array that is being filled from the end 235 // (which will only be compacted as we reach indices that are less than cutoff) - but this makes the check much faster. 236 if (!isDenseEnoughForVector(i + 1, storage->m_numValuesInVector + 1)) { 237 if (!map) { 238 map = new SparseArrayValueMap; 239 storage->m_sparseValueMap = map; 240 } 241 map->set(i, value); 242 return; 243 } 244 } 245 246 // We have decided that we'll put the new item into the vector. 247 // Fast case is when there is no sparse map, so we can increase the vector size without moving values from it. 248 if (!map || map->isEmpty()) { 230 249 increaseVectorLength(i + 1); 231 250 storage = m_storage; … … 235 254 } 236 255 237 SparseArrayValueMap* map = storage->m_sparseValueMap; 238 if (!map || map->isEmpty()) { 239 if (isDenseEnoughForVector(i + 1, storage->m_numValuesInVector + 1)) { 240 increaseVectorLength(i + 1); 241 storage = m_storage; 242 ++storage->m_numValuesInVector; 243 storage->m_vector[i] = value; 244 return; 245 } 246 if (!map) { 247 map = new SparseArrayValueMap; 248 storage->m_sparseValueMap = map; 249 } 250 map->set(i, value); 251 return; 252 } 253 256 // Decide how many values it would be best to move from the map. 254 257 unsigned newNumValuesInVector = storage->m_numValuesInVector + 1; 255 if (!isDenseEnoughForVector(i + 1, newNumValuesInVector)) {256 map->set(i, value);257 return;258 }259 260 258 unsigned newVectorLength = increasedVectorLength(i + 1); 261 for (unsigned j = m _vectorLength; j < newVectorLength; ++j)259 for (unsigned j = max(m_vectorLength, sparseArrayCutoff); j < newVectorLength; ++j) 262 260 newNumValuesInVector += map->contains(j); 263 newNumValuesInVector -= map->contains(i); 261 if (i >= sparseArrayCutoff) 262 newNumValuesInVector -= map->contains(i); 264 263 if (isDenseEnoughForVector(newVectorLength, newNumValuesInVector)) { 265 264 unsigned proposedNewNumValuesInVector = newNumValuesInVector; 266 265 while (true) { 267 266 unsigned proposedNewVectorLength = increasedVectorLength(newVectorLength + 1); 268 for (unsigned j = newVectorLength; j < proposedNewVectorLength; ++j)267 for (unsigned j = max(newVectorLength, sparseArrayCutoff); j < proposedNewVectorLength; ++j) 269 268 proposedNewNumValuesInVector += map->contains(j); 270 269 if (!isDenseEnoughForVector(proposedNewVectorLength, proposedNewNumValuesInVector)) … … 281 280 for (unsigned j = vectorLength; j < newVectorLength; ++j) 282 281 storage->m_vector[j] = 0; 283 map->remove(i); 282 if (i > sparseArrayCutoff) 283 map->remove(i); 284 284 } else { 285 for (unsigned j = vectorLength; j < newVectorLength; ++j) 285 for (unsigned j = vectorLength; j < max(vectorLength, sparseArrayCutoff); ++j) 286 storage->m_vector[j] = 0; 287 for (unsigned j = max(vectorLength, sparseArrayCutoff); j < newVectorLength; ++j) 286 288 storage->m_vector[j] = map->take(j); 287 289 } … … 291 293 m_vectorLength = newVectorLength; 292 294 storage->m_numValuesInVector = newNumValuesInVector; 295 296 m_storage = storage; 293 297 } 294 298 … … 358 362 bool ArrayInstance::increaseVectorLength(unsigned newLength) 359 363 { 364 // This function leaves the array in an internally inconsistent state, because it does not move any values from sparse value map 365 // to the vector. Callers have to account for that, because they can do it more efficiently. 366 360 367 ArrayStorage* storage = m_storage; 361 368 -
trunk/LayoutTests/ChangeLog
r34197 r34204 1 2008-05-29 Alexey Proskuryakov <ap@webkit.org> 2 3 Reviewed by Darin. 4 5 https://bugs.webkit.org/show_bug.cgi?id=19294 6 <rdar://problem/5969062> A crash when iterating over a sparse array backwards. 7 8 * fast/js/array-iterate-backwards-expected.txt: Added. 9 * fast/js/array-iterate-backwards.html: Added. 10 * fast/js/resources/array-iterate-backwards.js: Added. 11 1 12 2008-05-29 Alexey Proskuryakov <ap@webkit.org> 2 13
Note: See TracChangeset
for help on using the changeset viewer.