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

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

Issue 935603002: Stop using HeapType in IC and Crankshaft (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 10 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/ic/ic-compiler.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/v8.h" 5 #include "src/v8.h"
6 6
7 #include "src/accessors.h" 7 #include "src/accessors.h"
8 #include "src/api.h" 8 #include "src/api.h"
9 #include "src/arguments.h" 9 #include "src/arguments.h"
10 #include "src/base/bits.h" 10 #include "src/base/bits.h"
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after
258 case LookupIterator::DATA: 258 case LookupIterator::DATA:
259 return; 259 return;
260 } 260 }
261 } 261 }
262 } 262 }
263 263
264 264
265 bool IC::TryRemoveInvalidPrototypeDependentStub(Handle<Object> receiver, 265 bool IC::TryRemoveInvalidPrototypeDependentStub(Handle<Object> receiver,
266 Handle<String> name) { 266 Handle<String> name) {
267 if (!IsNameCompatibleWithPrototypeFailure(name)) return false; 267 if (!IsNameCompatibleWithPrototypeFailure(name)) return false;
268 Handle<Map> receiver_map = TypeToMap(*receiver_type(), isolate());
269 if (UseVector()) { 268 if (UseVector()) {
270 maybe_handler_ = nexus()->FindHandlerForMap(receiver_map); 269 maybe_handler_ = nexus()->FindHandlerForMap(receiver_map());
271 } else { 270 } else {
272 maybe_handler_ = target()->FindHandlerForMap(*receiver_map); 271 maybe_handler_ = target()->FindHandlerForMap(*receiver_map());
273 } 272 }
274 273
275 // The current map wasn't handled yet. There's no reason to stay monomorphic, 274 // The current map wasn't handled yet. There's no reason to stay monomorphic,
276 // *unless* we're moving from a deprecated map to its replacement, or 275 // *unless* we're moving from a deprecated map to its replacement, or
277 // to a more general elements kind. 276 // to a more general elements kind.
278 // TODO(verwaest): Check if the current map is actually what the old map 277 // TODO(verwaest): Check if the current map is actually what the old map
279 // would transition to. 278 // would transition to.
280 if (maybe_handler_.is_null()) { 279 if (maybe_handler_.is_null()) {
281 if (!receiver_map->IsJSObjectMap()) return false; 280 if (!receiver_map()->IsJSObjectMap()) return false;
282 Map* first_map = FirstTargetMap(); 281 Map* first_map = FirstTargetMap();
283 if (first_map == NULL) return false; 282 if (first_map == NULL) return false;
284 Handle<Map> old_map(first_map); 283 Handle<Map> old_map(first_map);
285 if (old_map->is_deprecated()) return true; 284 if (old_map->is_deprecated()) return true;
286 if (IsMoreGeneralElementsKindTransition(old_map->elements_kind(), 285 if (IsMoreGeneralElementsKindTransition(old_map->elements_kind(),
287 receiver_map->elements_kind())) { 286 receiver_map()->elements_kind())) {
288 return true; 287 return true;
289 } 288 }
290 return false; 289 return false;
291 } 290 }
292 291
293 CacheHolderFlag flag; 292 CacheHolderFlag flag;
294 Handle<Map> ic_holder_map( 293 Handle<Map> ic_holder_map(GetICCacheHolder(receiver_map(), isolate(), &flag));
295 GetICCacheHolder(*receiver_type(), isolate(), &flag));
296 294
297 DCHECK(flag != kCacheOnReceiver || receiver->IsJSObject()); 295 DCHECK(flag != kCacheOnReceiver || receiver->IsJSObject());
298 DCHECK(flag != kCacheOnPrototype || !receiver->IsJSReceiver()); 296 DCHECK(flag != kCacheOnPrototype || !receiver->IsJSReceiver());
299 DCHECK(flag != kCacheOnPrototypeReceiverIsDictionary); 297 DCHECK(flag != kCacheOnPrototypeReceiverIsDictionary);
300 298
301 if (state() == MONOMORPHIC) { 299 if (state() == MONOMORPHIC) {
302 int index = ic_holder_map->IndexInCodeCache(*name, *target()); 300 int index = ic_holder_map->IndexInCodeCache(*name, *target());
303 if (index >= 0) { 301 if (index >= 0) {
304 ic_holder_map->RemoveFromCodeCache(*name, *target(), index); 302 ic_holder_map->RemoveFromCodeCache(*name, *target(), index);
305 } 303 }
(...skipping 19 matching lines...) Expand all
325 Name* stub_name = 323 Name* stub_name =
326 UseVector() ? nexus()->FindFirstName() : target()->FindFirstName(); 324 UseVector() ? nexus()->FindFirstName() : target()->FindFirstName();
327 if (*name != stub_name) return false; 325 if (*name != stub_name) return false;
328 } 326 }
329 327
330 return true; 328 return true;
331 } 329 }
332 330
333 331
334 void IC::UpdateState(Handle<Object> receiver, Handle<Object> name) { 332 void IC::UpdateState(Handle<Object> receiver, Handle<Object> name) {
335 update_receiver_type(receiver); 333 update_receiver_map(receiver);
336 if (!name->IsString()) return; 334 if (!name->IsString()) return;
337 if (state() != MONOMORPHIC && state() != POLYMORPHIC) return; 335 if (state() != MONOMORPHIC && state() != POLYMORPHIC) return;
338 if (receiver->IsUndefined() || receiver->IsNull()) return; 336 if (receiver->IsUndefined() || receiver->IsNull()) return;
339 337
340 // Remove the target from the code cache if it became invalid 338 // Remove the target from the code cache if it became invalid
341 // because of changes in the prototype chain to avoid hitting it 339 // because of changes in the prototype chain to avoid hitting it
342 // again. 340 // again.
343 if (TryRemoveInvalidPrototypeDependentStub(receiver, 341 if (TryRemoveInvalidPrototypeDependentStub(receiver,
344 Handle<String>::cast(name))) { 342 Handle<String>::cast(name))) {
345 MarkPrototypeFailure(name); 343 MarkPrototypeFailure(name);
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after
643 } else { 641 } else {
644 UNREACHABLE(); 642 UNREACHABLE();
645 } 643 }
646 644
647 vector_set_ = true; 645 vector_set_ = true;
648 OnTypeFeedbackChanged(isolate(), get_host(), *vector(), saved_state(), 646 OnTypeFeedbackChanged(isolate(), get_host(), *vector(), saved_state(),
649 new_state); 647 new_state);
650 } 648 }
651 649
652 650
653 void IC::ConfigureVectorState(Handle<Name> name, Handle<HeapType> type, 651 void IC::ConfigureVectorState(Handle<Name> name, Handle<Map> map,
654 Handle<Code> handler) { 652 Handle<Code> handler) {
655 DCHECK(UseVector()); 653 DCHECK(UseVector());
656 if (kind() == Code::LOAD_IC) { 654 if (kind() == Code::LOAD_IC) {
657 LoadICNexus* nexus = casted_nexus<LoadICNexus>(); 655 LoadICNexus* nexus = casted_nexus<LoadICNexus>();
658 nexus->ConfigureMonomorphic(type, handler); 656 nexus->ConfigureMonomorphic(map, handler);
659 } else { 657 } else {
660 DCHECK(kind() == Code::KEYED_LOAD_IC); 658 DCHECK(kind() == Code::KEYED_LOAD_IC);
661 KeyedLoadICNexus* nexus = casted_nexus<KeyedLoadICNexus>(); 659 KeyedLoadICNexus* nexus = casted_nexus<KeyedLoadICNexus>();
662 nexus->ConfigureMonomorphic(name, type, handler); 660 nexus->ConfigureMonomorphic(name, map, handler);
663 } 661 }
664 662
665 vector_set_ = true; 663 vector_set_ = true;
666 OnTypeFeedbackChanged(isolate(), get_host(), *vector(), saved_state(), 664 OnTypeFeedbackChanged(isolate(), get_host(), *vector(), saved_state(),
667 MONOMORPHIC); 665 MONOMORPHIC);
668 } 666 }
669 667
670 668
671 void IC::ConfigureVectorState(Handle<Name> name, TypeHandleList* types, 669 void IC::ConfigureVectorState(Handle<Name> name, MapHandleList* maps,
672 CodeHandleList* handlers) { 670 CodeHandleList* handlers) {
673 DCHECK(UseVector()); 671 DCHECK(UseVector());
674 if (kind() == Code::LOAD_IC) { 672 if (kind() == Code::LOAD_IC) {
675 LoadICNexus* nexus = casted_nexus<LoadICNexus>(); 673 LoadICNexus* nexus = casted_nexus<LoadICNexus>();
676 nexus->ConfigurePolymorphic(types, handlers); 674 nexus->ConfigurePolymorphic(maps, handlers);
677 } else { 675 } else {
678 DCHECK(kind() == Code::KEYED_LOAD_IC); 676 DCHECK(kind() == Code::KEYED_LOAD_IC);
679 KeyedLoadICNexus* nexus = casted_nexus<KeyedLoadICNexus>(); 677 KeyedLoadICNexus* nexus = casted_nexus<KeyedLoadICNexus>();
680 nexus->ConfigurePolymorphic(name, types, handlers); 678 nexus->ConfigurePolymorphic(name, maps, handlers);
681 } 679 }
682 680
683 vector_set_ = true; 681 vector_set_ = true;
684 OnTypeFeedbackChanged(isolate(), get_host(), *vector(), saved_state(), 682 OnTypeFeedbackChanged(isolate(), get_host(), *vector(), saved_state(),
685 POLYMORPHIC); 683 POLYMORPHIC);
686 } 684 }
687 685
688 686
689 MaybeHandle<Object> LoadIC::Load(Handle<Object> object, Handle<Name> name) { 687 MaybeHandle<Object> LoadIC::Load(Handle<Object> object, Handle<Name> name) {
690 // If the object is undefined or null it's illegal to try to get any 688 // If the object is undefined or null it's illegal to try to get any
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
776 } 774 }
777 } 775 }
778 receiver_maps->Add(new_receiver_map); 776 receiver_maps->Add(new_receiver_map);
779 return true; 777 return true;
780 } 778 }
781 779
782 780
783 bool IC::UpdatePolymorphicIC(Handle<Name> name, Handle<Code> code) { 781 bool IC::UpdatePolymorphicIC(Handle<Name> name, Handle<Code> code) {
784 if (!code->is_handler()) return false; 782 if (!code->is_handler()) return false;
785 if (target()->is_keyed_stub() && state() != PROTOTYPE_FAILURE) return false; 783 if (target()->is_keyed_stub() && state() != PROTOTYPE_FAILURE) return false;
786 Handle<HeapType> type = receiver_type(); 784 Handle<Map> map = receiver_map();
787 TypeHandleList types; 785 MapHandleList maps;
788 CodeHandleList handlers; 786 CodeHandleList handlers;
789 787
790 TargetTypes(&types); 788 TargetMaps(&maps);
791 int number_of_types = types.length(); 789 int number_of_maps = maps.length();
792 int deprecated_types = 0; 790 int deprecated_maps = 0;
793 int handler_to_overwrite = -1; 791 int handler_to_overwrite = -1;
794 792
795 for (int i = 0; i < number_of_types; i++) { 793 for (int i = 0; i < number_of_maps; i++) {
796 Handle<HeapType> current_type = types.at(i); 794 Handle<Map> current_map = maps.at(i);
797 if (current_type->IsClass() && 795 if (current_map->is_deprecated()) {
798 current_type->AsClass()->Map()->is_deprecated()) {
799 // Filter out deprecated maps to ensure their instances get migrated. 796 // Filter out deprecated maps to ensure their instances get migrated.
800 ++deprecated_types; 797 ++deprecated_maps;
801 } else if (type->NowIs(current_type)) { 798 } else if (map.is_identical_to(current_map)) {
802 // If the receiver type is already in the polymorphic IC, this indicates 799 // If the receiver type is already in the polymorphic IC, this indicates
803 // there was a prototoype chain failure. In that case, just overwrite the 800 // there was a prototoype chain failure. In that case, just overwrite the
804 // handler. 801 // handler.
805 handler_to_overwrite = i; 802 handler_to_overwrite = i;
806 } else if (handler_to_overwrite == -1 && current_type->IsClass() && 803 } else if (handler_to_overwrite == -1 &&
807 type->IsClass() && 804 IsTransitionOfMonomorphicTarget(*current_map, *map)) {
808 IsTransitionOfMonomorphicTarget(*current_type->AsClass()->Map(),
809 *type->AsClass()->Map())) {
810 handler_to_overwrite = i; 805 handler_to_overwrite = i;
811 } 806 }
812 } 807 }
813 808
814 int number_of_valid_types = 809 int number_of_valid_maps =
815 number_of_types - deprecated_types - (handler_to_overwrite != -1); 810 number_of_maps - deprecated_maps - (handler_to_overwrite != -1);
816 811
817 if (number_of_valid_types >= 4) return false; 812 if (number_of_valid_maps >= 4) return false;
818 if (number_of_types == 0 && state() != MONOMORPHIC && 813 if (number_of_maps == 0 && state() != MONOMORPHIC && state() != POLYMORPHIC) {
819 state() != POLYMORPHIC) {
820 return false; 814 return false;
821 } 815 }
822 if (UseVector()) { 816 if (UseVector()) {
823 if (!nexus()->FindHandlers(&handlers, types.length())) return false; 817 if (!nexus()->FindHandlers(&handlers, maps.length())) return false;
824 } else { 818 } else {
825 if (!target()->FindHandlers(&handlers, types.length())) return false; 819 if (!target()->FindHandlers(&handlers, maps.length())) return false;
826 } 820 }
827 821
828 number_of_valid_types++; 822 number_of_valid_maps++;
829 if (number_of_valid_types > 1 && target()->is_keyed_stub()) return false; 823 if (number_of_valid_maps > 1 && target()->is_keyed_stub()) return false;
830 Handle<Code> ic; 824 Handle<Code> ic;
831 if (number_of_valid_types == 1) { 825 if (number_of_valid_maps == 1) {
832 if (UseVector()) { 826 if (UseVector()) {
833 ConfigureVectorState(name, receiver_type(), code); 827 ConfigureVectorState(name, receiver_map(), code);
834 } else { 828 } else {
835 ic = PropertyICCompiler::ComputeMonomorphic(kind(), name, type, code, 829 ic = PropertyICCompiler::ComputeMonomorphic(kind(), name, map, code,
836 extra_ic_state()); 830 extra_ic_state());
837 } 831 }
838 } else { 832 } else {
839 if (handler_to_overwrite >= 0) { 833 if (handler_to_overwrite >= 0) {
840 handlers.Set(handler_to_overwrite, code); 834 handlers.Set(handler_to_overwrite, code);
841 if (!type->NowIs(types.at(handler_to_overwrite))) { 835 if (!map.is_identical_to(maps.at(handler_to_overwrite))) {
842 types.Set(handler_to_overwrite, type); 836 maps.Set(handler_to_overwrite, map);
843 } 837 }
844 } else { 838 } else {
845 types.Add(type); 839 maps.Add(map);
846 handlers.Add(code); 840 handlers.Add(code);
847 } 841 }
848 842
849 if (UseVector()) { 843 if (UseVector()) {
850 ConfigureVectorState(name, &types, &handlers); 844 ConfigureVectorState(name, &maps, &handlers);
851 } else { 845 } else {
852 ic = PropertyICCompiler::ComputePolymorphic(kind(), &types, &handlers, 846 ic = PropertyICCompiler::ComputePolymorphic(kind(), &maps, &handlers,
853 number_of_valid_types, name, 847 number_of_valid_maps, name,
854 extra_ic_state()); 848 extra_ic_state());
855 } 849 }
856 } 850 }
857 851
858 if (!UseVector()) set_target(*ic); 852 if (!UseVector()) set_target(*ic);
859 return true; 853 return true;
860 } 854 }
861 855
862 856
863 Handle<HeapType> IC::CurrentTypeOf(Handle<Object> object, Isolate* isolate) {
864 return object->IsJSGlobalObject()
865 ? HeapType::Constant(Handle<JSGlobalObject>::cast(object), isolate)
866 : HeapType::NowOf(object, isolate);
867 }
868
869
870 Handle<Map> IC::TypeToMap(HeapType* type, Isolate* isolate) {
871 if (type->Is(HeapType::Number()))
872 return isolate->factory()->heap_number_map();
873 if (type->Is(HeapType::Boolean())) return isolate->factory()->boolean_map();
874 if (type->IsConstant()) {
875 return handle(
876 Handle<JSGlobalObject>::cast(type->AsConstant()->Value())->map());
877 }
878 DCHECK(type->IsClass());
879 return type->AsClass()->Map();
880 }
881
882
883 template <class T>
884 typename T::TypeHandle IC::MapToType(Handle<Map> map,
885 typename T::Region* region) {
886 if (map->instance_type() == HEAP_NUMBER_TYPE) {
887 return T::Number(region);
888 } else if (map->instance_type() == ODDBALL_TYPE) {
889 // The only oddballs that can be recorded in ICs are booleans.
890 return T::Boolean(region);
891 } else {
892 return T::Class(map, region);
893 }
894 }
895
896
897 template Type* IC::MapToType<Type>(Handle<Map> map, Zone* zone);
898
899
900 template Handle<HeapType> IC::MapToType<HeapType>(Handle<Map> map,
901 Isolate* region);
902
903
904 void IC::UpdateMonomorphicIC(Handle<Code> handler, Handle<Name> name) { 857 void IC::UpdateMonomorphicIC(Handle<Code> handler, Handle<Name> name) {
905 DCHECK(handler->is_handler()); 858 DCHECK(handler->is_handler());
906 if (UseVector()) { 859 if (UseVector()) {
907 ConfigureVectorState(name, receiver_type(), handler); 860 ConfigureVectorState(name, receiver_map(), handler);
908 } else { 861 } else {
909 Handle<Code> ic = PropertyICCompiler::ComputeMonomorphic( 862 Handle<Code> ic = PropertyICCompiler::ComputeMonomorphic(
910 kind(), name, receiver_type(), handler, extra_ic_state()); 863 kind(), name, receiver_map(), handler, extra_ic_state());
911 set_target(*ic); 864 set_target(*ic);
912 } 865 }
913 } 866 }
914 867
915 868
916 void IC::CopyICToMegamorphicCache(Handle<Name> name) { 869 void IC::CopyICToMegamorphicCache(Handle<Name> name) {
917 TypeHandleList types; 870 MapHandleList maps;
918 CodeHandleList handlers; 871 CodeHandleList handlers;
919 TargetTypes(&types); 872 TargetMaps(&maps);
920 if (!target()->FindHandlers(&handlers, types.length())) return; 873 if (!target()->FindHandlers(&handlers, maps.length())) return;
921 for (int i = 0; i < types.length(); i++) { 874 for (int i = 0; i < maps.length(); i++) {
922 UpdateMegamorphicCache(*types.at(i), *name, *handlers.at(i)); 875 UpdateMegamorphicCache(*maps.at(i), *name, *handlers.at(i));
923 } 876 }
924 } 877 }
925 878
926 879
927 bool IC::IsTransitionOfMonomorphicTarget(Map* source_map, Map* target_map) { 880 bool IC::IsTransitionOfMonomorphicTarget(Map* source_map, Map* target_map) {
928 if (source_map == NULL) return true; 881 if (source_map == NULL) return true;
929 if (target_map == NULL) return false; 882 if (target_map == NULL) return false;
930 ElementsKind target_elements_kind = target_map->elements_kind(); 883 ElementsKind target_elements_kind = target_map->elements_kind();
931 bool more_general_transition = IsMoreGeneralElementsKindTransition( 884 bool more_general_transition = IsMoreGeneralElementsKindTransition(
932 source_map->elements_kind(), target_elements_kind); 885 source_map->elements_kind(), target_elements_kind);
(...skipping 21 matching lines...) Expand all
954 // same key. 907 // same key.
955 CopyICToMegamorphicCache(name); 908 CopyICToMegamorphicCache(name);
956 } 909 }
957 if (UseVector()) { 910 if (UseVector()) {
958 ConfigureVectorState(MEGAMORPHIC); 911 ConfigureVectorState(MEGAMORPHIC);
959 } else { 912 } else {
960 set_target(*megamorphic_stub()); 913 set_target(*megamorphic_stub());
961 } 914 }
962 // Fall through. 915 // Fall through.
963 case MEGAMORPHIC: 916 case MEGAMORPHIC:
964 UpdateMegamorphicCache(*receiver_type(), *name, *code); 917 UpdateMegamorphicCache(*receiver_map(), *name, *code);
965 // Indicate that we've handled this case. 918 // Indicate that we've handled this case.
966 if (UseVector()) { 919 if (UseVector()) {
967 vector_set_ = true; 920 vector_set_ = true;
968 } else { 921 } else {
969 target_set_ = true; 922 target_set_ = true;
970 } 923 }
971 break; 924 break;
972 case DEBUG_STUB: 925 case DEBUG_STUB:
973 break; 926 break;
974 case DEFAULT: 927 case DEFAULT:
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
1067 return; 1020 return;
1068 } 1021 }
1069 1022
1070 Handle<Code> code; 1023 Handle<Code> code;
1071 if (lookup->state() == LookupIterator::JSPROXY || 1024 if (lookup->state() == LookupIterator::JSPROXY ||
1072 lookup->state() == LookupIterator::ACCESS_CHECK) { 1025 lookup->state() == LookupIterator::ACCESS_CHECK) {
1073 code = slow_stub(); 1026 code = slow_stub();
1074 } else if (!lookup->IsFound()) { 1027 } else if (!lookup->IsFound()) {
1075 if (kind() == Code::LOAD_IC) { 1028 if (kind() == Code::LOAD_IC) {
1076 code = NamedLoadHandlerCompiler::ComputeLoadNonexistent(lookup->name(), 1029 code = NamedLoadHandlerCompiler::ComputeLoadNonexistent(lookup->name(),
1077 receiver_type()); 1030 receiver_map());
1078 // TODO(jkummerow/verwaest): Introduce a builtin that handles this case. 1031 // TODO(jkummerow/verwaest): Introduce a builtin that handles this case.
1079 if (code.is_null()) code = slow_stub(); 1032 if (code.is_null()) code = slow_stub();
1080 } else { 1033 } else {
1081 code = slow_stub(); 1034 code = slow_stub();
1082 } 1035 }
1083 } else { 1036 } else {
1084 code = ComputeHandler(lookup); 1037 code = ComputeHandler(lookup);
1085 } 1038 }
1086 1039
1087 PatchCache(lookup->name(), code); 1040 PatchCache(lookup->name(), code);
1088 TRACE_IC("LoadIC", lookup->name()); 1041 TRACE_IC("LoadIC", lookup->name());
1089 } 1042 }
1090 1043
1091 1044
1092 void IC::UpdateMegamorphicCache(HeapType* type, Name* name, Code* code) { 1045 void IC::UpdateMegamorphicCache(Map* map, Name* name, Code* code) {
1093 Map* map = *TypeToMap(type, isolate());
1094 isolate()->stub_cache()->Set(name, map, code); 1046 isolate()->stub_cache()->Set(name, map, code);
1095 } 1047 }
1096 1048
1097 1049
1098 Handle<Code> IC::ComputeHandler(LookupIterator* lookup, Handle<Object> value) { 1050 Handle<Code> IC::ComputeHandler(LookupIterator* lookup, Handle<Object> value) {
1099 bool receiver_is_holder = 1051 bool receiver_is_holder =
1100 lookup->GetReceiver().is_identical_to(lookup->GetHolder<JSObject>()); 1052 lookup->GetReceiver().is_identical_to(lookup->GetHolder<JSObject>());
1101 CacheHolderFlag flag; 1053 CacheHolderFlag flag;
1102 Handle<Map> stub_holder_map = IC::GetHandlerCacheHolder( 1054 Handle<Map> stub_holder_map = IC::GetHandlerCacheHolder(
1103 *receiver_type(), receiver_is_holder, isolate(), &flag); 1055 receiver_map(), receiver_is_holder, isolate(), &flag);
1104 1056
1105 Handle<Code> code = PropertyHandlerCompiler::Find( 1057 Handle<Code> code = PropertyHandlerCompiler::Find(
1106 lookup->name(), stub_holder_map, kind(), flag, 1058 lookup->name(), stub_holder_map, kind(), flag,
1107 lookup->is_dictionary_holder() ? Code::NORMAL : Code::FAST); 1059 lookup->is_dictionary_holder() ? Code::NORMAL : Code::FAST);
1108 // Use the cached value if it exists, and if it is different from the 1060 // Use the cached value if it exists, and if it is different from the
1109 // handler that just missed. 1061 // handler that just missed.
1110 if (!code.is_null()) { 1062 if (!code.is_null()) {
1111 if (!maybe_handler_.is_null() && 1063 if (!maybe_handler_.is_null() &&
1112 !maybe_handler_.ToHandleChecked().is_identical_to(code)) { 1064 !maybe_handler_.ToHandleChecked().is_identical_to(code)) {
1113 return code; 1065 return code;
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
1166 Name::Equals(isolate()->factory()->prototype_string(), lookup->name()) && 1118 Name::Equals(isolate()->factory()->prototype_string(), lookup->name()) &&
1167 Handle<JSFunction>::cast(receiver)->should_have_prototype() && 1119 Handle<JSFunction>::cast(receiver)->should_have_prototype() &&
1168 !Handle<JSFunction>::cast(receiver) 1120 !Handle<JSFunction>::cast(receiver)
1169 ->map() 1121 ->map()
1170 ->has_non_instance_prototype()) { 1122 ->has_non_instance_prototype()) {
1171 Handle<Code> stub; 1123 Handle<Code> stub;
1172 FunctionPrototypeStub function_prototype_stub(isolate()); 1124 FunctionPrototypeStub function_prototype_stub(isolate());
1173 return function_prototype_stub.GetCode(); 1125 return function_prototype_stub.GetCode();
1174 } 1126 }
1175 1127
1176 Handle<HeapType> type = receiver_type(); 1128 Handle<Map> map = receiver_map();
1177 Handle<JSObject> holder = lookup->GetHolder<JSObject>(); 1129 Handle<JSObject> holder = lookup->GetHolder<JSObject>();
1178 bool receiver_is_holder = receiver.is_identical_to(holder); 1130 bool receiver_is_holder = receiver.is_identical_to(holder);
1179 switch (lookup->state()) { 1131 switch (lookup->state()) {
1180 case LookupIterator::INTERCEPTOR: { 1132 case LookupIterator::INTERCEPTOR: {
1181 DCHECK(!holder->GetNamedInterceptor()->getter()->IsUndefined()); 1133 DCHECK(!holder->GetNamedInterceptor()->getter()->IsUndefined());
1182 NamedLoadHandlerCompiler compiler(isolate(), receiver_type(), holder, 1134 NamedLoadHandlerCompiler compiler(isolate(), map, holder, cache_holder);
1183 cache_holder);
1184 // Perform a lookup behind the interceptor. Copy the LookupIterator since 1135 // Perform a lookup behind the interceptor. Copy the LookupIterator since
1185 // the original iterator will be used to fetch the value. 1136 // the original iterator will be used to fetch the value.
1186 LookupIterator it = *lookup; 1137 LookupIterator it = *lookup;
1187 it.Next(); 1138 it.Next();
1188 LookupForRead(&it); 1139 LookupForRead(&it);
1189 return compiler.CompileLoadInterceptor(&it); 1140 return compiler.CompileLoadInterceptor(&it);
1190 } 1141 }
1191 1142
1192 case LookupIterator::ACCESSOR: { 1143 case LookupIterator::ACCESSOR: {
1193 // Use simple field loads for some well-known callback properties. 1144 // Use simple field loads for some well-known callback properties.
1194 if (receiver_is_holder) { 1145 if (receiver_is_holder) {
1195 DCHECK(receiver->IsJSObject()); 1146 DCHECK(receiver->IsJSObject());
1196 Handle<JSObject> js_receiver = Handle<JSObject>::cast(receiver); 1147 Handle<JSObject> js_receiver = Handle<JSObject>::cast(receiver);
1197 int object_offset; 1148 int object_offset;
1198 if (Accessors::IsJSObjectFieldAccessor<HeapType>(type, lookup->name(), 1149 if (Accessors::IsJSObjectFieldAccessor(map, lookup->name(),
1199 &object_offset)) { 1150 &object_offset)) {
1200 FieldIndex index = 1151 FieldIndex index =
1201 FieldIndex::ForInObjectOffset(object_offset, js_receiver->map()); 1152 FieldIndex::ForInObjectOffset(object_offset, js_receiver->map());
1202 return SimpleFieldLoad(index); 1153 return SimpleFieldLoad(index);
1203 } 1154 }
1204 } 1155 }
1205 1156
1206 Handle<Object> accessors = lookup->GetAccessors(); 1157 Handle<Object> accessors = lookup->GetAccessors();
1207 if (accessors->IsExecutableAccessorInfo()) { 1158 if (accessors->IsExecutableAccessorInfo()) {
1208 Handle<ExecutableAccessorInfo> info = 1159 Handle<ExecutableAccessorInfo> info =
1209 Handle<ExecutableAccessorInfo>::cast(accessors); 1160 Handle<ExecutableAccessorInfo>::cast(accessors);
1210 if (v8::ToCData<Address>(info->getter()) == 0) break; 1161 if (v8::ToCData<Address>(info->getter()) == 0) break;
1211 if (!ExecutableAccessorInfo::IsCompatibleReceiverType(isolate(), info, 1162 if (!ExecutableAccessorInfo::IsCompatibleReceiverMap(isolate(), info,
1212 type)) { 1163 map)) {
1213 break; 1164 break;
1214 } 1165 }
1215 if (!holder->HasFastProperties()) break; 1166 if (!holder->HasFastProperties()) break;
1216 NamedLoadHandlerCompiler compiler(isolate(), receiver_type(), holder, 1167 NamedLoadHandlerCompiler compiler(isolate(), map, holder, cache_holder);
1217 cache_holder);
1218 return compiler.CompileLoadCallback(lookup->name(), info); 1168 return compiler.CompileLoadCallback(lookup->name(), info);
1219 } 1169 }
1220 if (accessors->IsAccessorPair()) { 1170 if (accessors->IsAccessorPair()) {
1221 Handle<Object> getter(Handle<AccessorPair>::cast(accessors)->getter(), 1171 Handle<Object> getter(Handle<AccessorPair>::cast(accessors)->getter(),
1222 isolate()); 1172 isolate());
1223 if (!getter->IsJSFunction()) break; 1173 if (!getter->IsJSFunction()) break;
1224 if (!holder->HasFastProperties()) break; 1174 if (!holder->HasFastProperties()) break;
1225 Handle<JSFunction> function = Handle<JSFunction>::cast(getter); 1175 Handle<JSFunction> function = Handle<JSFunction>::cast(getter);
1226 if (!receiver->IsJSObject() && !function->IsBuiltin() && 1176 if (!receiver->IsJSObject() && !function->IsBuiltin() &&
1227 is_sloppy(function->shared()->language_mode())) { 1177 is_sloppy(function->shared()->language_mode())) {
1228 // Calling sloppy non-builtins with a value as the receiver 1178 // Calling sloppy non-builtins with a value as the receiver
1229 // requires boxing. 1179 // requires boxing.
1230 break; 1180 break;
1231 } 1181 }
1232 CallOptimization call_optimization(function); 1182 CallOptimization call_optimization(function);
1233 NamedLoadHandlerCompiler compiler(isolate(), receiver_type(), holder, 1183 NamedLoadHandlerCompiler compiler(isolate(), map, holder, cache_holder);
1234 cache_holder);
1235 if (call_optimization.is_simple_api_call() && 1184 if (call_optimization.is_simple_api_call() &&
1236 call_optimization.IsCompatibleReceiver(receiver, holder)) { 1185 call_optimization.IsCompatibleReceiver(receiver, holder)) {
1237 return compiler.CompileLoadCallback(lookup->name(), call_optimization, 1186 return compiler.CompileLoadCallback(lookup->name(), call_optimization,
1238 lookup->GetAccessorIndex()); 1187 lookup->GetAccessorIndex());
1239 } 1188 }
1240 int expected_arguments = 1189 int expected_arguments =
1241 function->shared()->internal_formal_parameter_count(); 1190 function->shared()->internal_formal_parameter_count();
1242 return compiler.CompileLoadViaGetter( 1191 return compiler.CompileLoadViaGetter(
1243 lookup->name(), lookup->GetAccessorIndex(), expected_arguments); 1192 lookup->name(), lookup->GetAccessorIndex(), expected_arguments);
1244 } 1193 }
1245 break; 1194 break;
1246 } 1195 }
1247 1196
1248 case LookupIterator::DATA: { 1197 case LookupIterator::DATA: {
1249 if (lookup->is_dictionary_holder()) { 1198 if (lookup->is_dictionary_holder()) {
1250 if (kind() != Code::LOAD_IC) break; 1199 if (kind() != Code::LOAD_IC) break;
1251 if (holder->IsGlobalObject()) { 1200 if (holder->IsGlobalObject()) {
1252 NamedLoadHandlerCompiler compiler(isolate(), receiver_type(), holder, 1201 NamedLoadHandlerCompiler compiler(isolate(), map, holder,
1253 cache_holder); 1202 cache_holder);
1254 Handle<PropertyCell> cell = lookup->GetPropertyCell(); 1203 Handle<PropertyCell> cell = lookup->GetPropertyCell();
1255 Handle<Code> code = compiler.CompileLoadGlobal( 1204 Handle<Code> code = compiler.CompileLoadGlobal(
1256 cell, lookup->name(), lookup->IsConfigurable()); 1205 cell, lookup->name(), lookup->IsConfigurable());
1257 // TODO(verwaest): Move caching of these NORMAL stubs outside as well. 1206 // TODO(verwaest): Move caching of these NORMAL stubs outside as well.
1258 CacheHolderFlag flag; 1207 CacheHolderFlag flag;
1259 Handle<Map> stub_holder_map = GetHandlerCacheHolder( 1208 Handle<Map> stub_holder_map =
1260 *type, receiver_is_holder, isolate(), &flag); 1209 GetHandlerCacheHolder(map, receiver_is_holder, isolate(), &flag);
1261 Map::UpdateCodeCache(stub_holder_map, lookup->name(), code); 1210 Map::UpdateCodeCache(stub_holder_map, lookup->name(), code);
1262 return code; 1211 return code;
1263 } 1212 }
1264 // There is only one shared stub for loading normalized 1213 // There is only one shared stub for loading normalized
1265 // properties. It does not traverse the prototype chain, so the 1214 // properties. It does not traverse the prototype chain, so the
1266 // property must be found in the object for the stub to be 1215 // property must be found in the object for the stub to be
1267 // applicable. 1216 // applicable.
1268 if (!receiver_is_holder) break; 1217 if (!receiver_is_holder) break;
1269 return isolate()->builtins()->LoadIC_Normal(); 1218 return isolate()->builtins()->LoadIC_Normal();
1270 } 1219 }
1271 1220
1272 // -------------- Fields -------------- 1221 // -------------- Fields --------------
1273 if (lookup->property_details().type() == DATA) { 1222 if (lookup->property_details().type() == DATA) {
1274 FieldIndex field = lookup->GetFieldIndex(); 1223 FieldIndex field = lookup->GetFieldIndex();
1275 if (receiver_is_holder) { 1224 if (receiver_is_holder) {
1276 return SimpleFieldLoad(field); 1225 return SimpleFieldLoad(field);
1277 } 1226 }
1278 NamedLoadHandlerCompiler compiler(isolate(), receiver_type(), holder, 1227 NamedLoadHandlerCompiler compiler(isolate(), map, holder, cache_holder);
1279 cache_holder);
1280 return compiler.CompileLoadField(lookup->name(), field); 1228 return compiler.CompileLoadField(lookup->name(), field);
1281 } 1229 }
1282 1230
1283 // -------------- Constant properties -------------- 1231 // -------------- Constant properties --------------
1284 DCHECK(lookup->property_details().type() == DATA_CONSTANT); 1232 DCHECK(lookup->property_details().type() == DATA_CONSTANT);
1285 if (receiver_is_holder) { 1233 if (receiver_is_holder) {
1286 LoadConstantStub stub(isolate(), lookup->GetConstantIndex()); 1234 LoadConstantStub stub(isolate(), lookup->GetConstantIndex());
1287 return stub.GetCode(); 1235 return stub.GetCode();
1288 } 1236 }
1289 NamedLoadHandlerCompiler compiler(isolate(), receiver_type(), holder, 1237 NamedLoadHandlerCompiler compiler(isolate(), map, holder, cache_holder);
1290 cache_holder);
1291 return compiler.CompileLoadConstant(lookup->name(), 1238 return compiler.CompileLoadConstant(lookup->name(),
1292 lookup->GetConstantIndex()); 1239 lookup->GetConstantIndex());
1293 } 1240 }
1294 1241
1295 case LookupIterator::ACCESS_CHECK: 1242 case LookupIterator::ACCESS_CHECK:
1296 case LookupIterator::JSPROXY: 1243 case LookupIterator::JSPROXY:
1297 case LookupIterator::NOT_FOUND: 1244 case LookupIterator::NOT_FOUND:
1298 case LookupIterator::TRANSITION: 1245 case LookupIterator::TRANSITION:
1299 UNREACHABLE(); 1246 UNREACHABLE();
1300 } 1247 }
(...skipping 26 matching lines...) Expand all
1327 Handle<Code> null_handle; 1274 Handle<Code> null_handle;
1328 Handle<Map> receiver_map(receiver->map(), isolate()); 1275 Handle<Map> receiver_map(receiver->map(), isolate());
1329 MapHandleList target_receiver_maps; 1276 MapHandleList target_receiver_maps;
1330 TargetMaps(&target_receiver_maps); 1277 TargetMaps(&target_receiver_maps);
1331 1278
1332 1279
1333 if (target_receiver_maps.length() == 0) { 1280 if (target_receiver_maps.length() == 0) {
1334 if (FLAG_vector_ics) { 1281 if (FLAG_vector_ics) {
1335 Handle<Code> handler = 1282 Handle<Code> handler =
1336 PropertyICCompiler::ComputeKeyedLoadMonomorphicHandler(receiver_map); 1283 PropertyICCompiler::ComputeKeyedLoadMonomorphicHandler(receiver_map);
1337 ConfigureVectorState(Handle<Name>::null(), receiver_type(), handler); 1284 ConfigureVectorState(Handle<Name>::null(), receiver_map, handler);
1338 return null_handle; 1285 return null_handle;
1339 } 1286 }
1340 return PropertyICCompiler::ComputeKeyedLoadMonomorphic(receiver_map); 1287 return PropertyICCompiler::ComputeKeyedLoadMonomorphic(receiver_map);
1341 } 1288 }
1342 1289
1343 // The first time a receiver is seen that is a transitioned version of the 1290 // The first time a receiver is seen that is a transitioned version of the
1344 // previous monomorphic receiver type, assume the new ElementsKind is the 1291 // previous monomorphic receiver type, assume the new ElementsKind is the
1345 // monomorphic type. This benefits global arrays that only transition 1292 // monomorphic type. This benefits global arrays that only transition
1346 // once, and all call sites accessing them are faster if they remain 1293 // once, and all call sites accessing them are faster if they remain
1347 // monomorphic. If this optimistic assumption is not true, the IC will 1294 // monomorphic. If this optimistic assumption is not true, the IC will
1348 // miss again and it will become polymorphic and support both the 1295 // miss again and it will become polymorphic and support both the
1349 // untransitioned and transitioned maps. 1296 // untransitioned and transitioned maps.
1350 if (state() == MONOMORPHIC && !receiver->IsString() && 1297 if (state() == MONOMORPHIC && !receiver->IsString() &&
1351 IsMoreGeneralElementsKindTransition( 1298 IsMoreGeneralElementsKindTransition(
1352 target_receiver_maps.at(0)->elements_kind(), 1299 target_receiver_maps.at(0)->elements_kind(),
1353 Handle<JSObject>::cast(receiver)->GetElementsKind())) { 1300 Handle<JSObject>::cast(receiver)->GetElementsKind())) {
1354 if (FLAG_vector_ics) { 1301 if (FLAG_vector_ics) {
1355 Handle<Code> handler = 1302 Handle<Code> handler =
1356 PropertyICCompiler::ComputeKeyedLoadMonomorphicHandler(receiver_map); 1303 PropertyICCompiler::ComputeKeyedLoadMonomorphicHandler(receiver_map);
1357 ConfigureVectorState(Handle<Name>::null(), receiver_type(), handler); 1304 ConfigureVectorState(Handle<Name>::null(), receiver_map, handler);
1358 return null_handle; 1305 return null_handle;
1359 } 1306 }
1360 return PropertyICCompiler::ComputeKeyedLoadMonomorphic(receiver_map); 1307 return PropertyICCompiler::ComputeKeyedLoadMonomorphic(receiver_map);
1361 } 1308 }
1362 1309
1363 DCHECK(state() != GENERIC); 1310 DCHECK(state() != GENERIC);
1364 1311
1365 // Determine the list of receiver maps that this call site has seen, 1312 // Determine the list of receiver maps that this call site has seen,
1366 // adding the map that was just encountered. 1313 // adding the map that was just encountered.
1367 if (!AddOneReceiverMapIfMissing(&target_receiver_maps, receiver_map)) { 1314 if (!AddOneReceiverMapIfMissing(&target_receiver_maps, receiver_map)) {
1368 // If the miss wasn't due to an unseen map, a polymorphic stub 1315 // If the miss wasn't due to an unseen map, a polymorphic stub
1369 // won't help, use the generic stub. 1316 // won't help, use the generic stub.
1370 TRACE_GENERIC_IC(isolate(), "KeyedLoadIC", "same map added twice"); 1317 TRACE_GENERIC_IC(isolate(), "KeyedLoadIC", "same map added twice");
1371 return megamorphic_stub(); 1318 return megamorphic_stub();
1372 } 1319 }
1373 1320
1374 // If the maximum number of receiver maps has been exceeded, use the generic 1321 // If the maximum number of receiver maps has been exceeded, use the generic
1375 // version of the IC. 1322 // version of the IC.
1376 if (target_receiver_maps.length() > kMaxKeyedPolymorphism) { 1323 if (target_receiver_maps.length() > kMaxKeyedPolymorphism) {
1377 TRACE_GENERIC_IC(isolate(), "KeyedLoadIC", "max polymorph exceeded"); 1324 TRACE_GENERIC_IC(isolate(), "KeyedLoadIC", "max polymorph exceeded");
1378 return megamorphic_stub(); 1325 return megamorphic_stub();
1379 } 1326 }
1380 1327
1381 if (FLAG_vector_ics) { 1328 if (FLAG_vector_ics) {
1382 CodeHandleList handlers(target_receiver_maps.length()); 1329 CodeHandleList handlers(target_receiver_maps.length());
1383 ElementHandlerCompiler compiler(isolate()); 1330 ElementHandlerCompiler compiler(isolate());
1384 compiler.CompileElementHandlers(&target_receiver_maps, &handlers); 1331 compiler.CompileElementHandlers(&target_receiver_maps, &handlers);
1385 TypeHandleList types(target_receiver_maps.length()); 1332 ConfigureVectorState(Handle<Name>::null(), &target_receiver_maps,
1386 for (int i = 0; i < target_receiver_maps.length(); i++) { 1333 &handlers);
1387 types.Add(HeapType::Class(target_receiver_maps.at(i), isolate()));
1388 }
1389 ConfigureVectorState(Handle<Name>::null(), &types, &handlers);
1390 return null_handle; 1334 return null_handle;
1391 } 1335 }
1392 1336
1393 return PropertyICCompiler::ComputeKeyedLoadPolymorphic(&target_receiver_maps); 1337 return PropertyICCompiler::ComputeKeyedLoadPolymorphic(&target_receiver_maps);
1394 } 1338 }
1395 1339
1396 1340
1397 MaybeHandle<Object> KeyedLoadIC::Load(Handle<Object> object, 1341 MaybeHandle<Object> KeyedLoadIC::Load(Handle<Object> object,
1398 Handle<Object> key) { 1342 Handle<Object> key) {
1399 if (MigrateDeprecated(object)) { 1343 if (MigrateDeprecated(object)) {
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
1485 break; 1429 break;
1486 case LookupIterator::ACCESSOR: 1430 case LookupIterator::ACCESSOR:
1487 return !it->IsReadOnly(); 1431 return !it->IsReadOnly();
1488 case LookupIterator::DATA: { 1432 case LookupIterator::DATA: {
1489 if (it->IsReadOnly()) return false; 1433 if (it->IsReadOnly()) return false;
1490 Handle<JSObject> holder = it->GetHolder<JSObject>(); 1434 Handle<JSObject> holder = it->GetHolder<JSObject>();
1491 if (receiver.is_identical_to(holder)) { 1435 if (receiver.is_identical_to(holder)) {
1492 it->PrepareForDataProperty(value); 1436 it->PrepareForDataProperty(value);
1493 // The previous receiver map might just have been deprecated, 1437 // The previous receiver map might just have been deprecated,
1494 // so reload it. 1438 // so reload it.
1495 update_receiver_type(receiver); 1439 update_receiver_map(receiver);
1496 return true; 1440 return true;
1497 } 1441 }
1498 1442
1499 // Receiver != holder. 1443 // Receiver != holder.
1500 PrototypeIterator iter(it->isolate(), receiver); 1444 PrototypeIterator iter(it->isolate(), receiver);
1501 if (receiver->IsJSGlobalProxy()) { 1445 if (receiver->IsJSGlobalProxy()) {
1502 return it->GetHolder<Object>().is_identical_to( 1446 return it->GetHolder<Object>().is_identical_to(
1503 PrototypeIterator::GetCurrent(iter)); 1447 PrototypeIterator::GetCurrent(iter));
1504 } 1448 }
1505 1449
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after
1710 lookup->name(), cell, value); 1654 lookup->name(), cell, value);
1711 } 1655 }
1712 Handle<Map> transition = lookup->transition_map(); 1656 Handle<Map> transition = lookup->transition_map();
1713 // Currently not handled by CompileStoreTransition. 1657 // Currently not handled by CompileStoreTransition.
1714 if (!holder->HasFastProperties()) { 1658 if (!holder->HasFastProperties()) {
1715 TRACE_GENERIC_IC(isolate(), "StoreIC", "transition from slow"); 1659 TRACE_GENERIC_IC(isolate(), "StoreIC", "transition from slow");
1716 break; 1660 break;
1717 } 1661 }
1718 1662
1719 DCHECK(lookup->IsCacheableTransition()); 1663 DCHECK(lookup->IsCacheableTransition());
1720 NamedStoreHandlerCompiler compiler(isolate(), receiver_type(), holder); 1664 NamedStoreHandlerCompiler compiler(isolate(), receiver_map(), holder);
1721 return compiler.CompileStoreTransition(transition, lookup->name()); 1665 return compiler.CompileStoreTransition(transition, lookup->name());
1722 } 1666 }
1723 1667
1724 case LookupIterator::INTERCEPTOR: { 1668 case LookupIterator::INTERCEPTOR: {
1725 DCHECK(!holder->GetNamedInterceptor()->setter()->IsUndefined()); 1669 DCHECK(!holder->GetNamedInterceptor()->setter()->IsUndefined());
1726 NamedStoreHandlerCompiler compiler(isolate(), receiver_type(), holder); 1670 NamedStoreHandlerCompiler compiler(isolate(), receiver_map(), holder);
1727 return compiler.CompileStoreInterceptor(lookup->name()); 1671 return compiler.CompileStoreInterceptor(lookup->name());
1728 } 1672 }
1729 1673
1730 case LookupIterator::ACCESSOR: { 1674 case LookupIterator::ACCESSOR: {
1731 if (!holder->HasFastProperties()) { 1675 if (!holder->HasFastProperties()) {
1732 TRACE_GENERIC_IC(isolate(), "StoreIC", "accessor on slow map"); 1676 TRACE_GENERIC_IC(isolate(), "StoreIC", "accessor on slow map");
1733 break; 1677 break;
1734 } 1678 }
1735 Handle<Object> accessors = lookup->GetAccessors(); 1679 Handle<Object> accessors = lookup->GetAccessors();
1736 if (accessors->IsExecutableAccessorInfo()) { 1680 if (accessors->IsExecutableAccessorInfo()) {
1737 Handle<ExecutableAccessorInfo> info = 1681 Handle<ExecutableAccessorInfo> info =
1738 Handle<ExecutableAccessorInfo>::cast(accessors); 1682 Handle<ExecutableAccessorInfo>::cast(accessors);
1739 if (v8::ToCData<Address>(info->setter()) == 0) { 1683 if (v8::ToCData<Address>(info->setter()) == 0) {
1740 TRACE_GENERIC_IC(isolate(), "StoreIC", "setter == 0"); 1684 TRACE_GENERIC_IC(isolate(), "StoreIC", "setter == 0");
1741 break; 1685 break;
1742 } 1686 }
1743 if (!ExecutableAccessorInfo::IsCompatibleReceiverType( 1687 if (!ExecutableAccessorInfo::IsCompatibleReceiverMap(isolate(), info,
1744 isolate(), info, receiver_type())) { 1688 receiver_map())) {
1745 TRACE_GENERIC_IC(isolate(), "StoreIC", "incompatible receiver type"); 1689 TRACE_GENERIC_IC(isolate(), "StoreIC", "incompatible receiver type");
1746 break; 1690 break;
1747 } 1691 }
1748 NamedStoreHandlerCompiler compiler(isolate(), receiver_type(), holder); 1692 NamedStoreHandlerCompiler compiler(isolate(), receiver_map(), holder);
1749 return compiler.CompileStoreCallback(receiver, lookup->name(), 1693 return compiler.CompileStoreCallback(receiver, lookup->name(),
1750 lookup->GetAccessorIndex()); 1694 lookup->GetAccessorIndex());
1751 } else if (accessors->IsAccessorPair()) { 1695 } else if (accessors->IsAccessorPair()) {
1752 Handle<Object> setter(Handle<AccessorPair>::cast(accessors)->setter(), 1696 Handle<Object> setter(Handle<AccessorPair>::cast(accessors)->setter(),
1753 isolate()); 1697 isolate());
1754 if (!setter->IsJSFunction()) { 1698 if (!setter->IsJSFunction()) {
1755 TRACE_GENERIC_IC(isolate(), "StoreIC", "setter not a function"); 1699 TRACE_GENERIC_IC(isolate(), "StoreIC", "setter not a function");
1756 break; 1700 break;
1757 } 1701 }
1758 Handle<JSFunction> function = Handle<JSFunction>::cast(setter); 1702 Handle<JSFunction> function = Handle<JSFunction>::cast(setter);
1759 CallOptimization call_optimization(function); 1703 CallOptimization call_optimization(function);
1760 NamedStoreHandlerCompiler compiler(isolate(), receiver_type(), holder); 1704 NamedStoreHandlerCompiler compiler(isolate(), receiver_map(), holder);
1761 if (call_optimization.is_simple_api_call() && 1705 if (call_optimization.is_simple_api_call() &&
1762 call_optimization.IsCompatibleReceiver(receiver, holder)) { 1706 call_optimization.IsCompatibleReceiver(receiver, holder)) {
1763 return compiler.CompileStoreCallback(receiver, lookup->name(), 1707 return compiler.CompileStoreCallback(receiver, lookup->name(),
1764 call_optimization, 1708 call_optimization,
1765 lookup->GetAccessorIndex()); 1709 lookup->GetAccessorIndex());
1766 } 1710 }
1767 int expected_arguments = 1711 int expected_arguments =
1768 function->shared()->internal_formal_parameter_count(); 1712 function->shared()->internal_formal_parameter_count();
1769 return compiler.CompileStoreViaSetter(receiver, lookup->name(), 1713 return compiler.CompileStoreViaSetter(receiver, lookup->name(),
1770 lookup->GetAccessorIndex(), 1714 lookup->GetAccessorIndex(),
(...skipping 23 matching lines...) Expand all
1794 // Only use a generic stub if no types need to be tracked. 1738 // Only use a generic stub if no types need to be tracked.
1795 Handle<HeapType> field_type = lookup->GetFieldType(); 1739 Handle<HeapType> field_type = lookup->GetFieldType();
1796 HeapType::Iterator<Map> it = field_type->Classes(); 1740 HeapType::Iterator<Map> it = field_type->Classes();
1797 use_stub = it.Done(); 1741 use_stub = it.Done();
1798 } 1742 }
1799 if (use_stub) { 1743 if (use_stub) {
1800 StoreFieldStub stub(isolate(), lookup->GetFieldIndex(), 1744 StoreFieldStub stub(isolate(), lookup->GetFieldIndex(),
1801 lookup->representation()); 1745 lookup->representation());
1802 return stub.GetCode(); 1746 return stub.GetCode();
1803 } 1747 }
1804 NamedStoreHandlerCompiler compiler(isolate(), receiver_type(), holder); 1748 NamedStoreHandlerCompiler compiler(isolate(), receiver_map(), holder);
1805 return compiler.CompileStoreField(lookup); 1749 return compiler.CompileStoreField(lookup);
1806 } 1750 }
1807 1751
1808 // -------------- Constant properties -------------- 1752 // -------------- Constant properties --------------
1809 DCHECK(lookup->property_details().type() == DATA_CONSTANT); 1753 DCHECK(lookup->property_details().type() == DATA_CONSTANT);
1810 TRACE_GENERIC_IC(isolate(), "StoreIC", "constant property"); 1754 TRACE_GENERIC_IC(isolate(), "StoreIC", "constant property");
1811 break; 1755 break;
1812 } 1756 }
1813 1757
1814 case LookupIterator::ACCESS_CHECK: 1758 case LookupIterator::ACCESS_CHECK:
(...skipping 1199 matching lines...) Expand 10 before | Expand all | Expand 10 after
3014 static const Address IC_utilities[] = { 2958 static const Address IC_utilities[] = {
3015 #define ADDR(name) FUNCTION_ADDR(name), 2959 #define ADDR(name) FUNCTION_ADDR(name),
3016 IC_UTIL_LIST(ADDR) NULL 2960 IC_UTIL_LIST(ADDR) NULL
3017 #undef ADDR 2961 #undef ADDR
3018 }; 2962 };
3019 2963
3020 2964
3021 Address IC::AddressFromUtilityId(IC::UtilityId id) { return IC_utilities[id]; } 2965 Address IC::AddressFromUtilityId(IC::UtilityId id) { return IC_utilities[id]; }
3022 } 2966 }
3023 } // namespace v8::internal 2967 } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ic/ic.h ('k') | src/ic/ic-compiler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698