Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(881)

Unified Diff: src/elements.cc

Issue 1543563002: [elements] Enable left-trimming again (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: improve comment Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | src/flag-definitions.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/elements.cc
diff --git a/src/elements.cc b/src/elements.cc
index 28700b8f0abe31e90e32a0f2c6be65d787c915dd..f882ce8c6455c538871b3186537fed62e85f4ea1 100644
--- a/src/elements.cc
+++ b/src/elements.cc
@@ -677,11 +677,12 @@ class ElementsAccessorBase : public ElementsAccessor {
}
void SetLength(Handle<JSArray> array, uint32_t length) final {
- ElementsAccessorSubclass::SetLengthImpl(array, length,
+ ElementsAccessorSubclass::SetLengthImpl(array->GetIsolate(), array, length,
handle(array->elements()));
}
- static void SetLengthImpl(Handle<JSArray> array, uint32_t length,
+ static void SetLengthImpl(Isolate* isolate, Handle<JSArray> array,
+ uint32_t length,
Handle<FixedArrayBase> backing_store) {
DCHECK(!array->SetLengthWouldNormalize(length));
DCHECK(IsFastElementsKind(array->GetElementsKind()));
@@ -698,6 +699,7 @@ class ElementsAccessorBase : public ElementsAccessor {
// Check whether the backing store should be shrunk.
uint32_t capacity = backing_store->length();
+ old_length = Min(old_length, capacity);
if (length == 0) {
array->initialize_elements();
} else if (length <= capacity) {
@@ -706,7 +708,7 @@ class ElementsAccessorBase : public ElementsAccessor {
}
if (2 * length <= capacity) {
// If more than half the elements won't be used, trim the array.
- array->GetHeap()->RightTrimFixedArray<Heap::CONCURRENT_TO_SWEEPER>(
+ isolate->heap()->RightTrimFixedArray<Heap::CONCURRENT_TO_SWEEPER>(
*backing_store, capacity - length);
} else {
// Otherwise, fill the unused tail with holes.
@@ -972,11 +974,11 @@ class DictionaryElementsAccessor
: ElementsAccessorBase<DictionaryElementsAccessor,
ElementsKindTraits<DICTIONARY_ELEMENTS> >(name) {}
- static void SetLengthImpl(Handle<JSArray> array, uint32_t length,
+ static void SetLengthImpl(Isolate* isolate, Handle<JSArray> array,
+ uint32_t length,
Handle<FixedArrayBase> backing_store) {
Handle<SeededNumberDictionary> dict =
Handle<SeededNumberDictionary>::cast(backing_store);
- Isolate* isolate = array->GetIsolate();
int capacity = dict->Capacity();
uint32_t old_length = 0;
CHECK(array->length()->ToArrayLength(&old_length));
@@ -1352,9 +1354,10 @@ class FastElementsAccessor
receiver, backing_store, args, unshift_size, AT_START);
}
- static void MoveElements(Heap* heap, Handle<FixedArrayBase> backing_store,
- int dst_index, int src_index, int len,
- int hole_start, int hole_end) {
+ static void MoveElements(Isolate* isolate, Handle<JSArray> receiver,
+ Handle<FixedArrayBase> backing_store, int dst_index,
+ int src_index, int len, int hole_start,
+ int hole_end) {
UNREACHABLE();
}
@@ -1403,13 +1406,13 @@ class FastElementsAccessor
// Delete and move elements to make space for add_count new elements.
if (add_count < delete_count) {
- FastElementsAccessorSubclass::SpliceShrinkStep(backing_store, heap, start,
- delete_count, add_count,
- length, new_length);
+ FastElementsAccessorSubclass::SpliceShrinkStep(
+ isolate, receiver, backing_store, start, delete_count, add_count,
+ length, new_length);
} else if (add_count > delete_count) {
backing_store = FastElementsAccessorSubclass::SpliceGrowStep(
- receiver, backing_store, isolate, heap, start, delete_count,
- add_count, length, new_length);
+ isolate, receiver, backing_store, start, delete_count, add_count,
+ length, new_length);
}
// Copy over the arguments.
@@ -1423,29 +1426,33 @@ class FastElementsAccessor
}
private:
- static void SpliceShrinkStep(Handle<FixedArrayBase> backing_store, Heap* heap,
+ // SpliceShrinkStep might modify the backing_store.
+ static void SpliceShrinkStep(Isolate* isolate, Handle<JSArray> receiver,
+ Handle<FixedArrayBase> backing_store,
uint32_t start, uint32_t delete_count,
uint32_t add_count, uint32_t len,
uint32_t new_length) {
const int move_left_count = len - delete_count - start;
const int move_left_dst_index = start + add_count;
FastElementsAccessorSubclass::MoveElements(
- heap, backing_store, move_left_dst_index, start + delete_count,
- move_left_count, new_length, len);
+ isolate, receiver, backing_store, move_left_dst_index,
+ start + delete_count, move_left_count, new_length, len);
}
-
+ // SpliceGrowStep might modify the backing_store.
static Handle<FixedArrayBase> SpliceGrowStep(
- Handle<JSArray> receiver, Handle<FixedArrayBase> backing_store,
- Isolate* isolate, Heap* heap, uint32_t start, uint32_t delete_count,
- uint32_t add_count, uint32_t length, uint32_t new_length) {
+ Isolate* isolate, Handle<JSArray> receiver,
+ Handle<FixedArrayBase> backing_store, uint32_t start,
+ uint32_t delete_count, uint32_t add_count, uint32_t length,
+ uint32_t new_length) {
// Check we do not overflow the new_length.
DCHECK((add_count - delete_count) <= (Smi::kMaxValue - length));
// Check if backing_store is big enough.
if (new_length <= static_cast<uint32_t>(backing_store->length())) {
FastElementsAccessorSubclass::MoveElements(
- heap, backing_store, start + add_count, start + delete_count,
- (length - delete_count - start), 0, 0);
+ isolate, receiver, backing_store, start + add_count,
+ start + delete_count, (length - delete_count - start), 0, 0);
+ // MoveElements updates the backing_store in-place.
return backing_store;
}
// New backing storage is needed.
@@ -1466,20 +1473,19 @@ class FastElementsAccessor
static Handle<Object> RemoveElement(Handle<JSArray> receiver,
Handle<FixedArrayBase> backing_store,
Where remove_position) {
+ Isolate* isolate = receiver->GetIsolate();
uint32_t length =
static_cast<uint32_t>(Smi::cast(receiver->length())->value());
- Isolate* isolate = receiver->GetIsolate();
DCHECK(length > 0);
int new_length = length - 1;
int remove_index = remove_position == AT_START ? 0 : new_length;
Handle<Object> result =
FastElementsAccessorSubclass::GetImpl(backing_store, remove_index);
if (remove_position == AT_START) {
- Heap* heap = isolate->heap();
- FastElementsAccessorSubclass::MoveElements(heap, backing_store, 0, 1,
- new_length, 0, 0);
+ FastElementsAccessorSubclass::MoveElements(
+ isolate, receiver, backing_store, 0, 1, new_length, 0, 0);
}
- FastElementsAccessorSubclass::SetLengthImpl(receiver, new_length,
+ FastElementsAccessorSubclass::SetLengthImpl(isolate, receiver, new_length,
backing_store);
if (IsHoleyElementsKind(KindTraits::Kind) && result->IsTheHole()) {
@@ -1513,8 +1519,8 @@ class FastElementsAccessor
// If the backing store has enough capacity and we add elements to the
// start we have to shift the existing objects.
Isolate* isolate = receiver->GetIsolate();
- FastElementsAccessorSubclass::MoveElements(isolate->heap(), backing_store,
- add_size, 0, length, 0, 0);
+ FastElementsAccessorSubclass::MoveElements(
+ isolate, receiver, backing_store, add_size, 0, length, 0, 0);
}
int insertion_index = remove_position == AT_START ? 0 : length;
@@ -1567,11 +1573,22 @@ class FastSmiOrObjectElementsAccessor
return backing_store->get(index);
}
- static void MoveElements(Heap* heap, Handle<FixedArrayBase> backing_store,
- int dst_index, int src_index, int len,
- int hole_start, int hole_end) {
+ static void MoveElements(Isolate* isolate, Handle<JSArray> receiver,
+ Handle<FixedArrayBase> backing_store, int dst_index,
+ int src_index, int len, int hole_start,
+ int hole_end) {
+ Heap* heap = isolate->heap();
Handle<FixedArray> dst_elms = Handle<FixedArray>::cast(backing_store);
- if (len != 0) {
+ if (heap->CanMoveObjectStart(*dst_elms) && dst_index == 0) {
+ // Update all the copies of this backing_store handle.
+ *dst_elms.location() =
+ FixedArray::cast(heap->LeftTrimFixedArray(*dst_elms, src_index));
+ receiver->set_elements(*dst_elms);
+ // Adjust the hole offset as the array has been shrunk.
+ hole_end -= src_index;
+ DCHECK_LE(hole_start, backing_store->length());
+ DCHECK_LE(hole_end, backing_store->length());
+ } else if (len != 0) {
DisallowHeapAllocation no_gc;
heap->MoveElements(*dst_elms, dst_index, src_index, len);
}
@@ -1690,12 +1707,23 @@ class FastDoubleElementsAccessor
FixedDoubleArray::cast(backing_store)->set(entry, value->Number());
}
- static void MoveElements(Heap* heap, Handle<FixedArrayBase> backing_store,
- int dst_index, int src_index, int len,
- int hole_start, int hole_end) {
+ static void MoveElements(Isolate* isolate, Handle<JSArray> receiver,
+ Handle<FixedArrayBase> backing_store, int dst_index,
+ int src_index, int len, int hole_start,
+ int hole_end) {
+ Heap* heap = isolate->heap();
Handle<FixedDoubleArray> dst_elms =
Handle<FixedDoubleArray>::cast(backing_store);
- if (len != 0) {
+ if (heap->CanMoveObjectStart(*dst_elms) && dst_index == 0) {
+ // Update all the copies of this backing_store handle.
+ *dst_elms.location() = FixedDoubleArray::cast(
+ heap->LeftTrimFixedArray(*dst_elms, src_index));
+ receiver->set_elements(*dst_elms);
+ // Adjust the hole offset as the array has been shrunk.
+ hole_end -= src_index;
+ DCHECK_LE(hole_start, backing_store->length());
+ DCHECK_LE(hole_end, backing_store->length());
+ } else if (len != 0) {
MemMove(dst_elms->data_start() + dst_index,
dst_elms->data_start() + src_index, len * kDoubleSize);
}
@@ -1801,7 +1829,8 @@ class TypedElementsAccessor
return PropertyDetails(DONT_DELETE, DATA, 0, PropertyCellType::kNoCell);
}
- static void SetLengthImpl(Handle<JSArray> array, uint32_t length,
+ static void SetLengthImpl(Isolate* isolate, Handle<JSArray> array,
+ uint32_t length,
Handle<FixedArrayBase> backing_store) {
// External arrays do not support changing their length.
UNREACHABLE();
@@ -1915,7 +1944,8 @@ class SloppyArgumentsElementsAccessor
}
}
- static void SetLengthImpl(Handle<JSArray> array, uint32_t length,
+ static void SetLengthImpl(Isolate* isolate, Handle<JSArray> array,
+ uint32_t length,
Handle<FixedArrayBase> parameter_map) {
// Sloppy arguments objects are not arrays.
UNREACHABLE();
« no previous file with comments | « no previous file | src/flag-definitions.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698