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

Side by Side Diff: src/elements.cc

Issue 1230213002: Use entry rather than index in ElementsAccessor::Get (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 5 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
« no previous file with comments | « src/elements.h ('k') | src/lookup.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/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 530 matching lines...) Expand 10 before | Expand all | Expand 10 after
541 DisallowHeapAllocation no_gc; 541 DisallowHeapAllocation no_gc;
542 ElementsAccessorSubclass::ValidateImpl(holder); 542 ElementsAccessorSubclass::ValidateImpl(holder);
543 } 543 }
544 544
545 virtual bool HasElement(Handle<JSObject> holder, uint32_t index, 545 virtual bool HasElement(Handle<JSObject> holder, uint32_t index,
546 Handle<FixedArrayBase> backing_store) final { 546 Handle<FixedArrayBase> backing_store) final {
547 return ElementsAccessorSubclass::GetEntryForIndexImpl( 547 return ElementsAccessorSubclass::GetEntryForIndexImpl(
548 *holder, *backing_store, index) != kMaxUInt32; 548 *holder, *backing_store, index) != kMaxUInt32;
549 } 549 }
550 550
551 virtual Handle<Object> Get(Handle<JSObject> holder, uint32_t index, 551 virtual Handle<Object> Get(Handle<FixedArrayBase> backing_store,
552 Handle<FixedArrayBase> backing_store) final { 552 uint32_t entry) final {
553 if (!IsExternalArrayElementsKind(ElementsTraits::Kind) && 553 return ElementsAccessorSubclass::GetImpl(backing_store, entry);
554 FLAG_trace_js_array_abuse) {
555 CheckArrayAbuse(holder, "elements read", index);
556 }
557
558 if (IsExternalArrayElementsKind(ElementsTraits::Kind) &&
559 FLAG_trace_external_array_abuse) {
560 CheckArrayAbuse(holder, "external elements read", index);
561 }
562
563 return ElementsAccessorSubclass::GetImpl(holder, index, backing_store);
564 } 554 }
565 555
566 static Handle<Object> GetImpl(Handle<JSObject> obj, uint32_t index, 556 static Handle<Object> GetImpl(Handle<FixedArrayBase> backing_store,
567 Handle<FixedArrayBase> backing_store) { 557 uint32_t entry) {
568 if (index < 558 uint32_t index = GetIndexForEntryImpl(*backing_store, entry);
569 ElementsAccessorSubclass::GetCapacityImpl(*obj, *backing_store)) { 559 return BackingStore::get(Handle<BackingStore>::cast(backing_store), index);
570 return BackingStore::get(Handle<BackingStore>::cast(backing_store),
571 index);
572 } else {
573 return backing_store->GetIsolate()->factory()->the_hole_value();
574 }
575 } 560 }
576 561
577 virtual void Set(FixedArrayBase* backing_store, uint32_t entry, 562 virtual void Set(FixedArrayBase* backing_store, uint32_t entry,
578 Object* value) final { 563 Object* value) final {
579 ElementsAccessorSubclass::SetImpl(backing_store, entry, value); 564 ElementsAccessorSubclass::SetImpl(backing_store, entry, value);
580 } 565 }
581 566
582 static void SetImpl(FixedArrayBase* backing_store, uint32_t entry, 567 static void SetImpl(FixedArrayBase* backing_store, uint32_t entry,
583 Object* value) { 568 Object* value) {
584 BackingStore::cast(backing_store)->SetValue(entry, value); 569 BackingStore::cast(backing_store)->SetValue(entry, value);
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
751 // We cannot optimize if 'this' is empty, as other may have holes. 736 // We cannot optimize if 'this' is empty, as other may have holes.
752 uint32_t len1 = ElementsAccessorSubclass::GetCapacityImpl(*receiver, *from); 737 uint32_t len1 = ElementsAccessorSubclass::GetCapacityImpl(*receiver, *from);
753 if (len1 == 0) return to; 738 if (len1 == 0) return to;
754 739
755 Isolate* isolate = from->GetIsolate(); 740 Isolate* isolate = from->GetIsolate();
756 741
757 // Compute how many elements are not in other. 742 // Compute how many elements are not in other.
758 uint32_t extra = 0; 743 uint32_t extra = 0;
759 for (uint32_t y = 0; y < len1; y++) { 744 for (uint32_t y = 0; y < len1; y++) {
760 if (ElementsAccessorSubclass::HasEntryImpl(*from, y)) { 745 if (ElementsAccessorSubclass::HasEntryImpl(*from, y)) {
761 uint32_t index = 746 Handle<Object> value = ElementsAccessorSubclass::GetImpl(from, y);
762 ElementsAccessorSubclass::GetIndexForEntryImpl(*from, y);
763 Handle<Object> value =
764 ElementsAccessorSubclass::GetImpl(receiver, index, from);
765 747
766 DCHECK(!value->IsTheHole()); 748 DCHECK(!value->IsTheHole());
767 DCHECK(!value->IsAccessorPair()); 749 DCHECK(!value->IsAccessorPair());
768 DCHECK(!value->IsExecutableAccessorInfo()); 750 DCHECK(!value->IsExecutableAccessorInfo());
769 if (filter == FixedArray::NON_SYMBOL_KEYS && value->IsSymbol()) { 751 if (filter == FixedArray::NON_SYMBOL_KEYS && value->IsSymbol()) {
770 continue; 752 continue;
771 } 753 }
772 if (!HasIndex(to, value)) { 754 if (!HasIndex(to, value)) {
773 extra++; 755 extra++;
774 } 756 }
(...skipping 12 matching lines...) Expand all
787 for (int i = 0; i < len0; i++) { 769 for (int i = 0; i < len0; i++) {
788 Object* e = to->get(i); 770 Object* e = to->get(i);
789 DCHECK(e->IsString() || e->IsNumber()); 771 DCHECK(e->IsString() || e->IsNumber());
790 result->set(i, e, mode); 772 result->set(i, e, mode);
791 } 773 }
792 } 774 }
793 // Fill in the extra values. 775 // Fill in the extra values.
794 uint32_t entry = 0; 776 uint32_t entry = 0;
795 for (uint32_t y = 0; y < len1; y++) { 777 for (uint32_t y = 0; y < len1; y++) {
796 if (ElementsAccessorSubclass::HasEntryImpl(*from, y)) { 778 if (ElementsAccessorSubclass::HasEntryImpl(*from, y)) {
797 uint32_t index = 779 Handle<Object> value = ElementsAccessorSubclass::GetImpl(from, y);
798 ElementsAccessorSubclass::GetIndexForEntryImpl(*from, y);
799 Handle<Object> value =
800 ElementsAccessorSubclass::GetImpl(receiver, index, from);
801 DCHECK(!value->IsAccessorPair()); 780 DCHECK(!value->IsAccessorPair());
802 DCHECK(!value->IsExecutableAccessorInfo()); 781 DCHECK(!value->IsExecutableAccessorInfo());
803 if (filter == FixedArray::NON_SYMBOL_KEYS && value->IsSymbol()) { 782 if (filter == FixedArray::NON_SYMBOL_KEYS && value->IsSymbol()) {
804 continue; 783 continue;
805 } 784 }
806 if (!value->IsTheHole() && !HasIndex(to, value)) { 785 if (!value->IsTheHole() && !HasIndex(to, value)) {
807 result->set(len0 + entry, *value); 786 result->set(len0 + entry, *value);
808 entry++; 787 entry++;
809 } 788 }
810 } 789 }
(...skipping 16 matching lines...) Expand all
827 } 806 }
828 807
829 static uint32_t GetIndexForEntryImpl(FixedArrayBase* backing_store, 808 static uint32_t GetIndexForEntryImpl(FixedArrayBase* backing_store,
830 uint32_t entry) { 809 uint32_t entry) {
831 return entry; 810 return entry;
832 } 811 }
833 812
834 static uint32_t GetEntryForIndexImpl(JSObject* holder, 813 static uint32_t GetEntryForIndexImpl(JSObject* holder,
835 FixedArrayBase* backing_store, 814 FixedArrayBase* backing_store,
836 uint32_t index) { 815 uint32_t index) {
837 return index < ElementsAccessorSubclass::GetCapacityImpl(holder, 816 if (IsHoleyElementsKind(kind())) {
838 backing_store) && 817 return index < ElementsAccessorSubclass::GetCapacityImpl(holder,
839 !BackingStore::cast(backing_store)->is_the_hole(index) 818 backing_store) &&
840 ? index 819 !BackingStore::cast(backing_store)->is_the_hole(index)
841 : kMaxUInt32; 820 ? index
821 : kMaxUInt32;
822 } else {
823 Smi* smi_length = Smi::cast(JSArray::cast(holder)->length());
824 uint32_t length = static_cast<uint32_t>(smi_length->value());
825 return index < length ? index : kMaxUInt32;
826 }
842 } 827 }
843 828
844 virtual uint32_t GetEntryForIndex(JSObject* holder, 829 virtual uint32_t GetEntryForIndex(JSObject* holder,
845 FixedArrayBase* backing_store, 830 FixedArrayBase* backing_store,
846 uint32_t index) final { 831 uint32_t index) final {
847 return ElementsAccessorSubclass::GetEntryForIndexImpl(holder, backing_store, 832 return ElementsAccessorSubclass::GetEntryForIndexImpl(holder, backing_store,
848 index); 833 index);
849 } 834 }
850 835
851 static PropertyDetails GetDetailsImpl(FixedArrayBase* backing_store, 836 static PropertyDetails GetDetailsImpl(FixedArrayBase* backing_store,
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
938 SeededNumberDictionary::cast(obj->elements())); 923 SeededNumberDictionary::cast(obj->elements()));
939 uint32_t index = GetIndexForEntryImpl(*dict, entry); 924 uint32_t index = GetIndexForEntryImpl(*dict, entry);
940 Handle<Object> result = SeededNumberDictionary::DeleteProperty(dict, entry); 925 Handle<Object> result = SeededNumberDictionary::DeleteProperty(dict, entry);
941 USE(result); 926 USE(result);
942 DCHECK(result->IsTrue()); 927 DCHECK(result->IsTrue());
943 Handle<FixedArray> new_elements = 928 Handle<FixedArray> new_elements =
944 SeededNumberDictionary::Shrink(dict, index); 929 SeededNumberDictionary::Shrink(dict, index);
945 obj->set_elements(*new_elements); 930 obj->set_elements(*new_elements);
946 } 931 }
947 932
948 static Handle<Object> GetImpl(Handle<JSObject> obj, uint32_t index, 933 static Handle<Object> GetImpl(Handle<FixedArrayBase> store, uint32_t entry) {
949 Handle<FixedArrayBase> store) {
950 Handle<SeededNumberDictionary> backing_store = 934 Handle<SeededNumberDictionary> backing_store =
951 Handle<SeededNumberDictionary>::cast(store); 935 Handle<SeededNumberDictionary>::cast(store);
952 Isolate* isolate = backing_store->GetIsolate(); 936 Isolate* isolate = backing_store->GetIsolate();
953 int entry = backing_store->FindEntry(index); 937 return handle(backing_store->ValueAt(entry), isolate);
954 if (entry != SeededNumberDictionary::kNotFound) {
955 return handle(backing_store->ValueAt(entry), isolate);
956 }
957 return isolate->factory()->the_hole_value();
958 } 938 }
959 939
960 static void SetImpl(FixedArrayBase* store, uint32_t entry, Object* value) { 940 static void SetImpl(FixedArrayBase* store, uint32_t entry, Object* value) {
961 SeededNumberDictionary* dictionary = SeededNumberDictionary::cast(store); 941 SeededNumberDictionary* dictionary = SeededNumberDictionary::cast(store);
962 dictionary->ValueAtPut(entry, value); 942 dictionary->ValueAtPut(entry, value);
963 } 943 }
964 944
965 static void ReconfigureImpl(Handle<JSObject> object, 945 static void ReconfigureImpl(Handle<JSObject> object,
966 Handle<FixedArrayBase> store, uint32_t entry, 946 Handle<FixedArrayBase> store, uint32_t entry,
967 Handle<Object> value, 947 Handle<Object> value,
(...skipping 398 matching lines...) Expand 10 before | Expand all | Expand 10 after
1366 : public ElementsAccessorBase<TypedElementsAccessor<Kind>, 1346 : public ElementsAccessorBase<TypedElementsAccessor<Kind>,
1367 ElementsKindTraits<Kind> > { 1347 ElementsKindTraits<Kind> > {
1368 public: 1348 public:
1369 explicit TypedElementsAccessor(const char* name) 1349 explicit TypedElementsAccessor(const char* name)
1370 : ElementsAccessorBase<AccessorClass, 1350 : ElementsAccessorBase<AccessorClass,
1371 ElementsKindTraits<Kind> >(name) {} 1351 ElementsKindTraits<Kind> >(name) {}
1372 1352
1373 typedef typename ElementsKindTraits<Kind>::BackingStore BackingStore; 1353 typedef typename ElementsKindTraits<Kind>::BackingStore BackingStore;
1374 typedef TypedElementsAccessor<Kind> AccessorClass; 1354 typedef TypedElementsAccessor<Kind> AccessorClass;
1375 1355
1376 static Handle<Object> GetImpl(Handle<JSObject> obj, uint32_t index, 1356 static Handle<Object> GetImpl(Handle<FixedArrayBase> backing_store,
1377 Handle<FixedArrayBase> backing_store) { 1357 uint32_t entry) {
1378 if (index < AccessorClass::GetCapacityImpl(*obj, *backing_store)) { 1358 uint32_t index = GetIndexForEntryImpl(*backing_store, entry);
1379 return BackingStore::get(Handle<BackingStore>::cast(backing_store), 1359 return BackingStore::get(Handle<BackingStore>::cast(backing_store), index);
1380 index);
1381 } else {
1382 return backing_store->GetIsolate()->factory()->undefined_value();
1383 }
1384 } 1360 }
1385 1361
1386 static PropertyDetails GetDetailsImpl(FixedArrayBase* backing_store, 1362 static PropertyDetails GetDetailsImpl(FixedArrayBase* backing_store,
1387 uint32_t entry) { 1363 uint32_t entry) {
1388 return PropertyDetails(DONT_DELETE, DATA, 0, PropertyCellType::kNoCell); 1364 return PropertyDetails(DONT_DELETE, DATA, 0, PropertyCellType::kNoCell);
1389 } 1365 }
1390 1366
1391 static void SetLengthImpl(Handle<JSArray> array, uint32_t length, 1367 static void SetLengthImpl(Handle<JSArray> array, uint32_t length,
1392 Handle<FixedArrayBase> backing_store) { 1368 Handle<FixedArrayBase> backing_store) {
1393 // External arrays do not support changing their length. 1369 // External arrays do not support changing their length.
1394 UNREACHABLE(); 1370 UNREACHABLE();
1395 } 1371 }
1396 1372
1397 static void DeleteImpl(Handle<JSObject> obj, uint32_t entry) { 1373 static void DeleteImpl(Handle<JSObject> obj, uint32_t entry) {
1398 UNREACHABLE(); 1374 UNREACHABLE();
1399 } 1375 }
1400 1376
1377 static uint32_t GetIndexForEntryImpl(FixedArrayBase* backing_store,
1378 uint32_t entry) {
1379 return entry;
1380 }
1381
1401 static uint32_t GetEntryForIndexImpl(JSObject* holder, 1382 static uint32_t GetEntryForIndexImpl(JSObject* holder,
1402 FixedArrayBase* backing_store, 1383 FixedArrayBase* backing_store,
1403 uint32_t index) { 1384 uint32_t index) {
1404 return index < AccessorClass::GetCapacityImpl(holder, backing_store) 1385 return index < AccessorClass::GetCapacityImpl(holder, backing_store)
1405 ? index 1386 ? index
1406 : kMaxUInt32; 1387 : kMaxUInt32;
1407 } 1388 }
1408 1389
1409 static uint32_t GetCapacityImpl(JSObject* holder, 1390 static uint32_t GetCapacityImpl(JSObject* holder,
1410 FixedArrayBase* backing_store) { 1391 FixedArrayBase* backing_store) {
(...skipping 21 matching lines...) Expand all
1432 1413
1433 1414
1434 template <typename SloppyArgumentsElementsAccessorSubclass, 1415 template <typename SloppyArgumentsElementsAccessorSubclass,
1435 typename ArgumentsAccessor, typename KindTraits> 1416 typename ArgumentsAccessor, typename KindTraits>
1436 class SloppyArgumentsElementsAccessor 1417 class SloppyArgumentsElementsAccessor
1437 : public ElementsAccessorBase<SloppyArgumentsElementsAccessorSubclass, 1418 : public ElementsAccessorBase<SloppyArgumentsElementsAccessorSubclass,
1438 KindTraits> { 1419 KindTraits> {
1439 public: 1420 public:
1440 explicit SloppyArgumentsElementsAccessor(const char* name) 1421 explicit SloppyArgumentsElementsAccessor(const char* name)
1441 : ElementsAccessorBase<SloppyArgumentsElementsAccessorSubclass, 1422 : ElementsAccessorBase<SloppyArgumentsElementsAccessorSubclass,
1442 KindTraits>(name) {} 1423 KindTraits>(name) {
1424 USE(KindTraits::Kind);
1425 }
1443 1426
1444 static Handle<Object> GetImpl(Handle<JSObject> obj, uint32_t index, 1427 static Handle<Object> GetImpl(Handle<FixedArrayBase> parameters,
1445 Handle<FixedArrayBase> parameters) { 1428 uint32_t entry) {
1446 Isolate* isolate = obj->GetIsolate(); 1429 Isolate* isolate = parameters->GetIsolate();
1447 Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(parameters); 1430 Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(parameters);
1448 Handle<Object> probe(GetParameterMapArg(*parameter_map, index), isolate); 1431 uint32_t length = parameter_map->length() - 2;
1449 if (!probe->IsTheHole()) { 1432 if (entry < length) {
1450 DisallowHeapAllocation no_gc; 1433 DisallowHeapAllocation no_gc;
1434 Object* probe = parameter_map->get(entry + 2);
1451 Context* context = Context::cast(parameter_map->get(0)); 1435 Context* context = Context::cast(parameter_map->get(0));
1452 int context_entry = Handle<Smi>::cast(probe)->value(); 1436 int context_entry = Smi::cast(probe)->value();
1453 DCHECK(!context->get(context_entry)->IsTheHole()); 1437 DCHECK(!context->get(context_entry)->IsTheHole());
1454 return handle(context->get(context_entry), isolate); 1438 return handle(context->get(context_entry), isolate);
1455 } else { 1439 } else {
1456 // Object is not mapped, defer to the arguments. 1440 // Object is not mapped, defer to the arguments.
1457 Handle<FixedArray> arguments(FixedArray::cast(parameter_map->get(1)), 1441 Handle<FixedArray> arguments(FixedArray::cast(parameter_map->get(1)),
1458 isolate); 1442 isolate);
1459 Handle<Object> result = ArgumentsAccessor::GetImpl(obj, index, arguments); 1443 Handle<Object> result =
1444 ArgumentsAccessor::GetImpl(arguments, entry - length);
1460 // Elements of the arguments object in slow mode might be slow aliases. 1445 // Elements of the arguments object in slow mode might be slow aliases.
1461 if (result->IsAliasedArgumentsEntry()) { 1446 if (result->IsAliasedArgumentsEntry()) {
1462 DisallowHeapAllocation no_gc; 1447 DisallowHeapAllocation no_gc;
1463 AliasedArgumentsEntry* entry = AliasedArgumentsEntry::cast(*result); 1448 AliasedArgumentsEntry* entry = AliasedArgumentsEntry::cast(*result);
1464 Context* context = Context::cast(parameter_map->get(0)); 1449 Context* context = Context::cast(parameter_map->get(0));
1465 int context_entry = entry->aliased_context_slot(); 1450 int context_entry = entry->aliased_context_slot();
1466 DCHECK(!context->get(context_entry)->IsTheHole()); 1451 DCHECK(!context->get(context_entry)->IsTheHole());
1467 return handle(context->get(context_entry), isolate); 1452 return handle(context->get(context_entry), isolate);
1468 } else {
1469 return result;
1470 } 1453 }
1454 return result;
1471 } 1455 }
1472 } 1456 }
1473 1457
1474 static void GrowCapacityAndConvertImpl(Handle<JSObject> object, 1458 static void GrowCapacityAndConvertImpl(Handle<JSObject> object,
1475 uint32_t capacity) { 1459 uint32_t capacity) {
1476 UNREACHABLE(); 1460 UNREACHABLE();
1477 } 1461 }
1478 1462
1479 static void SetImpl(FixedArrayBase* store, uint32_t entry, Object* value) { 1463 static void SetImpl(FixedArrayBase* store, uint32_t entry, Object* value) {
1480 FixedArray* parameter_map = FixedArray::cast(store); 1464 FixedArray* parameter_map = FixedArray::cast(store);
(...skipping 454 matching lines...) Expand 10 before | Expand all | Expand 10 after
1935 #define ACCESSOR_DELETE(Class, Kind, Store) delete elements_accessors_[Kind]; 1919 #define ACCESSOR_DELETE(Class, Kind, Store) delete elements_accessors_[Kind];
1936 ELEMENTS_LIST(ACCESSOR_DELETE) 1920 ELEMENTS_LIST(ACCESSOR_DELETE)
1937 #undef ACCESSOR_DELETE 1921 #undef ACCESSOR_DELETE
1938 elements_accessors_ = NULL; 1922 elements_accessors_ = NULL;
1939 } 1923 }
1940 1924
1941 1925
1942 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; 1926 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL;
1943 } // namespace internal 1927 } // namespace internal
1944 } // namespace v8 1928 } // namespace v8
OLDNEW
« no previous file with comments | « src/elements.h ('k') | src/lookup.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698