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

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

Issue 1912633002: [ic] Split LoadIC into LoadGlobalIC and LoadIC. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/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
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
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 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
509 if (!receiver->map()->is_deprecated()) return false; 515 if (!receiver->map()->is_deprecated()) return false;
510 JSObject::MigrateInstance(Handle<JSObject>::cast(object)); 516 JSObject::MigrateInstance(Handle<JSObject>::cast(object));
511 return true; 517 return true;
512 } 518 }
513 519
514 void IC::ConfigureVectorState(IC::State new_state, Handle<Object> key) { 520 void IC::ConfigureVectorState(IC::State new_state, Handle<Object> key) {
515 DCHECK(UseVector()); 521 DCHECK(UseVector());
516 if (new_state == PREMONOMORPHIC) { 522 if (new_state == PREMONOMORPHIC) {
517 nexus()->ConfigurePremonomorphic(); 523 nexus()->ConfigurePremonomorphic();
518 } else if (new_state == MEGAMORPHIC) { 524 } else if (new_state == MEGAMORPHIC) {
519 if (kind() == Code::LOAD_IC || kind() == Code::STORE_IC) { 525 if (kind() == Code::LOAD_IC || kind() == Code::LOAD_GLOBAL_IC ||
526 kind() == Code::STORE_IC) {
520 nexus()->ConfigureMegamorphic(); 527 nexus()->ConfigureMegamorphic();
521 } else if (kind() == Code::KEYED_LOAD_IC) { 528 } else if (kind() == Code::KEYED_LOAD_IC) {
522 KeyedLoadICNexus* nexus = casted_nexus<KeyedLoadICNexus>(); 529 KeyedLoadICNexus* nexus = casted_nexus<KeyedLoadICNexus>();
523 nexus->ConfigureMegamorphicKeyed(key->IsName() ? PROPERTY : ELEMENT); 530 nexus->ConfigureMegamorphicKeyed(key->IsName() ? PROPERTY : ELEMENT);
524 } else { 531 } else {
525 DCHECK(kind() == Code::KEYED_STORE_IC); 532 DCHECK(kind() == Code::KEYED_STORE_IC);
526 KeyedStoreICNexus* nexus = casted_nexus<KeyedStoreICNexus>(); 533 KeyedStoreICNexus* nexus = casted_nexus<KeyedStoreICNexus>();
527 nexus->ConfigureMegamorphicKeyed(key->IsName() ? PROPERTY : ELEMENT); 534 nexus->ConfigureMegamorphicKeyed(key->IsName() ? PROPERTY : ELEMENT);
528 } 535 }
529 } else { 536 } else {
530 UNREACHABLE(); 537 UNREACHABLE();
531 } 538 }
532 539
533 vector_set_ = true; 540 vector_set_ = true;
534 OnTypeFeedbackChanged(isolate(), get_host()); 541 OnTypeFeedbackChanged(isolate(), get_host());
535 } 542 }
536 543
537 544
538 void IC::ConfigureVectorState(Handle<Name> name, Handle<Map> map, 545 void IC::ConfigureVectorState(Handle<Name> name, Handle<Map> map,
539 Handle<Code> handler) { 546 Handle<Code> handler) {
540 DCHECK(UseVector()); 547 DCHECK(UseVector());
541 if (kind() == Code::LOAD_IC) { 548 if (kind() == Code::LOAD_IC) {
542 LoadICNexus* nexus = casted_nexus<LoadICNexus>(); 549 LoadICNexus* nexus = casted_nexus<LoadICNexus>();
543 nexus->ConfigureMonomorphic(map, handler); 550 nexus->ConfigureMonomorphic(map, handler);
551 } else if (kind() == Code::LOAD_GLOBAL_IC) {
552 LoadGlobalICNexus* nexus = casted_nexus<LoadGlobalICNexus>();
553 nexus->ConfigureMonomorphic(map, handler);
544 } else if (kind() == Code::KEYED_LOAD_IC) { 554 } else if (kind() == Code::KEYED_LOAD_IC) {
545 KeyedLoadICNexus* nexus = casted_nexus<KeyedLoadICNexus>(); 555 KeyedLoadICNexus* nexus = casted_nexus<KeyedLoadICNexus>();
546 nexus->ConfigureMonomorphic(name, map, handler); 556 nexus->ConfigureMonomorphic(name, map, handler);
547 } else if (kind() == Code::STORE_IC) { 557 } else if (kind() == Code::STORE_IC) {
548 StoreICNexus* nexus = casted_nexus<StoreICNexus>(); 558 StoreICNexus* nexus = casted_nexus<StoreICNexus>();
549 nexus->ConfigureMonomorphic(map, handler); 559 nexus->ConfigureMonomorphic(map, handler);
550 } else { 560 } else {
551 DCHECK(kind() == Code::KEYED_STORE_IC); 561 DCHECK(kind() == Code::KEYED_STORE_IC);
552 KeyedStoreICNexus* nexus = casted_nexus<KeyedStoreICNexus>(); 562 KeyedStoreICNexus* nexus = casted_nexus<KeyedStoreICNexus>();
553 nexus->ConfigureMonomorphic(name, map, handler); 563 nexus->ConfigureMonomorphic(name, map, handler);
554 } 564 }
555 565
556 vector_set_ = true; 566 vector_set_ = true;
557 OnTypeFeedbackChanged(isolate(), get_host()); 567 OnTypeFeedbackChanged(isolate(), get_host());
558 } 568 }
559 569
560 570
561 void IC::ConfigureVectorState(Handle<Name> name, MapHandleList* maps, 571 void IC::ConfigureVectorState(Handle<Name> name, MapHandleList* maps,
562 CodeHandleList* handlers) { 572 CodeHandleList* handlers) {
563 DCHECK(UseVector()); 573 DCHECK(UseVector());
564 if (kind() == Code::LOAD_IC) { 574 if (kind() == Code::LOAD_IC) {
565 LoadICNexus* nexus = casted_nexus<LoadICNexus>(); 575 LoadICNexus* nexus = casted_nexus<LoadICNexus>();
566 nexus->ConfigurePolymorphic(maps, handlers); 576 nexus->ConfigurePolymorphic(maps, handlers);
577 } else if (kind() == Code::LOAD_GLOBAL_IC) {
578 LoadGlobalICNexus* nexus = casted_nexus<LoadGlobalICNexus>();
579 nexus->ConfigurePolymorphic(maps, handlers);
567 } else if (kind() == Code::KEYED_LOAD_IC) { 580 } else if (kind() == Code::KEYED_LOAD_IC) {
568 KeyedLoadICNexus* nexus = casted_nexus<KeyedLoadICNexus>(); 581 KeyedLoadICNexus* nexus = casted_nexus<KeyedLoadICNexus>();
569 nexus->ConfigurePolymorphic(name, maps, handlers); 582 nexus->ConfigurePolymorphic(name, maps, handlers);
570 } else if (kind() == Code::STORE_IC) { 583 } else if (kind() == Code::STORE_IC) {
571 StoreICNexus* nexus = casted_nexus<StoreICNexus>(); 584 StoreICNexus* nexus = casted_nexus<StoreICNexus>();
572 nexus->ConfigurePolymorphic(maps, handlers); 585 nexus->ConfigurePolymorphic(maps, handlers);
573 } else { 586 } else {
574 DCHECK(kind() == Code::KEYED_STORE_IC); 587 DCHECK(kind() == Code::KEYED_STORE_IC);
575 KeyedStoreICNexus* nexus = casted_nexus<KeyedStoreICNexus>(); 588 KeyedStoreICNexus* nexus = casted_nexus<KeyedStoreICNexus>();
576 nexus->ConfigurePolymorphic(name, maps, handlers); 589 nexus->ConfigurePolymorphic(name, maps, handlers);
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
614 } 627 }
615 Handle<Object> result; 628 Handle<Object> result;
616 ASSIGN_RETURN_ON_EXCEPTION(isolate(), result, 629 ASSIGN_RETURN_ON_EXCEPTION(isolate(), result,
617 Object::GetElement(isolate(), object, index), 630 Object::GetElement(isolate(), object, index),
618 Object); 631 Object);
619 return result; 632 return result;
620 } 633 }
621 634
622 bool use_ic = MigrateDeprecated(object) ? false : FLAG_use_ic; 635 bool use_ic = MigrateDeprecated(object) ? false : FLAG_use_ic;
623 636
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) { 637 if (state() != UNINITIALIZED) {
653 JSObject::MakePrototypesFast(object, kStartAtReceiver, isolate()); 638 JSObject::MakePrototypesFast(object, kStartAtReceiver, isolate());
654 update_receiver_map(object); 639 update_receiver_map(object);
655 } 640 }
656 // Named lookup in the object. 641 // Named lookup in the object.
657 LookupIterator it(object, name); 642 LookupIterator it(object, name);
658 LookupForRead(&it); 643 LookupForRead(&it);
659 644
660 if (it.IsFound() || !ShouldThrowReferenceError(object)) { 645 if (it.IsFound() || !ShouldThrowReferenceError()) {
661 // Update inline cache and stub cache. 646 // Update inline cache and stub cache.
662 if (use_ic) UpdateCaches(&it); 647 if (use_ic) UpdateCaches(&it);
663 648
664 // Get the property. 649 // Get the property.
665 Handle<Object> result; 650 Handle<Object> result;
666 651
667 ASSIGN_RETURN_ON_EXCEPTION(isolate(), result, Object::GetProperty(&it), 652 ASSIGN_RETURN_ON_EXCEPTION(isolate(), result, Object::GetProperty(&it),
668 Object); 653 Object);
669 if (it.IsFound()) { 654 if (it.IsFound()) {
670 return result; 655 return result;
671 } else if (!ShouldThrowReferenceError(object)) { 656 } else if (!ShouldThrowReferenceError()) {
672 LOG(isolate(), SuspectReadEvent(*name, *object)); 657 LOG(isolate(), SuspectReadEvent(*name, *object));
673 return result; 658 return result;
674 } 659 }
675 } 660 }
676 return ReferenceError(name); 661 return ReferenceError(name);
677 } 662 }
678 663
664 MaybeHandle<Object> LoadGlobalIC::Load(Handle<Name> name) {
665 Handle<JSGlobalObject> global = isolate()->global_object();
666
667 if (name->IsString()) {
668 // Look up in script context table.
669 Handle<String> str_name = Handle<String>::cast(name);
670 Handle<ScriptContextTable> script_contexts(
671 global->native_context()->script_context_table());
672
673 ScriptContextTable::LookupResult lookup_result;
674 if (ScriptContextTable::Lookup(script_contexts, str_name, &lookup_result)) {
675 Handle<Object> result =
676 FixedArray::get(*ScriptContextTable::GetContext(
677 script_contexts, lookup_result.context_index),
678 lookup_result.slot_index, isolate());
679 if (result->IsTheHole(isolate())) {
680 // Do not install stubs and stay pre-monomorphic for
681 // uninitialized accesses.
682 return ReferenceError(name);
683 }
684
685 if (FLAG_use_ic && LoadScriptContextFieldStub::Accepted(&lookup_result)) {
686 TRACE_HANDLER_STATS(isolate(), LoadIC_LoadScriptContextFieldStub);
687 LoadScriptContextFieldStub stub(isolate(), &lookup_result);
688 PatchCache(name, stub.GetCode());
689 TRACE_IC("LoadGlobalIC", name);
690 }
691 return result;
692 }
693 }
694 return LoadIC::Load(global, name);
695 }
679 696
680 static bool AddOneReceiverMapIfMissing(MapHandleList* receiver_maps, 697 static bool AddOneReceiverMapIfMissing(MapHandleList* receiver_maps,
681 Handle<Map> new_receiver_map) { 698 Handle<Map> new_receiver_map) {
682 DCHECK(!new_receiver_map.is_null()); 699 DCHECK(!new_receiver_map.is_null());
683 for (int current = 0; current < receiver_maps->length(); ++current) { 700 for (int current = 0; current < receiver_maps->length(); ++current) {
684 if (!receiver_maps->at(current).is_null() && 701 if (!receiver_maps->at(current).is_null() &&
685 receiver_maps->at(current).is_identical_to(new_receiver_map)) { 702 receiver_maps->at(current).is_identical_to(new_receiver_map)) {
686 return false; 703 return false;
687 } 704 }
688 } 705 }
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
816 } 833 }
817 834
818 Handle<Code> LoadIC::initialize_stub_in_optimized_code( 835 Handle<Code> LoadIC::initialize_stub_in_optimized_code(
819 Isolate* isolate, ExtraICState extra_state) { 836 Isolate* isolate, ExtraICState extra_state) {
820 if (FLAG_tf_load_ic_stub) { 837 if (FLAG_tf_load_ic_stub) {
821 return LoadICTFStub(isolate, LoadICState(extra_state)).GetCode(); 838 return LoadICTFStub(isolate, LoadICState(extra_state)).GetCode();
822 } 839 }
823 return LoadICStub(isolate, LoadICState(extra_state)).GetCode(); 840 return LoadICStub(isolate, LoadICState(extra_state)).GetCode();
824 } 841 }
825 842
843 Handle<Code> LoadGlobalIC::initialize_stub_in_optimized_code(
844 Isolate* isolate, ExtraICState extra_state) {
845 return LoadGlobalICStub(isolate, LoadICState(extra_state)).GetCode();
846 }
847
826 Handle<Code> KeyedLoadIC::initialize_stub_in_optimized_code( 848 Handle<Code> KeyedLoadIC::initialize_stub_in_optimized_code(
827 Isolate* isolate, ExtraICState extra_state) { 849 Isolate* isolate, ExtraICState extra_state) {
828 return KeyedLoadICStub(isolate, LoadICState(extra_state)).GetCode(); 850 return KeyedLoadICStub(isolate, LoadICState(extra_state)).GetCode();
829 } 851 }
830 852
831 Handle<Code> KeyedStoreIC::initialize_stub_in_optimized_code( 853 Handle<Code> KeyedStoreIC::initialize_stub_in_optimized_code(
832 Isolate* isolate, LanguageMode language_mode) { 854 Isolate* isolate, LanguageMode language_mode) {
833 StoreICState state = StoreICState(language_mode); 855 StoreICState state = StoreICState(language_mode);
834 return VectorKeyedStoreICStub(isolate, state).GetCode(); 856 return VectorKeyedStoreICStub(isolate, state).GetCode();
835 } 857 }
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
897 ConfigureVectorState(PREMONOMORPHIC, Handle<Object>()); 919 ConfigureVectorState(PREMONOMORPHIC, Handle<Object>());
898 TRACE_IC("LoadIC", lookup->name()); 920 TRACE_IC("LoadIC", lookup->name());
899 return; 921 return;
900 } 922 }
901 923
902 Handle<Code> code; 924 Handle<Code> code;
903 if (lookup->state() == LookupIterator::JSPROXY || 925 if (lookup->state() == LookupIterator::JSPROXY ||
904 lookup->state() == LookupIterator::ACCESS_CHECK) { 926 lookup->state() == LookupIterator::ACCESS_CHECK) {
905 code = slow_stub(); 927 code = slow_stub();
906 } else if (!lookup->IsFound()) { 928 } else if (!lookup->IsFound()) {
907 if (kind() == Code::LOAD_IC) { 929 if (kind() == Code::LOAD_IC || kind() == Code::LOAD_GLOBAL_IC) {
908 code = NamedLoadHandlerCompiler::ComputeLoadNonexistent(lookup->name(), 930 code = NamedLoadHandlerCompiler::ComputeLoadNonexistent(lookup->name(),
909 receiver_map()); 931 receiver_map());
910 // TODO(jkummerow/verwaest): Introduce a builtin that handles this case. 932 // TODO(jkummerow/verwaest): Introduce a builtin that handles this case.
911 if (code.is_null()) code = slow_stub(); 933 if (code.is_null()) code = slow_stub();
912 } else { 934 } else {
913 code = slow_stub(); 935 code = slow_stub();
914 } 936 }
915 } else { 937 } else {
916 if (lookup->state() == LookupIterator::ACCESSOR) { 938 if (lookup->state() == LookupIterator::ACCESSOR) {
917 if (!IsCompatibleReceiver(lookup, receiver_map())) { 939 if (!IsCompatibleReceiver(lookup, receiver_map())) {
(...skipping 29 matching lines...) Expand all
947 // Try to find a globally shared handler stub. 969 // Try to find a globally shared handler stub.
948 Handle<Code> code = GetMapIndependentHandler(lookup); 970 Handle<Code> code = GetMapIndependentHandler(lookup);
949 if (!code.is_null()) return code; 971 if (!code.is_null()) return code;
950 972
951 // Otherwise check the map's handler cache for a map-specific handler, and 973 // Otherwise check the map's handler cache for a map-specific handler, and
952 // compile one if the cache comes up empty. 974 // compile one if the cache comes up empty.
953 bool receiver_is_holder = 975 bool receiver_is_holder =
954 lookup->GetReceiver().is_identical_to(lookup->GetHolder<JSObject>()); 976 lookup->GetReceiver().is_identical_to(lookup->GetHolder<JSObject>());
955 CacheHolderFlag flag; 977 CacheHolderFlag flag;
956 Handle<Map> stub_holder_map; 978 Handle<Map> stub_holder_map;
957 if (kind() == Code::LOAD_IC || kind() == Code::KEYED_LOAD_IC) { 979 if (kind() == Code::LOAD_IC || kind() == Code::LOAD_GLOBAL_IC ||
980 kind() == Code::KEYED_LOAD_IC) {
958 stub_holder_map = IC::GetHandlerCacheHolder( 981 stub_holder_map = IC::GetHandlerCacheHolder(
959 receiver_map(), receiver_is_holder, isolate(), &flag); 982 receiver_map(), receiver_is_holder, isolate(), &flag);
960 } else { 983 } else {
961 DCHECK(kind() == Code::STORE_IC || kind() == Code::KEYED_STORE_IC); 984 DCHECK(kind() == Code::STORE_IC || kind() == Code::KEYED_STORE_IC);
962 // Store handlers cannot be cached on prototypes. 985 // Store handlers cannot be cached on prototypes.
963 flag = kCacheOnReceiver; 986 flag = kCacheOnReceiver;
964 stub_holder_map = receiver_map(); 987 stub_holder_map = receiver_map();
965 } 988 }
966 989
967 code = PropertyHandlerCompiler::Find(lookup->name(), stub_holder_map, kind(), 990 code = PropertyHandlerCompiler::Find(lookup->name(), stub_holder_map, kind(),
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
1082 } 1105 }
1083 break; // Custom-compiled handler. 1106 break; // Custom-compiled handler.
1084 } 1107 }
1085 } 1108 }
1086 TRACE_HANDLER_STATS(isolate(), LoadIC_SlowStub); 1109 TRACE_HANDLER_STATS(isolate(), LoadIC_SlowStub);
1087 return slow_stub(); 1110 return slow_stub();
1088 } 1111 }
1089 1112
1090 case LookupIterator::DATA: { 1113 case LookupIterator::DATA: {
1091 if (lookup->is_dictionary_holder()) { 1114 if (lookup->is_dictionary_holder()) {
1092 if (kind() != Code::LOAD_IC) { 1115 if (kind() != Code::LOAD_IC && kind() != Code::LOAD_GLOBAL_IC) {
1093 TRACE_HANDLER_STATS(isolate(), LoadIC_SlowStub); 1116 TRACE_HANDLER_STATS(isolate(), LoadIC_SlowStub);
1094 return slow_stub(); 1117 return slow_stub();
1095 } 1118 }
1096 if (holder->IsJSGlobalObject()) { 1119 if (holder->IsJSGlobalObject()) {
1097 break; // Custom-compiled handler. 1120 break; // Custom-compiled handler.
1098 } 1121 }
1099 // There is only one shared stub for loading normalized 1122 // There is only one shared stub for loading normalized
1100 // properties. It does not traverse the prototype chain, so the 1123 // properties. It does not traverse the prototype chain, so the
1101 // property must be found in the object for the stub to be 1124 // property must be found in the object for the stub to be
1102 // applicable. 1125 // applicable.
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
1219 NamedLoadHandlerCompiler compiler(isolate(), map, holder, cache_holder); 1242 NamedLoadHandlerCompiler compiler(isolate(), map, holder, cache_holder);
1220 Handle<Code> code = compiler.CompileLoadCallback(lookup->name(), info); 1243 Handle<Code> code = compiler.CompileLoadCallback(lookup->name(), info);
1221 if (FLAG_runtime_call_stats) return slow_stub(); 1244 if (FLAG_runtime_call_stats) return slow_stub();
1222 return code; 1245 return code;
1223 } 1246 }
1224 UNREACHABLE(); 1247 UNREACHABLE();
1225 } 1248 }
1226 1249
1227 case LookupIterator::DATA: { 1250 case LookupIterator::DATA: {
1228 if (lookup->is_dictionary_holder()) { 1251 if (lookup->is_dictionary_holder()) {
1229 DCHECK(kind() == Code::LOAD_IC); 1252 DCHECK(kind() == Code::LOAD_IC || kind() == Code::LOAD_GLOBAL_IC);
1230 DCHECK(holder->IsJSGlobalObject()); 1253 DCHECK(holder->IsJSGlobalObject());
1231 TRACE_HANDLER_STATS(isolate(), LoadIC_LoadGlobal); 1254 TRACE_HANDLER_STATS(isolate(), LoadIC_LoadGlobal);
1232 NamedLoadHandlerCompiler compiler(isolate(), map, holder, cache_holder); 1255 NamedLoadHandlerCompiler compiler(isolate(), map, holder, cache_holder);
1233 Handle<PropertyCell> cell = lookup->GetPropertyCell(); 1256 Handle<PropertyCell> cell = lookup->GetPropertyCell();
1234 Handle<Code> code = compiler.CompileLoadGlobal( 1257 Handle<Code> code = compiler.CompileLoadGlobal(
1235 cell, lookup->name(), lookup->IsConfigurable()); 1258 cell, lookup->name(), lookup->IsConfigurable());
1236 return code; 1259 return code;
1237 } 1260 }
1238 1261
1239 // -------------- Fields -------------- 1262 // -------------- Fields --------------
(...skipping 1021 matching lines...) Expand 10 before | Expand all | Expand 10 after
2261 Handle<Object> receiver = args.at<Object>(0); 2284 Handle<Object> receiver = args.at<Object>(0);
2262 Handle<Name> key = args.at<Name>(1); 2285 Handle<Name> key = args.at<Name>(1);
2263 2286
2264 DCHECK_EQ(4, args.length()); 2287 DCHECK_EQ(4, args.length());
2265 Handle<Smi> slot = args.at<Smi>(2); 2288 Handle<Smi> slot = args.at<Smi>(2);
2266 Handle<TypeFeedbackVector> vector = args.at<TypeFeedbackVector>(3); 2289 Handle<TypeFeedbackVector> vector = args.at<TypeFeedbackVector>(3);
2267 FeedbackVectorSlot vector_slot = vector->ToSlot(slot->value()); 2290 FeedbackVectorSlot vector_slot = vector->ToSlot(slot->value());
2268 // A monomorphic or polymorphic KeyedLoadIC with a string key can call the 2291 // 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 2292 // LoadIC miss handler if the handler misses. Since the vector Nexus is
2270 // set up outside the IC, handle that here. 2293 // set up outside the IC, handle that here.
2271 if (vector->GetKind(vector_slot) == FeedbackVectorSlotKind::LOAD_IC) { 2294 FeedbackVectorSlotKind kind = vector->GetKind(vector_slot);
2295 if (kind == FeedbackVectorSlotKind::LOAD_IC) {
2272 LoadICNexus nexus(vector, vector_slot); 2296 LoadICNexus nexus(vector, vector_slot);
2273 LoadIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus); 2297 LoadIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus);
2274 ic.UpdateState(receiver, key); 2298 ic.UpdateState(receiver, key);
2275 RETURN_RESULT_OR_FAILURE(isolate, ic.Load(receiver, key)); 2299 RETURN_RESULT_OR_FAILURE(isolate, ic.Load(receiver, key));
2300
2301 } else if (kind == FeedbackVectorSlotKind::LOAD_GLOBAL_IC) {
2302 DCHECK_EQ(*isolate->global_object(), *receiver);
2303 LoadGlobalICNexus nexus(vector, vector_slot);
2304 LoadGlobalIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus);
2305 ic.UpdateState(receiver, key);
2306 RETURN_RESULT_OR_FAILURE(isolate, ic.Load(key));
2307
2276 } else { 2308 } else {
2277 DCHECK_EQ(FeedbackVectorSlotKind::KEYED_LOAD_IC, 2309 DCHECK_EQ(FeedbackVectorSlotKind::KEYED_LOAD_IC, kind);
2278 vector->GetKind(vector_slot));
2279 KeyedLoadICNexus nexus(vector, vector_slot); 2310 KeyedLoadICNexus nexus(vector, vector_slot);
2280 KeyedLoadIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus); 2311 KeyedLoadIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus);
2281 ic.UpdateState(receiver, key); 2312 ic.UpdateState(receiver, key);
2282 RETURN_RESULT_OR_FAILURE(isolate, ic.Load(receiver, key)); 2313 RETURN_RESULT_OR_FAILURE(isolate, ic.Load(receiver, key));
2283 } 2314 }
2284 } 2315 }
2285 2316
2317 // Used from ic-<arch>.cc.
2318 RUNTIME_FUNCTION(Runtime_LoadGlobalIC_Miss) {
2319 TimerEventScope<TimerEventIcMiss> timer(isolate);
2320 HandleScope scope(isolate);
2321 DCHECK_EQ(3, args.length());
2322 Handle<JSGlobalObject> global = isolate->global_object();
2323 Handle<Name> name = args.at<Name>(0);
2324 Handle<Smi> slot = args.at<Smi>(1);
2325 Handle<TypeFeedbackVector> vector = args.at<TypeFeedbackVector>(2);
2326 FeedbackVectorSlot vector_slot = vector->ToSlot(slot->value());
2327 DCHECK_EQ(FeedbackVectorSlotKind::LOAD_GLOBAL_IC,
2328 vector->GetKind(vector_slot));
2329
2330 LoadGlobalICNexus nexus(vector, vector_slot);
2331 LoadGlobalIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus);
2332 ic.UpdateState(global, name);
2333
2334 Handle<Object> result;
2335 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(name));
2336 return *result;
2337 }
2286 2338
2287 // Used from ic-<arch>.cc 2339 // Used from ic-<arch>.cc
2288 RUNTIME_FUNCTION(Runtime_KeyedLoadIC_Miss) { 2340 RUNTIME_FUNCTION(Runtime_KeyedLoadIC_Miss) {
2289 TimerEventScope<TimerEventIcMiss> timer(isolate); 2341 TimerEventScope<TimerEventIcMiss> timer(isolate);
2290 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8"), "V8.IcMiss"); 2342 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8"), "V8.IcMiss");
2291 HandleScope scope(isolate); 2343 HandleScope scope(isolate);
2292 Handle<Object> receiver = args.at<Object>(0); 2344 Handle<Object> receiver = args.at<Object>(0);
2293 Handle<Object> key = args.at<Object>(1); 2345 Handle<Object> key = args.at<Object>(1);
2294 2346
2295 DCHECK(args.length() == 4); 2347 DCHECK(args.length() == 4);
(...skipping 547 matching lines...) Expand 10 before | Expand all | Expand 10 after
2843 it.Next(); 2895 it.Next();
2844 } 2896 }
2845 // Skip past the interceptor. 2897 // Skip past the interceptor.
2846 it.Next(); 2898 it.Next();
2847 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, Object::GetProperty(&it)); 2899 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, Object::GetProperty(&it));
2848 2900
2849 if (it.IsFound()) return *result; 2901 if (it.IsFound()) return *result;
2850 2902
2851 LoadICNexus nexus(isolate); 2903 LoadICNexus nexus(isolate);
2852 LoadIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus); 2904 LoadIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus);
2853 if (!ic.ShouldThrowReferenceError(it.GetReceiver())) { 2905 // It could actually be any kind of LoadICs here but the predicate handles
2906 // all the cases properly.
2907 if (!ic.ShouldThrowReferenceError()) {
2854 return isolate->heap()->undefined_value(); 2908 return isolate->heap()->undefined_value();
2855 } 2909 }
2856 2910
2857 // Throw a reference error. 2911 // Throw a reference error.
2858 THROW_NEW_ERROR_RETURN_FAILURE( 2912 THROW_NEW_ERROR_RETURN_FAILURE(
2859 isolate, NewReferenceError(MessageTemplate::kNotDefined, it.name())); 2913 isolate, NewReferenceError(MessageTemplate::kNotDefined, it.name()));
2860 } 2914 }
2861 2915
2862 2916
2863 RUNTIME_FUNCTION(Runtime_StorePropertyWithInterceptor) { 2917 RUNTIME_FUNCTION(Runtime_StorePropertyWithInterceptor) {
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
2951 DCHECK_EQ(FeedbackVectorSlotKind::KEYED_LOAD_IC, 3005 DCHECK_EQ(FeedbackVectorSlotKind::KEYED_LOAD_IC,
2952 vector->GetKind(vector_slot)); 3006 vector->GetKind(vector_slot));
2953 KeyedLoadICNexus nexus(vector, vector_slot); 3007 KeyedLoadICNexus nexus(vector, vector_slot);
2954 KeyedLoadIC ic(IC::EXTRA_CALL_FRAME, isolate, &nexus); 3008 KeyedLoadIC ic(IC::EXTRA_CALL_FRAME, isolate, &nexus);
2955 ic.UpdateState(receiver, key); 3009 ic.UpdateState(receiver, key);
2956 RETURN_RESULT_OR_FAILURE(isolate, ic.Load(receiver, key)); 3010 RETURN_RESULT_OR_FAILURE(isolate, ic.Load(receiver, key));
2957 } 3011 }
2958 } 3012 }
2959 } // namespace internal 3013 } // namespace internal
2960 } // namespace v8 3014 } // namespace v8
OLDNEW
« src/ast/ast.cc ('K') | « src/ic/ic.h ('k') | src/ic/x64/stub-cache-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698