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

Side by Side Diff: src/ic/ic.cc

Issue 2133233002: [LoadIC] Handle simple field loads in the dispatcher (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: fix release builds for realz Created 4 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/ic/ic.h ('k') | src/type-feedback-vector.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 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/ic/ic.h" 5 #include "src/ic/ic.h"
6 6
7 #include "src/accessors.h" 7 #include "src/accessors.h"
8 #include "src/api-arguments-inl.h" 8 #include "src/api-arguments-inl.h"
9 #include "src/api.h" 9 #include "src/api.h"
10 #include "src/arguments.h" 10 #include "src/arguments.h"
(...skipping 523 matching lines...) Expand 10 before | Expand all | Expand 10 after
534 nexus->ConfigureMegamorphicKeyed(key->IsName() ? PROPERTY : ELEMENT); 534 nexus->ConfigureMegamorphicKeyed(key->IsName() ? PROPERTY : ELEMENT);
535 } 535 }
536 } else { 536 } else {
537 UNREACHABLE(); 537 UNREACHABLE();
538 } 538 }
539 539
540 vector_set_ = true; 540 vector_set_ = true;
541 OnTypeFeedbackChanged(isolate(), get_host()); 541 OnTypeFeedbackChanged(isolate(), get_host());
542 } 542 }
543 543
544
545 void IC::ConfigureVectorState(Handle<Name> name, Handle<Map> map, 544 void IC::ConfigureVectorState(Handle<Name> name, Handle<Map> map,
546 Handle<Code> handler) { 545 Handle<Object> handler) {
547 DCHECK(UseVector()); 546 DCHECK(UseVector());
548 if (kind() == Code::LOAD_IC) { 547 if (kind() == Code::LOAD_IC) {
549 LoadICNexus* nexus = casted_nexus<LoadICNexus>(); 548 LoadICNexus* nexus = casted_nexus<LoadICNexus>();
550 nexus->ConfigureMonomorphic(map, handler); 549 nexus->ConfigureMonomorphic(map, handler);
551 } else if (kind() == Code::LOAD_GLOBAL_IC) { 550 } else if (kind() == Code::LOAD_GLOBAL_IC) {
552 LoadGlobalICNexus* nexus = casted_nexus<LoadGlobalICNexus>(); 551 LoadGlobalICNexus* nexus = casted_nexus<LoadGlobalICNexus>();
553 nexus->ConfigureHandlerMode(handler); 552 nexus->ConfigureHandlerMode(Handle<Code>::cast(handler));
554 } else if (kind() == Code::KEYED_LOAD_IC) { 553 } else if (kind() == Code::KEYED_LOAD_IC) {
555 KeyedLoadICNexus* nexus = casted_nexus<KeyedLoadICNexus>(); 554 KeyedLoadICNexus* nexus = casted_nexus<KeyedLoadICNexus>();
556 nexus->ConfigureMonomorphic(name, map, handler); 555 nexus->ConfigureMonomorphic(name, map, Handle<Code>::cast(handler));
557 } else if (kind() == Code::STORE_IC) { 556 } else if (kind() == Code::STORE_IC) {
558 StoreICNexus* nexus = casted_nexus<StoreICNexus>(); 557 StoreICNexus* nexus = casted_nexus<StoreICNexus>();
559 nexus->ConfigureMonomorphic(map, handler); 558 nexus->ConfigureMonomorphic(map, Handle<Code>::cast(handler));
560 } else { 559 } else {
561 DCHECK(kind() == Code::KEYED_STORE_IC); 560 DCHECK(kind() == Code::KEYED_STORE_IC);
562 KeyedStoreICNexus* nexus = casted_nexus<KeyedStoreICNexus>(); 561 KeyedStoreICNexus* nexus = casted_nexus<KeyedStoreICNexus>();
563 nexus->ConfigureMonomorphic(name, map, handler); 562 nexus->ConfigureMonomorphic(name, map, Handle<Code>::cast(handler));
564 } 563 }
565 564
566 vector_set_ = true; 565 vector_set_ = true;
567 OnTypeFeedbackChanged(isolate(), get_host()); 566 OnTypeFeedbackChanged(isolate(), get_host());
568 } 567 }
569 568
570
571 void IC::ConfigureVectorState(Handle<Name> name, MapHandleList* maps, 569 void IC::ConfigureVectorState(Handle<Name> name, MapHandleList* maps,
572 CodeHandleList* handlers) { 570 List<Handle<Object>>* handlers) {
573 DCHECK(UseVector()); 571 DCHECK(UseVector());
574 if (kind() == Code::LOAD_IC) { 572 if (kind() == Code::LOAD_IC) {
575 LoadICNexus* nexus = casted_nexus<LoadICNexus>(); 573 LoadICNexus* nexus = casted_nexus<LoadICNexus>();
576 nexus->ConfigurePolymorphic(maps, handlers); 574 nexus->ConfigurePolymorphic(maps, handlers);
577 } else if (kind() == Code::KEYED_LOAD_IC) { 575 } else if (kind() == Code::KEYED_LOAD_IC) {
578 KeyedLoadICNexus* nexus = casted_nexus<KeyedLoadICNexus>(); 576 KeyedLoadICNexus* nexus = casted_nexus<KeyedLoadICNexus>();
579 nexus->ConfigurePolymorphic(name, maps, handlers); 577 nexus->ConfigurePolymorphic(name, maps, handlers);
580 } else if (kind() == Code::STORE_IC) { 578 } else if (kind() == Code::STORE_IC) {
581 StoreICNexus* nexus = casted_nexus<StoreICNexus>(); 579 StoreICNexus* nexus = casted_nexus<StoreICNexus>();
582 nexus->ConfigurePolymorphic(maps, handlers); 580 nexus->ConfigurePolymorphic(maps, handlers);
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
679 for (int current = 0; current < receiver_maps->length(); ++current) { 677 for (int current = 0; current < receiver_maps->length(); ++current) {
680 if (!receiver_maps->at(current).is_null() && 678 if (!receiver_maps->at(current).is_null() &&
681 receiver_maps->at(current).is_identical_to(new_receiver_map)) { 679 receiver_maps->at(current).is_identical_to(new_receiver_map)) {
682 return false; 680 return false;
683 } 681 }
684 } 682 }
685 receiver_maps->Add(new_receiver_map); 683 receiver_maps->Add(new_receiver_map);
686 return true; 684 return true;
687 } 685 }
688 686
689 687 bool IC::UpdatePolymorphicIC(Handle<Name> name, Handle<Object> code) {
690 bool IC::UpdatePolymorphicIC(Handle<Name> name, Handle<Code> code) { 688 DCHECK(code->IsSmi() || code->IsCode());
691 if (!code->is_handler()) return false; 689 if (!code->IsSmi() && !Code::cast(*code)->is_handler()) {
690 return false;
691 }
692 if (is_keyed() && state() != RECOMPUTE_HANDLER) return false; 692 if (is_keyed() && state() != RECOMPUTE_HANDLER) return false;
693 Handle<Map> map = receiver_map(); 693 Handle<Map> map = receiver_map();
694 MapHandleList maps; 694 MapHandleList maps;
695 CodeHandleList handlers; 695 List<Handle<Object>> handlers;
696 696
697 TargetMaps(&maps); 697 TargetMaps(&maps);
698 int number_of_maps = maps.length(); 698 int number_of_maps = maps.length();
699 int deprecated_maps = 0; 699 int deprecated_maps = 0;
700 int handler_to_overwrite = -1; 700 int handler_to_overwrite = -1;
701 701
702 for (int i = 0; i < number_of_maps; i++) { 702 for (int i = 0; i < number_of_maps; i++) {
703 Handle<Map> current_map = maps.at(i); 703 Handle<Map> current_map = maps.at(i);
704 if (current_map->is_deprecated()) { 704 if (current_map->is_deprecated()) {
705 // Filter out deprecated maps to ensure their instances get migrated. 705 // Filter out deprecated maps to ensure their instances get migrated.
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
740 maps.Add(map); 740 maps.Add(map);
741 handlers.Add(code); 741 handlers.Add(code);
742 } 742 }
743 743
744 ConfigureVectorState(name, &maps, &handlers); 744 ConfigureVectorState(name, &maps, &handlers);
745 } 745 }
746 746
747 return true; 747 return true;
748 } 748 }
749 749
750 750 void IC::UpdateMonomorphicIC(Handle<Object> handler, Handle<Name> name) {
751 void IC::UpdateMonomorphicIC(Handle<Code> handler, Handle<Name> name) { 751 DCHECK(handler->IsSmi() ||
752 DCHECK(handler->is_handler()); 752 (handler->IsCode() && Handle<Code>::cast(handler)->is_handler()));
753 ConfigureVectorState(name, receiver_map(), handler); 753 ConfigureVectorState(name, receiver_map(), handler);
754 } 754 }
755 755
756 756
757 void IC::CopyICToMegamorphicCache(Handle<Name> name) { 757 void IC::CopyICToMegamorphicCache(Handle<Name> name) {
758 MapHandleList maps; 758 MapHandleList maps;
759 CodeHandleList handlers; 759 List<Handle<Object>> handlers;
760 TargetMaps(&maps); 760 TargetMaps(&maps);
761 if (!nexus()->FindHandlers(&handlers, maps.length())) return; 761 if (!nexus()->FindHandlers(&handlers, maps.length())) return;
762 for (int i = 0; i < maps.length(); i++) { 762 for (int i = 0; i < maps.length(); i++) {
763 UpdateMegamorphicCache(*maps.at(i), *name, *handlers.at(i)); 763 UpdateMegamorphicCache(*maps.at(i), *name, *handlers.at(i));
764 } 764 }
765 } 765 }
766 766
767 767
768 bool IC::IsTransitionOfMonomorphicTarget(Map* source_map, Map* target_map) { 768 bool IC::IsTransitionOfMonomorphicTarget(Map* source_map, Map* target_map) {
769 if (source_map == NULL) return true; 769 if (source_map == NULL) return true;
770 if (target_map == NULL) return false; 770 if (target_map == NULL) return false;
771 ElementsKind target_elements_kind = target_map->elements_kind(); 771 ElementsKind target_elements_kind = target_map->elements_kind();
772 bool more_general_transition = IsMoreGeneralElementsKindTransition( 772 bool more_general_transition = IsMoreGeneralElementsKindTransition(
773 source_map->elements_kind(), target_elements_kind); 773 source_map->elements_kind(), target_elements_kind);
774 Map* transitioned_map = nullptr; 774 Map* transitioned_map = nullptr;
775 if (more_general_transition) { 775 if (more_general_transition) {
776 MapHandleList map_list; 776 MapHandleList map_list;
777 map_list.Add(handle(target_map)); 777 map_list.Add(handle(target_map));
778 transitioned_map = source_map->FindElementsKindTransitionedMap(&map_list); 778 transitioned_map = source_map->FindElementsKindTransitionedMap(&map_list);
779 } 779 }
780 return transitioned_map == target_map; 780 return transitioned_map == target_map;
781 } 781 }
782 782
783 783 void IC::PatchCache(Handle<Name> name, Handle<Object> code) {
784 void IC::PatchCache(Handle<Name> name, Handle<Code> code) { 784 DCHECK(code->IsCode() || (kind() == Code::LOAD_IC && code->IsSmi()));
785 switch (state()) { 785 switch (state()) {
786 case UNINITIALIZED: 786 case UNINITIALIZED:
787 case PREMONOMORPHIC: 787 case PREMONOMORPHIC:
788 UpdateMonomorphicIC(code, name); 788 UpdateMonomorphicIC(code, name);
789 break; 789 break;
790 case RECOMPUTE_HANDLER: 790 case RECOMPUTE_HANDLER:
791 case MONOMORPHIC: 791 case MONOMORPHIC:
792 if (kind() == Code::LOAD_GLOBAL_IC) { 792 if (kind() == Code::LOAD_GLOBAL_IC) {
793 UpdateMonomorphicIC(code, name); 793 UpdateMonomorphicIC(code, name);
794 break; 794 break;
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
842 842
843 843
844 Handle<Code> KeyedStoreIC::ChooseMegamorphicStub(Isolate* isolate, 844 Handle<Code> KeyedStoreIC::ChooseMegamorphicStub(Isolate* isolate,
845 ExtraICState extra_state) { 845 ExtraICState extra_state) {
846 LanguageMode mode = StoreICState::GetLanguageMode(extra_state); 846 LanguageMode mode = StoreICState::GetLanguageMode(extra_state);
847 return is_strict(mode) 847 return is_strict(mode)
848 ? isolate->builtins()->KeyedStoreIC_Megamorphic_Strict() 848 ? isolate->builtins()->KeyedStoreIC_Megamorphic_Strict()
849 : isolate->builtins()->KeyedStoreIC_Megamorphic(); 849 : isolate->builtins()->KeyedStoreIC_Megamorphic();
850 } 850 }
851 851
852 852 Handle<Object> LoadIC::SimpleFieldLoad(FieldIndex index) {
853 Handle<Code> LoadIC::SimpleFieldLoad(FieldIndex index) { 853 if (kind() == Code::LOAD_IC && FLAG_tf_load_ic_stub) {
854 return handle(Smi::FromInt(index.GetLoadByFieldOffset()), isolate());
855 }
856 DCHECK(kind() == Code::KEYED_LOAD_IC || !FLAG_tf_load_ic_stub);
854 TRACE_HANDLER_STATS(isolate(), LoadIC_LoadFieldStub); 857 TRACE_HANDLER_STATS(isolate(), LoadIC_LoadFieldStub);
855 LoadFieldStub stub(isolate(), index); 858 LoadFieldStub stub(isolate(), index);
856 return stub.GetCode(); 859 return stub.GetCode();
857 } 860 }
858 861
859 862
860 bool IsCompatibleReceiver(LookupIterator* lookup, Handle<Map> receiver_map) { 863 bool IsCompatibleReceiver(LookupIterator* lookup, Handle<Map> receiver_map) {
861 DCHECK(lookup->state() == LookupIterator::ACCESSOR); 864 DCHECK(lookup->state() == LookupIterator::ACCESSOR);
862 Isolate* isolate = lookup->isolate(); 865 Isolate* isolate = lookup->isolate();
863 Handle<Object> accessors = lookup->GetAccessors(); 866 Handle<Object> accessors = lookup->GetAccessors();
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
898 901
899 void LoadIC::UpdateCaches(LookupIterator* lookup) { 902 void LoadIC::UpdateCaches(LookupIterator* lookup) {
900 if (state() == UNINITIALIZED && kind() != Code::LOAD_GLOBAL_IC) { 903 if (state() == UNINITIALIZED && kind() != Code::LOAD_GLOBAL_IC) {
901 // This is the first time we execute this inline cache. Set the target to 904 // This is the first time we execute this inline cache. Set the target to
902 // the pre monomorphic stub to delay setting the monomorphic state. 905 // the pre monomorphic stub to delay setting the monomorphic state.
903 ConfigureVectorState(PREMONOMORPHIC, Handle<Object>()); 906 ConfigureVectorState(PREMONOMORPHIC, Handle<Object>());
904 TRACE_IC("LoadIC", lookup->name()); 907 TRACE_IC("LoadIC", lookup->name());
905 return; 908 return;
906 } 909 }
907 910
908 Handle<Code> code; 911 Handle<Object> code;
909 if (lookup->state() == LookupIterator::JSPROXY || 912 if (lookup->state() == LookupIterator::JSPROXY ||
910 lookup->state() == LookupIterator::ACCESS_CHECK) { 913 lookup->state() == LookupIterator::ACCESS_CHECK) {
911 code = slow_stub(); 914 code = slow_stub();
912 } else if (!lookup->IsFound()) { 915 } else if (!lookup->IsFound()) {
913 if (kind() == Code::LOAD_IC || kind() == Code::LOAD_GLOBAL_IC) { 916 if (kind() == Code::LOAD_IC || kind() == Code::LOAD_GLOBAL_IC) {
914 code = NamedLoadHandlerCompiler::ComputeLoadNonexistent(lookup->name(), 917 code = NamedLoadHandlerCompiler::ComputeLoadNonexistent(lookup->name(),
915 receiver_map()); 918 receiver_map());
916 // TODO(jkummerow/verwaest): Introduce a builtin that handles this case. 919 // TODO(jkummerow/verwaest): Introduce a builtin that handles this case.
917 if (code.is_null()) code = slow_stub(); 920 if (code.is_null()) code = slow_stub();
918 } else { 921 } else {
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
973 case Code::KEYED_STORE_IC: 976 case Code::KEYED_STORE_IC:
974 return isolate()->store_stub_cache(); 977 return isolate()->store_stub_cache();
975 978
976 default: 979 default:
977 break; 980 break;
978 } 981 }
979 UNREACHABLE(); 982 UNREACHABLE();
980 return nullptr; 983 return nullptr;
981 } 984 }
982 985
983 void IC::UpdateMegamorphicCache(Map* map, Name* name, Code* code) { 986 void IC::UpdateMegamorphicCache(Map* map, Name* name, Object* code) {
984 stub_cache()->Set(name, map, code); 987 if (code->IsSmi()) {
988 // TODO(jkummerow): Support Smis in the code cache.
989 Handle<Map> map_handle(map, isolate());
990 Handle<Name> name_handle(name, isolate());
991 FieldIndex index =
992 FieldIndex::ForLoadByFieldOffset(map, Smi::cast(code)->value());
993 TRACE_HANDLER_STATS(isolate(), LoadIC_LoadFieldStub);
994 LoadFieldStub stub(isolate(), index);
995 Code* handler = *stub.GetCode();
996 stub_cache()->Set(*name_handle, *map_handle, handler);
997 return;
998 }
999 DCHECK(code->IsCode());
1000 stub_cache()->Set(name, map, Code::cast(code));
985 } 1001 }
986 1002
987 1003 Handle<Object> IC::ComputeHandler(LookupIterator* lookup,
988 Handle<Code> IC::ComputeHandler(LookupIterator* lookup, Handle<Object> value) { 1004 Handle<Object> value) {
989 // Try to find a globally shared handler stub. 1005 // Try to find a globally shared handler stub.
990 Handle<Code> code = GetMapIndependentHandler(lookup); 1006 Handle<Object> handler_or_index = GetMapIndependentHandler(lookup);
991 if (!code.is_null()) return code; 1007 if (!handler_or_index.is_null()) {
1008 DCHECK(handler_or_index->IsCode() || handler_or_index->IsSmi());
1009 return handler_or_index;
1010 }
992 1011
993 // Otherwise check the map's handler cache for a map-specific handler, and 1012 // Otherwise check the map's handler cache for a map-specific handler, and
994 // compile one if the cache comes up empty. 1013 // compile one if the cache comes up empty.
995 bool receiver_is_holder = 1014 bool receiver_is_holder =
996 lookup->GetReceiver().is_identical_to(lookup->GetHolder<JSObject>()); 1015 lookup->GetReceiver().is_identical_to(lookup->GetHolder<JSObject>());
997 CacheHolderFlag flag; 1016 CacheHolderFlag flag;
998 Handle<Map> stub_holder_map; 1017 Handle<Map> stub_holder_map;
999 if (kind() == Code::LOAD_IC || kind() == Code::LOAD_GLOBAL_IC || 1018 if (kind() == Code::LOAD_IC || kind() == Code::LOAD_GLOBAL_IC ||
1000 kind() == Code::KEYED_LOAD_IC) { 1019 kind() == Code::KEYED_LOAD_IC) {
1001 stub_holder_map = IC::GetHandlerCacheHolder( 1020 stub_holder_map = IC::GetHandlerCacheHolder(
1002 receiver_map(), receiver_is_holder, isolate(), &flag); 1021 receiver_map(), receiver_is_holder, isolate(), &flag);
1003 } else { 1022 } else {
1004 DCHECK(kind() == Code::STORE_IC || kind() == Code::KEYED_STORE_IC); 1023 DCHECK(kind() == Code::STORE_IC || kind() == Code::KEYED_STORE_IC);
1005 // Store handlers cannot be cached on prototypes. 1024 // Store handlers cannot be cached on prototypes.
1006 flag = kCacheOnReceiver; 1025 flag = kCacheOnReceiver;
1007 stub_holder_map = receiver_map(); 1026 stub_holder_map = receiver_map();
1008 } 1027 }
1009 1028
1010 code = PropertyHandlerCompiler::Find(lookup->name(), stub_holder_map, kind(), 1029 Handle<Code> code = PropertyHandlerCompiler::Find(
1011 flag); 1030 lookup->name(), stub_holder_map, kind(), flag);
1012 // Use the cached value if it exists, and if it is different from the 1031 // Use the cached value if it exists, and if it is different from the
1013 // handler that just missed. 1032 // handler that just missed.
1014 if (!code.is_null()) { 1033 if (!code.is_null()) {
1015 Handle<Code> handler; 1034 Handle<Object> handler;
1016 if (maybe_handler_.ToHandle(&handler)) { 1035 if (maybe_handler_.ToHandle(&handler)) {
1017 if (!handler.is_identical_to(code)) { 1036 if (!handler.is_identical_to(code)) {
1018 TRACE_HANDLER_STATS(isolate(), IC_HandlerCacheHit); 1037 TRACE_HANDLER_STATS(isolate(), IC_HandlerCacheHit);
1019 return code; 1038 return code;
1020 } 1039 }
1021 } else { 1040 } else {
1022 // maybe_handler_ is only populated for MONOMORPHIC and POLYMORPHIC ICs. 1041 // maybe_handler_ is only populated for MONOMORPHIC and POLYMORPHIC ICs.
1023 // In MEGAMORPHIC case, check if the handler in the megamorphic stub 1042 // In MEGAMORPHIC case, check if the handler in the megamorphic stub
1024 // cache (which just missed) is different from the cached handler. 1043 // cache (which just missed) is different from the cached handler.
1025 if (state() == MEGAMORPHIC && lookup->GetReceiver()->IsHeapObject()) { 1044 if (state() == MEGAMORPHIC && lookup->GetReceiver()->IsHeapObject()) {
(...skipping 11 matching lines...) Expand all
1037 } 1056 }
1038 1057
1039 code = CompileHandler(lookup, value, flag); 1058 code = CompileHandler(lookup, value, flag);
1040 DCHECK(code->is_handler()); 1059 DCHECK(code->is_handler());
1041 DCHECK(Code::ExtractCacheHolderFromFlags(code->flags()) == flag); 1060 DCHECK(Code::ExtractCacheHolderFromFlags(code->flags()) == flag);
1042 Map::UpdateCodeCache(stub_holder_map, lookup->name(), code); 1061 Map::UpdateCodeCache(stub_holder_map, lookup->name(), code);
1043 1062
1044 return code; 1063 return code;
1045 } 1064 }
1046 1065
1047 Handle<Code> LoadIC::GetMapIndependentHandler(LookupIterator* lookup) { 1066 Handle<Object> LoadIC::GetMapIndependentHandler(LookupIterator* lookup) {
1048 Handle<Object> receiver = lookup->GetReceiver(); 1067 Handle<Object> receiver = lookup->GetReceiver();
1049 if (receiver->IsString() && 1068 if (receiver->IsString() &&
1050 Name::Equals(isolate()->factory()->length_string(), lookup->name())) { 1069 Name::Equals(isolate()->factory()->length_string(), lookup->name())) {
1051 FieldIndex index = FieldIndex::ForInObjectOffset(String::kLengthOffset); 1070 FieldIndex index = FieldIndex::ForInObjectOffset(String::kLengthOffset);
1052 return SimpleFieldLoad(index); 1071 return SimpleFieldLoad(index);
1053 } 1072 }
1054 1073
1055 if (receiver->IsStringWrapper() && 1074 if (receiver->IsStringWrapper() &&
1056 Name::Equals(isolate()->factory()->length_string(), lookup->name())) { 1075 Name::Equals(isolate()->factory()->length_string(), lookup->name())) {
1057 TRACE_HANDLER_STATS(isolate(), LoadIC_StringLengthStub); 1076 TRACE_HANDLER_STATS(isolate(), LoadIC_StringLengthStub);
(...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after
1381 return; 1400 return;
1382 } 1401 }
1383 1402
1384 // If the maximum number of receiver maps has been exceeded, use the generic 1403 // If the maximum number of receiver maps has been exceeded, use the generic
1385 // version of the IC. 1404 // version of the IC.
1386 if (target_receiver_maps.length() > kMaxKeyedPolymorphism) { 1405 if (target_receiver_maps.length() > kMaxKeyedPolymorphism) {
1387 TRACE_GENERIC_IC(isolate(), "KeyedLoadIC", "max polymorph exceeded"); 1406 TRACE_GENERIC_IC(isolate(), "KeyedLoadIC", "max polymorph exceeded");
1388 return; 1407 return;
1389 } 1408 }
1390 1409
1391 CodeHandleList handlers(target_receiver_maps.length()); 1410 List<Handle<Object>> handlers(target_receiver_maps.length());
1392 TRACE_HANDLER_STATS(isolate(), KeyedLoadIC_PolymorphicElement); 1411 TRACE_HANDLER_STATS(isolate(), KeyedLoadIC_PolymorphicElement);
1393 ElementHandlerCompiler compiler(isolate()); 1412 ElementHandlerCompiler compiler(isolate());
1394 compiler.CompileElementHandlers(&target_receiver_maps, &handlers); 1413 compiler.CompileElementHandlers(&target_receiver_maps, &handlers);
1395 ConfigureVectorState(Handle<Name>(), &target_receiver_maps, &handlers); 1414 ConfigureVectorState(Handle<Name>(), &target_receiver_maps, &handlers);
1396 } 1415 }
1397 1416
1398 1417
1399 MaybeHandle<Object> KeyedLoadIC::Load(Handle<Object> object, 1418 MaybeHandle<Object> KeyedLoadIC::Load(Handle<Object> object,
1400 Handle<Object> key) { 1419 Handle<Object> key) {
1401 if (MigrateDeprecated(object)) { 1420 if (MigrateDeprecated(object)) {
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after
1598 // the pre monomorphic stub to delay setting the monomorphic state. 1617 // the pre monomorphic stub to delay setting the monomorphic state.
1599 ConfigureVectorState(PREMONOMORPHIC, Handle<Object>()); 1618 ConfigureVectorState(PREMONOMORPHIC, Handle<Object>());
1600 TRACE_IC("StoreIC", lookup->name()); 1619 TRACE_IC("StoreIC", lookup->name());
1601 return; 1620 return;
1602 } 1621 }
1603 1622
1604 bool use_ic = LookupForWrite(lookup, value, store_mode); 1623 bool use_ic = LookupForWrite(lookup, value, store_mode);
1605 if (!use_ic) { 1624 if (!use_ic) {
1606 TRACE_GENERIC_IC(isolate(), "StoreIC", "LookupForWrite said 'false'"); 1625 TRACE_GENERIC_IC(isolate(), "StoreIC", "LookupForWrite said 'false'");
1607 } 1626 }
1608 Handle<Code> code = use_ic ? ComputeHandler(lookup, value) : slow_stub(); 1627 Handle<Code> code =
1628 use_ic ? Handle<Code>::cast(ComputeHandler(lookup, value)) : slow_stub();
1609 1629
1610 PatchCache(lookup->name(), code); 1630 PatchCache(lookup->name(), code);
1611 TRACE_IC("StoreIC", lookup->name()); 1631 TRACE_IC("StoreIC", lookup->name());
1612 } 1632 }
1613 1633
1614 1634
1615 static Handle<Code> PropertyCellStoreHandler( 1635 static Handle<Code> PropertyCellStoreHandler(
1616 Isolate* isolate, Handle<JSObject> receiver, Handle<JSGlobalObject> holder, 1636 Isolate* isolate, Handle<JSObject> receiver, Handle<JSGlobalObject> holder,
1617 Handle<Name> name, Handle<PropertyCell> cell, PropertyCellType type) { 1637 Handle<Name> name, Handle<PropertyCell> cell, PropertyCellType type) {
1618 auto constant_type = Nothing<PropertyCellConstantType>(); 1638 auto constant_type = Nothing<PropertyCellConstantType>();
1619 if (type == PropertyCellType::kConstantType) { 1639 if (type == PropertyCellType::kConstantType) {
1620 constant_type = Just(cell->GetConstantType()); 1640 constant_type = Just(cell->GetConstantType());
1621 } 1641 }
1622 StoreGlobalStub stub(isolate, type, constant_type, 1642 StoreGlobalStub stub(isolate, type, constant_type,
1623 receiver->IsJSGlobalProxy()); 1643 receiver->IsJSGlobalProxy());
1624 auto code = stub.GetCodeCopyFromTemplate(holder, cell); 1644 auto code = stub.GetCodeCopyFromTemplate(holder, cell);
1625 // TODO(verwaest): Move caching of these NORMAL stubs outside as well. 1645 // TODO(verwaest): Move caching of these NORMAL stubs outside as well.
1626 HeapObject::UpdateMapCodeCache(receiver, name, code); 1646 HeapObject::UpdateMapCodeCache(receiver, name, code);
1627 return code; 1647 return code;
1628 } 1648 }
1629 1649
1630 Handle<Code> StoreIC::GetMapIndependentHandler(LookupIterator* lookup) { 1650 Handle<Object> StoreIC::GetMapIndependentHandler(LookupIterator* lookup) {
1631 DCHECK_NE(LookupIterator::JSPROXY, lookup->state()); 1651 DCHECK_NE(LookupIterator::JSPROXY, lookup->state());
1632 1652
1633 // This is currently guaranteed by checks in StoreIC::Store. 1653 // This is currently guaranteed by checks in StoreIC::Store.
1634 Handle<JSObject> receiver = Handle<JSObject>::cast(lookup->GetReceiver()); 1654 Handle<JSObject> receiver = Handle<JSObject>::cast(lookup->GetReceiver());
1635 Handle<JSObject> holder = lookup->GetHolder<JSObject>(); 1655 Handle<JSObject> holder = lookup->GetHolder<JSObject>();
1636 DCHECK(!receiver->IsAccessCheckNeeded() || lookup->name()->IsPrivate()); 1656 DCHECK(!receiver->IsAccessCheckNeeded() || lookup->name()->IsPrivate());
1637 1657
1638 switch (lookup->state()) { 1658 switch (lookup->state()) {
1639 case LookupIterator::TRANSITION: { 1659 case LookupIterator::TRANSITION: {
1640 auto store_target = lookup->GetStoreTarget(); 1660 auto store_target = lookup->GetStoreTarget();
(...skipping 1351 matching lines...) Expand 10 before | Expand all | Expand 10 after
2992 DCHECK_EQ(FeedbackVectorSlotKind::KEYED_LOAD_IC, 3012 DCHECK_EQ(FeedbackVectorSlotKind::KEYED_LOAD_IC,
2993 vector->GetKind(vector_slot)); 3013 vector->GetKind(vector_slot));
2994 KeyedLoadICNexus nexus(vector, vector_slot); 3014 KeyedLoadICNexus nexus(vector, vector_slot);
2995 KeyedLoadIC ic(IC::EXTRA_CALL_FRAME, isolate, &nexus); 3015 KeyedLoadIC ic(IC::EXTRA_CALL_FRAME, isolate, &nexus);
2996 ic.UpdateState(receiver, key); 3016 ic.UpdateState(receiver, key);
2997 RETURN_RESULT_OR_FAILURE(isolate, ic.Load(receiver, key)); 3017 RETURN_RESULT_OR_FAILURE(isolate, ic.Load(receiver, key));
2998 } 3018 }
2999 } 3019 }
3000 } // namespace internal 3020 } // namespace internal
3001 } // namespace v8 3021 } // namespace v8
OLDNEW
« no previous file with comments | « src/ic/ic.h ('k') | src/type-feedback-vector.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698