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

Side by Side Diff: src/ic.cc

Issue 458813002: Prototype implementation of GET_OWN_PROPERTY intrinsic. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 4 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 | Annotate | Revision Log
« no previous file with comments | « src/ic.h ('k') | src/parser.cc » ('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/codegen.h" 10 #include "src/codegen.h"
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
98 JavaScriptFrame::PrintFunctionAndOffset(function, function->code(), pc(), 98 JavaScriptFrame::PrintFunctionAndOffset(function, function->code(), pc(),
99 stdout, true); 99 stdout, true);
100 } 100 }
101 101
102 ExtraICState extra_state = new_target->extra_ic_state(); 102 ExtraICState extra_state = new_target->extra_ic_state();
103 const char* modifier = ""; 103 const char* modifier = "";
104 if (new_target->kind() == Code::KEYED_STORE_IC) { 104 if (new_target->kind() == Code::KEYED_STORE_IC) {
105 modifier = GetTransitionMarkModifier( 105 modifier = GetTransitionMarkModifier(
106 KeyedStoreIC::GetKeyedAccessStoreMode(extra_state)); 106 KeyedStoreIC::GetKeyedAccessStoreMode(extra_state));
107 } 107 }
108 if (new_target->kind() == Code::LOAD_IC || new_target->kind() == Code::KEYED _LOAD_IC) {
109 LoadIC::PropertyLookupMode lookup_mode = LoadIC::PropertyLookupMode(extra_ state);
110 PrintF("<%s>", lookup_mode == LoadIC::NORMAL_LOOKUP ? "normal" : "own");
111 }
112
108 PrintF(" (%c->%c%s)", TransitionMarkFromState(old_state), 113 PrintF(" (%c->%c%s)", TransitionMarkFromState(old_state),
109 TransitionMarkFromState(new_state), modifier); 114 TransitionMarkFromState(new_state), modifier);
110 #ifdef OBJECT_PRINT 115 #ifdef OBJECT_PRINT
111 OFStream os(stdout); 116 OFStream os(stdout);
112 name->Print(os); 117 name->Print(os);
113 #else 118 #else
114 name->ShortPrint(stdout); 119 name->ShortPrint(stdout);
115 #endif 120 #endif
116 PrintF("]\n"); 121 PrintF("]\n");
122 if (name->IsString() && strcmp(String::cast(*name)->ToCString().get(), "xBas e") == 0 &&
123 new_state == MEGAMORPHIC) {
124 PrintF("Here!\n");
125 }
117 } 126 }
118 } 127 }
119 128
120 #define TRACE_IC(type, name) TraceIC(type, name) 129 #define TRACE_IC(type, name) TraceIC(type, name)
121 #define TRACE_VECTOR_IC(type, name, old_state, new_state) \ 130 #define TRACE_VECTOR_IC(type, name, old_state, new_state) \
122 TraceIC(type, name, old_state, new_state) 131 TraceIC(type, name, old_state, new_state)
123 132
124 IC::IC(FrameDepth depth, Isolate* isolate) 133 IC::IC(FrameDepth depth, Isolate* isolate)
125 : isolate_(isolate), 134 : isolate_(isolate),
126 target_set_(false), 135 target_set_(false),
(...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after
503 512
504 513
505 void KeyedLoadIC::Clear(Isolate* isolate, 514 void KeyedLoadIC::Clear(Isolate* isolate,
506 Address address, 515 Address address,
507 Code* target, 516 Code* target,
508 ConstantPoolArray* constant_pool) { 517 ConstantPoolArray* constant_pool) {
509 if (IsCleared(target)) return; 518 if (IsCleared(target)) return;
510 // Make sure to also clear the map used in inline fast cases. If we 519 // Make sure to also clear the map used in inline fast cases. If we
511 // do not clear these maps, cached code can keep objects alive 520 // do not clear these maps, cached code can keep objects alive
512 // through the embedded maps. 521 // through the embedded maps.
513 SetTargetAtAddress(address, *pre_monomorphic_stub(isolate), constant_pool); 522 Code* code = PropertyICCompiler::FindPreMonomorphic(isolate, Code::KEYED_LOAD_ IC,
523 target->extra_ic_state());
524 SetTargetAtAddress(address, code, constant_pool);
514 } 525 }
515 526
516 527
517 void CallIC::Clear(Isolate* isolate, 528 void CallIC::Clear(Isolate* isolate,
518 Address address, 529 Address address,
519 Code* target, 530 Code* target,
520 ConstantPoolArray* constant_pool) { 531 ConstantPoolArray* constant_pool) {
521 // Currently, CallIC doesn't have state changes. 532 // Currently, CallIC doesn't have state changes.
522 } 533 }
523 534
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
565 Token::Value op; 576 Token::Value op;
566 ICCompareStub::DecodeKey(target->stub_key(), NULL, NULL, &handler_state, &op); 577 ICCompareStub::DecodeKey(target->stub_key(), NULL, NULL, &handler_state, &op);
567 // Only clear CompareICs that can retain objects. 578 // Only clear CompareICs that can retain objects.
568 if (handler_state != KNOWN_OBJECT) return; 579 if (handler_state != KNOWN_OBJECT) return;
569 SetTargetAtAddress(address, GetRawUninitialized(isolate, op), constant_pool); 580 SetTargetAtAddress(address, GetRawUninitialized(isolate, op), constant_pool);
570 PatchInlinedSmiCode(address, DISABLE_INLINED_SMI_CHECK); 581 PatchInlinedSmiCode(address, DISABLE_INLINED_SMI_CHECK);
571 } 582 }
572 583
573 584
574 // static 585 // static
575 Handle<Code> KeyedLoadIC::generic_stub(Isolate* isolate) { 586 Handle<Code> KeyedLoadIC::generic_stub(Isolate* isolate, ExtraICState extra_ic_s tate) {
587 // TODO: plumbing
576 if (FLAG_compiled_keyed_generic_loads) { 588 if (FLAG_compiled_keyed_generic_loads) {
577 return KeyedLoadGenericStub(isolate).GetCode(); 589 return KeyedLoadGenericStub(isolate, GetPropertyLookupMode(extra_ic_state)). GetCode();
578 } else { 590 } else {
579 return isolate->builtins()->KeyedLoadIC_Generic(); 591 return PropertyICCompiler::ComputeKeyedLoad(isolate, GENERIC, extra_ic_state );
580 } 592 }
581 } 593 }
582 594
583 595
584 static bool MigrateDeprecated(Handle<Object> object) { 596 static bool MigrateDeprecated(Handle<Object> object) {
585 if (!object->IsJSObject()) return false; 597 if (!object->IsJSObject()) return false;
586 Handle<JSObject> receiver = Handle<JSObject>::cast(object); 598 Handle<JSObject> receiver = Handle<JSObject>::cast(object);
587 if (!receiver->map()->is_deprecated()) return false; 599 if (!receiver->map()->is_deprecated()) return false;
588 JSObject::MigrateInstance(Handle<JSObject>::cast(object)); 600 JSObject::MigrateInstance(Handle<JSObject>::cast(object));
589 return true; 601 return true;
590 } 602 }
591 603
592 604
593 MaybeHandle<Object> LoadIC::Load(Handle<Object> object, Handle<String> name) { 605 MaybeHandle<Object> LoadIC::Load(Handle<Object> object, Handle<Name> name) {
594 // If the object is undefined or null it's illegal to try to get any 606 // If the object is undefined or null it's illegal to try to get any
595 // of its properties; throw a TypeError in that case. 607 // of its properties; throw a TypeError in that case.
596 if (object->IsUndefined() || object->IsNull()) { 608 if (object->IsUndefined() || object->IsNull()) {
597 return TypeError("non_object_property_load", object, name); 609 return TypeError("non_object_property_load", object, name);
598 } 610 }
599 611
600 // Check if the name is trivially convertible to an index and get 612 // Check if the name is trivially convertible to an index and get
601 // the element or char if so. 613 // the element or char if so.
602 uint32_t index; 614 uint32_t index;
603 if (kind() == Code::KEYED_LOAD_IC && name->AsArrayIndex(&index)) { 615 if (kind() == Code::KEYED_LOAD_IC &&
616 name->IsString() && String::cast(*name)->AsArrayIndex(&index)) {
604 // Rewrite to the generic keyed load stub. 617 // Rewrite to the generic keyed load stub.
605 if (FLAG_use_ic) { 618 if (FLAG_use_ic) {
606 set_target(*KeyedLoadIC::generic_stub(isolate())); 619 set_target(*KeyedLoadIC::generic_stub(isolate(), extra_ic_state()));
607 TRACE_IC("LoadIC", name); 620 TRACE_IC("LoadIC", name);
608 TRACE_GENERIC_IC(isolate(), "LoadIC", "name as array index"); 621 TRACE_GENERIC_IC(isolate(), "LoadIC", "name as array index");
609 } 622 }
610 Handle<Object> result; 623 Handle<Object> result;
611 ASSIGN_RETURN_ON_EXCEPTION( 624 ASSIGN_RETURN_ON_EXCEPTION(
612 isolate(), 625 isolate(),
613 result, 626 result,
614 Runtime::GetElementOrCharAt(isolate(), object, index), 627 Runtime::GetElementOrCharAt(isolate(), object, index),
615 Object); 628 Object);
616 return result; 629 return result;
617 } 630 }
618 631
619 bool use_ic = MigrateDeprecated(object) ? false : FLAG_use_ic; 632 bool use_ic = MigrateDeprecated(object) ? false : FLAG_use_ic;
620 633
621 // Named lookup in the object. 634 // Named lookup in the object.
622 LookupIterator it(object, name); 635 LookupIterator::Configuration lookup_configuration =
623 LookupForRead(&it); 636 property_lookup_mode() == OWN_PROPERTY_LOOKUP ?
637 LookupIterator::CHECK_OWN_REAL :
638 LookupIterator::CHECK_ALL;
639
640 LookupIterator it(object, name, lookup_configuration);
641 LookupForRead(&it);
624 642
625 // If we did not find a property, check if we need to throw an exception. 643 // If we did not find a property, check if we need to throw an exception.
626 if (!it.IsFound()) { 644 if (!it.IsFound()) {
627 if (IsUndeclaredGlobal(object)) { 645 if (IsUndeclaredGlobal(object)) {
628 return ReferenceError("not_defined", name); 646 return ReferenceError("not_defined",
647 name->IsString()
648 ? Handle<String>::cast(name)
649 : Handle<String>());
629 } 650 }
630 LOG(isolate(), SuspectReadEvent(*name, *object)); 651 LOG(isolate(), SuspectReadEvent(*name, *object));
631 } 652 }
632 653
633 // Update inline cache and stub cache. 654 // Update inline cache and stub cache.
634 if (use_ic) UpdateCaches(&it, object, name); 655 if (use_ic) UpdateCaches(&it, object, name);
635 656
636 // Get the property. 657 // Get the property.
637 Handle<Object> result; 658 Handle<Object> result;
638 ASSIGN_RETURN_ON_EXCEPTION( 659 ASSIGN_RETURN_ON_EXCEPTION(
639 isolate(), result, Object::GetProperty(&it), Object); 660 isolate(), result, Object::GetProperty(&it), Object);
640 // If the property is not present, check if we need to throw an exception. 661 // If the property is not present, check if we need to throw an exception.
641 if (!it.IsFound() && IsUndeclaredGlobal(object)) { 662 if (!it.IsFound() && IsUndeclaredGlobal(object)) {
642 return ReferenceError("not_defined", name); 663 return ReferenceError("not_defined",
664 name->IsString()
665 ? Handle<String>::cast(name)
666 : Handle<String>());
643 } 667 }
644 668
645 return result; 669 return result;
646 } 670 }
647 671
648 672
649 static bool AddOneReceiverMapIfMissing(MapHandleList* receiver_maps, 673 static bool AddOneReceiverMapIfMissing(MapHandleList* receiver_maps,
650 Handle<Map> new_receiver_map) { 674 Handle<Map> new_receiver_map) {
651 DCHECK(!new_receiver_map.is_null()); 675 DCHECK(!new_receiver_map.is_null());
652 for (int current = 0; current < receiver_maps->length(); ++current) { 676 for (int current = 0; current < receiver_maps->length(); ++current) {
653 if (!receiver_maps->at(current).is_null() && 677 if (!receiver_maps->at(current).is_null() &&
654 receiver_maps->at(current).is_identical_to(new_receiver_map)) { 678 receiver_maps->at(current).is_identical_to(new_receiver_map)) {
655 return false; 679 return false;
656 } 680 }
657 } 681 }
658 receiver_maps->Add(new_receiver_map); 682 receiver_maps->Add(new_receiver_map);
659 return true; 683 return true;
660 } 684 }
661 685
662 686
663 bool IC::UpdatePolymorphicIC(Handle<String> name, Handle<Code> code) { 687 bool IC::UpdatePolymorphicIC(Handle<Name> name, Handle<Code> code) {
664 if (!code->is_handler()) return false; 688 if (!code->is_handler()) return false;
665 if (target()->is_keyed_stub() && state() != PROTOTYPE_FAILURE) return false; 689 if (target()->is_keyed_stub() && state() != PROTOTYPE_FAILURE) return false;
666 Handle<HeapType> type = receiver_type(); 690 Handle<HeapType> type = receiver_type();
667 TypeHandleList types; 691 TypeHandleList types;
668 CodeHandleList handlers; 692 CodeHandleList handlers;
669 693
670 TargetTypes(&types); 694 TargetTypes(&types);
671 int number_of_types = types.length(); 695 int number_of_types = types.length();
672 int deprecated_types = 0; 696 int deprecated_types = 0;
673 int handler_to_overwrite = -1; 697 int handler_to_overwrite = -1;
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
759 783
760 784
761 template 785 template
762 Type* IC::MapToType<Type>(Handle<Map> map, Zone* zone); 786 Type* IC::MapToType<Type>(Handle<Map> map, Zone* zone);
763 787
764 788
765 template 789 template
766 Handle<HeapType> IC::MapToType<HeapType>(Handle<Map> map, Isolate* region); 790 Handle<HeapType> IC::MapToType<HeapType>(Handle<Map> map, Isolate* region);
767 791
768 792
769 void IC::UpdateMonomorphicIC(Handle<Code> handler, Handle<String> name) { 793 void IC::UpdateMonomorphicIC(Handle<Code> handler, Handle<Name> name) {
770 DCHECK(handler->is_handler()); 794 DCHECK(handler->is_handler());
771 Handle<Code> ic = PropertyICCompiler::ComputeMonomorphic( 795 Handle<Code> ic = PropertyICCompiler::ComputeMonomorphic(
772 kind(), name, receiver_type(), handler, extra_ic_state()); 796 kind(), name, receiver_type(), handler, extra_ic_state());
773 set_target(*ic); 797 set_target(*ic);
774 } 798 }
775 799
776 800
777 void IC::CopyICToMegamorphicCache(Handle<String> name) { 801 void IC::CopyICToMegamorphicCache(Handle<Name> name) {
778 TypeHandleList types; 802 TypeHandleList types;
779 CodeHandleList handlers; 803 CodeHandleList handlers;
780 TargetTypes(&types); 804 TargetTypes(&types);
781 if (!target()->FindHandlers(&handlers, types.length())) return; 805 if (!target()->FindHandlers(&handlers, types.length())) return;
782 for (int i = 0; i < types.length(); i++) { 806 for (int i = 0; i < types.length(); i++) {
783 UpdateMegamorphicCache(*types.at(i), *name, *handlers.at(i)); 807 UpdateMegamorphicCache(*types.at(i), *name, *handlers.at(i));
784 } 808 }
785 } 809 }
786 810
787 811
788 bool IC::IsTransitionOfMonomorphicTarget(Map* source_map, Map* target_map) { 812 bool IC::IsTransitionOfMonomorphicTarget(Map* source_map, Map* target_map) {
789 if (source_map == NULL) return true; 813 if (source_map == NULL) return true;
790 if (target_map == NULL) return false; 814 if (target_map == NULL) return false;
791 ElementsKind target_elements_kind = target_map->elements_kind(); 815 ElementsKind target_elements_kind = target_map->elements_kind();
792 bool more_general_transition = 816 bool more_general_transition =
793 IsMoreGeneralElementsKindTransition( 817 IsMoreGeneralElementsKindTransition(
794 source_map->elements_kind(), target_elements_kind); 818 source_map->elements_kind(), target_elements_kind);
795 Map* transitioned_map = more_general_transition 819 Map* transitioned_map = more_general_transition
796 ? source_map->LookupElementsTransitionMap(target_elements_kind) 820 ? source_map->LookupElementsTransitionMap(target_elements_kind)
797 : NULL; 821 : NULL;
798 822
799 return transitioned_map == target_map; 823 return transitioned_map == target_map;
800 } 824 }
801 825
802 826
803 void IC::PatchCache(Handle<String> name, Handle<Code> code) { 827 void IC::PatchCache(Handle<Name> name, Handle<Code> code) {
804 switch (state()) { 828 switch (state()) {
805 case UNINITIALIZED: 829 case UNINITIALIZED:
806 case PREMONOMORPHIC: 830 case PREMONOMORPHIC:
807 UpdateMonomorphicIC(code, name); 831 UpdateMonomorphicIC(code, name);
808 break; 832 break;
809 case PROTOTYPE_FAILURE: 833 case PROTOTYPE_FAILURE:
810 case MONOMORPHIC: 834 case MONOMORPHIC:
811 case POLYMORPHIC: 835 case POLYMORPHIC:
812 if (!target()->is_keyed_stub() || state() == PROTOTYPE_FAILURE) { 836 if (!target()->is_keyed_stub() || state() == PROTOTYPE_FAILURE) {
813 if (UpdatePolymorphicIC(name, code)) break; 837 if (UpdatePolymorphicIC(name, code)) break;
(...skipping 13 matching lines...) Expand all
827 } 851 }
828 } 852 }
829 853
830 854
831 Handle<Code> LoadIC::initialize_stub(Isolate* isolate, 855 Handle<Code> LoadIC::initialize_stub(Isolate* isolate,
832 ExtraICState extra_state) { 856 ExtraICState extra_state) {
833 return PropertyICCompiler::ComputeLoad(isolate, UNINITIALIZED, extra_state); 857 return PropertyICCompiler::ComputeLoad(isolate, UNINITIALIZED, extra_state);
834 } 858 }
835 859
836 860
861 Handle<Code> KeyedLoadIC::initialize_stub(Isolate* isolate,
862 ExtraICState extra_state) {
863 return PropertyICCompiler::ComputeKeyedLoad(isolate, UNINITIALIZED, extra_stat e);
864 }
865
866
837 Handle<Code> LoadIC::megamorphic_stub() { 867 Handle<Code> LoadIC::megamorphic_stub() {
838 if (kind() == Code::LOAD_IC) { 868 if (kind() == Code::LOAD_IC) {
839 return PropertyICCompiler::ComputeLoad(isolate(), MEGAMORPHIC, 869 return PropertyICCompiler::ComputeLoad(isolate(), MEGAMORPHIC,
840 extra_ic_state()); 870 extra_ic_state());
841 } else { 871 } else {
842 DCHECK_EQ(Code::KEYED_LOAD_IC, kind()); 872 DCHECK_EQ(Code::KEYED_LOAD_IC, kind());
843 return KeyedLoadIC::generic_stub(isolate()); 873 return KeyedLoadIC::generic_stub(isolate(), extra_ic_state());
844 } 874 }
845 } 875 }
846 876
847 877
848 Handle<Code> LoadIC::pre_monomorphic_stub(Isolate* isolate, 878 Handle<Code> LoadIC::pre_monomorphic_stub(Isolate* isolate,
849 ExtraICState extra_state) { 879 ExtraICState extra_state) {
850 return PropertyICCompiler::ComputeLoad(isolate, PREMONOMORPHIC, extra_state); 880 return PropertyICCompiler::ComputeLoad(isolate, PREMONOMORPHIC, extra_state);
851 } 881 }
852 882
853 883
854 Handle<Code> KeyedLoadIC::pre_monomorphic_stub(Isolate* isolate) { 884 Handle<Code> KeyedLoadIC::pre_monomorphic_stub(Isolate* isolate,
855 return isolate->builtins()->KeyedLoadIC_PreMonomorphic(); 885 ExtraICState extra_state) {
886 return PropertyICCompiler::ComputeKeyedLoad(isolate, PREMONOMORPHIC, extra_sta te);
856 } 887 }
857 888
858 889
859 Handle<Code> LoadIC::pre_monomorphic_stub() const { 890 Handle<Code> LoadIC::pre_monomorphic_stub() const {
860 if (kind() == Code::LOAD_IC) { 891 if (kind() == Code::LOAD_IC) {
861 return LoadIC::pre_monomorphic_stub(isolate(), extra_ic_state()); 892 return LoadIC::pre_monomorphic_stub(isolate(), extra_ic_state());
862 } else { 893 } else {
863 DCHECK_EQ(Code::KEYED_LOAD_IC, kind()); 894 DCHECK_EQ(Code::KEYED_LOAD_IC, kind());
864 return KeyedLoadIC::pre_monomorphic_stub(isolate()); 895 return KeyedLoadIC::pre_monomorphic_stub(isolate(), extra_ic_state());
865 } 896 }
866 } 897 }
867 898
868 899
869 Handle<Code> LoadIC::SimpleFieldLoad(FieldIndex index) { 900 Handle<Code> LoadIC::SimpleFieldLoad(FieldIndex index) {
870 LoadFieldStub stub(isolate(), index); 901 LoadFieldStub stub(isolate(), index);
871 return stub.GetCode(); 902 return stub.GetCode();
872 } 903 }
873 904
874 905
875 void LoadIC::UpdateCaches(LookupIterator* lookup, Handle<Object> object, 906 void LoadIC::UpdateCaches(LookupIterator* lookup, Handle<Object> object,
876 Handle<String> name) { 907 Handle<Name> name) {
877 if (state() == UNINITIALIZED) { 908 if (state() == UNINITIALIZED) {
878 // This is the first time we execute this inline cache. 909 // This is the first time we execute this inline cache.
879 // Set the target to the pre monomorphic stub to delay 910 // Set the target to the pre monomorphic stub to delay
880 // setting the monomorphic state. 911 // setting the monomorphic state.
881 set_target(*pre_monomorphic_stub()); 912 set_target(*pre_monomorphic_stub());
882 TRACE_IC("LoadIC", name); 913 TRACE_IC("LoadIC", name);
883 return; 914 return;
884 } 915 }
885 916
886 Handle<Code> code; 917 Handle<Code> code;
887 if (lookup->state() == LookupIterator::JSPROXY || 918 if (lookup->state() == LookupIterator::JSPROXY ||
888 lookup->state() == LookupIterator::ACCESS_CHECK) { 919 lookup->state() == LookupIterator::ACCESS_CHECK) {
889 code = slow_stub(); 920 code = slow_stub();
890 } else if (!lookup->IsFound()) { 921 } else if (!lookup->IsFound()) {
891 if (kind() == Code::LOAD_IC) { 922 if (kind() == Code::LOAD_IC && property_lookup_mode() == NORMAL_LOOKUP) {
892 code = NamedLoadHandlerCompiler::ComputeLoadNonexistent(name, 923 code = NamedLoadHandlerCompiler::ComputeLoadNonexistent(name,
893 receiver_type()); 924 receiver_type());
894 // TODO(jkummerow/verwaest): Introduce a builtin that handles this case. 925 // TODO(jkummerow/verwaest): Introduce a builtin that handles this case.
895 if (code.is_null()) code = slow_stub(); 926 if (code.is_null()) code = slow_stub();
896 } else { 927 } else {
897 code = slow_stub(); 928 code = slow_stub();
898 } 929 }
899 } else { 930 } else {
900 code = ComputeHandler(lookup, object, name); 931 code = ComputeHandler(lookup, object, name);
901 } 932 }
902 933
903 PatchCache(name, code); 934 PatchCache(name, code);
904 TRACE_IC("LoadIC", name); 935 TRACE_IC("LoadIC", name);
905 } 936 }
906 937
907 938
908 void IC::UpdateMegamorphicCache(HeapType* type, Name* name, Code* code) { 939 void IC::UpdateMegamorphicCache(HeapType* type, Name* name, Code* code) {
909 if (kind() == Code::KEYED_LOAD_IC || kind() == Code::KEYED_STORE_IC) return; 940 if (kind() == Code::KEYED_LOAD_IC || kind() == Code::KEYED_STORE_IC) return;
910 Map* map = *TypeToMap(type, isolate()); 941 Map* map = *TypeToMap(type, isolate());
911 isolate()->stub_cache()->Set(name, map, code); 942 isolate()->stub_cache()->Set(name, map, code);
912 } 943 }
913 944
914 945
915 Handle<Code> IC::ComputeHandler(LookupIterator* lookup, Handle<Object> object, 946 Handle<Code> IC::ComputeHandler(LookupIterator* lookup, Handle<Object> object,
916 Handle<String> name, Handle<Object> value) { 947 Handle<Name> name, Handle<Object> value) {
917 bool receiver_is_holder = 948 bool receiver_is_holder =
918 object.is_identical_to(lookup->GetHolder<JSObject>()); 949 object.is_identical_to(lookup->GetHolder<JSObject>());
919 CacheHolderFlag flag; 950 CacheHolderFlag flag;
920 Handle<Map> stub_holder_map = IC::GetHandlerCacheHolder( 951 Handle<Map> stub_holder_map = IC::GetHandlerCacheHolder(
921 *receiver_type(), receiver_is_holder, isolate(), &flag); 952 *receiver_type(), receiver_is_holder, isolate(), &flag);
922 953
923 Handle<Code> code = PropertyHandlerCompiler::Find( 954 Handle<Code> code = PropertyHandlerCompiler::Find(
924 name, stub_holder_map, kind(), flag, 955 name, stub_holder_map, kind(), flag,
925 lookup->holder_map()->is_dictionary_map() ? Code::NORMAL : Code::FAST); 956 lookup->holder_map()->is_dictionary_map() ? Code::NORMAL : Code::FAST);
926 // Use the cached value if it exists, and if it is different from the 957 // Use the cached value if it exists, and if it is different from the
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
994 1025
995 if (code->type() != Code::NORMAL) { 1026 if (code->type() != Code::NORMAL) {
996 Map::UpdateCodeCache(stub_holder_map, name, code); 1027 Map::UpdateCodeCache(stub_holder_map, name, code);
997 } 1028 }
998 1029
999 return code; 1030 return code;
1000 } 1031 }
1001 1032
1002 1033
1003 Handle<Code> LoadIC::CompileHandler(LookupIterator* lookup, 1034 Handle<Code> LoadIC::CompileHandler(LookupIterator* lookup,
1004 Handle<Object> object, Handle<String> name, 1035 Handle<Object> object, Handle<Name> name,
1005 Handle<Object> unused, 1036 Handle<Object> unused,
1006 CacheHolderFlag cache_holder) { 1037 CacheHolderFlag cache_holder) {
1007 if (object->IsString() && 1038 if (object->IsString() &&
1008 String::Equals(isolate()->factory()->length_string(), name)) { 1039 Name::Equals(isolate()->factory()->length_string(), name)) {
1009 FieldIndex index = FieldIndex::ForInObjectOffset(String::kLengthOffset); 1040 FieldIndex index = FieldIndex::ForInObjectOffset(String::kLengthOffset);
1010 return SimpleFieldLoad(index); 1041 return SimpleFieldLoad(index);
1011 } 1042 }
1012 1043
1013 if (object->IsStringWrapper() && 1044 if (object->IsStringWrapper() &&
1014 String::Equals(isolate()->factory()->length_string(), name)) { 1045 Name::Equals(isolate()->factory()->length_string(), name)) {
1015 StringLengthStub string_length_stub(isolate()); 1046 StringLengthStub string_length_stub(isolate());
1016 return string_length_stub.GetCode(); 1047 return string_length_stub.GetCode();
1017 } 1048 }
1018 1049
1019 // Use specialized code for getting prototype of functions. 1050 // Use specialized code for getting prototype of functions.
1020 if (object->IsJSFunction() && 1051 if (object->IsJSFunction() &&
1021 String::Equals(isolate()->factory()->prototype_string(), name) && 1052 Name::Equals(isolate()->factory()->prototype_string(), name) &&
1022 Handle<JSFunction>::cast(object)->should_have_prototype() && 1053 Handle<JSFunction>::cast(object)->should_have_prototype() &&
1023 !Handle<JSFunction>::cast(object)->map()->has_non_instance_prototype()) { 1054 !Handle<JSFunction>::cast(object)->map()->has_non_instance_prototype()) {
1024 Handle<Code> stub; 1055 Handle<Code> stub;
1025 FunctionPrototypeStub function_prototype_stub(isolate()); 1056 FunctionPrototypeStub function_prototype_stub(isolate());
1026 return function_prototype_stub.GetCode(); 1057 return function_prototype_stub.GetCode();
1027 } 1058 }
1028 1059
1029 Handle<HeapType> type = receiver_type(); 1060 Handle<HeapType> type = receiver_type();
1030 Handle<JSObject> holder = lookup->GetHolder<JSObject>(); 1061 Handle<JSObject> holder = lookup->GetHolder<JSObject>();
1031 bool receiver_is_holder = object.is_identical_to(holder); 1062 bool receiver_is_holder = object.is_identical_to(holder);
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
1230 return result; 1261 return result;
1231 } 1262 }
1232 1263
1233 Handle<Object> load_handle; 1264 Handle<Object> load_handle;
1234 Handle<Code> stub = generic_stub(); 1265 Handle<Code> stub = generic_stub();
1235 1266
1236 // Check for non-string values that can be converted into an 1267 // Check for non-string values that can be converted into an
1237 // internalized string directly or is representable as a smi. 1268 // internalized string directly or is representable as a smi.
1238 key = TryConvertKey(key, isolate()); 1269 key = TryConvertKey(key, isolate());
1239 1270
1240 if (key->IsInternalizedString()) { 1271 if (key->IsInternalizedString() || key->IsSymbol()) {
1241 ASSIGN_RETURN_ON_EXCEPTION( 1272 ASSIGN_RETURN_ON_EXCEPTION(
1242 isolate(), 1273 isolate(),
1243 load_handle, 1274 load_handle,
1244 LoadIC::Load(object, Handle<String>::cast(key)), 1275 LoadIC::Load(object, Handle<Name>::cast(key)),
1245 Object); 1276 Object);
1246 } else if (FLAG_use_ic && !object->IsAccessCheckNeeded()) { 1277 } else if (FLAG_use_ic && !object->IsAccessCheckNeeded()) {
1247 if (object->IsString() && key->IsNumber()) { 1278 if (object->IsString() && key->IsNumber()) {
1248 if (state() == UNINITIALIZED) stub = string_stub(); 1279 if (state() == UNINITIALIZED) stub = string_stub();
1249 } else if (object->IsJSObject()) { 1280 } else if (object->IsJSObject()) {
1250 Handle<JSObject> receiver = Handle<JSObject>::cast(object); 1281 Handle<JSObject> receiver = Handle<JSObject>::cast(object);
1251 if (receiver->elements()->map() == 1282 if (receiver->elements()->map() ==
1252 isolate()->heap()->sloppy_arguments_elements_map()) { 1283 isolate()->heap()->sloppy_arguments_elements_map()) {
1253 stub = sloppy_arguments_stub(); 1284 stub = sloppy_arguments_stub();
1254 } else if (receiver->HasIndexedInterceptor()) { 1285 } else if (receiver->HasIndexedInterceptor()) {
(...skipping 843 matching lines...) Expand 10 before | Expand all | Expand 10 after
2098 } 2129 }
2099 2130
2100 2131
2101 // Used from ic-<arch>.cc. 2132 // Used from ic-<arch>.cc.
2102 RUNTIME_FUNCTION(LoadIC_Miss) { 2133 RUNTIME_FUNCTION(LoadIC_Miss) {
2103 TimerEventScope<TimerEventIcMiss> timer(isolate); 2134 TimerEventScope<TimerEventIcMiss> timer(isolate);
2104 HandleScope scope(isolate); 2135 HandleScope scope(isolate);
2105 DCHECK(args.length() == 2); 2136 DCHECK(args.length() == 2);
2106 LoadIC ic(IC::NO_EXTRA_FRAME, isolate); 2137 LoadIC ic(IC::NO_EXTRA_FRAME, isolate);
2107 Handle<Object> receiver = args.at<Object>(0); 2138 Handle<Object> receiver = args.at<Object>(0);
2108 Handle<String> key = args.at<String>(1); 2139 Handle<Name> key = args.at<Name>(1);
2109 ic.UpdateState(receiver, key); 2140 ic.UpdateState(receiver, key);
2110 Handle<Object> result; 2141 Handle<Object> result;
2111 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key)); 2142 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key));
2112 return *result; 2143 return *result;
2113 } 2144 }
2114 2145
2115 2146
2116 // Used from ic-<arch>.cc 2147 // Used from ic-<arch>.cc
2117 RUNTIME_FUNCTION(KeyedLoadIC_Miss) { 2148 RUNTIME_FUNCTION(KeyedLoadIC_Miss) {
2118 TimerEventScope<TimerEventIcMiss> timer(isolate); 2149 TimerEventScope<TimerEventIcMiss> timer(isolate);
(...skipping 1051 matching lines...) Expand 10 before | Expand all | Expand 10 after
3170 #undef ADDR 3201 #undef ADDR
3171 }; 3202 };
3172 3203
3173 3204
3174 Address IC::AddressFromUtilityId(IC::UtilityId id) { 3205 Address IC::AddressFromUtilityId(IC::UtilityId id) {
3175 return IC_utilities[id]; 3206 return IC_utilities[id];
3176 } 3207 }
3177 3208
3178 3209
3179 } } // namespace v8::internal 3210 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ic.h ('k') | src/parser.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698