OLD | NEW |
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 567 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
578 push_size, direction); | 578 push_size, direction); |
579 } | 579 } |
580 | 580 |
581 static uint32_t PushImpl(Handle<JSArray> receiver, | 581 static uint32_t PushImpl(Handle<JSArray> receiver, |
582 Handle<FixedArrayBase> elms_obj, Object** objects, | 582 Handle<FixedArrayBase> elms_obj, Object** objects, |
583 uint32_t push_size, int direction) { | 583 uint32_t push_size, int direction) { |
584 UNREACHABLE(); | 584 UNREACHABLE(); |
585 return 0; | 585 return 0; |
586 } | 586 } |
587 | 587 |
| 588 virtual uint32_t Unshift(Handle<JSArray> receiver, |
| 589 Handle<FixedArrayBase> backing_store, Arguments args, |
| 590 uint32_t add_count) { |
| 591 return ElementsAccessorSubclass::UnshiftImpl(receiver, backing_store, args, |
| 592 add_count); |
| 593 } |
| 594 |
| 595 static uint32_t UnshiftImpl(Handle<JSArray> receiver, |
| 596 Handle<FixedArrayBase> backing_store, |
| 597 Arguments args, uint32_t add_count) { |
| 598 UNREACHABLE(); |
| 599 return 0; |
| 600 } |
| 601 |
588 virtual Handle<JSArray> Splice(Handle<JSArray> receiver, | 602 virtual Handle<JSArray> Splice(Handle<JSArray> receiver, |
589 Handle<FixedArrayBase> backing_store, | 603 Handle<FixedArrayBase> backing_store, |
590 uint32_t start, uint32_t delete_count, | 604 uint32_t start, uint32_t delete_count, |
591 Arguments args, uint32_t add_count) { | 605 Arguments args, uint32_t add_count) { |
592 return ElementsAccessorSubclass::SpliceImpl(receiver, backing_store, start, | 606 return ElementsAccessorSubclass::SpliceImpl(receiver, backing_store, start, |
593 delete_count, args, add_count); | 607 delete_count, args, add_count); |
594 } | 608 } |
595 | 609 |
596 static Handle<JSArray> SpliceImpl(Handle<JSArray> receiver, | 610 static Handle<JSArray> SpliceImpl(Handle<JSArray> receiver, |
597 Handle<FixedArrayBase> backing_store, | 611 Handle<FixedArrayBase> backing_store, |
(...skipping 576 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1174 if (IsFastSmiElementsKind(KindTraits::Kind)) { | 1188 if (IsFastSmiElementsKind(KindTraits::Kind)) { |
1175 for (int i = 0; i < length; i++) { | 1189 for (int i = 0; i < length; i++) { |
1176 DCHECK(BackingStore::get(backing_store, i)->IsSmi() || | 1190 DCHECK(BackingStore::get(backing_store, i)->IsSmi() || |
1177 (IsFastHoleyElementsKind(KindTraits::Kind) && | 1191 (IsFastHoleyElementsKind(KindTraits::Kind) && |
1178 backing_store->is_the_hole(i))); | 1192 backing_store->is_the_hole(i))); |
1179 } | 1193 } |
1180 } | 1194 } |
1181 #endif | 1195 #endif |
1182 } | 1196 } |
1183 | 1197 |
| 1198 |
| 1199 static uint32_t UnshiftImpl(Handle<JSArray> receiver, |
| 1200 Handle<FixedArrayBase> backing_store, |
| 1201 Arguments args, uint32_t add_count) { |
| 1202 int len = Smi::cast(receiver->length())->value(); |
| 1203 if (add_count == 0) { |
| 1204 return len; |
| 1205 } |
| 1206 // Currently fixed arrays cannot grow too big, so |
| 1207 // we should never hit this case. |
| 1208 DCHECK(add_count <= static_cast<uint32_t>(Smi::kMaxValue - len)); |
| 1209 int new_length = len + add_count; |
| 1210 Handle<FixedArrayBase> new_elements; |
| 1211 |
| 1212 if (new_length > backing_store->length()) { |
| 1213 // New backing storage is needed. |
| 1214 int capacity = new_length + (new_length >> 1) + 16; |
| 1215 new_elements = FastElementsAccessorSubclass::ConvertElementsWithCapacity( |
| 1216 receiver, backing_store, KindTraits::Kind, capacity, 0); |
| 1217 FastElementsAccessorSubclass::CopyElementsImpl( |
| 1218 *backing_store, 0, *new_elements, KindTraits::Kind, add_count, |
| 1219 kPackedSizeNotKnown, ElementsAccessor::kCopyToEndAndInitializeToHole); |
| 1220 } else { |
| 1221 DisallowHeapAllocation no_gc; |
| 1222 Heap* heap = receiver->GetIsolate()->heap(); |
| 1223 FastElementsAccessorSubclass::MoveElements(heap, backing_store, add_count, |
| 1224 0, len, 0, 0); |
| 1225 new_elements = backing_store; |
| 1226 } |
| 1227 |
| 1228 // Add the provided values. |
| 1229 DisallowHeapAllocation no_gc; |
| 1230 for (uint32_t i = 0; i < add_count; i++) { |
| 1231 FastElementsAccessorSubclass::SetImpl(*new_elements, i, args[i + 1]); |
| 1232 } |
| 1233 if (!new_elements.is_identical_to(backing_store)) { |
| 1234 receiver->set_elements(*new_elements); |
| 1235 } |
| 1236 // Set the length. |
| 1237 receiver->set_length(Smi::FromInt(new_length)); |
| 1238 return new_length; |
| 1239 } |
| 1240 |
| 1241 |
1184 static uint32_t PushImpl(Handle<JSArray> receiver, | 1242 static uint32_t PushImpl(Handle<JSArray> receiver, |
1185 Handle<FixedArrayBase> backing_store, | 1243 Handle<FixedArrayBase> backing_store, |
1186 Object** objects, uint32_t push_size, | 1244 Object** objects, uint32_t push_size, |
1187 int direction) { | 1245 int direction) { |
1188 uint32_t len = Smi::cast(receiver->length())->value(); | 1246 uint32_t len = Smi::cast(receiver->length())->value(); |
1189 if (push_size == 0) { | 1247 if (push_size == 0) { |
1190 return len; | 1248 return len; |
1191 } | 1249 } |
1192 uint32_t elms_len = backing_store->length(); | |
1193 // Currently fixed arrays cannot grow too big, so | 1250 // Currently fixed arrays cannot grow too big, so |
1194 // we should never hit this case. | 1251 // we should never hit this case. |
1195 DCHECK(push_size <= static_cast<uint32_t>(Smi::kMaxValue - len)); | 1252 DCHECK(push_size <= static_cast<uint32_t>(Smi::kMaxValue - len)); |
1196 uint32_t new_length = len + push_size; | 1253 uint32_t new_length = len + push_size; |
1197 Handle<FixedArrayBase> new_elms; | 1254 Handle<FixedArrayBase> new_elms; |
1198 | 1255 |
1199 if (new_length > elms_len) { | 1256 if (new_length > static_cast<uint32_t>(backing_store->length())) { |
1200 // New backing storage is needed. | 1257 // New backing storage is needed. |
1201 uint32_t capacity = new_length + (new_length >> 1) + 16; | 1258 uint32_t capacity = new_length + (new_length >> 1) + 16; |
1202 new_elms = FastElementsAccessorSubclass::ConvertElementsWithCapacity( | 1259 new_elms = FastElementsAccessorSubclass::ConvertElementsWithCapacity( |
1203 receiver, backing_store, KindTraits::Kind, capacity); | 1260 receiver, backing_store, KindTraits::Kind, capacity); |
1204 } else { | 1261 } else { |
1205 // push_size is > 0 and new_length <= elms_len, so backing_store cannot be | 1262 // push_size is > 0 and new_length <= elms_len, so backing_store cannot be |
1206 // the empty_fixed_array. | 1263 // the empty_fixed_array. |
1207 new_elms = backing_store; | 1264 new_elms = backing_store; |
1208 } | 1265 } |
1209 | 1266 |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1264 if (add_count < delete_count) { | 1321 if (add_count < delete_count) { |
1265 elms_changed = SpliceShrinkStep(backing_store, heap, start, delete_count, | 1322 elms_changed = SpliceShrinkStep(backing_store, heap, start, delete_count, |
1266 add_count, len, new_length); | 1323 add_count, len, new_length); |
1267 } else if (add_count > delete_count) { | 1324 } else if (add_count > delete_count) { |
1268 elms_changed = | 1325 elms_changed = |
1269 SpliceGrowStep(receiver, backing_store, isolate, heap, start, | 1326 SpliceGrowStep(receiver, backing_store, isolate, heap, start, |
1270 delete_count, add_count, len, new_length); | 1327 delete_count, add_count, len, new_length); |
1271 } | 1328 } |
1272 | 1329 |
1273 // Copy new Elements from args | 1330 // Copy new Elements from args |
1274 if (IsFastDoubleElementsKind(KindTraits::Kind)) { | 1331 DisallowHeapAllocation no_gc; |
1275 for (uint32_t index = start; index < start + add_count; index++) { | 1332 for (uint32_t index = start; index < start + add_count; index++) { |
1276 Object* arg = args[3 + index - start]; | 1333 Object* object = args[3 + index - start]; |
1277 FastElementsAccessorSubclass::SetImpl(*backing_store, index, arg); | 1334 FastElementsAccessorSubclass::SetImpl(*backing_store, index, object); |
1278 } | |
1279 } else { | |
1280 // FastSmiOrObjectElementsKind | |
1281 Handle<FixedArray> elms = Handle<FixedArray>::cast(backing_store); | |
1282 DisallowHeapAllocation no_gc; | |
1283 WriteBarrierMode mode = elms->GetWriteBarrierMode(no_gc); | |
1284 for (uint32_t index = start; index < start + add_count; index++) { | |
1285 elms->set(index, args[3 + index - start], mode); | |
1286 } | |
1287 } | 1335 } |
1288 | 1336 |
1289 if (elms_changed) { | 1337 if (elms_changed) { |
1290 receiver->set_elements(*backing_store); | 1338 receiver->set_elements(*backing_store); |
1291 } | 1339 } |
1292 receiver->set_length(Smi::FromInt(new_length)); | 1340 receiver->set_length(Smi::FromInt(new_length)); |
1293 return deleted_elements; | 1341 return deleted_elements; |
1294 } | 1342 } |
1295 | 1343 |
1296 private: | 1344 private: |
(...skipping 851 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2148 #define ACCESSOR_DELETE(Class, Kind, Store) delete elements_accessors_[Kind]; | 2196 #define ACCESSOR_DELETE(Class, Kind, Store) delete elements_accessors_[Kind]; |
2149 ELEMENTS_LIST(ACCESSOR_DELETE) | 2197 ELEMENTS_LIST(ACCESSOR_DELETE) |
2150 #undef ACCESSOR_DELETE | 2198 #undef ACCESSOR_DELETE |
2151 elements_accessors_ = NULL; | 2199 elements_accessors_ = NULL; |
2152 } | 2200 } |
2153 | 2201 |
2154 | 2202 |
2155 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; | 2203 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; |
2156 } // namespace internal | 2204 } // namespace internal |
2157 } // namespace v8 | 2205 } // namespace v8 |
OLD | NEW |