OLD | NEW |
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 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
270 } | 270 } |
271 | 271 |
272 bool IC::ShouldRecomputeHandler(Handle<Object> receiver, Handle<String> name) { | 272 bool IC::ShouldRecomputeHandler(Handle<Object> receiver, Handle<String> name) { |
273 if (!RecomputeHandlerForName(name)) return false; | 273 if (!RecomputeHandlerForName(name)) return false; |
274 | 274 |
275 DCHECK(UseVector()); | 275 DCHECK(UseVector()); |
276 maybe_handler_ = nexus()->FindHandlerForMap(receiver_map()); | 276 maybe_handler_ = nexus()->FindHandlerForMap(receiver_map()); |
277 | 277 |
278 // This is a contextual access, always just update the handler and stay | 278 // This is a contextual access, always just update the handler and stay |
279 // monomorphic. | 279 // monomorphic. |
280 if (receiver->IsJSGlobalObject()) return true; | 280 if (kind() == Code::LOAD_GLOBAL_IC) return true; |
281 | 281 |
282 // The current map wasn't handled yet. There's no reason to stay monomorphic, | 282 // The current map wasn't handled yet. There's no reason to stay monomorphic, |
283 // *unless* we're moving from a deprecated map to its replacement, or | 283 // *unless* we're moving from a deprecated map to its replacement, or |
284 // to a more general elements kind. | 284 // to a more general elements kind. |
285 // TODO(verwaest): Check if the current map is actually what the old map | 285 // TODO(verwaest): Check if the current map is actually what the old map |
286 // would transition to. | 286 // would transition to. |
287 if (maybe_handler_.is_null()) { | 287 if (maybe_handler_.is_null()) { |
288 if (!receiver_map()->IsJSObjectMap()) return false; | 288 if (!receiver_map()->IsJSObjectMap()) return false; |
289 Map* first_map = FirstTargetMap(); | 289 Map* first_map = FirstTargetMap(); |
290 if (first_map == NULL) return false; | 290 if (first_map == NULL) return false; |
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
457 } | 457 } |
458 } | 458 } |
459 | 459 |
460 | 460 |
461 void LoadIC::Clear(Isolate* isolate, Code* host, LoadICNexus* nexus) { | 461 void LoadIC::Clear(Isolate* isolate, Code* host, LoadICNexus* nexus) { |
462 if (IsCleared(nexus)) return; | 462 if (IsCleared(nexus)) return; |
463 nexus->ConfigurePremonomorphic(); | 463 nexus->ConfigurePremonomorphic(); |
464 OnTypeFeedbackChanged(isolate, host); | 464 OnTypeFeedbackChanged(isolate, host); |
465 } | 465 } |
466 | 466 |
| 467 void LoadGlobalIC::Clear(Isolate* isolate, Code* host, |
| 468 LoadGlobalICNexus* nexus) { |
| 469 if (IsCleared(nexus)) return; |
| 470 nexus->ConfigureUninitialized(); |
| 471 OnTypeFeedbackChanged(isolate, host); |
| 472 } |
467 | 473 |
468 void StoreIC::Clear(Isolate* isolate, Code* host, StoreICNexus* nexus) { | 474 void StoreIC::Clear(Isolate* isolate, Code* host, StoreICNexus* nexus) { |
469 if (IsCleared(nexus)) return; | 475 if (IsCleared(nexus)) return; |
470 nexus->ConfigurePremonomorphic(); | 476 nexus->ConfigurePremonomorphic(); |
471 OnTypeFeedbackChanged(isolate, host); | 477 OnTypeFeedbackChanged(isolate, host); |
472 } | 478 } |
473 | 479 |
474 | 480 |
475 void KeyedStoreIC::Clear(Isolate* isolate, Code* host, | 481 void KeyedStoreIC::Clear(Isolate* isolate, Code* host, |
476 KeyedStoreICNexus* nexus) { | 482 KeyedStoreICNexus* nexus) { |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
534 OnTypeFeedbackChanged(isolate(), get_host()); | 540 OnTypeFeedbackChanged(isolate(), get_host()); |
535 } | 541 } |
536 | 542 |
537 | 543 |
538 void IC::ConfigureVectorState(Handle<Name> name, Handle<Map> map, | 544 void IC::ConfigureVectorState(Handle<Name> name, Handle<Map> map, |
539 Handle<Code> handler) { | 545 Handle<Code> handler) { |
540 DCHECK(UseVector()); | 546 DCHECK(UseVector()); |
541 if (kind() == Code::LOAD_IC) { | 547 if (kind() == Code::LOAD_IC) { |
542 LoadICNexus* nexus = casted_nexus<LoadICNexus>(); | 548 LoadICNexus* nexus = casted_nexus<LoadICNexus>(); |
543 nexus->ConfigureMonomorphic(map, handler); | 549 nexus->ConfigureMonomorphic(map, handler); |
| 550 } else if (kind() == Code::LOAD_GLOBAL_IC) { |
| 551 LoadGlobalICNexus* nexus = casted_nexus<LoadGlobalICNexus>(); |
| 552 nexus->ConfigureMonomorphic(map, handler); |
544 } else if (kind() == Code::KEYED_LOAD_IC) { | 553 } else if (kind() == Code::KEYED_LOAD_IC) { |
545 KeyedLoadICNexus* nexus = casted_nexus<KeyedLoadICNexus>(); | 554 KeyedLoadICNexus* nexus = casted_nexus<KeyedLoadICNexus>(); |
546 nexus->ConfigureMonomorphic(name, map, handler); | 555 nexus->ConfigureMonomorphic(name, map, handler); |
547 } else if (kind() == Code::STORE_IC) { | 556 } else if (kind() == Code::STORE_IC) { |
548 StoreICNexus* nexus = casted_nexus<StoreICNexus>(); | 557 StoreICNexus* nexus = casted_nexus<StoreICNexus>(); |
549 nexus->ConfigureMonomorphic(map, handler); | 558 nexus->ConfigureMonomorphic(map, handler); |
550 } else { | 559 } else { |
551 DCHECK(kind() == Code::KEYED_STORE_IC); | 560 DCHECK(kind() == Code::KEYED_STORE_IC); |
552 KeyedStoreICNexus* nexus = casted_nexus<KeyedStoreICNexus>(); | 561 KeyedStoreICNexus* nexus = casted_nexus<KeyedStoreICNexus>(); |
553 nexus->ConfigureMonomorphic(name, map, handler); | 562 nexus->ConfigureMonomorphic(name, map, handler); |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
614 } | 623 } |
615 Handle<Object> result; | 624 Handle<Object> result; |
616 ASSIGN_RETURN_ON_EXCEPTION(isolate(), result, | 625 ASSIGN_RETURN_ON_EXCEPTION(isolate(), result, |
617 Object::GetElement(isolate(), object, index), | 626 Object::GetElement(isolate(), object, index), |
618 Object); | 627 Object); |
619 return result; | 628 return result; |
620 } | 629 } |
621 | 630 |
622 bool use_ic = MigrateDeprecated(object) ? false : FLAG_use_ic; | 631 bool use_ic = MigrateDeprecated(object) ? false : FLAG_use_ic; |
623 | 632 |
624 if (object->IsJSGlobalObject() && name->IsString()) { | |
625 // Look up in script context table. | |
626 Handle<String> str_name = Handle<String>::cast(name); | |
627 Handle<JSGlobalObject> global = Handle<JSGlobalObject>::cast(object); | |
628 Handle<ScriptContextTable> script_contexts( | |
629 global->native_context()->script_context_table()); | |
630 | |
631 ScriptContextTable::LookupResult lookup_result; | |
632 if (ScriptContextTable::Lookup(script_contexts, str_name, &lookup_result)) { | |
633 Handle<Object> result = | |
634 FixedArray::get(*ScriptContextTable::GetContext( | |
635 script_contexts, lookup_result.context_index), | |
636 lookup_result.slot_index, isolate()); | |
637 if (result->IsTheHole(isolate())) { | |
638 // Do not install stubs and stay pre-monomorphic for | |
639 // uninitialized accesses. | |
640 return ReferenceError(name); | |
641 } | |
642 | |
643 if (use_ic && LoadScriptContextFieldStub::Accepted(&lookup_result)) { | |
644 TRACE_HANDLER_STATS(isolate(), LoadIC_LoadScriptContextFieldStub); | |
645 LoadScriptContextFieldStub stub(isolate(), &lookup_result); | |
646 PatchCache(name, stub.GetCode()); | |
647 } | |
648 return result; | |
649 } | |
650 } | |
651 | |
652 if (state() != UNINITIALIZED) { | 633 if (state() != UNINITIALIZED) { |
653 JSObject::MakePrototypesFast(object, kStartAtReceiver, isolate()); | 634 JSObject::MakePrototypesFast(object, kStartAtReceiver, isolate()); |
654 update_receiver_map(object); | 635 update_receiver_map(object); |
655 } | 636 } |
656 // Named lookup in the object. | 637 // Named lookup in the object. |
657 LookupIterator it(object, name); | 638 LookupIterator it(object, name); |
658 LookupForRead(&it); | 639 LookupForRead(&it); |
659 | 640 |
660 if (it.IsFound() || !ShouldThrowReferenceError(object)) { | 641 if (it.IsFound() || !ShouldThrowReferenceError()) { |
661 // Update inline cache and stub cache. | 642 // Update inline cache and stub cache. |
662 if (use_ic) UpdateCaches(&it); | 643 if (use_ic) UpdateCaches(&it); |
663 | 644 |
664 // Get the property. | 645 // Get the property. |
665 Handle<Object> result; | 646 Handle<Object> result; |
666 | 647 |
667 ASSIGN_RETURN_ON_EXCEPTION(isolate(), result, Object::GetProperty(&it), | 648 ASSIGN_RETURN_ON_EXCEPTION(isolate(), result, Object::GetProperty(&it), |
668 Object); | 649 Object); |
669 if (it.IsFound()) { | 650 if (it.IsFound()) { |
670 return result; | 651 return result; |
671 } else if (!ShouldThrowReferenceError(object)) { | 652 } else if (!ShouldThrowReferenceError()) { |
672 LOG(isolate(), SuspectReadEvent(*name, *object)); | 653 LOG(isolate(), SuspectReadEvent(*name, *object)); |
673 return result; | 654 return result; |
674 } | 655 } |
675 } | 656 } |
676 return ReferenceError(name); | 657 return ReferenceError(name); |
677 } | 658 } |
678 | 659 |
| 660 MaybeHandle<Object> LoadGlobalIC::Load(Handle<Name> name) { |
| 661 Handle<JSGlobalObject> global = isolate()->global_object(); |
| 662 |
| 663 if (name->IsString()) { |
| 664 // Look up in script context table. |
| 665 Handle<String> str_name = Handle<String>::cast(name); |
| 666 Handle<ScriptContextTable> script_contexts( |
| 667 global->native_context()->script_context_table()); |
| 668 |
| 669 ScriptContextTable::LookupResult lookup_result; |
| 670 if (ScriptContextTable::Lookup(script_contexts, str_name, &lookup_result)) { |
| 671 Handle<Object> result = |
| 672 FixedArray::get(*ScriptContextTable::GetContext( |
| 673 script_contexts, lookup_result.context_index), |
| 674 lookup_result.slot_index, isolate()); |
| 675 if (result->IsTheHole(isolate())) { |
| 676 // Do not install stubs and stay pre-monomorphic for |
| 677 // uninitialized accesses. |
| 678 return ReferenceError(name); |
| 679 } |
| 680 |
| 681 if (FLAG_use_ic && LoadScriptContextFieldStub::Accepted(&lookup_result)) { |
| 682 TRACE_HANDLER_STATS(isolate(), LoadIC_LoadScriptContextFieldStub); |
| 683 LoadScriptContextFieldStub stub(isolate(), &lookup_result); |
| 684 PatchCache(name, stub.GetCode()); |
| 685 TRACE_IC("LoadGlobalIC", name); |
| 686 } |
| 687 return result; |
| 688 } |
| 689 } |
| 690 return LoadIC::Load(global, name); |
| 691 } |
679 | 692 |
680 static bool AddOneReceiverMapIfMissing(MapHandleList* receiver_maps, | 693 static bool AddOneReceiverMapIfMissing(MapHandleList* receiver_maps, |
681 Handle<Map> new_receiver_map) { | 694 Handle<Map> new_receiver_map) { |
682 DCHECK(!new_receiver_map.is_null()); | 695 DCHECK(!new_receiver_map.is_null()); |
683 for (int current = 0; current < receiver_maps->length(); ++current) { | 696 for (int current = 0; current < receiver_maps->length(); ++current) { |
684 if (!receiver_maps->at(current).is_null() && | 697 if (!receiver_maps->at(current).is_null() && |
685 receiver_maps->at(current).is_identical_to(new_receiver_map)) { | 698 receiver_maps->at(current).is_identical_to(new_receiver_map)) { |
686 return false; | 699 return false; |
687 } | 700 } |
688 } | 701 } |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
786 | 799 |
787 | 800 |
788 void IC::PatchCache(Handle<Name> name, Handle<Code> code) { | 801 void IC::PatchCache(Handle<Name> name, Handle<Code> code) { |
789 switch (state()) { | 802 switch (state()) { |
790 case UNINITIALIZED: | 803 case UNINITIALIZED: |
791 case PREMONOMORPHIC: | 804 case PREMONOMORPHIC: |
792 UpdateMonomorphicIC(code, name); | 805 UpdateMonomorphicIC(code, name); |
793 break; | 806 break; |
794 case RECOMPUTE_HANDLER: | 807 case RECOMPUTE_HANDLER: |
795 case MONOMORPHIC: | 808 case MONOMORPHIC: |
| 809 if (kind() == Code::LOAD_GLOBAL_IC) { |
| 810 UpdateMonomorphicIC(code, name); |
| 811 break; |
| 812 } |
| 813 // Fall through. |
796 case POLYMORPHIC: | 814 case POLYMORPHIC: |
797 if (!is_keyed() || state() == RECOMPUTE_HANDLER) { | 815 if (!is_keyed() || state() == RECOMPUTE_HANDLER) { |
798 if (UpdatePolymorphicIC(name, code)) break; | 816 if (UpdatePolymorphicIC(name, code)) break; |
799 // For keyed stubs, we can't know whether old handlers were for the | 817 // For keyed stubs, we can't know whether old handlers were for the |
800 // same key. | 818 // same key. |
801 CopyICToMegamorphicCache(name); | 819 CopyICToMegamorphicCache(name); |
802 } | 820 } |
803 DCHECK(UseVector()); | 821 DCHECK(UseVector()); |
804 ConfigureVectorState(MEGAMORPHIC, name); | 822 ConfigureVectorState(MEGAMORPHIC, name); |
805 // Fall through. | 823 // Fall through. |
(...skipping 10 matching lines...) Expand all Loading... |
816 } | 834 } |
817 | 835 |
818 Handle<Code> LoadIC::initialize_stub_in_optimized_code( | 836 Handle<Code> LoadIC::initialize_stub_in_optimized_code( |
819 Isolate* isolate, ExtraICState extra_state) { | 837 Isolate* isolate, ExtraICState extra_state) { |
820 if (FLAG_tf_load_ic_stub) { | 838 if (FLAG_tf_load_ic_stub) { |
821 return LoadICTFStub(isolate, LoadICState(extra_state)).GetCode(); | 839 return LoadICTFStub(isolate, LoadICState(extra_state)).GetCode(); |
822 } | 840 } |
823 return LoadICStub(isolate, LoadICState(extra_state)).GetCode(); | 841 return LoadICStub(isolate, LoadICState(extra_state)).GetCode(); |
824 } | 842 } |
825 | 843 |
| 844 Handle<Code> LoadGlobalIC::initialize_stub_in_optimized_code( |
| 845 Isolate* isolate, ExtraICState extra_state) { |
| 846 return LoadGlobalICStub(isolate, LoadICState(extra_state)).GetCode(); |
| 847 } |
| 848 |
826 Handle<Code> KeyedLoadIC::initialize_stub_in_optimized_code( | 849 Handle<Code> KeyedLoadIC::initialize_stub_in_optimized_code( |
827 Isolate* isolate, ExtraICState extra_state) { | 850 Isolate* isolate, ExtraICState extra_state) { |
828 return KeyedLoadICStub(isolate, LoadICState(extra_state)).GetCode(); | 851 return KeyedLoadICStub(isolate, LoadICState(extra_state)).GetCode(); |
829 } | 852 } |
830 | 853 |
831 Handle<Code> KeyedStoreIC::initialize_stub_in_optimized_code( | 854 Handle<Code> KeyedStoreIC::initialize_stub_in_optimized_code( |
832 Isolate* isolate, LanguageMode language_mode) { | 855 Isolate* isolate, LanguageMode language_mode) { |
833 StoreICState state = StoreICState(language_mode); | 856 StoreICState state = StoreICState(language_mode); |
834 return VectorKeyedStoreICStub(isolate, state).GetCode(); | 857 return VectorKeyedStoreICStub(isolate, state).GetCode(); |
835 } | 858 } |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
897 ConfigureVectorState(PREMONOMORPHIC, Handle<Object>()); | 920 ConfigureVectorState(PREMONOMORPHIC, Handle<Object>()); |
898 TRACE_IC("LoadIC", lookup->name()); | 921 TRACE_IC("LoadIC", lookup->name()); |
899 return; | 922 return; |
900 } | 923 } |
901 | 924 |
902 Handle<Code> code; | 925 Handle<Code> code; |
903 if (lookup->state() == LookupIterator::JSPROXY || | 926 if (lookup->state() == LookupIterator::JSPROXY || |
904 lookup->state() == LookupIterator::ACCESS_CHECK) { | 927 lookup->state() == LookupIterator::ACCESS_CHECK) { |
905 code = slow_stub(); | 928 code = slow_stub(); |
906 } else if (!lookup->IsFound()) { | 929 } else if (!lookup->IsFound()) { |
907 if (kind() == Code::LOAD_IC) { | 930 if (kind() == Code::LOAD_IC || kind() == Code::LOAD_GLOBAL_IC) { |
908 code = NamedLoadHandlerCompiler::ComputeLoadNonexistent(lookup->name(), | 931 code = NamedLoadHandlerCompiler::ComputeLoadNonexistent(lookup->name(), |
909 receiver_map()); | 932 receiver_map()); |
910 // TODO(jkummerow/verwaest): Introduce a builtin that handles this case. | 933 // TODO(jkummerow/verwaest): Introduce a builtin that handles this case. |
911 if (code.is_null()) code = slow_stub(); | 934 if (code.is_null()) code = slow_stub(); |
912 } else { | 935 } else { |
913 code = slow_stub(); | 936 code = slow_stub(); |
914 } | 937 } |
915 } else { | 938 } else { |
916 if (lookup->state() == LookupIterator::ACCESSOR) { | 939 if (lookup->state() == LookupIterator::ACCESSOR) { |
917 if (!IsCompatibleReceiver(lookup, receiver_map())) { | 940 if (!IsCompatibleReceiver(lookup, receiver_map())) { |
(...skipping 29 matching lines...) Expand all Loading... |
947 // Try to find a globally shared handler stub. | 970 // Try to find a globally shared handler stub. |
948 Handle<Code> code = GetMapIndependentHandler(lookup); | 971 Handle<Code> code = GetMapIndependentHandler(lookup); |
949 if (!code.is_null()) return code; | 972 if (!code.is_null()) return code; |
950 | 973 |
951 // Otherwise check the map's handler cache for a map-specific handler, and | 974 // Otherwise check the map's handler cache for a map-specific handler, and |
952 // compile one if the cache comes up empty. | 975 // compile one if the cache comes up empty. |
953 bool receiver_is_holder = | 976 bool receiver_is_holder = |
954 lookup->GetReceiver().is_identical_to(lookup->GetHolder<JSObject>()); | 977 lookup->GetReceiver().is_identical_to(lookup->GetHolder<JSObject>()); |
955 CacheHolderFlag flag; | 978 CacheHolderFlag flag; |
956 Handle<Map> stub_holder_map; | 979 Handle<Map> stub_holder_map; |
957 if (kind() == Code::LOAD_IC || kind() == Code::KEYED_LOAD_IC) { | 980 if (kind() == Code::LOAD_IC || kind() == Code::LOAD_GLOBAL_IC || |
| 981 kind() == Code::KEYED_LOAD_IC) { |
958 stub_holder_map = IC::GetHandlerCacheHolder( | 982 stub_holder_map = IC::GetHandlerCacheHolder( |
959 receiver_map(), receiver_is_holder, isolate(), &flag); | 983 receiver_map(), receiver_is_holder, isolate(), &flag); |
960 } else { | 984 } else { |
961 DCHECK(kind() == Code::STORE_IC || kind() == Code::KEYED_STORE_IC); | 985 DCHECK(kind() == Code::STORE_IC || kind() == Code::KEYED_STORE_IC); |
962 // Store handlers cannot be cached on prototypes. | 986 // Store handlers cannot be cached on prototypes. |
963 flag = kCacheOnReceiver; | 987 flag = kCacheOnReceiver; |
964 stub_holder_map = receiver_map(); | 988 stub_holder_map = receiver_map(); |
965 } | 989 } |
966 | 990 |
967 code = PropertyHandlerCompiler::Find(lookup->name(), stub_holder_map, kind(), | 991 code = PropertyHandlerCompiler::Find(lookup->name(), stub_holder_map, kind(), |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1082 } | 1106 } |
1083 break; // Custom-compiled handler. | 1107 break; // Custom-compiled handler. |
1084 } | 1108 } |
1085 } | 1109 } |
1086 TRACE_HANDLER_STATS(isolate(), LoadIC_SlowStub); | 1110 TRACE_HANDLER_STATS(isolate(), LoadIC_SlowStub); |
1087 return slow_stub(); | 1111 return slow_stub(); |
1088 } | 1112 } |
1089 | 1113 |
1090 case LookupIterator::DATA: { | 1114 case LookupIterator::DATA: { |
1091 if (lookup->is_dictionary_holder()) { | 1115 if (lookup->is_dictionary_holder()) { |
1092 if (kind() != Code::LOAD_IC) { | 1116 if (kind() != Code::LOAD_IC && kind() != Code::LOAD_GLOBAL_IC) { |
1093 TRACE_HANDLER_STATS(isolate(), LoadIC_SlowStub); | 1117 TRACE_HANDLER_STATS(isolate(), LoadIC_SlowStub); |
1094 return slow_stub(); | 1118 return slow_stub(); |
1095 } | 1119 } |
1096 if (holder->IsJSGlobalObject()) { | 1120 if (holder->IsJSGlobalObject()) { |
1097 break; // Custom-compiled handler. | 1121 break; // Custom-compiled handler. |
1098 } | 1122 } |
1099 // There is only one shared stub for loading normalized | 1123 // There is only one shared stub for loading normalized |
1100 // properties. It does not traverse the prototype chain, so the | 1124 // properties. It does not traverse the prototype chain, so the |
1101 // property must be found in the object for the stub to be | 1125 // property must be found in the object for the stub to be |
1102 // applicable. | 1126 // applicable. |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1219 NamedLoadHandlerCompiler compiler(isolate(), map, holder, cache_holder); | 1243 NamedLoadHandlerCompiler compiler(isolate(), map, holder, cache_holder); |
1220 Handle<Code> code = compiler.CompileLoadCallback(lookup->name(), info); | 1244 Handle<Code> code = compiler.CompileLoadCallback(lookup->name(), info); |
1221 if (FLAG_runtime_call_stats) return slow_stub(); | 1245 if (FLAG_runtime_call_stats) return slow_stub(); |
1222 return code; | 1246 return code; |
1223 } | 1247 } |
1224 UNREACHABLE(); | 1248 UNREACHABLE(); |
1225 } | 1249 } |
1226 | 1250 |
1227 case LookupIterator::DATA: { | 1251 case LookupIterator::DATA: { |
1228 if (lookup->is_dictionary_holder()) { | 1252 if (lookup->is_dictionary_holder()) { |
1229 DCHECK(kind() == Code::LOAD_IC); | 1253 DCHECK(kind() == Code::LOAD_IC || kind() == Code::LOAD_GLOBAL_IC); |
1230 DCHECK(holder->IsJSGlobalObject()); | 1254 DCHECK(holder->IsJSGlobalObject()); |
1231 TRACE_HANDLER_STATS(isolate(), LoadIC_LoadGlobal); | 1255 TRACE_HANDLER_STATS(isolate(), LoadIC_LoadGlobal); |
1232 NamedLoadHandlerCompiler compiler(isolate(), map, holder, cache_holder); | 1256 NamedLoadHandlerCompiler compiler(isolate(), map, holder, cache_holder); |
1233 Handle<PropertyCell> cell = lookup->GetPropertyCell(); | 1257 Handle<PropertyCell> cell = lookup->GetPropertyCell(); |
1234 Handle<Code> code = compiler.CompileLoadGlobal( | 1258 Handle<Code> code = compiler.CompileLoadGlobal( |
1235 cell, lookup->name(), lookup->IsConfigurable()); | 1259 cell, lookup->name(), lookup->IsConfigurable()); |
1236 return code; | 1260 return code; |
1237 } | 1261 } |
1238 | 1262 |
1239 // -------------- Fields -------------- | 1263 // -------------- Fields -------------- |
(...skipping 1021 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2261 Handle<Object> receiver = args.at<Object>(0); | 2285 Handle<Object> receiver = args.at<Object>(0); |
2262 Handle<Name> key = args.at<Name>(1); | 2286 Handle<Name> key = args.at<Name>(1); |
2263 | 2287 |
2264 DCHECK_EQ(4, args.length()); | 2288 DCHECK_EQ(4, args.length()); |
2265 Handle<Smi> slot = args.at<Smi>(2); | 2289 Handle<Smi> slot = args.at<Smi>(2); |
2266 Handle<TypeFeedbackVector> vector = args.at<TypeFeedbackVector>(3); | 2290 Handle<TypeFeedbackVector> vector = args.at<TypeFeedbackVector>(3); |
2267 FeedbackVectorSlot vector_slot = vector->ToSlot(slot->value()); | 2291 FeedbackVectorSlot vector_slot = vector->ToSlot(slot->value()); |
2268 // A monomorphic or polymorphic KeyedLoadIC with a string key can call the | 2292 // A monomorphic or polymorphic KeyedLoadIC with a string key can call the |
2269 // LoadIC miss handler if the handler misses. Since the vector Nexus is | 2293 // LoadIC miss handler if the handler misses. Since the vector Nexus is |
2270 // set up outside the IC, handle that here. | 2294 // set up outside the IC, handle that here. |
2271 if (vector->GetKind(vector_slot) == FeedbackVectorSlotKind::LOAD_IC) { | 2295 FeedbackVectorSlotKind kind = vector->GetKind(vector_slot); |
| 2296 if (kind == FeedbackVectorSlotKind::LOAD_IC) { |
2272 LoadICNexus nexus(vector, vector_slot); | 2297 LoadICNexus nexus(vector, vector_slot); |
2273 LoadIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus); | 2298 LoadIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus); |
2274 ic.UpdateState(receiver, key); | 2299 ic.UpdateState(receiver, key); |
2275 RETURN_RESULT_OR_FAILURE(isolate, ic.Load(receiver, key)); | 2300 RETURN_RESULT_OR_FAILURE(isolate, ic.Load(receiver, key)); |
| 2301 |
| 2302 } else if (kind == FeedbackVectorSlotKind::LOAD_GLOBAL_IC) { |
| 2303 DCHECK_EQ(*isolate->global_object(), *receiver); |
| 2304 LoadGlobalICNexus nexus(vector, vector_slot); |
| 2305 LoadGlobalIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus); |
| 2306 ic.UpdateState(receiver, key); |
| 2307 RETURN_RESULT_OR_FAILURE(isolate, ic.Load(key)); |
| 2308 |
2276 } else { | 2309 } else { |
2277 DCHECK_EQ(FeedbackVectorSlotKind::KEYED_LOAD_IC, | 2310 DCHECK_EQ(FeedbackVectorSlotKind::KEYED_LOAD_IC, kind); |
2278 vector->GetKind(vector_slot)); | |
2279 KeyedLoadICNexus nexus(vector, vector_slot); | 2311 KeyedLoadICNexus nexus(vector, vector_slot); |
2280 KeyedLoadIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus); | 2312 KeyedLoadIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus); |
2281 ic.UpdateState(receiver, key); | 2313 ic.UpdateState(receiver, key); |
2282 RETURN_RESULT_OR_FAILURE(isolate, ic.Load(receiver, key)); | 2314 RETURN_RESULT_OR_FAILURE(isolate, ic.Load(receiver, key)); |
2283 } | 2315 } |
2284 } | 2316 } |
2285 | 2317 |
| 2318 // Used from ic-<arch>.cc. |
| 2319 RUNTIME_FUNCTION(Runtime_LoadGlobalIC_Miss) { |
| 2320 TimerEventScope<TimerEventIcMiss> timer(isolate); |
| 2321 HandleScope scope(isolate); |
| 2322 DCHECK_EQ(3, args.length()); |
| 2323 Handle<JSGlobalObject> global = isolate->global_object(); |
| 2324 Handle<Name> name = args.at<Name>(0); |
| 2325 Handle<Smi> slot = args.at<Smi>(1); |
| 2326 Handle<TypeFeedbackVector> vector = args.at<TypeFeedbackVector>(2); |
| 2327 FeedbackVectorSlot vector_slot = vector->ToSlot(slot->value()); |
| 2328 DCHECK_EQ(FeedbackVectorSlotKind::LOAD_GLOBAL_IC, |
| 2329 vector->GetKind(vector_slot)); |
| 2330 |
| 2331 LoadGlobalICNexus nexus(vector, vector_slot); |
| 2332 LoadGlobalIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus); |
| 2333 ic.UpdateState(global, name); |
| 2334 |
| 2335 Handle<Object> result; |
| 2336 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(name)); |
| 2337 return *result; |
| 2338 } |
2286 | 2339 |
2287 // Used from ic-<arch>.cc | 2340 // Used from ic-<arch>.cc |
2288 RUNTIME_FUNCTION(Runtime_KeyedLoadIC_Miss) { | 2341 RUNTIME_FUNCTION(Runtime_KeyedLoadIC_Miss) { |
2289 TimerEventScope<TimerEventIcMiss> timer(isolate); | 2342 TimerEventScope<TimerEventIcMiss> timer(isolate); |
2290 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8"), "V8.IcMiss"); | 2343 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8"), "V8.IcMiss"); |
2291 HandleScope scope(isolate); | 2344 HandleScope scope(isolate); |
2292 Handle<Object> receiver = args.at<Object>(0); | 2345 Handle<Object> receiver = args.at<Object>(0); |
2293 Handle<Object> key = args.at<Object>(1); | 2346 Handle<Object> key = args.at<Object>(1); |
2294 | 2347 |
2295 DCHECK(args.length() == 4); | 2348 DCHECK(args.length() == 4); |
(...skipping 547 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2843 it.Next(); | 2896 it.Next(); |
2844 } | 2897 } |
2845 // Skip past the interceptor. | 2898 // Skip past the interceptor. |
2846 it.Next(); | 2899 it.Next(); |
2847 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, Object::GetProperty(&it)); | 2900 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, Object::GetProperty(&it)); |
2848 | 2901 |
2849 if (it.IsFound()) return *result; | 2902 if (it.IsFound()) return *result; |
2850 | 2903 |
2851 LoadICNexus nexus(isolate); | 2904 LoadICNexus nexus(isolate); |
2852 LoadIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus); | 2905 LoadIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus); |
2853 if (!ic.ShouldThrowReferenceError(it.GetReceiver())) { | 2906 // It could actually be any kind of LoadICs here but the predicate handles |
| 2907 // all the cases properly. |
| 2908 if (!ic.ShouldThrowReferenceError()) { |
2854 return isolate->heap()->undefined_value(); | 2909 return isolate->heap()->undefined_value(); |
2855 } | 2910 } |
2856 | 2911 |
2857 // Throw a reference error. | 2912 // Throw a reference error. |
2858 THROW_NEW_ERROR_RETURN_FAILURE( | 2913 THROW_NEW_ERROR_RETURN_FAILURE( |
2859 isolate, NewReferenceError(MessageTemplate::kNotDefined, it.name())); | 2914 isolate, NewReferenceError(MessageTemplate::kNotDefined, it.name())); |
2860 } | 2915 } |
2861 | 2916 |
2862 | 2917 |
2863 RUNTIME_FUNCTION(Runtime_StorePropertyWithInterceptor) { | 2918 RUNTIME_FUNCTION(Runtime_StorePropertyWithInterceptor) { |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2951 DCHECK_EQ(FeedbackVectorSlotKind::KEYED_LOAD_IC, | 3006 DCHECK_EQ(FeedbackVectorSlotKind::KEYED_LOAD_IC, |
2952 vector->GetKind(vector_slot)); | 3007 vector->GetKind(vector_slot)); |
2953 KeyedLoadICNexus nexus(vector, vector_slot); | 3008 KeyedLoadICNexus nexus(vector, vector_slot); |
2954 KeyedLoadIC ic(IC::EXTRA_CALL_FRAME, isolate, &nexus); | 3009 KeyedLoadIC ic(IC::EXTRA_CALL_FRAME, isolate, &nexus); |
2955 ic.UpdateState(receiver, key); | 3010 ic.UpdateState(receiver, key); |
2956 RETURN_RESULT_OR_FAILURE(isolate, ic.Load(receiver, key)); | 3011 RETURN_RESULT_OR_FAILURE(isolate, ic.Load(receiver, key)); |
2957 } | 3012 } |
2958 } | 3013 } |
2959 } // namespace internal | 3014 } // namespace internal |
2960 } // namespace v8 | 3015 } // namespace v8 |
OLD | NEW |