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

Side by Side Diff: src/elements.cc

Issue 1317053006: Adding ElementsAccessor::Shift (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@2015-09-01_array_builtin_cleanup
Patch Set: SetLengthImpl cleanup Created 5 years, 3 months 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 unified diff | Download patch
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/elements.h" 5 #include "src/elements.h"
6 6
7 #include "src/arguments.h" 7 #include "src/arguments.h"
8 #include "src/conversions.h" 8 #include "src/conversions.h"
9 #include "src/factory.h" 9 #include "src/factory.h"
10 #include "src/messages.h" 10 #include "src/messages.h"
(...skipping 652 matching lines...) Expand 10 before | Expand all | Expand 10 after
663 Handle<FixedArrayBase> backing_store) final { 663 Handle<FixedArrayBase> backing_store) final {
664 return ElementsAccessorSubclass::PopImpl(receiver, backing_store); 664 return ElementsAccessorSubclass::PopImpl(receiver, backing_store);
665 } 665 }
666 666
667 static Handle<Object> PopImpl(Handle<JSArray> receiver, 667 static Handle<Object> PopImpl(Handle<JSArray> receiver,
668 Handle<FixedArrayBase> backing_store) { 668 Handle<FixedArrayBase> backing_store) {
669 UNREACHABLE(); 669 UNREACHABLE();
670 return Handle<Object>(); 670 return Handle<Object>();
671 } 671 }
672 672
673 virtual Handle<Object> Shift(Handle<JSArray> receiver,
674 Handle<FixedArrayBase> backing_store) final {
675 return ElementsAccessorSubclass::ShiftImpl(receiver, backing_store);
676 }
677
678 static Handle<Object> ShiftImpl(Handle<JSArray> receiver,
679 Handle<FixedArrayBase> backing_store) {
680 UNREACHABLE();
681 return Handle<Object>();
682 }
683
673 virtual void SetLength(Handle<JSArray> array, uint32_t length) final { 684 virtual void SetLength(Handle<JSArray> array, uint32_t length) final {
674 ElementsAccessorSubclass::SetLengthImpl(array, length, 685 ElementsAccessorSubclass::SetLengthImpl(array, length,
675 handle(array->elements())); 686 handle(array->elements()));
676 } 687 }
677 688
678 static void SetLengthImpl(Handle<JSArray> array, uint32_t length, 689 static void SetLengthImpl(Handle<JSArray> array, uint32_t length,
679 Handle<FixedArrayBase> backing_store); 690 Handle<FixedArrayBase> backing_store) {
691 DCHECK(!array->SetLengthWouldNormalize(length));
692 DCHECK(IsFastElementsKind(array->GetElementsKind()));
693 uint32_t old_length = 0;
694 CHECK(array->length()->ToArrayIndex(&old_length));
695
696 if (old_length < length) {
697 ElementsKind kind = array->GetElementsKind();
698 if (!IsFastHoleyElementsKind(kind)) {
699 kind = GetHoleyElementsKind(kind);
700 JSObject::TransitionElementsKind(array, kind);
701 }
702 }
703
704 // Check whether the backing store should be shrunk.
705 uint32_t capacity = backing_store->length();
706 if (length == 0) {
707 array->initialize_elements();
708 } else if (length <= capacity) {
709 if (array->HasFastSmiOrObjectElements()) {
710 backing_store = JSObject::EnsureWritableFastElements(array);
711 }
712 if (2 * length <= capacity) {
713 // If more than half the elements won't be used, trim the array.
714 array->GetHeap()->RightTrimFixedArray<Heap::CONCURRENT_TO_SWEEPER>(
715 *backing_store, capacity - length);
716 } else {
717 // Otherwise, fill the unused tail with holes.
718 for (uint32_t i = length; i < old_length; i++) {
719 BackingStore::cast(*backing_store)->set_the_hole(i);
720 }
721 }
722 } else {
723 // Check whether the backing store should be expanded.
724 capacity = Max(length, JSObject::NewElementsCapacity(capacity));
725 ElementsAccessorSubclass::GrowCapacityAndConvertImpl(array, capacity);
726 }
727
728 array->set_length(Smi::FromInt(length));
729 JSObject::ValidateElements(array);
730 }
680 731
681 static Handle<FixedArrayBase> ConvertElementsWithCapacity( 732 static Handle<FixedArrayBase> ConvertElementsWithCapacity(
682 Handle<JSObject> object, Handle<FixedArrayBase> old_elements, 733 Handle<JSObject> object, Handle<FixedArrayBase> old_elements,
683 ElementsKind from_kind, uint32_t capacity) { 734 ElementsKind from_kind, uint32_t capacity) {
684 return ConvertElementsWithCapacity( 735 return ConvertElementsWithCapacity(
685 object, old_elements, from_kind, capacity, 0, 0, 736 object, old_elements, from_kind, capacity, 0, 0,
686 ElementsAccessor::kCopyToEndAndInitializeToHole); 737 ElementsAccessor::kCopyToEndAndInitializeToHole);
687 } 738 }
688 739
689 static Handle<FixedArrayBase> ConvertElementsWithCapacity( 740 static Handle<FixedArrayBase> ConvertElementsWithCapacity(
(...skipping 564 matching lines...) Expand 10 before | Expand all | Expand 10 after
1254 DCHECK(BackingStore::get(backing_store, i)->IsSmi() || 1305 DCHECK(BackingStore::get(backing_store, i)->IsSmi() ||
1255 (IsFastHoleyElementsKind(KindTraits::Kind) && 1306 (IsFastHoleyElementsKind(KindTraits::Kind) &&
1256 backing_store->is_the_hole(i))); 1307 backing_store->is_the_hole(i)));
1257 } 1308 }
1258 } 1309 }
1259 #endif 1310 #endif
1260 } 1311 }
1261 1312
1262 static Handle<Object> PopImpl(Handle<JSArray> receiver, 1313 static Handle<Object> PopImpl(Handle<JSArray> receiver,
1263 Handle<FixedArrayBase> backing_store) { 1314 Handle<FixedArrayBase> backing_store) {
1264 uint32_t new_length = 1315 uint32_t len =
1265 static_cast<uint32_t>(Smi::cast(receiver->length())->value()) - 1; 1316 static_cast<uint32_t>(Smi::cast(receiver->length())->value());
1317 if (len == 0) {
Igor Sheludko 2015/09/02 12:35:20 ArrayPop already handles this case. Maybe this sho
Camillo Bruni 2015/09/02 13:04:55 Right.
1318 return receiver->GetIsolate()->factory()->undefined_value();
1319 }
1320 uint32_t new_length = len - 1;
1266 Handle<Object> result = 1321 Handle<Object> result =
1267 FastElementsAccessorSubclass::GetImpl(backing_store, new_length); 1322 FastElementsAccessorSubclass::GetImpl(backing_store, new_length);
1268 FastElementsAccessorSubclass::SetLengthImpl(receiver, new_length, 1323 FastElementsAccessorSubclass::SetLengthImpl(receiver, new_length,
1269 backing_store); 1324 backing_store);
1270 1325
1271 if (IsHoleyElementsKind(KindTraits::Kind) && result->IsTheHole()) { 1326 if (IsHoleyElementsKind(KindTraits::Kind) && result->IsTheHole()) {
1327 return receiver->GetIsolate()->factory()->undefined_value();
1328 }
1329 return result;
1330 }
1331
1332 static Handle<Object> ShiftImpl(Handle<JSArray> receiver,
1333 Handle<FixedArrayBase> backing_store) {
1334 uint32_t len =
1335 static_cast<uint32_t>(Smi::cast(receiver->length())->value());
1336 Isolate* isolate = receiver->GetIsolate();
1337 if (len == 0) {
Igor Sheludko 2015/09/02 12:35:20 Same here.
Camillo Bruni 2015/09/02 13:04:55 ditto.
1338 return isolate->factory()->undefined_value();
1339 }
1340 int new_length = len - 1;
1341 Handle<Object> result =
1342 FastElementsAccessorSubclass::GetImpl(backing_store, 0);
1343 Heap* heap = isolate->heap();
1344 if (heap->CanMoveObjectStart(*backing_store)) {
1345 receiver->set_elements(heap->LeftTrimFixedArray(*backing_store, 1));
1346 } else {
1347 FastElementsAccessorSubclass::MoveElements(heap, backing_store, 0, 1,
1348 new_length, 0, 0);
1349 }
1350 FastElementsAccessorSubclass::SetLengthImpl(receiver, new_length,
1351 backing_store);
1352
1353 if (IsHoleyElementsKind(KindTraits::Kind) && result->IsTheHole()) {
1272 result = receiver->GetIsolate()->factory()->undefined_value(); 1354 result = receiver->GetIsolate()->factory()->undefined_value();
1273 } 1355 }
1274 return result; 1356 return result;
1275 } 1357 }
1276 1358
1277 static uint32_t PushImpl(Handle<JSArray> receiver, 1359 static uint32_t PushImpl(Handle<JSArray> receiver,
1278 Handle<FixedArrayBase> backing_store, 1360 Handle<FixedArrayBase> backing_store,
1279 Arguments* args, uint32_t push_size) { 1361 Arguments* args, uint32_t push_size) {
1280 uint32_t len = Smi::cast(receiver->length())->value(); 1362 uint32_t len = Smi::cast(receiver->length())->value();
1281 if (push_size == 0) { 1363 if (push_size == 0) {
(...skipping 833 matching lines...) Expand 10 before | Expand all | Expand 10 after
2115 ConvertElementsWithCapacity(object, old_elements, from_kind, capacity); 2197 ConvertElementsWithCapacity(object, old_elements, from_kind, capacity);
2116 Handle<Map> new_map = JSObject::GetElementsTransitionMap( 2198 Handle<Map> new_map = JSObject::GetElementsTransitionMap(
2117 object, FAST_SLOPPY_ARGUMENTS_ELEMENTS); 2199 object, FAST_SLOPPY_ARGUMENTS_ELEMENTS);
2118 JSObject::MigrateToMap(object, new_map); 2200 JSObject::MigrateToMap(object, new_map);
2119 parameter_map->set(1, *elements); 2201 parameter_map->set(1, *elements);
2120 JSObject::ValidateElements(object); 2202 JSObject::ValidateElements(object);
2121 } 2203 }
2122 }; 2204 };
2123 2205
2124 2206
2125 template <typename ElementsAccessorSubclass, typename ElementsKindTraits>
2126 void ElementsAccessorBase<ElementsAccessorSubclass, ElementsKindTraits>::
2127 SetLengthImpl(Handle<JSArray> array, uint32_t length,
2128 Handle<FixedArrayBase> backing_store) {
2129 DCHECK(!array->SetLengthWouldNormalize(length));
2130 DCHECK(IsFastElementsKind(array->GetElementsKind()));
2131 uint32_t old_length = 0;
2132 CHECK(array->length()->ToArrayIndex(&old_length));
2133
2134 if (old_length < length) {
2135 ElementsKind kind = array->GetElementsKind();
2136 if (!IsFastHoleyElementsKind(kind)) {
2137 kind = GetHoleyElementsKind(kind);
2138 JSObject::TransitionElementsKind(array, kind);
2139 }
2140 }
2141
2142 // Check whether the backing store should be shrunk.
2143 uint32_t capacity = backing_store->length();
2144 if (length == 0) {
2145 array->initialize_elements();
2146 } else if (length <= capacity) {
2147 if (array->HasFastSmiOrObjectElements()) {
2148 backing_store = JSObject::EnsureWritableFastElements(array);
2149 }
2150 if (2 * length <= capacity) {
2151 // If more than half the elements won't be used, trim the array.
2152 array->GetHeap()->RightTrimFixedArray<Heap::CONCURRENT_TO_SWEEPER>(
2153 *backing_store, capacity - length);
2154 } else {
2155 // Otherwise, fill the unused tail with holes.
2156 for (uint32_t i = length; i < old_length; i++) {
2157 BackingStore::cast(*backing_store)->set_the_hole(i);
2158 }
2159 }
2160 } else {
2161 // Check whether the backing store should be expanded.
2162 capacity = Max(length, JSObject::NewElementsCapacity(capacity));
2163 ElementsAccessorSubclass::GrowCapacityAndConvertImpl(array, capacity);
2164 }
2165
2166 array->set_length(Smi::FromInt(length));
2167 JSObject::ValidateElements(array);
2168 }
2169 } // namespace 2207 } // namespace
2170 2208
2171 2209
2172 void CheckArrayAbuse(Handle<JSObject> obj, const char* op, uint32_t index, 2210 void CheckArrayAbuse(Handle<JSObject> obj, const char* op, uint32_t index,
2173 bool allow_appending) { 2211 bool allow_appending) {
2174 DisallowHeapAllocation no_allocation; 2212 DisallowHeapAllocation no_allocation;
2175 Object* raw_length = NULL; 2213 Object* raw_length = NULL;
2176 const char* elements_type = "array"; 2214 const char* elements_type = "array";
2177 if (obj->IsJSArray()) { 2215 if (obj->IsJSArray()) {
2178 JSArray* array = JSArray::cast(*obj); 2216 JSArray* array = JSArray::cast(*obj);
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
2317 if (elements_accessors_ == NULL) return; 2355 if (elements_accessors_ == NULL) return;
2318 #define ACCESSOR_DELETE(Class, Kind, Store) delete elements_accessors_[Kind]; 2356 #define ACCESSOR_DELETE(Class, Kind, Store) delete elements_accessors_[Kind];
2319 ELEMENTS_LIST(ACCESSOR_DELETE) 2357 ELEMENTS_LIST(ACCESSOR_DELETE)
2320 #undef ACCESSOR_DELETE 2358 #undef ACCESSOR_DELETE
2321 elements_accessors_ = NULL; 2359 elements_accessors_ = NULL;
2322 } 2360 }
2323 2361
2324 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; 2362 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL;
2325 } // namespace internal 2363 } // namespace internal
2326 } // namespace v8 2364 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698