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

Side by Side Diff: src/elements.cc

Issue 1159433003: Use GetProperty for getting elements. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 7 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
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 567 matching lines...) Expand 10 before | Expand all | Expand 10 after
578 ElementsAccessorSubclass::ValidateContents(holder, length); 578 ElementsAccessorSubclass::ValidateContents(holder, length);
579 } 579 }
580 580
581 void Validate(Handle<JSObject> holder) final { 581 void Validate(Handle<JSObject> holder) final {
582 DisallowHeapAllocation no_gc; 582 DisallowHeapAllocation no_gc;
583 ElementsAccessorSubclass::ValidateImpl(holder); 583 ElementsAccessorSubclass::ValidateImpl(holder);
584 } 584 }
585 585
586 static bool HasElementImpl(Handle<JSObject> holder, uint32_t key, 586 static bool HasElementImpl(Handle<JSObject> holder, uint32_t key,
587 Handle<FixedArrayBase> backing_store) { 587 Handle<FixedArrayBase> backing_store) {
588 return ElementsAccessorSubclass::GetAttributesImpl(holder, key, 588 return ElementsAccessorSubclass::GetAttributesImpl(
589 backing_store) != ABSENT; 589 *holder, key, *backing_store) != ABSENT;
590 } 590 }
591 591
592 virtual bool HasElement(Handle<JSObject> holder, uint32_t key, 592 virtual bool HasElement(Handle<JSObject> holder, uint32_t key,
593 Handle<FixedArrayBase> backing_store) final { 593 Handle<FixedArrayBase> backing_store) final {
594 return ElementsAccessorSubclass::HasElementImpl(holder, key, backing_store); 594 return ElementsAccessorSubclass::HasElementImpl(holder, key, backing_store);
595 } 595 }
596 596
597 MUST_USE_RESULT virtual MaybeHandle<Object> Get( 597 virtual Handle<Object> Get(Handle<Object> receiver, Handle<JSObject> holder,
598 Handle<Object> receiver, Handle<JSObject> holder, uint32_t key, 598 uint32_t key,
599 Handle<FixedArrayBase> backing_store) final { 599 Handle<FixedArrayBase> backing_store) final {
600 if (!IsExternalArrayElementsKind(ElementsTraits::Kind) && 600 if (!IsExternalArrayElementsKind(ElementsTraits::Kind) &&
601 FLAG_trace_js_array_abuse) { 601 FLAG_trace_js_array_abuse) {
602 CheckArrayAbuse(holder, "elements read", key); 602 CheckArrayAbuse(holder, "elements read", key);
603 } 603 }
604 604
605 if (IsExternalArrayElementsKind(ElementsTraits::Kind) && 605 if (IsExternalArrayElementsKind(ElementsTraits::Kind) &&
606 FLAG_trace_external_array_abuse) { 606 FLAG_trace_external_array_abuse) {
607 CheckArrayAbuse(holder, "external elements read", key); 607 CheckArrayAbuse(holder, "external elements read", key);
608 } 608 }
609 609
610 return ElementsAccessorSubclass::GetImpl( 610 return ElementsAccessorSubclass::GetImpl(
611 receiver, holder, key, backing_store); 611 receiver, holder, key, backing_store);
612 } 612 }
613 613
614 MUST_USE_RESULT static MaybeHandle<Object> GetImpl( 614 static Handle<Object> GetImpl(Handle<Object> receiver, Handle<JSObject> obj,
615 Handle<Object> receiver, 615 uint32_t key,
616 Handle<JSObject> obj, 616 Handle<FixedArrayBase> backing_store) {
617 uint32_t key,
618 Handle<FixedArrayBase> backing_store) {
619 if (key < ElementsAccessorSubclass::GetCapacityImpl(*obj, *backing_store)) { 617 if (key < ElementsAccessorSubclass::GetCapacityImpl(*obj, *backing_store)) {
620 return BackingStore::get(Handle<BackingStore>::cast(backing_store), key); 618 return BackingStore::get(Handle<BackingStore>::cast(backing_store), key);
621 } else { 619 } else {
622 return backing_store->GetIsolate()->factory()->the_hole_value(); 620 return backing_store->GetIsolate()->factory()->the_hole_value();
623 } 621 }
624 } 622 }
625 623
626 MUST_USE_RESULT virtual PropertyAttributes GetAttributes( 624 virtual PropertyAttributes GetAttributes(
627 Handle<JSObject> holder, uint32_t key, 625 JSObject* holder, uint32_t key, FixedArrayBase* backing_store) final {
628 Handle<FixedArrayBase> backing_store) final {
629 return ElementsAccessorSubclass::GetAttributesImpl(holder, key, 626 return ElementsAccessorSubclass::GetAttributesImpl(holder, key,
630 backing_store); 627 backing_store);
631 } 628 }
632 629
633 MUST_USE_RESULT static PropertyAttributes GetAttributesImpl( 630 static PropertyAttributes GetAttributesImpl(JSObject* obj, uint32_t key,
634 Handle<JSObject> obj, 631 FixedArrayBase* backing_store) {
635 uint32_t key, 632 if (key >= ElementsAccessorSubclass::GetCapacityImpl(obj, backing_store)) {
636 Handle<FixedArrayBase> backing_store) {
637 if (key >=
638 ElementsAccessorSubclass::GetCapacityImpl(*obj, *backing_store)) {
639 return ABSENT; 633 return ABSENT;
640 } 634 }
641 return 635 return BackingStore::cast(backing_store)->is_the_hole(key) ? ABSENT : NONE;
642 Handle<BackingStore>::cast(backing_store)->is_the_hole(key)
643 ? ABSENT : NONE;
644 } 636 }
645 637
646 MUST_USE_RESULT virtual MaybeHandle<AccessorPair> GetAccessorPair( 638 virtual MaybeHandle<AccessorPair> GetAccessorPair(
647 Handle<JSObject> holder, uint32_t key, 639 Handle<JSObject> holder, uint32_t key,
648 Handle<FixedArrayBase> backing_store) final { 640 Handle<FixedArrayBase> backing_store) final {
649 return ElementsAccessorSubclass::GetAccessorPairImpl(holder, key, 641 return ElementsAccessorSubclass::GetAccessorPairImpl(holder, key,
650 backing_store); 642 backing_store);
651 } 643 }
652 644
653 MUST_USE_RESULT static MaybeHandle<AccessorPair> GetAccessorPairImpl( 645 static MaybeHandle<AccessorPair> GetAccessorPairImpl(
654 Handle<JSObject> obj, 646 Handle<JSObject> obj, uint32_t key,
655 uint32_t key,
656 Handle<FixedArrayBase> backing_store) { 647 Handle<FixedArrayBase> backing_store) {
657 return MaybeHandle<AccessorPair>(); 648 return MaybeHandle<AccessorPair>();
658 } 649 }
659 650
660 MUST_USE_RESULT virtual MaybeHandle<Object> SetLength( 651 MUST_USE_RESULT virtual MaybeHandle<Object> SetLength(
661 Handle<JSArray> array, Handle<Object> length) final { 652 Handle<JSArray> array, Handle<Object> length) final {
662 return ElementsAccessorSubclass::SetLengthImpl( 653 return ElementsAccessorSubclass::SetLengthImpl(
663 array, length, handle(array->elements())); 654 array, length, handle(array->elements()));
664 } 655 }
665 656
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
727 // intentionally to avoid ArrayConcat() builtin performance degradation. 718 // intentionally to avoid ArrayConcat() builtin performance degradation.
728 // 719 //
729 // Details: The idea is that allocations actually happen only in case of 720 // Details: The idea is that allocations actually happen only in case of
730 // copying from object with fast double elements to object with object 721 // copying from object with fast double elements to object with object
731 // elements. In all the other cases there are no allocations performed and 722 // elements. In all the other cases there are no allocations performed and
732 // handle creation causes noticeable performance degradation of the builtin. 723 // handle creation causes noticeable performance degradation of the builtin.
733 ElementsAccessorSubclass::CopyElementsImpl( 724 ElementsAccessorSubclass::CopyElementsImpl(
734 from, from_start, *to, from_kind, to_start, packed_size, copy_size); 725 from, from_start, *to, from_kind, to_start, packed_size, copy_size);
735 } 726 }
736 727
737 virtual MaybeHandle<FixedArray> AddElementsToFixedArray( 728 virtual Handle<FixedArray> AddElementsToFixedArray(
738 Handle<JSObject> receiver, Handle<FixedArray> to, 729 Handle<JSObject> receiver, Handle<FixedArray> to,
739 FixedArray::KeyFilter filter) final { 730 FixedArray::KeyFilter filter) final {
740 Handle<FixedArrayBase> from(receiver->elements()); 731 Handle<FixedArrayBase> from(receiver->elements());
741 732
742 int len0 = to->length(); 733 int len0 = to->length();
743 #ifdef ENABLE_SLOW_DCHECKS 734 #ifdef ENABLE_SLOW_DCHECKS
744 if (FLAG_enable_slow_asserts) { 735 if (FLAG_enable_slow_asserts) {
745 for (int i = 0; i < len0; i++) { 736 for (int i = 0; i < len0; i++) {
746 DCHECK(!to->get(i)->IsTheHole()); 737 DCHECK(!to->get(i)->IsTheHole());
747 } 738 }
748 } 739 }
749 #endif 740 #endif
750 741
751 // Optimize if 'other' is empty. 742 // Optimize if 'other' is empty.
752 // We cannot optimize if 'this' is empty, as other may have holes. 743 // We cannot optimize if 'this' is empty, as other may have holes.
753 uint32_t len1 = ElementsAccessorSubclass::GetCapacityImpl(*receiver, *from); 744 uint32_t len1 = ElementsAccessorSubclass::GetCapacityImpl(*receiver, *from);
754 if (len1 == 0) return to; 745 if (len1 == 0) return to;
755 746
756 Isolate* isolate = from->GetIsolate(); 747 Isolate* isolate = from->GetIsolate();
757 748
758 // Compute how many elements are not in other. 749 // Compute how many elements are not in other.
759 uint32_t extra = 0; 750 uint32_t extra = 0;
760 for (uint32_t y = 0; y < len1; y++) { 751 for (uint32_t y = 0; y < len1; y++) {
761 uint32_t key = ElementsAccessorSubclass::GetKeyForIndexImpl(*from, y); 752 uint32_t key = ElementsAccessorSubclass::GetKeyForIndexImpl(*from, y);
762 if (ElementsAccessorSubclass::HasElementImpl(receiver, key, from)) { 753 if (ElementsAccessorSubclass::HasElementImpl(receiver, key, from)) {
763 Handle<Object> value; 754 Handle<Object> value =
764 ASSIGN_RETURN_ON_EXCEPTION( 755 ElementsAccessorSubclass::GetImpl(receiver, receiver, key, from);
765 isolate, value,
766 ElementsAccessorSubclass::GetImpl(receiver, receiver, key, from),
767 FixedArray);
768 756
769 DCHECK(!value->IsTheHole()); 757 DCHECK(!value->IsTheHole());
758 DCHECK(!value->IsAccessorPair());
759 DCHECK(!value->IsExecutableAccessorInfo());
770 if (filter == FixedArray::NON_SYMBOL_KEYS && value->IsSymbol()) { 760 if (filter == FixedArray::NON_SYMBOL_KEYS && value->IsSymbol()) {
771 continue; 761 continue;
772 } 762 }
773 if (!HasKey(to, value)) { 763 if (!HasKey(to, value)) {
774 extra++; 764 extra++;
775 } 765 }
776 } 766 }
777 } 767 }
778 768
779 if (extra == 0) return to; 769 if (extra == 0) return to;
780 770
781 // Allocate the result 771 // Allocate the result
782 Handle<FixedArray> result = isolate->factory()->NewFixedArray(len0 + extra); 772 Handle<FixedArray> result = isolate->factory()->NewFixedArray(len0 + extra);
783 773
784 // Fill in the content 774 // Fill in the content
785 { 775 {
786 DisallowHeapAllocation no_gc; 776 DisallowHeapAllocation no_gc;
787 WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc); 777 WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc);
788 for (int i = 0; i < len0; i++) { 778 for (int i = 0; i < len0; i++) {
789 Object* e = to->get(i); 779 Object* e = to->get(i);
790 DCHECK(e->IsString() || e->IsNumber()); 780 DCHECK(e->IsString() || e->IsNumber());
791 result->set(i, e, mode); 781 result->set(i, e, mode);
792 } 782 }
793 } 783 }
794 // Fill in the extra values. 784 // Fill in the extra values.
795 uint32_t index = 0; 785 uint32_t index = 0;
796 for (uint32_t y = 0; y < len1; y++) { 786 for (uint32_t y = 0; y < len1; y++) {
797 uint32_t key = ElementsAccessorSubclass::GetKeyForIndexImpl(*from, y); 787 uint32_t key = ElementsAccessorSubclass::GetKeyForIndexImpl(*from, y);
798 if (ElementsAccessorSubclass::HasElementImpl(receiver, key, from)) { 788 if (ElementsAccessorSubclass::HasElementImpl(receiver, key, from)) {
799 Handle<Object> value; 789 Handle<Object> value =
800 ASSIGN_RETURN_ON_EXCEPTION( 790 ElementsAccessorSubclass::GetImpl(receiver, receiver, key, from);
801 isolate, value, 791 DCHECK(!value->IsAccessorPair());
802 ElementsAccessorSubclass::GetImpl(receiver, receiver, key, from), 792 DCHECK(!value->IsExecutableAccessorInfo());
803 FixedArray);
804 if (filter == FixedArray::NON_SYMBOL_KEYS && value->IsSymbol()) { 793 if (filter == FixedArray::NON_SYMBOL_KEYS && value->IsSymbol()) {
805 continue; 794 continue;
806 } 795 }
807 if (!value->IsTheHole() && !HasKey(to, value)) { 796 if (!value->IsTheHole() && !HasKey(to, value)) {
808 result->set(len0 + index, *value); 797 result->set(len0 + index, *value);
809 index++; 798 index++;
810 } 799 }
811 } 800 }
812 } 801 }
813 DCHECK(extra == index); 802 DCHECK(extra == index);
(...skipping 453 matching lines...) Expand 10 before | Expand all | Expand 10 after
1267 : ElementsAccessorBase<AccessorClass, 1256 : ElementsAccessorBase<AccessorClass,
1268 ElementsKindTraits<Kind> >(name) {} 1257 ElementsKindTraits<Kind> >(name) {}
1269 1258
1270 protected: 1259 protected:
1271 typedef typename ElementsKindTraits<Kind>::BackingStore BackingStore; 1260 typedef typename ElementsKindTraits<Kind>::BackingStore BackingStore;
1272 typedef TypedElementsAccessor<Kind> AccessorClass; 1261 typedef TypedElementsAccessor<Kind> AccessorClass;
1273 1262
1274 friend class ElementsAccessorBase<AccessorClass, 1263 friend class ElementsAccessorBase<AccessorClass,
1275 ElementsKindTraits<Kind> >; 1264 ElementsKindTraits<Kind> >;
1276 1265
1277 MUST_USE_RESULT static MaybeHandle<Object> GetImpl( 1266 static Handle<Object> GetImpl(Handle<Object> receiver, Handle<JSObject> obj,
1278 Handle<Object> receiver, 1267 uint32_t key,
1279 Handle<JSObject> obj, 1268 Handle<FixedArrayBase> backing_store) {
1280 uint32_t key,
1281 Handle<FixedArrayBase> backing_store) {
1282 if (key < AccessorClass::GetCapacityImpl(*obj, *backing_store)) { 1269 if (key < AccessorClass::GetCapacityImpl(*obj, *backing_store)) {
1283 return BackingStore::get(Handle<BackingStore>::cast(backing_store), key); 1270 return BackingStore::get(Handle<BackingStore>::cast(backing_store), key);
1284 } else { 1271 } else {
1285 return backing_store->GetIsolate()->factory()->undefined_value(); 1272 return backing_store->GetIsolate()->factory()->undefined_value();
1286 } 1273 }
1287 } 1274 }
1288 1275
1289 MUST_USE_RESULT static PropertyAttributes GetAttributesImpl( 1276 static PropertyAttributes GetAttributesImpl(JSObject* obj, uint32_t key,
1290 Handle<JSObject> obj, 1277 FixedArrayBase* backing_store) {
1291 uint32_t key, 1278 return key < AccessorClass::GetCapacityImpl(obj, backing_store) ? NONE
1292 Handle<FixedArrayBase> backing_store) { 1279 : ABSENT;
1293 return key < AccessorClass::GetCapacityImpl(*obj, *backing_store) ? NONE
1294 : ABSENT;
1295 } 1280 }
1296 1281
1297 MUST_USE_RESULT static MaybeHandle<Object> SetLengthImpl( 1282 MUST_USE_RESULT static MaybeHandle<Object> SetLengthImpl(
1298 Handle<JSObject> obj, 1283 Handle<JSObject> obj,
1299 Handle<Object> length, 1284 Handle<Object> length,
1300 Handle<FixedArrayBase> backing_store) { 1285 Handle<FixedArrayBase> backing_store) {
1301 // External arrays do not support changing their length. 1286 // External arrays do not support changing their length.
1302 UNREACHABLE(); 1287 UNREACHABLE();
1303 return obj; 1288 return obj;
1304 } 1289 }
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
1455 1440
1456 protected: 1441 protected:
1457 friend class ElementsAccessorBase<DictionaryElementsAccessor, 1442 friend class ElementsAccessorBase<DictionaryElementsAccessor,
1458 ElementsKindTraits<DICTIONARY_ELEMENTS> >; 1443 ElementsKindTraits<DICTIONARY_ELEMENTS> >;
1459 1444
1460 MUST_USE_RESULT virtual MaybeHandle<Object> Delete( 1445 MUST_USE_RESULT virtual MaybeHandle<Object> Delete(
1461 Handle<JSObject> obj, uint32_t key, LanguageMode language_mode) final { 1446 Handle<JSObject> obj, uint32_t key, LanguageMode language_mode) final {
1462 return DeleteCommon(obj, key, language_mode); 1447 return DeleteCommon(obj, key, language_mode);
1463 } 1448 }
1464 1449
1465 MUST_USE_RESULT static MaybeHandle<Object> GetImpl( 1450 static Handle<Object> GetImpl(Handle<Object> receiver, Handle<JSObject> obj,
1466 Handle<Object> receiver, 1451 uint32_t key, Handle<FixedArrayBase> store) {
1467 Handle<JSObject> obj,
1468 uint32_t key,
1469 Handle<FixedArrayBase> store) {
1470 Handle<SeededNumberDictionary> backing_store = 1452 Handle<SeededNumberDictionary> backing_store =
1471 Handle<SeededNumberDictionary>::cast(store); 1453 Handle<SeededNumberDictionary>::cast(store);
1472 Isolate* isolate = backing_store->GetIsolate(); 1454 Isolate* isolate = backing_store->GetIsolate();
1473 int entry = backing_store->FindEntry(key); 1455 int entry = backing_store->FindEntry(key);
1474 if (entry != SeededNumberDictionary::kNotFound) { 1456 if (entry != SeededNumberDictionary::kNotFound) {
1475 Handle<Object> element(backing_store->ValueAt(entry), isolate); 1457 return handle(backing_store->ValueAt(entry), isolate);
1476 PropertyDetails details = backing_store->DetailsAt(entry);
1477 if (details.type() == ACCESSOR_CONSTANT) {
1478 return JSObject::GetElementWithCallback(
1479 obj, receiver, element, key, obj);
1480 } else {
1481 return element;
1482 }
1483 } 1458 }
1484 return isolate->factory()->the_hole_value(); 1459 return isolate->factory()->the_hole_value();
1485 } 1460 }
1486 1461
1487 MUST_USE_RESULT static PropertyAttributes GetAttributesImpl( 1462 static PropertyAttributes GetAttributesImpl(JSObject* obj, uint32_t key,
1488 Handle<JSObject> obj, 1463 FixedArrayBase* backing_store) {
1489 uint32_t key, 1464 SeededNumberDictionary* dictionary =
1490 Handle<FixedArrayBase> backing_store) { 1465 SeededNumberDictionary::cast(backing_store);
1491 Handle<SeededNumberDictionary> dictionary =
1492 Handle<SeededNumberDictionary>::cast(backing_store);
1493 int entry = dictionary->FindEntry(key); 1466 int entry = dictionary->FindEntry(key);
1494 if (entry != SeededNumberDictionary::kNotFound) { 1467 if (entry != SeededNumberDictionary::kNotFound) {
1495 return dictionary->DetailsAt(entry).attributes(); 1468 return dictionary->DetailsAt(entry).attributes();
1496 } 1469 }
1497 return ABSENT; 1470 return ABSENT;
1498 } 1471 }
1499 1472
1500 MUST_USE_RESULT static MaybeHandle<AccessorPair> GetAccessorPairImpl( 1473 static MaybeHandle<AccessorPair> GetAccessorPairImpl(
1501 Handle<JSObject> obj, 1474 Handle<JSObject> obj, uint32_t key, Handle<FixedArrayBase> store) {
1502 uint32_t key,
1503 Handle<FixedArrayBase> store) {
1504 Handle<SeededNumberDictionary> backing_store = 1475 Handle<SeededNumberDictionary> backing_store =
1505 Handle<SeededNumberDictionary>::cast(store); 1476 Handle<SeededNumberDictionary>::cast(store);
1506 int entry = backing_store->FindEntry(key); 1477 int entry = backing_store->FindEntry(key);
1507 if (entry != SeededNumberDictionary::kNotFound && 1478 if (entry != SeededNumberDictionary::kNotFound &&
1508 backing_store->DetailsAt(entry).type() == ACCESSOR_CONSTANT && 1479 backing_store->DetailsAt(entry).type() == ACCESSOR_CONSTANT &&
1509 backing_store->ValueAt(entry)->IsAccessorPair()) { 1480 backing_store->ValueAt(entry)->IsAccessorPair()) {
1510 return handle(AccessorPair::cast(backing_store->ValueAt(entry))); 1481 return handle(AccessorPair::cast(backing_store->ValueAt(entry)));
1511 } 1482 }
1512 return MaybeHandle<AccessorPair>(); 1483 return MaybeHandle<AccessorPair>();
1513 } 1484 }
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1549 public: 1520 public:
1550 explicit SloppyArgumentsElementsAccessor(const char* name) 1521 explicit SloppyArgumentsElementsAccessor(const char* name)
1551 : ElementsAccessorBase< 1522 : ElementsAccessorBase<
1552 SloppyArgumentsElementsAccessor, 1523 SloppyArgumentsElementsAccessor,
1553 ElementsKindTraits<SLOPPY_ARGUMENTS_ELEMENTS> >(name) {} 1524 ElementsKindTraits<SLOPPY_ARGUMENTS_ELEMENTS> >(name) {}
1554 protected: 1525 protected:
1555 friend class ElementsAccessorBase< 1526 friend class ElementsAccessorBase<
1556 SloppyArgumentsElementsAccessor, 1527 SloppyArgumentsElementsAccessor,
1557 ElementsKindTraits<SLOPPY_ARGUMENTS_ELEMENTS> >; 1528 ElementsKindTraits<SLOPPY_ARGUMENTS_ELEMENTS> >;
1558 1529
1559 MUST_USE_RESULT static MaybeHandle<Object> GetImpl( 1530 static Handle<Object> GetImpl(Handle<Object> receiver, Handle<JSObject> obj,
1560 Handle<Object> receiver, 1531 uint32_t key,
1561 Handle<JSObject> obj, 1532 Handle<FixedArrayBase> parameters) {
1562 uint32_t key,
1563 Handle<FixedArrayBase> parameters) {
1564 Isolate* isolate = obj->GetIsolate(); 1533 Isolate* isolate = obj->GetIsolate();
1565 Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(parameters); 1534 Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(parameters);
1566 Handle<Object> probe = GetParameterMapArg(obj, parameter_map, key); 1535 Handle<Object> probe(GetParameterMapArg(*parameter_map, key), isolate);
1567 if (!probe->IsTheHole()) { 1536 if (!probe->IsTheHole()) {
1568 DisallowHeapAllocation no_gc; 1537 DisallowHeapAllocation no_gc;
1569 Context* context = Context::cast(parameter_map->get(0)); 1538 Context* context = Context::cast(parameter_map->get(0));
1570 int context_index = Handle<Smi>::cast(probe)->value(); 1539 int context_index = Handle<Smi>::cast(probe)->value();
1571 DCHECK(!context->get(context_index)->IsTheHole()); 1540 DCHECK(!context->get(context_index)->IsTheHole());
1572 return handle(context->get(context_index), isolate); 1541 return handle(context->get(context_index), isolate);
1573 } else { 1542 } else {
1574 // Object is not mapped, defer to the arguments. 1543 // Object is not mapped, defer to the arguments.
1575 Handle<FixedArray> arguments(FixedArray::cast(parameter_map->get(1)), 1544 Handle<FixedArray> arguments(FixedArray::cast(parameter_map->get(1)),
1576 isolate); 1545 isolate);
1577 Handle<Object> result; 1546 Handle<Object> result = ElementsAccessor::ForArray(arguments)
1578 ASSIGN_RETURN_ON_EXCEPTION( 1547 ->Get(receiver, obj, key, arguments);
1579 isolate, result,
1580 ElementsAccessor::ForArray(arguments)->Get(
1581 receiver, obj, key, arguments),
1582 Object);
1583 // Elements of the arguments object in slow mode might be slow aliases. 1548 // Elements of the arguments object in slow mode might be slow aliases.
1584 if (result->IsAliasedArgumentsEntry()) { 1549 if (result->IsAliasedArgumentsEntry()) {
1585 DisallowHeapAllocation no_gc; 1550 DisallowHeapAllocation no_gc;
1586 AliasedArgumentsEntry* entry = AliasedArgumentsEntry::cast(*result); 1551 AliasedArgumentsEntry* entry = AliasedArgumentsEntry::cast(*result);
1587 Context* context = Context::cast(parameter_map->get(0)); 1552 Context* context = Context::cast(parameter_map->get(0));
1588 int context_index = entry->aliased_context_slot(); 1553 int context_index = entry->aliased_context_slot();
1589 DCHECK(!context->get(context_index)->IsTheHole()); 1554 DCHECK(!context->get(context_index)->IsTheHole());
1590 return handle(context->get(context_index), isolate); 1555 return handle(context->get(context_index), isolate);
1591 } else { 1556 } else {
1592 return result; 1557 return result;
1593 } 1558 }
1594 } 1559 }
1595 } 1560 }
1596 1561
1597 MUST_USE_RESULT static PropertyAttributes GetAttributesImpl( 1562 static PropertyAttributes GetAttributesImpl(JSObject* obj, uint32_t key,
1598 Handle<JSObject> obj, 1563 FixedArrayBase* backing_store) {
1599 uint32_t key, 1564 FixedArray* parameter_map = FixedArray::cast(backing_store);
1600 Handle<FixedArrayBase> backing_store) { 1565 Object* probe = GetParameterMapArg(parameter_map, key);
1601 Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(backing_store);
1602 Handle<Object> probe = GetParameterMapArg(obj, parameter_map, key);
1603 if (!probe->IsTheHole()) { 1566 if (!probe->IsTheHole()) {
1604 return NONE; 1567 return NONE;
1605 } else { 1568 } else {
1606 // If not aliased, check the arguments. 1569 // If not aliased, check the arguments.
1607 Handle<FixedArray> arguments(FixedArray::cast(parameter_map->get(1))); 1570 FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
1608 return ElementsAccessor::ForArray(arguments) 1571 return ElementsAccessor::ForArray(arguments)
1609 ->GetAttributes(obj, key, arguments); 1572 ->GetAttributes(obj, key, arguments);
1610 } 1573 }
1611 } 1574 }
1612 1575
1613 MUST_USE_RESULT static MaybeHandle<AccessorPair> GetAccessorPairImpl( 1576 static MaybeHandle<AccessorPair> GetAccessorPairImpl(
1614 Handle<JSObject> obj, 1577 Handle<JSObject> obj, uint32_t key, Handle<FixedArrayBase> parameters) {
1615 uint32_t key,
1616 Handle<FixedArrayBase> parameters) {
1617 Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(parameters); 1578 Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(parameters);
1618 Handle<Object> probe = GetParameterMapArg(obj, parameter_map, key); 1579 Handle<Object> probe(GetParameterMapArg(*parameter_map, key),
1580 obj->GetIsolate());
1619 if (!probe->IsTheHole()) { 1581 if (!probe->IsTheHole()) {
1620 return MaybeHandle<AccessorPair>(); 1582 return MaybeHandle<AccessorPair>();
1621 } else { 1583 } else {
1622 // If not aliased, check the arguments. 1584 // If not aliased, check the arguments.
1623 Handle<FixedArray> arguments(FixedArray::cast(parameter_map->get(1))); 1585 Handle<FixedArray> arguments(FixedArray::cast(parameter_map->get(1)));
1624 return ElementsAccessor::ForArray(arguments) 1586 return ElementsAccessor::ForArray(arguments)
1625 ->GetAccessorPair(obj, key, arguments); 1587 ->GetAccessorPair(obj, key, arguments);
1626 } 1588 }
1627 } 1589 }
1628 1590
1629 MUST_USE_RESULT static MaybeHandle<Object> SetLengthImpl( 1591 MUST_USE_RESULT static MaybeHandle<Object> SetLengthImpl(
1630 Handle<JSObject> obj, 1592 Handle<JSObject> obj,
1631 Handle<Object> length, 1593 Handle<Object> length,
1632 Handle<FixedArrayBase> parameter_map) { 1594 Handle<FixedArrayBase> parameter_map) {
1633 // TODO(mstarzinger): This was never implemented but will be used once we 1595 // TODO(mstarzinger): This was never implemented but will be used once we
1634 // correctly implement [[DefineOwnProperty]] on arrays. 1596 // correctly implement [[DefineOwnProperty]] on arrays.
1635 UNIMPLEMENTED(); 1597 UNIMPLEMENTED();
1636 return obj; 1598 return obj;
1637 } 1599 }
1638 1600
1639 MUST_USE_RESULT virtual MaybeHandle<Object> Delete( 1601 MUST_USE_RESULT virtual MaybeHandle<Object> Delete(
1640 Handle<JSObject> obj, uint32_t key, LanguageMode language_mode) final { 1602 Handle<JSObject> obj, uint32_t key, LanguageMode language_mode) final {
1641 Isolate* isolate = obj->GetIsolate(); 1603 Isolate* isolate = obj->GetIsolate();
1642 Handle<FixedArray> parameter_map(FixedArray::cast(obj->elements())); 1604 Handle<FixedArray> parameter_map(FixedArray::cast(obj->elements()));
1643 Handle<Object> probe = GetParameterMapArg(obj, parameter_map, key); 1605 Handle<Object> probe(GetParameterMapArg(*parameter_map, key), isolate);
1644 if (!probe->IsTheHole()) { 1606 if (!probe->IsTheHole()) {
1645 // TODO(kmillikin): We could check if this was the last aliased 1607 // TODO(kmillikin): We could check if this was the last aliased
1646 // parameter, and revert to normal elements in that case. That 1608 // parameter, and revert to normal elements in that case. That
1647 // would enable GC of the context. 1609 // would enable GC of the context.
1648 parameter_map->set_the_hole(key + 2); 1610 parameter_map->set_the_hole(key + 2);
1649 } else { 1611 } else {
1650 Handle<FixedArray> arguments(FixedArray::cast(parameter_map->get(1))); 1612 Handle<FixedArray> arguments(FixedArray::cast(parameter_map->get(1)));
1651 if (arguments->IsDictionary()) { 1613 if (arguments->IsDictionary()) {
1652 return DictionaryElementsAccessor::DeleteCommon(obj, key, 1614 return DictionaryElementsAccessor::DeleteCommon(obj, key,
1653 language_mode); 1615 language_mode);
(...skipping 17 matching lines...) Expand all
1671 1633
1672 static uint32_t GetCapacityImpl(JSObject* holder, 1634 static uint32_t GetCapacityImpl(JSObject* holder,
1673 FixedArrayBase* backing_store) { 1635 FixedArrayBase* backing_store) {
1674 FixedArray* parameter_map = FixedArray::cast(backing_store); 1636 FixedArray* parameter_map = FixedArray::cast(backing_store);
1675 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1)); 1637 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1));
1676 return Max(static_cast<uint32_t>(parameter_map->length() - 2), 1638 return Max(static_cast<uint32_t>(parameter_map->length() - 2),
1677 ForArray(arguments)->GetCapacity(holder, arguments)); 1639 ForArray(arguments)->GetCapacity(holder, arguments));
1678 } 1640 }
1679 1641
1680 static uint32_t GetKeyForIndexImpl(FixedArrayBase* dict, uint32_t index) { 1642 static uint32_t GetKeyForIndexImpl(FixedArrayBase* dict, uint32_t index) {
1681 return index; 1643 return index;
Igor Sheludko 2015/05/26 17:11:56 I think we should not break this invariant: DCHECK
1682 } 1644 }
1683 1645
1684 static uint32_t GetIndexForKeyImpl(FixedArrayBase* dict, uint32_t key) { 1646 static uint32_t GetIndexForKeyImpl(FixedArrayBase* parameters, uint32_t key) {
1685 return key; 1647 FixedArray* parameter_map = FixedArray::cast(parameters);
1648 Object* probe = GetParameterMapArg(parameter_map, key);
1649 if (!probe->IsTheHole()) {
1650 return key;
1651 } else {
1652 uint32_t length = parameter_map->length();
1653 FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
1654 return length +
1655 ElementsAccessor::ForArray(arguments)
1656 ->GetIndexForKey(arguments, key);
1657 }
1686 } 1658 }
1687 1659
1688 static PropertyDetails GetDetailsImpl(FixedArrayBase* backing_store, 1660 static PropertyDetails GetDetailsImpl(FixedArrayBase* parameters,
1689 uint32_t index) { 1661 uint32_t index) {
1690 return PropertyDetails(NONE, DATA, 0, PropertyCellType::kNoCell); 1662 FixedArray* parameter_map = FixedArray::cast(parameters);
1663 uint32_t length = parameter_map->length();
1664 if (index < length) {
1665 return PropertyDetails(NONE, DATA, 0, PropertyCellType::kNoCell);
1666 }
1667 index -= length;
1668 FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
1669 return ElementsAccessor::ForArray(arguments)->GetDetails(arguments, index);
1691 } 1670 }
1692 1671
1693
1694 private: 1672 private:
1695 static Handle<Object> GetParameterMapArg(Handle<JSObject> holder, 1673 static Object* GetParameterMapArg(FixedArray* parameter_map, uint32_t key) {
1696 Handle<FixedArray> parameter_map, 1674 uint32_t length = parameter_map->length();
1697 uint32_t key) {
1698 Isolate* isolate = holder->GetIsolate();
1699 uint32_t length = holder->IsJSArray()
1700 ? Smi::cast(Handle<JSArray>::cast(holder)->length())->value()
1701 : parameter_map->length();
1702 return key < (length - 2) 1675 return key < (length - 2)
1703 ? handle(parameter_map->get(key + 2), isolate) 1676 ? parameter_map->get(key + 2)
1704 : Handle<Object>::cast(isolate->factory()->the_hole_value()); 1677 : Object::cast(parameter_map->GetHeap()->the_hole_value());
1705 } 1678 }
1706 }; 1679 };
1707 1680
1708 1681
1709 ElementsAccessor* ElementsAccessor::ForArray(FixedArrayBase* array) { 1682 ElementsAccessor* ElementsAccessor::ForArray(FixedArrayBase* array) {
1710 return elements_accessors_[ElementsKindForArray(array)]; 1683 return elements_accessors_[ElementsKindForArray(array)];
1711 } 1684 }
1712 1685
1713 1686
1714 ElementsAccessor* ElementsAccessor::ForArray(Handle<FixedArrayBase> array) { 1687 ElementsAccessor* ElementsAccessor::ForArray(Handle<FixedArrayBase> array) {
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
1775 } 1748 }
1776 } else { 1749 } else {
1777 return ThrowArrayLengthRangeError(isolate); 1750 return ThrowArrayLengthRangeError(isolate);
1778 } 1751 }
1779 } 1752 }
1780 1753
1781 // Slow case: The new length does not fit into a Smi or conversion 1754 // Slow case: The new length does not fit into a Smi or conversion
1782 // to slow elements is needed for other reasons. 1755 // to slow elements is needed for other reasons.
1783 if (length->IsNumber()) { 1756 if (length->IsNumber()) {
1784 uint32_t value; 1757 uint32_t value;
1785 if (length->ToArrayIndex(&value)) { 1758 if (length->ToArrayLength(&value)) {
1786 Handle<SeededNumberDictionary> dictionary = 1759 Handle<SeededNumberDictionary> dictionary =
1787 JSObject::NormalizeElements(array); 1760 JSObject::NormalizeElements(array);
1788 DCHECK(!dictionary.is_null()); 1761 DCHECK(!dictionary.is_null());
1789 1762
1790 Handle<Object> new_length = DictionaryElementsAccessor:: 1763 Handle<Object> new_length = DictionaryElementsAccessor::
1791 SetLengthWithoutNormalize(dictionary, array, length, value); 1764 SetLengthWithoutNormalize(dictionary, array, length, value);
1792 DCHECK(!new_length.is_null()); 1765 DCHECK(!new_length.is_null());
1793 1766
1794 DCHECK(new_length->IsNumber()); 1767 DCHECK(new_length->IsNumber());
1795 array->set_length(*new_length); 1768 array->set_length(*new_length);
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
1894 UNREACHABLE(); 1867 UNREACHABLE();
1895 break; 1868 break;
1896 } 1869 }
1897 1870
1898 array->set_elements(*elms); 1871 array->set_elements(*elms);
1899 array->set_length(Smi::FromInt(number_of_elements)); 1872 array->set_length(Smi::FromInt(number_of_elements));
1900 return array; 1873 return array;
1901 } 1874 }
1902 1875
1903 } } // namespace v8::internal 1876 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698