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/v8.h" | 5 #include "src/v8.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/elements.h" | 9 #include "src/elements.h" |
10 #include "src/messages.h" | 10 #include "src/messages.h" |
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
238 // existing heap objects to be propertly initialized. | 238 // existing heap objects to be propertly initialized. |
239 int start = to_start; | 239 int start = to_start; |
240 int length = to_base->length() - start; | 240 int length = to_base->length() - start; |
241 if (length > 0) { | 241 if (length > 0) { |
242 Heap* heap = from_base->GetHeap(); | 242 Heap* heap = from_base->GetHeap(); |
243 MemsetPointer(FixedArray::cast(to_base)->data_start() + start, | 243 MemsetPointer(FixedArray::cast(to_base)->data_start() + start, |
244 heap->the_hole_value(), length); | 244 heap->the_hole_value(), length); |
245 } | 245 } |
246 } | 246 } |
247 } | 247 } |
248 | |
248 DCHECK((copy_size + static_cast<int>(to_start)) <= to_base->length() && | 249 DCHECK((copy_size + static_cast<int>(to_start)) <= to_base->length() && |
249 (copy_size + static_cast<int>(from_start)) <= from_base->length()); | 250 (copy_size + static_cast<int>(from_start)) <= from_base->length()); |
250 if (copy_size == 0) return; | 251 if (copy_size == 0) return; |
251 | 252 |
252 // From here on, the code below could actually allocate. Therefore the raw | 253 // From here on, the code below could actually allocate. Therefore the raw |
253 // values are wrapped into handles. | 254 // values are wrapped into handles. |
254 Isolate* isolate = from_base->GetIsolate(); | 255 Isolate* isolate = from_base->GetIsolate(); |
255 Handle<FixedDoubleArray> from(FixedDoubleArray::cast(from_base), isolate); | 256 Handle<FixedDoubleArray> from(FixedDoubleArray::cast(from_base), isolate); |
256 Handle<FixedArray> to(FixedArray::cast(to_base), isolate); | 257 Handle<FixedArray> to(FixedArray::cast(to_base), isolate); |
257 for (int i = 0; i < copy_size; ++i) { | 258 for (int i = 0; i < copy_size; ++i) { |
(...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
564 ElementsAccessorSubclass::AddImpl(object, index, value, attributes, | 565 ElementsAccessorSubclass::AddImpl(object, index, value, attributes, |
565 new_capacity); | 566 new_capacity); |
566 } | 567 } |
567 | 568 |
568 static void AddImpl(Handle<JSObject> object, uint32_t index, | 569 static void AddImpl(Handle<JSObject> object, uint32_t index, |
569 Handle<Object> value, PropertyAttributes attributes, | 570 Handle<Object> value, PropertyAttributes attributes, |
570 uint32_t new_capacity) { | 571 uint32_t new_capacity) { |
571 UNREACHABLE(); | 572 UNREACHABLE(); |
572 } | 573 } |
573 | 574 |
575 virtual uint32_t Push(Handle<JSObject> receiver, | |
576 Handle<FixedArrayBase> backing_store, Object** objects, | |
577 uint32_t start, uint32_t push_size, | |
578 uint32_t direction) { | |
579 return ElementsAccessorSubclass::PushImpl(receiver, backing_store, objects, | |
580 start, push_size, direction); | |
581 } | |
582 | |
583 static uint32_t PushImpl(Handle<JSObject> receiver, | |
584 Handle<FixedArrayBase> elms_obj, Object** objects, | |
585 uint32_t start, uint32_t push_size, | |
586 uint32_t direction) { | |
587 UNREACHABLE(); | |
588 return 0; | |
589 } | |
590 | |
574 virtual void SetLength(Handle<JSArray> array, uint32_t length) final { | 591 virtual void SetLength(Handle<JSArray> array, uint32_t length) final { |
575 ElementsAccessorSubclass::SetLengthImpl(array, length, | 592 ElementsAccessorSubclass::SetLengthImpl(array, length, |
576 handle(array->elements())); | 593 handle(array->elements())); |
577 } | 594 } |
578 | 595 |
579 static void SetLengthImpl(Handle<JSArray> array, uint32_t length, | 596 static void SetLengthImpl(Handle<JSArray> array, uint32_t length, |
580 Handle<FixedArrayBase> backing_store); | 597 Handle<FixedArrayBase> backing_store); |
581 | 598 |
582 static Handle<FixedArrayBase> ConvertElementsWithCapacity( | 599 static Handle<FixedArrayBase> ConvertElementsWithCapacity( |
583 Handle<JSObject> object, Handle<FixedArrayBase> old_elements, | 600 Handle<JSObject> object, Handle<FixedArrayBase> old_elements, |
(...skipping 607 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1191 case FAST_SLOPPY_ARGUMENTS_ELEMENTS: | 1208 case FAST_SLOPPY_ARGUMENTS_ELEMENTS: |
1192 case SLOW_SLOPPY_ARGUMENTS_ELEMENTS: | 1209 case SLOW_SLOPPY_ARGUMENTS_ELEMENTS: |
1193 UNREACHABLE(); | 1210 UNREACHABLE(); |
1194 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ | 1211 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ |
1195 case TYPE##_ELEMENTS: \ | 1212 case TYPE##_ELEMENTS: \ |
1196 UNREACHABLE(); | 1213 UNREACHABLE(); |
1197 TYPED_ARRAYS(TYPED_ARRAY_CASE) | 1214 TYPED_ARRAYS(TYPED_ARRAY_CASE) |
1198 #undef TYPED_ARRAY_CASE | 1215 #undef TYPED_ARRAY_CASE |
1199 } | 1216 } |
1200 } | 1217 } |
1218 | |
1219 static uint32_t PushImpl(Handle<JSObject> receiver, | |
1220 Handle<FixedArrayBase> backing_store, | |
1221 Object** objects, uint32_t start, uint32_t push_size, | |
1222 uint32_t direction) { | |
1223 Handle<JSArray> array = Handle<JSArray>::cast(receiver); | |
Jakob Kummerow
2015/07/30 11:54:59
Just take a Handle<JSArray> (instead of Handle<JSO
| |
1224 int len = Smi::cast(array->length())->value(); | |
Jakob Kummerow
2015/07/30 11:54:59
Let's use the opportunity to clean up the types he
| |
1225 int elms_len = backing_store->length(); | |
1226 if (push_size == 0) { | |
1227 return len; | |
1228 } | |
1229 // Currently fixed arrays cannot grow too big, so | |
1230 // we should never hit this case. | |
1231 DCHECK(static_cast<int>(push_size) <= (Smi::kMaxValue - len)); | |
Jakob Kummerow
2015/07/30 11:54:59
This should cast the other way round:
DCHECK(push
| |
1232 int new_length = len + push_size; | |
1233 Handle<FixedArrayBase> new_elms; | |
1234 | |
1235 if (new_length > elms_len) { | |
1236 // New backing storage is needed. | |
1237 int capacity = new_length + (new_length >> 1) + 16; | |
1238 new_elms = receiver->GetIsolate()->factory()->NewUninitializedFixedArray( | |
Jakob Kummerow
2015/07/30 11:54:59
This should use ElementsAccessorBase::ConvertEleme
| |
1239 capacity); | |
1240 CopyElementsImpl(*backing_store, 0, *new_elms, KindTraits::Kind, 0, | |
1241 kPackedSizeNotKnown, | |
1242 ElementsAccessor::kCopyToEndAndInitializeToHole); | |
1243 } else { | |
1244 // to_add is > 0 and new_length <= elms_len, so elms_obj cannot be the | |
1245 // empty_fixed_array. | |
1246 new_elms = Handle<FixedArray>::cast(backing_store); | |
1247 } | |
1248 | |
1249 // Add the provided values. | |
1250 DisallowHeapAllocation no_gc; | |
1251 WriteBarrierMode mode = new_elms->GetWriteBarrierMode(no_gc); | |
1252 Object* object; | |
1253 int offset; | |
1254 for (uint32_t index = 0; index < push_size; index++) { | |
1255 if (direction == -1) { | |
Jakob Kummerow
2015/07/30 11:54:59
s/-1/kDirectionReverse/
Or consider this:
STATIC
| |
1256 offset = 0 - index - start; | |
1257 } else { | |
1258 offset = index + start; | |
1259 } | |
1260 object = objects[offset]; | |
1261 Handle<FixedArray>::cast(new_elms)->set(index + len, object, mode); | |
Jakob Kummerow
2015/07/30 11:54:59
This should use ElementsAccessorBase::SetImpl to a
| |
1262 } | |
1263 if (*new_elms != array->elements()) { | |
Jakob Kummerow
2015/07/30 11:54:59
if (!new_elms.is_identical_to(backing_store)) {
I
| |
1264 array->set_elements(*new_elms); | |
1265 } | |
1266 // Set the length. | |
1267 array->set_length(Smi::FromInt(new_length)); | |
1268 return new_length; | |
1269 } | |
1201 }; | 1270 }; |
1202 | 1271 |
1203 | 1272 |
1204 class FastPackedSmiElementsAccessor | 1273 class FastPackedSmiElementsAccessor |
1205 : public FastSmiOrObjectElementsAccessor< | 1274 : public FastSmiOrObjectElementsAccessor< |
1206 FastPackedSmiElementsAccessor, | 1275 FastPackedSmiElementsAccessor, |
1207 ElementsKindTraits<FAST_SMI_ELEMENTS> > { | 1276 ElementsKindTraits<FAST_SMI_ELEMENTS> > { |
1208 public: | 1277 public: |
1209 explicit FastPackedSmiElementsAccessor(const char* name) | 1278 explicit FastPackedSmiElementsAccessor(const char* name) |
1210 : FastSmiOrObjectElementsAccessor< | 1279 : FastSmiOrObjectElementsAccessor< |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1287 case SLOW_SLOPPY_ARGUMENTS_ELEMENTS: | 1356 case SLOW_SLOPPY_ARGUMENTS_ELEMENTS: |
1288 UNREACHABLE(); | 1357 UNREACHABLE(); |
1289 | 1358 |
1290 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ | 1359 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ |
1291 case TYPE##_ELEMENTS: \ | 1360 case TYPE##_ELEMENTS: \ |
1292 UNREACHABLE(); | 1361 UNREACHABLE(); |
1293 TYPED_ARRAYS(TYPED_ARRAY_CASE) | 1362 TYPED_ARRAYS(TYPED_ARRAY_CASE) |
1294 #undef TYPED_ARRAY_CASE | 1363 #undef TYPED_ARRAY_CASE |
1295 } | 1364 } |
1296 } | 1365 } |
1366 | |
1367 static uint32_t PushImpl(Handle<JSObject> receiver, | |
Jakob Kummerow
2015/07/30 11:54:59
This is not needed at all if you move the other im
| |
1368 Handle<FixedArrayBase> backing_store, | |
1369 Object** objects, uint32_t start, uint32_t push_size, | |
1370 uint32_t direction) { | |
1371 Handle<JSArray> array = Handle<JSArray>::cast(receiver); | |
1372 int len = Smi::cast(array->length())->value(); | |
1373 int elms_len = backing_store->length(); | |
1374 if (push_size == 0) { | |
1375 return len; | |
1376 } | |
1377 // Currently fixed arrays cannot grow too big, so | |
1378 // we should never hit this case. | |
1379 DCHECK(static_cast<int>(push_size) <= (Smi::kMaxValue - len)); | |
1380 int new_length = len + push_size; | |
1381 Handle<FixedArrayBase> new_elms; | |
1382 | |
1383 if (new_length > elms_len) { | |
1384 // New backing storage is needed. | |
1385 int capacity = new_length + (new_length >> 1) + 16; | |
1386 new_elms = | |
1387 receiver->GetIsolate()->factory()->NewFixedDoubleArray(capacity); | |
1388 CopyElementsImpl(*backing_store, 0, *new_elms, KindTraits::Kind, 0, | |
1389 kPackedSizeNotKnown, | |
1390 ElementsAccessor::kCopyToEndAndInitializeToHole); | |
1391 } else { | |
1392 // to_add is > 0 and new_length <= elms_len, so elms_obj cannot be the | |
1393 // empty_fixed_array. | |
1394 new_elms = Handle<FixedDoubleArray>::cast(backing_store); | |
1395 } | |
1396 | |
1397 // Add the provided values. | |
1398 DisallowHeapAllocation no_gc; | |
1399 int offset; | |
1400 for (uint32_t index = 0; index < push_size; index++) { | |
1401 if (direction == ElementsAccessor::kDirectionReverse) { | |
1402 offset = 0 - index - start; | |
1403 } else { | |
1404 offset = index + start; | |
1405 } | |
1406 Handle<FixedDoubleArray>::cast(new_elms) | |
1407 ->set(index + len, objects[offset]->Number()); | |
1408 } | |
1409 if (*new_elms != array->elements()) { | |
1410 array->set_elements(*new_elms); | |
1411 } | |
1412 // Set the length. | |
1413 array->set_length(Smi::FromInt(new_length)); | |
1414 return new_length; | |
1415 } | |
1297 }; | 1416 }; |
1298 | 1417 |
1299 | 1418 |
1300 class FastPackedDoubleElementsAccessor | 1419 class FastPackedDoubleElementsAccessor |
1301 : public FastDoubleElementsAccessor< | 1420 : public FastDoubleElementsAccessor< |
1302 FastPackedDoubleElementsAccessor, | 1421 FastPackedDoubleElementsAccessor, |
1303 ElementsKindTraits<FAST_DOUBLE_ELEMENTS> > { | 1422 ElementsKindTraits<FAST_DOUBLE_ELEMENTS> > { |
1304 public: | 1423 public: |
1305 explicit FastPackedDoubleElementsAccessor(const char* name) | 1424 explicit FastPackedDoubleElementsAccessor(const char* name) |
1306 : FastDoubleElementsAccessor< | 1425 : FastDoubleElementsAccessor< |
(...skipping 603 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1910 #define ACCESSOR_DELETE(Class, Kind, Store) delete elements_accessors_[Kind]; | 2029 #define ACCESSOR_DELETE(Class, Kind, Store) delete elements_accessors_[Kind]; |
1911 ELEMENTS_LIST(ACCESSOR_DELETE) | 2030 ELEMENTS_LIST(ACCESSOR_DELETE) |
1912 #undef ACCESSOR_DELETE | 2031 #undef ACCESSOR_DELETE |
1913 elements_accessors_ = NULL; | 2032 elements_accessors_ = NULL; |
1914 } | 2033 } |
1915 | 2034 |
1916 | 2035 |
1917 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; | 2036 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; |
1918 } // namespace internal | 2037 } // namespace internal |
1919 } // namespace v8 | 2038 } // namespace v8 |
OLD | NEW |