Chromium Code Reviews| 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 |