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

Side by Side Diff: src/type-feedback-vector.cc

Issue 1316953003: Vector ICs: Make the Oracle gather feedback for vector stores. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Slight update. Created 5 years, 3 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/type-feedback-vector.h ('k') | src/type-info.h » ('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 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 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/type-feedback-vector.h" 5 #include "src/type-feedback-vector.h"
6 6
7 #include "src/code-stubs.h" 7 #include "src/code-stubs.h"
8 #include "src/ic/ic.h" 8 #include "src/ic/ic.h"
9 #include "src/ic/ic-state.h" 9 #include "src/ic/ic-state.h"
10 #include "src/objects.h" 10 #include "src/objects.h"
(...skipping 566 matching lines...) Expand 10 before | Expand all | Expand 10 after
577 SKIP_WRITE_BARRIER); 577 SKIP_WRITE_BARRIER);
578 } else { 578 } else {
579 SetFeedback(*name); 579 SetFeedback(*name);
580 array = EnsureExtraArrayOfSize(receiver_count * 2); 580 array = EnsureExtraArrayOfSize(receiver_count * 2);
581 } 581 }
582 582
583 InstallHandlers(array, maps, handlers); 583 InstallHandlers(array, maps, handlers);
584 } 584 }
585 585
586 586
587 void KeyedStoreICNexus::ConfigurePolymorphic(MapHandleList* maps,
588 MapHandleList* transitioned_maps,
589 CodeHandleList* handlers) {
590 int receiver_count = maps->length();
591 DCHECK(receiver_count > 1);
592 Handle<FixedArray> array = EnsureArrayOfSize(receiver_count * 3);
593 SetFeedbackExtra(*TypeFeedbackVector::UninitializedSentinel(GetIsolate()),
594 SKIP_WRITE_BARRIER);
595
596 Handle<Oddball> undefined_value = GetIsolate()->factory()->undefined_value();
597 for (int i = 0; i < receiver_count; ++i) {
598 Handle<Map> map = maps->at(i);
599 Handle<WeakCell> cell = Map::WeakCellForMap(map);
600 array->set(i * 3, *cell);
601 if (!transitioned_maps->at(i).is_null()) {
602 Handle<Map> transitioned_map = transitioned_maps->at(i);
603 cell = Map::WeakCellForMap(transitioned_map);
604 array->set((i * 3) + 1, *cell);
605 } else {
606 array->set((i * 3) + 1, *undefined_value);
607 }
608 array->set((i * 3) + 2, *handlers->at(i));
609 }
610 }
611
612
587 int FeedbackNexus::ExtractMaps(MapHandleList* maps) const { 613 int FeedbackNexus::ExtractMaps(MapHandleList* maps) const {
588 Isolate* isolate = GetIsolate(); 614 Isolate* isolate = GetIsolate();
589 Object* feedback = GetFeedback(); 615 Object* feedback = GetFeedback();
590 if (feedback->IsFixedArray() || feedback->IsString()) { 616 if (feedback->IsFixedArray() || feedback->IsString()) {
591 int found = 0; 617 int found = 0;
592 if (feedback->IsString()) { 618 if (feedback->IsString()) {
593 feedback = GetFeedbackExtra(); 619 feedback = GetFeedbackExtra();
594 } 620 }
595 FixedArray* array = FixedArray::cast(feedback); 621 FixedArray* array = FixedArray::cast(feedback);
596 // The array should be of the form [<optional name>], then 622 // The array should be of the form
597 // [map, handler, map, handler, ... ] 623 // [map, handler, map, handler, ...]
624 // or
625 // [map, map, handler, map, map, handler, ...]
598 DCHECK(array->length() >= 2); 626 DCHECK(array->length() >= 2);
599 for (int i = 0; i < array->length(); i += 2) { 627 int increment = array->get(1)->IsCode() ? 2 : 3;
628 for (int i = 0; i < array->length(); i += increment) {
600 DCHECK(array->get(i)->IsWeakCell()); 629 DCHECK(array->get(i)->IsWeakCell());
601 WeakCell* cell = WeakCell::cast(array->get(i)); 630 WeakCell* cell = WeakCell::cast(array->get(i));
602 if (!cell->cleared()) { 631 if (!cell->cleared()) {
603 Map* map = Map::cast(cell->value()); 632 Map* map = Map::cast(cell->value());
604 maps->Add(handle(map, isolate)); 633 maps->Add(handle(map, isolate));
605 found++; 634 found++;
606 } 635 }
607 } 636 }
608 return found; 637 return found;
609 } else if (feedback->IsWeakCell()) { 638 } else if (feedback->IsWeakCell()) {
610 WeakCell* cell = WeakCell::cast(feedback); 639 WeakCell* cell = WeakCell::cast(feedback);
611 if (!cell->cleared()) { 640 if (!cell->cleared()) {
612 Map* map = Map::cast(cell->value()); 641 Map* map = Map::cast(cell->value());
613 maps->Add(handle(map, isolate)); 642 maps->Add(handle(map, isolate));
614 return 1; 643 return 1;
615 } 644 }
616 } 645 }
617 646
618 return 0; 647 return 0;
619 } 648 }
620 649
621 650
622 MaybeHandle<Code> FeedbackNexus::FindHandlerForMap(Handle<Map> map) const { 651 MaybeHandle<Code> FeedbackNexus::FindHandlerForMap(Handle<Map> map) const {
623 Object* feedback = GetFeedback(); 652 Object* feedback = GetFeedback();
624 if (feedback->IsFixedArray() || feedback->IsString()) { 653 if (feedback->IsFixedArray() || feedback->IsString()) {
625 if (feedback->IsString()) { 654 if (feedback->IsString()) {
626 feedback = GetFeedbackExtra(); 655 feedback = GetFeedbackExtra();
627 } 656 }
628 FixedArray* array = FixedArray::cast(feedback); 657 FixedArray* array = FixedArray::cast(feedback);
629 for (int i = 0; i < array->length(); i += 2) { 658 DCHECK(array->length() >= 2);
659 int increment = array->get(1)->IsCode() ? 2 : 3;
660 for (int i = 0; i < array->length(); i += increment) {
630 DCHECK(array->get(i)->IsWeakCell()); 661 DCHECK(array->get(i)->IsWeakCell());
631 WeakCell* cell = WeakCell::cast(array->get(i)); 662 WeakCell* cell = WeakCell::cast(array->get(i));
632 if (!cell->cleared()) { 663 if (!cell->cleared()) {
633 Map* array_map = Map::cast(cell->value()); 664 Map* array_map = Map::cast(cell->value());
634 if (array_map == *map) { 665 if (array_map == *map) {
635 Code* code = Code::cast(array->get(i + 1)); 666 Code* code = Code::cast(array->get(i + increment - 1));
636 DCHECK(code->kind() == Code::HANDLER); 667 DCHECK(code->kind() == Code::HANDLER);
637 return handle(code); 668 return handle(code);
638 } 669 }
639 } 670 }
640 } 671 }
641 } else if (feedback->IsWeakCell()) { 672 } else if (feedback->IsWeakCell()) {
642 WeakCell* cell = WeakCell::cast(feedback); 673 WeakCell* cell = WeakCell::cast(feedback);
643 if (!cell->cleared()) { 674 if (!cell->cleared()) {
644 Map* cell_map = Map::cast(cell->value()); 675 Map* cell_map = Map::cast(cell->value());
645 if (cell_map == *map) { 676 if (cell_map == *map) {
646 Code* code = Code::cast(GetFeedbackExtra()); 677 Code* code = Code::cast(GetFeedbackExtra());
647 DCHECK(code->kind() == Code::HANDLER); 678 DCHECK(code->kind() == Code::HANDLER);
648 return handle(code); 679 return handle(code);
649 } 680 }
650 } 681 }
651 } 682 }
652 683
653 return MaybeHandle<Code>(); 684 return MaybeHandle<Code>();
654 } 685 }
655 686
656 687
657 bool FeedbackNexus::FindHandlers(CodeHandleList* code_list, int length) const { 688 bool FeedbackNexus::FindHandlers(CodeHandleList* code_list, int length) const {
658 Object* feedback = GetFeedback(); 689 Object* feedback = GetFeedback();
659 int count = 0; 690 int count = 0;
660 if (feedback->IsFixedArray() || feedback->IsString()) { 691 if (feedback->IsFixedArray() || feedback->IsString()) {
661 if (feedback->IsString()) { 692 if (feedback->IsString()) {
662 feedback = GetFeedbackExtra(); 693 feedback = GetFeedbackExtra();
663 } 694 }
664 FixedArray* array = FixedArray::cast(feedback); 695 FixedArray* array = FixedArray::cast(feedback);
665 // The array should be of the form [map, handler, map, handler, ... ]. 696 // The array should be of the form
697 // [map, handler, map, handler, ...]
698 // or
699 // [map, map, handler, map, map, handler, ...]
666 // Be sure to skip handlers whose maps have been cleared. 700 // Be sure to skip handlers whose maps have been cleared.
667 DCHECK(array->length() >= 2); 701 DCHECK(array->length() >= 2);
668 for (int i = 0; i < array->length(); i += 2) { 702 int increment = array->get(1)->IsCode() ? 2 : 3;
703 for (int i = 0; i < array->length(); i += increment) {
669 DCHECK(array->get(i)->IsWeakCell()); 704 DCHECK(array->get(i)->IsWeakCell());
670 WeakCell* cell = WeakCell::cast(array->get(i)); 705 WeakCell* cell = WeakCell::cast(array->get(i));
671 if (!cell->cleared()) { 706 if (!cell->cleared()) {
672 Code* code = Code::cast(array->get(i + 1)); 707 Code* code = Code::cast(array->get(i + increment - 1));
673 DCHECK(code->kind() == Code::HANDLER); 708 DCHECK(code->kind() == Code::HANDLER);
674 code_list->Add(handle(code)); 709 code_list->Add(handle(code));
675 count++; 710 count++;
676 } 711 }
677 } 712 }
678 } else if (feedback->IsWeakCell()) { 713 } else if (feedback->IsWeakCell()) {
679 WeakCell* cell = WeakCell::cast(feedback); 714 WeakCell* cell = WeakCell::cast(feedback);
680 if (!cell->cleared()) { 715 if (!cell->cleared()) {
681 Code* code = Code::cast(GetFeedbackExtra()); 716 Code* code = Code::cast(GetFeedbackExtra());
682 DCHECK(code->kind() == Code::HANDLER); 717 DCHECK(code->kind() == Code::HANDLER);
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
715 750
716 751
717 void StoreICNexus::Clear(Code* host) { 752 void StoreICNexus::Clear(Code* host) {
718 StoreIC::Clear(GetIsolate(), host, this); 753 StoreIC::Clear(GetIsolate(), host, this);
719 } 754 }
720 755
721 756
722 void KeyedStoreICNexus::Clear(Code* host) { 757 void KeyedStoreICNexus::Clear(Code* host) {
723 KeyedStoreIC::Clear(GetIsolate(), host, this); 758 KeyedStoreIC::Clear(GetIsolate(), host, this);
724 } 759 }
760
761
762 KeyedAccessStoreMode KeyedStoreICNexus::GetKeyedAccessStoreMode() const {
763 KeyedAccessStoreMode mode = STANDARD_STORE;
764 MapHandleList maps;
765 CodeHandleList handlers;
766
767 if (GetKeyType() == PROPERTY) return mode;
768
769 ExtractMaps(&maps);
770 FindHandlers(&handlers, maps.length());
771 for (int i = 0; i < handlers.length(); i++) {
772 // The first handler that isn't the slow handler will have the bits we need.
773 Handle<Code> handler = handlers.at(i);
774 CodeStub::Major major_key = CodeStub::MajorKeyFromKey(handler->stub_key());
775 uint32_t minor_key = CodeStub::MinorKeyFromKey(handler->stub_key());
776 CHECK(major_key == CodeStub::KeyedStoreSloppyArguments ||
777 major_key == CodeStub::StoreFastElement ||
778 major_key == CodeStub::StoreElement ||
779 major_key == CodeStub::ElementsTransitionAndStore ||
780 major_key == CodeStub::NoCache);
781 if (major_key != CodeStub::NoCache) {
782 mode = CommonStoreModeBits::decode(minor_key);
783 break;
784 }
785 }
786
787 return mode;
788 }
789
790
791 IcCheckType KeyedStoreICNexus::GetKeyType() const {
792 // The structure of the vector slots tells us the type.
793 return GetFeedback()->IsName() ? PROPERTY : ELEMENT;
794 }
725 } // namespace internal 795 } // namespace internal
726 } // namespace v8 796 } // namespace v8
OLDNEW
« no previous file with comments | « src/type-feedback-vector.h ('k') | src/type-info.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698