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 | |
602 virtual Handle<JSArray> Splice(Handle<JSArray> receiver, | 588 virtual Handle<JSArray> Splice(Handle<JSArray> receiver, |
603 Handle<FixedArrayBase> backing_store, | 589 Handle<FixedArrayBase> backing_store, |
604 uint32_t start, uint32_t delete_count, | 590 uint32_t start, uint32_t delete_count, |
605 Arguments args, uint32_t add_count) { | 591 Arguments args, uint32_t add_count) { |
606 return ElementsAccessorSubclass::SpliceImpl(receiver, backing_store, start, | 592 return ElementsAccessorSubclass::SpliceImpl(receiver, backing_store, start, |
607 delete_count, args, add_count); | 593 delete_count, args, add_count); |
608 } | 594 } |
609 | 595 |
610 static Handle<JSArray> SpliceImpl(Handle<JSArray> receiver, | 596 static Handle<JSArray> SpliceImpl(Handle<JSArray> receiver, |
611 Handle<FixedArrayBase> backing_store, | 597 Handle<FixedArrayBase> backing_store, |
(...skipping 576 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1188 if (IsFastSmiElementsKind(KindTraits::Kind)) { | 1174 if (IsFastSmiElementsKind(KindTraits::Kind)) { |
1189 for (int i = 0; i < length; i++) { | 1175 for (int i = 0; i < length; i++) { |
1190 DCHECK(BackingStore::get(backing_store, i)->IsSmi() || | 1176 DCHECK(BackingStore::get(backing_store, i)->IsSmi() || |
1191 (IsFastHoleyElementsKind(KindTraits::Kind) && | 1177 (IsFastHoleyElementsKind(KindTraits::Kind) && |
1192 backing_store->is_the_hole(i))); | 1178 backing_store->is_the_hole(i))); |
1193 } | 1179 } |
1194 } | 1180 } |
1195 #endif | 1181 #endif |
1196 } | 1182 } |
1197 | 1183 |
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 | |
1242 static uint32_t PushImpl(Handle<JSArray> receiver, | 1184 static uint32_t PushImpl(Handle<JSArray> receiver, |
1243 Handle<FixedArrayBase> backing_store, | 1185 Handle<FixedArrayBase> backing_store, |
1244 Object** objects, uint32_t push_size, | 1186 Object** objects, uint32_t push_size, |
1245 int direction) { | 1187 int direction) { |
1246 uint32_t len = Smi::cast(receiver->length())->value(); | 1188 uint32_t len = Smi::cast(receiver->length())->value(); |
1247 if (push_size == 0) { | 1189 if (push_size == 0) { |
1248 return len; | 1190 return len; |
1249 } | 1191 } |
| 1192 uint32_t elms_len = backing_store->length(); |
1250 // Currently fixed arrays cannot grow too big, so | 1193 // Currently fixed arrays cannot grow too big, so |
1251 // we should never hit this case. | 1194 // we should never hit this case. |
1252 DCHECK(push_size <= static_cast<uint32_t>(Smi::kMaxValue - len)); | 1195 DCHECK(push_size <= static_cast<uint32_t>(Smi::kMaxValue - len)); |
1253 uint32_t new_length = len + push_size; | 1196 uint32_t new_length = len + push_size; |
1254 Handle<FixedArrayBase> new_elms; | 1197 Handle<FixedArrayBase> new_elms; |
1255 | 1198 |
1256 if (new_length > static_cast<uint32_t>(backing_store->length())) { | 1199 if (new_length > elms_len) { |
1257 // New backing storage is needed. | 1200 // New backing storage is needed. |
1258 uint32_t capacity = new_length + (new_length >> 1) + 16; | 1201 uint32_t capacity = new_length + (new_length >> 1) + 16; |
1259 new_elms = FastElementsAccessorSubclass::ConvertElementsWithCapacity( | 1202 new_elms = FastElementsAccessorSubclass::ConvertElementsWithCapacity( |
1260 receiver, backing_store, KindTraits::Kind, capacity); | 1203 receiver, backing_store, KindTraits::Kind, capacity); |
1261 } else { | 1204 } else { |
1262 // push_size is > 0 and new_length <= elms_len, so backing_store cannot be | 1205 // push_size is > 0 and new_length <= elms_len, so backing_store cannot be |
1263 // the empty_fixed_array. | 1206 // the empty_fixed_array. |
1264 new_elms = backing_store; | 1207 new_elms = backing_store; |
1265 } | 1208 } |
1266 | 1209 |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1321 if (add_count < delete_count) { | 1264 if (add_count < delete_count) { |
1322 elms_changed = SpliceShrinkStep(backing_store, heap, start, delete_count, | 1265 elms_changed = SpliceShrinkStep(backing_store, heap, start, delete_count, |
1323 add_count, len, new_length); | 1266 add_count, len, new_length); |
1324 } else if (add_count > delete_count) { | 1267 } else if (add_count > delete_count) { |
1325 elms_changed = | 1268 elms_changed = |
1326 SpliceGrowStep(receiver, backing_store, isolate, heap, start, | 1269 SpliceGrowStep(receiver, backing_store, isolate, heap, start, |
1327 delete_count, add_count, len, new_length); | 1270 delete_count, add_count, len, new_length); |
1328 } | 1271 } |
1329 | 1272 |
1330 // Copy new Elements from args | 1273 // Copy new Elements from args |
1331 DisallowHeapAllocation no_gc; | 1274 if (IsFastDoubleElementsKind(KindTraits::Kind)) { |
1332 for (uint32_t index = start; index < start + add_count; index++) { | 1275 for (uint32_t index = start; index < start + add_count; index++) { |
1333 Object* object = args[3 + index - start]; | 1276 Object* arg = args[3 + index - start]; |
1334 FastElementsAccessorSubclass::SetImpl(*backing_store, index, object); | 1277 FastElementsAccessorSubclass::SetImpl(*backing_store, index, arg); |
| 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 } |
1335 } | 1287 } |
1336 | 1288 |
1337 if (elms_changed) { | 1289 if (elms_changed) { |
1338 receiver->set_elements(*backing_store); | 1290 receiver->set_elements(*backing_store); |
1339 } | 1291 } |
1340 receiver->set_length(Smi::FromInt(new_length)); | 1292 receiver->set_length(Smi::FromInt(new_length)); |
1341 return deleted_elements; | 1293 return deleted_elements; |
1342 } | 1294 } |
1343 | 1295 |
1344 private: | 1296 private: |
(...skipping 851 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2196 #define ACCESSOR_DELETE(Class, Kind, Store) delete elements_accessors_[Kind]; | 2148 #define ACCESSOR_DELETE(Class, Kind, Store) delete elements_accessors_[Kind]; |
2197 ELEMENTS_LIST(ACCESSOR_DELETE) | 2149 ELEMENTS_LIST(ACCESSOR_DELETE) |
2198 #undef ACCESSOR_DELETE | 2150 #undef ACCESSOR_DELETE |
2199 elements_accessors_ = NULL; | 2151 elements_accessors_ = NULL; |
2200 } | 2152 } |
2201 | 2153 |
2202 | 2154 |
2203 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; | 2155 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; |
2204 } // namespace internal | 2156 } // namespace internal |
2205 } // namespace v8 | 2157 } // namespace v8 |
OLD | NEW |