+ if (!oldLength)
+ return true;
+
+ unsigned length = oldLength - count;
+
+ storage->m_numValuesInVector -= count;
+ storage->setLength(length);
+
+ unsigned vectorLength = storage->vectorLength();
+ if (!vectorLength)
+ return true;
+
+ if (startIndex >= vectorLength)
+ return true;
+
+ if (startIndex + count > vectorLength)
+ count = vectorLength - startIndex;
+
+ unsigned usedVectorLength = min(vectorLength, oldLength);
+
+ unsigned numElementsBeforeShiftRegion = startIndex;
+ unsigned firstIndexAfterShiftRegion = startIndex + count;
+ unsigned numElementsAfterShiftRegion = usedVectorLength - firstIndexAfterShiftRegion;
+ ASSERT(numElementsBeforeShiftRegion + count + numElementsAfterShiftRegion == usedVectorLength);
+
+ // The point of this comparison seems to be to minimize the amount of elements that have to
+ // be moved during a shift operation.
+ if (numElementsBeforeShiftRegion < numElementsAfterShiftRegion) {
+ // The number of elements before the shift region is less than the number of elements
+ // after the shift region, so we move the elements before to the right.
+ if (numElementsBeforeShiftRegion) {
+ RELEASE_ASSERT(count + startIndex <= vectorLength);
+ if (storage->hasHoles()) {
+ for (unsigned i = startIndex; i-- > 0;) {
+ unsigned destinationIndex = count + i;
+ JSValue source = storage->m_vector[i].get();
+ JSValue dest = storage->m_vector[destinationIndex].get();
+ // Any time we overwrite a hole we know we overcounted the number of values we removed
+ // when we subtracted count from m_numValuesInVector above.
+ if (!dest && destinationIndex >= firstIndexAfterShiftRegion)
+ storage->m_numValuesInVector++;
+ storage->m_vector[count + i].setWithoutWriteBarrier(source);
+ }
+ } else {
+ memmove(storage->m_vector + count,
+ storage->m_vector,
+ sizeof(JSValue) * startIndex);
+ }
+ }
+ // Adjust the Butterfly and the index bias. We only need to do this here because we're changing
+ // the start of the Butterfly, which needs to point at the first indexed property in the used
+ // portion of the vector.
+ m_butterfly.setWithoutWriteBarrier(m_butterfly->shift(structure(), count));
+ storage = m_butterfly->arrayStorage();
+ storage->m_indexBias += count;
+
+ // Since we're consuming part of the vector by moving its beginning to the left,
+ // we need to modify the vector length appropriately.
+ storage->setVectorLength(vectorLength - count);
+ } else {
+ // The number of elements before the shift region is greater than or equal to the number
+ // of elements after the shift region, so we move the elements after the shift region to the left.
+ if (storage->hasHoles()) {
+ for (unsigned i = 0; i < numElementsAfterShiftRegion; ++i) {
+ unsigned destinationIndex = startIndex + i;
+ JSValue source = storage->m_vector[firstIndexAfterShiftRegion + i].get();
+ JSValue dest = storage->m_vector[destinationIndex].get();
+ // Any time we overwrite a hole we know we overcounted the number of values we removed
+ // when we subtracted count from m_numValuesInVector above.
+ if (!dest && destinationIndex < firstIndexAfterShiftRegion)
+ storage->m_numValuesInVector++;
+ storage->m_vector[startIndex + i].setWithoutWriteBarrier(source);