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

Side by Side Diff: src/ic.cc

Issue 8357010: Handlify the stub cache lookup and patching for CallIC and KeyedCallIC. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 9 years, 2 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/objects.h » ('j') | src/stub-cache.h » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
93 } else { 93 } else {
94 PrintF("<unknown>"); 94 PrintF("<unknown>");
95 } 95 }
96 PrintF(" (%c->%c)", 96 PrintF(" (%c->%c)",
97 TransitionMarkFromState(old_state), 97 TransitionMarkFromState(old_state),
98 TransitionMarkFromState(new_state)); 98 TransitionMarkFromState(new_state));
99 name->Print(); 99 name->Print();
100 PrintF("]\n"); 100 PrintF("]\n");
101 } 101 }
102 } 102 }
103 #endif 103 #endif // DEBUG
104
105
106 #define TRACE_IC(type, name, old_state, new_target) \
107 ASSERT((TraceIC(type, name, old_state, new_target), true))
104 108
105 109
106 IC::IC(FrameDepth depth, Isolate* isolate) : isolate_(isolate) { 110 IC::IC(FrameDepth depth, Isolate* isolate) : isolate_(isolate) {
107 ASSERT(isolate == Isolate::Current()); 111 ASSERT(isolate == Isolate::Current());
108 // To improve the performance of the (much used) IC code, we unfold 112 // To improve the performance of the (much used) IC code, we unfold
109 // a few levels of the stack frame iteration code. This yields a 113 // a few levels of the stack frame iteration code. This yields a
110 // ~35% speedup when running DeltaBlue with the '--nouse-ic' flag. 114 // ~35% speedup when running DeltaBlue with the '--nouse-ic' flag.
111 const Address entry = 115 const Address entry =
112 Isolate::c_entry_fp(isolate->thread_local_top()); 116 Isolate::c_entry_fp(isolate->thread_local_top());
113 Address* pc_address = 117 Address* pc_address =
(...skipping 496 matching lines...) Expand 10 before | Expand all | Expand 10 after
610 } 614 }
611 } 615 }
612 break; 616 break;
613 default: 617 default:
614 return false; 618 return false;
615 } 619 }
616 return false; 620 return false;
617 } 621 }
618 622
619 623
620 MaybeObject* CallICBase::ComputeMonomorphicStub( 624 Handle<Code> CallICBase::ComputeMonomorphicStub(LookupResult* lookup,
621 LookupResult* lookup, 625 State state,
622 State state, 626 Code::ExtraICState extra_state,
623 Code::ExtraICState extra_ic_state, 627 Handle<Object> object,
624 Handle<Object> object, 628 Handle<String> name) {
625 Handle<String> name) {
626 int argc = target()->arguments_count(); 629 int argc = target()->arguments_count();
627 MaybeObject* maybe_code = NULL; 630 Handle<JSObject> holder(lookup->holder());
628 switch (lookup->type()) { 631 switch (lookup->type()) {
629 case FIELD: { 632 case FIELD: {
630 int index = lookup->GetFieldIndex(); 633 int index = lookup->GetFieldIndex();
631 maybe_code = isolate()->stub_cache()->ComputeCallField(argc, 634 return isolate()->stub_cache()->ComputeCallField(
632 kind_, 635 argc, kind_, extra_state, name, object, holder, index);
633 extra_ic_state,
634 *name,
635 *object,
636 lookup->holder(),
637 index);
638 break;
639 } 636 }
640 case CONSTANT_FUNCTION: { 637 case CONSTANT_FUNCTION: {
641 // Get the constant function and compute the code stub for this 638 // Get the constant function and compute the code stub for this
642 // call; used for rewriting to monomorphic state and making sure 639 // call; used for rewriting to monomorphic state and making sure
643 // that the code stub is in the stub cache. 640 // that the code stub is in the stub cache.
644 JSFunction* function = lookup->GetConstantFunction(); 641 Handle<JSFunction> function(lookup->GetConstantFunction());
645 maybe_code = 642 return isolate()->stub_cache()->ComputeCallConstant(
646 isolate()->stub_cache()->ComputeCallConstant(argc, 643 argc, kind_, extra_state, name, object, holder, function);
647 kind_,
648 extra_ic_state,
649 *name,
650 *object,
651 lookup->holder(),
652 function);
653 break;
654 } 644 }
655 case NORMAL: { 645 case NORMAL: {
656 if (!object->IsJSObject()) return NULL; 646 // If we return a null handle, the IC will not be patched.
647 if (!object->IsJSObject()) return Handle<Code>::null();
657 Handle<JSObject> receiver = Handle<JSObject>::cast(object); 648 Handle<JSObject> receiver = Handle<JSObject>::cast(object);
658 649
659 if (lookup->holder()->IsGlobalObject()) { 650 if (holder->IsGlobalObject()) {
660 GlobalObject* global = GlobalObject::cast(lookup->holder()); 651 Handle<GlobalObject> global = Handle<GlobalObject>::cast(holder);
661 JSGlobalPropertyCell* cell = 652 Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(lookup));
662 JSGlobalPropertyCell::cast(global->GetPropertyCell(lookup)); 653 if (!cell->value()->IsJSFunction()) return Handle<Code>::null();
663 if (!cell->value()->IsJSFunction()) return NULL; 654 Handle<JSFunction> function(JSFunction::cast(cell->value()));
664 JSFunction* function = JSFunction::cast(cell->value()); 655 return isolate()->stub_cache()->ComputeCallGlobal(
665 maybe_code = isolate()->stub_cache()->ComputeCallGlobal(argc, 656 argc, kind_, extra_state, name, receiver, global, cell, function);
666 kind_,
667 extra_ic_state,
668 *name,
669 *receiver,
670 global,
671 cell,
672 function);
673 } else { 657 } else {
674 // There is only one shared stub for calling normalized 658 // There is only one shared stub for calling normalized
675 // properties. It does not traverse the prototype chain, so the 659 // properties. It does not traverse the prototype chain, so the
676 // property must be found in the receiver for the stub to be 660 // property must be found in the receiver for the stub to be
677 // applicable. 661 // applicable.
678 if (lookup->holder() != *receiver) return NULL; 662 if (!holder.is_identical_to(receiver)) return Handle<Code>::null();
679 maybe_code = isolate()->stub_cache()->ComputeCallNormal(argc, 663 return isolate()->stub_cache()->ComputeCallNormal(
680 kind_, 664 argc, kind_, extra_state);
681 extra_ic_state,
682 *name,
683 *receiver);
684 } 665 }
685 break; 666 break;
686 } 667 }
687 case INTERCEPTOR: { 668 case INTERCEPTOR:
688 ASSERT(HasInterceptorGetter(lookup->holder())); 669 ASSERT(HasInterceptorGetter(*holder));
689 maybe_code = isolate()->stub_cache()->ComputeCallInterceptor( 670 return isolate()->stub_cache()->ComputeCallInterceptor(
690 argc, 671 argc, kind_, extra_state, name, object, holder);
691 kind_,
692 extra_ic_state,
693 *name,
694 *object,
695 lookup->holder());
696 break;
697 }
698 default: 672 default:
699 maybe_code = NULL; 673 return Handle<Code>::null();
700 break;
701 } 674 }
702 return maybe_code;
703 } 675 }
704 676
705 677
706 void CallICBase::UpdateCaches(LookupResult* lookup, 678 void CallICBase::UpdateCaches(LookupResult* lookup,
707 State state, 679 State state,
708 Code::ExtraICState extra_ic_state, 680 Code::ExtraICState extra_ic_state,
709 Handle<Object> object, 681 Handle<Object> object,
710 Handle<String> name) { 682 Handle<String> name) {
711 // Bail out if we didn't find a result. 683 // Bail out if we didn't find a result.
712 if (!lookup->IsProperty() || !lookup->IsCacheable()) return; 684 if (!lookup->IsProperty() || !lookup->IsCacheable()) return;
713 685
714 if (lookup->holder() != *object && 686 if (lookup->holder() != *object &&
715 HasNormalObjectsInPrototypeChain( 687 HasNormalObjectsInPrototypeChain(
716 isolate(), lookup, object->GetPrototype())) { 688 isolate(), lookup, object->GetPrototype())) {
717 // Suppress optimization for prototype chains with slow properties objects 689 // Suppress optimization for prototype chains with slow properties objects
718 // in the middle. 690 // in the middle.
719 return; 691 return;
720 } 692 }
721 693
722 // Compute the number of arguments. 694 // Compute the number of arguments.
723 int argc = target()->arguments_count(); 695 int argc = target()->arguments_count();
724 MaybeObject* maybe_code = NULL;
725 bool had_proto_failure = false; 696 bool had_proto_failure = false;
697 Handle<Code> code;
726 if (state == UNINITIALIZED) { 698 if (state == UNINITIALIZED) {
727 // This is the first time we execute this inline cache. 699 // This is the first time we execute this inline cache.
728 // Set the target to the pre monomorphic stub to delay 700 // Set the target to the pre monomorphic stub to delay
729 // setting the monomorphic state. 701 // setting the monomorphic state.
730 maybe_code = 702 code = isolate()->stub_cache()->ComputeCallPreMonomorphic(
731 isolate()->stub_cache()->ComputeCallPreMonomorphic(argc, 703 argc, kind_, extra_ic_state);
732 kind_,
733 extra_ic_state);
734 } else if (state == MONOMORPHIC) { 704 } else if (state == MONOMORPHIC) {
735 if (kind_ == Code::CALL_IC && 705 if (kind_ == Code::CALL_IC &&
736 TryUpdateExtraICState(lookup, object, &extra_ic_state)) { 706 TryUpdateExtraICState(lookup, object, &extra_ic_state)) {
737 maybe_code = ComputeMonomorphicStub(lookup, 707 code = ComputeMonomorphicStub(lookup, state, extra_ic_state,
738 state, 708 object, name);
739 extra_ic_state,
740 object,
741 name);
742 } else if (kind_ == Code::CALL_IC && 709 } else if (kind_ == Code::CALL_IC &&
743 TryRemoveInvalidPrototypeDependentStub(target(), 710 TryRemoveInvalidPrototypeDependentStub(target(),
744 *object, 711 *object,
745 *name)) { 712 *name)) {
746 had_proto_failure = true; 713 had_proto_failure = true;
747 maybe_code = ComputeMonomorphicStub(lookup, 714 code = ComputeMonomorphicStub(lookup, state, extra_ic_state,
748 state, 715 object, name);
749 extra_ic_state,
750 object,
751 name);
752 } else { 716 } else {
753 maybe_code = 717 code = isolate()->stub_cache()->ComputeCallMegamorphic(
754 isolate()->stub_cache()->ComputeCallMegamorphic(argc, 718 argc, kind_, extra_ic_state);
755 kind_,
756 extra_ic_state);
757 } 719 }
758 } else { 720 } else {
759 maybe_code = ComputeMonomorphicStub(lookup, 721 code = ComputeMonomorphicStub(lookup, state, extra_ic_state,
760 state, 722 object, name);
761 extra_ic_state,
762 object,
763 name);
764 } 723 }
765 724
766 // If we're unable to compute the stub (not enough memory left), we 725 // If there's no appropriate stub we simply avoid updating the caches.
767 // simply avoid updating the caches. 726 if (code.is_null()) return;
768 Object* code;
769 if (maybe_code == NULL || !maybe_code->ToObject(&code)) return;
770 727
771 // Patch the call site depending on the state of the cache. 728 // Patch the call site depending on the state of the cache.
772 if (state == UNINITIALIZED || 729 if (state == UNINITIALIZED ||
773 state == PREMONOMORPHIC || 730 state == PREMONOMORPHIC ||
774 state == MONOMORPHIC || 731 state == MONOMORPHIC ||
775 state == MONOMORPHIC_PROTOTYPE_FAILURE) { 732 state == MONOMORPHIC_PROTOTYPE_FAILURE) {
776 set_target(Code::cast(code)); 733 set_target(*code);
777 } else if (state == MEGAMORPHIC) { 734 } else if (state == MEGAMORPHIC) {
778 // Cache code holding map should be consistent with 735 // Cache code holding map should be consistent with
779 // GenerateMonomorphicCacheProbe. It is not the map which holds the stub. 736 // GenerateMonomorphicCacheProbe. It is not the map which holds the stub.
780 Map* map = JSObject::cast(object->IsJSObject() ? *object : 737 Handle<JSObject> cache_object = object->IsJSObject()
781 object->GetPrototype())->map(); 738 ? Handle<JSObject>::cast(object)
782 739 : Handle<JSObject>(JSObject::cast(object->GetPrototype()));
783 // Update the stub cache. 740 // Update the stub cache.
784 isolate()->stub_cache()->Set(*name, map, Code::cast(code)); 741 isolate()->stub_cache()->Set(*name, cache_object->map(), *code);
785 } 742 }
786 743
787 USE(had_proto_failure);
788 #ifdef DEBUG
789 if (had_proto_failure) state = MONOMORPHIC_PROTOTYPE_FAILURE; 744 if (had_proto_failure) state = MONOMORPHIC_PROTOTYPE_FAILURE;
790 TraceIC(kind_ == Code::CALL_IC ? "CallIC" : "KeyedCallIC", 745 TRACE_IC(kind_ == Code::CALL_IC ? "CallIC" : "KeyedCallIC",
791 name, state, target()); 746 name, state, target());
792 #endif
793 } 747 }
794 748
795 749
796 MaybeObject* KeyedCallIC::LoadFunction(State state, 750 MaybeObject* KeyedCallIC::LoadFunction(State state,
797 Handle<Object> object, 751 Handle<Object> object,
798 Handle<Object> key) { 752 Handle<Object> key) {
799 if (key->IsSymbol()) { 753 if (key->IsSymbol()) {
800 return CallICBase::LoadFunction(state, 754 return CallICBase::LoadFunction(state,
801 Code::kNoExtraICState, 755 Code::kNoExtraICState,
802 object, 756 object,
803 Handle<String>::cast(key)); 757 Handle<String>::cast(key));
804 } 758 }
805 759
806 if (object->IsUndefined() || object->IsNull()) { 760 if (object->IsUndefined() || object->IsNull()) {
807 return TypeError("non_object_property_call", object, key); 761 return TypeError("non_object_property_call", object, key);
808 } 762 }
809 763
810 if (FLAG_use_ic && state != MEGAMORPHIC && object->IsHeapObject()) { 764 if (FLAG_use_ic && state != MEGAMORPHIC && object->IsHeapObject()) {
811 int argc = target()->arguments_count(); 765 int argc = target()->arguments_count();
812 Handle<Map> map = 766 Handle<Map> map =
813 isolate()->factory()->non_strict_arguments_elements_map(); 767 isolate()->factory()->non_strict_arguments_elements_map();
814 if (object->IsJSObject() && 768 if (object->IsJSObject() &&
815 Handle<JSObject>::cast(object)->elements()->map() == *map) { 769 Handle<JSObject>::cast(object)->elements()->map() == *map) {
816 MaybeObject* maybe_code = isolate()->stub_cache()->ComputeCallArguments( 770 Handle<Code> code = isolate()->stub_cache()->ComputeCallArguments(
817 argc, Code::KEYED_CALL_IC); 771 argc, Code::KEYED_CALL_IC);
818 Code* code = NULL; 772 set_target(*code);
819 if (maybe_code->To(&code)) { 773 TRACE_IC("KeyedCallIC", key, state, target());
820 set_target(code);
821 #ifdef DEBUG
822 TraceIC("KeyedCallIC", key, state, target());
823 #endif
824 }
825 } else if (!object->IsAccessCheckNeeded()) { 774 } else if (!object->IsAccessCheckNeeded()) {
826 MaybeObject* maybe_code = isolate()->stub_cache()->ComputeCallMegamorphic( 775 Handle<Code> code = isolate()->stub_cache()->ComputeCallMegamorphic(
827 argc, Code::KEYED_CALL_IC, Code::kNoExtraICState); 776 argc, Code::KEYED_CALL_IC, Code::kNoExtraICState);
828 Code* code; 777 set_target(*code);
829 if (maybe_code->To(&code)) { 778 TRACE_IC("KeyedCallIC", key, state, target());
830 set_target(code);
831 #ifdef DEBUG
832 TraceIC("KeyedCallIC", key, state, target());
833 #endif
834 }
835 } 779 }
836 } 780 }
837 781
838 Handle<Object> result = GetProperty(object, key); 782 Handle<Object> result = GetProperty(object, key);
839 RETURN_IF_EMPTY_HANDLE(isolate(), result); 783 RETURN_IF_EMPTY_HANDLE(isolate(), result);
840 784
841 // Make receiver an object if the callee requires it. Strict mode or builtin 785 // Make receiver an object if the callee requires it. Strict mode or builtin
842 // functions do not wrap the receiver, non-strict functions and objects 786 // functions do not wrap the receiver, non-strict functions and objects
843 // called as functions do. 787 // called as functions do.
844 ReceiverToObjectIfRequired(result, object); 788 ReceiverToObjectIfRequired(result, object);
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after
1055 state == MONOMORPHIC_PROTOTYPE_FAILURE) { 999 state == MONOMORPHIC_PROTOTYPE_FAILURE) {
1056 set_target(*code); 1000 set_target(*code);
1057 } else if (state == MONOMORPHIC) { 1001 } else if (state == MONOMORPHIC) {
1058 set_target(*megamorphic_stub()); 1002 set_target(*megamorphic_stub());
1059 } else if (state == MEGAMORPHIC) { 1003 } else if (state == MEGAMORPHIC) {
1060 // Cache code holding map should be consistent with 1004 // Cache code holding map should be consistent with
1061 // GenerateMonomorphicCacheProbe. 1005 // GenerateMonomorphicCacheProbe.
1062 isolate()->stub_cache()->Set(*name, receiver->map(), *code); 1006 isolate()->stub_cache()->Set(*name, receiver->map(), *code);
1063 } 1007 }
1064 1008
1065 #ifdef DEBUG 1009 TRACE_IC("LoadIC", name, state, target());
1066 TraceIC("LoadIC", name, state, target());
1067 #endif
1068 } 1010 }
1069 1011
1070 1012
1071 MaybeObject* KeyedLoadIC::GetElementStubWithoutMapCheck( 1013 MaybeObject* KeyedLoadIC::GetElementStubWithoutMapCheck(
1072 bool is_js_array, 1014 bool is_js_array,
1073 ElementsKind elements_kind) { 1015 ElementsKind elements_kind) {
1074 return KeyedLoadElementStub(elements_kind).TryGetCode(); 1016 return KeyedLoadElementStub(elements_kind).TryGetCode();
1075 } 1017 }
1076 1018
1077 1019
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
1131 if (object->IsString() && 1073 if (object->IsString() &&
1132 name->Equals(isolate()->heap()->length_symbol())) { 1074 name->Equals(isolate()->heap()->length_symbol())) {
1133 Handle<String> string = Handle<String>::cast(object); 1075 Handle<String> string = Handle<String>::cast(object);
1134 Object* code = NULL; 1076 Object* code = NULL;
1135 { MaybeObject* maybe_code = 1077 { MaybeObject* maybe_code =
1136 isolate()->stub_cache()->ComputeKeyedLoadStringLength(*name, 1078 isolate()->stub_cache()->ComputeKeyedLoadStringLength(*name,
1137 *string); 1079 *string);
1138 if (!maybe_code->ToObject(&code)) return maybe_code; 1080 if (!maybe_code->ToObject(&code)) return maybe_code;
1139 } 1081 }
1140 set_target(Code::cast(code)); 1082 set_target(Code::cast(code));
1141 #ifdef DEBUG 1083 TRACE_IC("KeyedLoadIC", name, state, target());
1142 TraceIC("KeyedLoadIC", name, state, target());
1143 #endif // DEBUG
1144 return Smi::FromInt(string->length()); 1084 return Smi::FromInt(string->length());
1145 } 1085 }
1146 1086
1147 // Use specialized code for getting the length of arrays. 1087 // Use specialized code for getting the length of arrays.
1148 if (object->IsJSArray() && 1088 if (object->IsJSArray() &&
1149 name->Equals(isolate()->heap()->length_symbol())) { 1089 name->Equals(isolate()->heap()->length_symbol())) {
1150 Handle<JSArray> array = Handle<JSArray>::cast(object); 1090 Handle<JSArray> array = Handle<JSArray>::cast(object);
1151 Object* code; 1091 Object* code;
1152 { MaybeObject* maybe_code = 1092 { MaybeObject* maybe_code =
1153 isolate()->stub_cache()->ComputeKeyedLoadArrayLength(*name, 1093 isolate()->stub_cache()->ComputeKeyedLoadArrayLength(*name,
1154 *array); 1094 *array);
1155 if (!maybe_code->ToObject(&code)) return maybe_code; 1095 if (!maybe_code->ToObject(&code)) return maybe_code;
1156 } 1096 }
1157 set_target(Code::cast(code)); 1097 set_target(Code::cast(code));
1158 #ifdef DEBUG 1098 TRACE_IC("KeyedLoadIC", name, state, target());
1159 TraceIC("KeyedLoadIC", name, state, target());
1160 #endif // DEBUG
1161 return JSArray::cast(*object)->length(); 1099 return JSArray::cast(*object)->length();
1162 } 1100 }
1163 1101
1164 // Use specialized code for getting prototype of functions. 1102 // Use specialized code for getting prototype of functions.
1165 if (object->IsJSFunction() && 1103 if (object->IsJSFunction() &&
1166 name->Equals(isolate()->heap()->prototype_symbol()) && 1104 name->Equals(isolate()->heap()->prototype_symbol()) &&
1167 JSFunction::cast(*object)->should_have_prototype()) { 1105 JSFunction::cast(*object)->should_have_prototype()) {
1168 Handle<JSFunction> function = Handle<JSFunction>::cast(object); 1106 Handle<JSFunction> function = Handle<JSFunction>::cast(object);
1169 Object* code; 1107 Object* code;
1170 { MaybeObject* maybe_code = 1108 { MaybeObject* maybe_code =
1171 isolate()->stub_cache()->ComputeKeyedLoadFunctionPrototype( 1109 isolate()->stub_cache()->ComputeKeyedLoadFunctionPrototype(
1172 *name, *function); 1110 *name, *function);
1173 if (!maybe_code->ToObject(&code)) return maybe_code; 1111 if (!maybe_code->ToObject(&code)) return maybe_code;
1174 } 1112 }
1175 set_target(Code::cast(code)); 1113 set_target(Code::cast(code));
1176 #ifdef DEBUG 1114 TRACE_IC("KeyedLoadIC", name, state, target());
1177 TraceIC("KeyedLoadIC", name, state, target());
1178 #endif // DEBUG
1179 return Accessors::FunctionGetPrototype(*object, 0); 1115 return Accessors::FunctionGetPrototype(*object, 0);
1180 } 1116 }
1181 } 1117 }
1182 1118
1183 // Check if the name is trivially convertible to an index and get 1119 // Check if the name is trivially convertible to an index and get
1184 // the element or char if so. 1120 // the element or char if so.
1185 uint32_t index = 0; 1121 uint32_t index = 0;
1186 if (name->AsArrayIndex(&index)) { 1122 if (name->AsArrayIndex(&index)) {
1187 HandleScope scope(isolate()); 1123 HandleScope scope(isolate());
1188 // Rewrite to the generic keyed load stub. 1124 // Rewrite to the generic keyed load stub.
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
1247 kNonStrictMode, 1183 kNonStrictMode,
1248 stub); 1184 stub);
1249 stub = maybe_stub->IsFailure() ? 1185 stub = maybe_stub->IsFailure() ?
1250 NULL : Code::cast(maybe_stub->ToObjectUnchecked()); 1186 NULL : Code::cast(maybe_stub->ToObjectUnchecked());
1251 } 1187 }
1252 } 1188 }
1253 } 1189 }
1254 if (stub != NULL) set_target(stub); 1190 if (stub != NULL) set_target(stub);
1255 } 1191 }
1256 1192
1257 #ifdef DEBUG 1193 TRACE_IC("KeyedLoadIC", key, state, target());
1258 TraceIC("KeyedLoadIC", key, state, target());
1259 #endif // DEBUG
1260 1194
1261 // Get the property. 1195 // Get the property.
1262 return Runtime::GetObjectProperty(isolate(), object, key); 1196 return Runtime::GetObjectProperty(isolate(), object, key);
1263 } 1197 }
1264 1198
1265 1199
1266 void KeyedLoadIC::UpdateCaches(LookupResult* lookup, State state, 1200 void KeyedLoadIC::UpdateCaches(LookupResult* lookup, State state,
1267 Handle<Object> object, Handle<String> name) { 1201 Handle<Object> object, Handle<String> name) {
1268 // Bail out if we didn't find a result. 1202 // Bail out if we didn't find a result.
1269 if (!lookup->IsProperty() || !lookup->IsCacheable()) return; 1203 if (!lookup->IsProperty() || !lookup->IsCacheable()) return;
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
1326 1260
1327 // Patch the call site depending on the state of the cache. Make 1261 // Patch the call site depending on the state of the cache. Make
1328 // sure to always rewrite from monomorphic to megamorphic. 1262 // sure to always rewrite from monomorphic to megamorphic.
1329 ASSERT(state != MONOMORPHIC_PROTOTYPE_FAILURE); 1263 ASSERT(state != MONOMORPHIC_PROTOTYPE_FAILURE);
1330 if (state == UNINITIALIZED || state == PREMONOMORPHIC) { 1264 if (state == UNINITIALIZED || state == PREMONOMORPHIC) {
1331 set_target(Code::cast(code)); 1265 set_target(Code::cast(code));
1332 } else if (state == MONOMORPHIC) { 1266 } else if (state == MONOMORPHIC) {
1333 set_target(megamorphic_stub()); 1267 set_target(megamorphic_stub());
1334 } 1268 }
1335 1269
1336 #ifdef DEBUG 1270 TRACE_IC("KeyedLoadIC", name, state, target());
1337 TraceIC("KeyedLoadIC", name, state, target());
1338 #endif
1339 } 1271 }
1340 1272
1341 1273
1342 static bool StoreICableLookup(LookupResult* lookup) { 1274 static bool StoreICableLookup(LookupResult* lookup) {
1343 // Bail out if we didn't find a result. 1275 // Bail out if we didn't find a result.
1344 if (!lookup->IsPropertyOrTransition() || !lookup->IsCacheable()) return false; 1276 if (!lookup->IsPropertyOrTransition() || !lookup->IsCacheable()) return false;
1345 1277
1346 // If the property is read-only, we leave the IC in its current 1278 // If the property is read-only, we leave the IC in its current
1347 // state. 1279 // state.
1348 if (lookup->IsReadOnly()) return false; 1280 if (lookup->IsReadOnly()) return false;
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
1443 1375
1444 if (receiver->IsJSGlobalProxy()) { 1376 if (receiver->IsJSGlobalProxy()) {
1445 // TODO(ulan): find out why we patch this site even with --no-use-ic 1377 // TODO(ulan): find out why we patch this site even with --no-use-ic
1446 // Generate a generic stub that goes to the runtime when we see a global 1378 // Generate a generic stub that goes to the runtime when we see a global
1447 // proxy as receiver. 1379 // proxy as receiver.
1448 Handle<Code> stub = (strict_mode == kStrictMode) 1380 Handle<Code> stub = (strict_mode == kStrictMode)
1449 ? global_proxy_stub_strict() 1381 ? global_proxy_stub_strict()
1450 : global_proxy_stub(); 1382 : global_proxy_stub();
1451 if (target() != *stub) { 1383 if (target() != *stub) {
1452 set_target(*stub); 1384 set_target(*stub);
1453 #ifdef DEBUG 1385 TRACE_IC("StoreIC", name, state, target());
1454 TraceIC("StoreIC", name, state, target());
1455 #endif
1456 } 1386 }
1457 } 1387 }
1458 1388
1459 // Set the property. 1389 // Set the property.
1460 return receiver->SetProperty(*name, *value, NONE, strict_mode); 1390 return receiver->SetProperty(*name, *value, NONE, strict_mode);
1461 } 1391 }
1462 1392
1463 1393
1464 void StoreIC::UpdateCaches(LookupResult* lookup, 1394 void StoreIC::UpdateCaches(LookupResult* lookup,
1465 State state, 1395 State state,
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
1539 if (target() != *code) { 1469 if (target() != *code) {
1540 set_target((strict_mode == kStrictMode) 1470 set_target((strict_mode == kStrictMode)
1541 ? megamorphic_stub_strict() 1471 ? megamorphic_stub_strict()
1542 : megamorphic_stub()); 1472 : megamorphic_stub());
1543 } 1473 }
1544 } else if (state == MEGAMORPHIC) { 1474 } else if (state == MEGAMORPHIC) {
1545 // Update the stub cache. 1475 // Update the stub cache.
1546 isolate()->stub_cache()->Set(*name, receiver->map(), *code); 1476 isolate()->stub_cache()->Set(*name, receiver->map(), *code);
1547 } 1477 }
1548 1478
1549 #ifdef DEBUG 1479 TRACE_IC("StoreIC", name, state, target());
1550 TraceIC("StoreIC", name, state, target());
1551 #endif
1552 } 1480 }
1553 1481
1554 1482
1555 static bool AddOneReceiverMapIfMissing(MapList* receiver_maps, 1483 static bool AddOneReceiverMapIfMissing(MapList* receiver_maps,
1556 Map* new_receiver_map) { 1484 Map* new_receiver_map) {
1557 for (int current = 0; current < receiver_maps->length(); ++current) { 1485 for (int current = 0; current < receiver_maps->length(); ++current) {
1558 if (receiver_maps->at(current) == new_receiver_map) { 1486 if (receiver_maps->at(current) == new_receiver_map) {
1559 return false; 1487 return false;
1560 } 1488 }
1561 } 1489 }
(...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after
1879 strict_mode, 1807 strict_mode,
1880 stub); 1808 stub);
1881 stub = maybe_stub->IsFailure() ? 1809 stub = maybe_stub->IsFailure() ?
1882 NULL : Code::cast(maybe_stub->ToObjectUnchecked()); 1810 NULL : Code::cast(maybe_stub->ToObjectUnchecked());
1883 } 1811 }
1884 } 1812 }
1885 } 1813 }
1886 if (stub != NULL) set_target(stub); 1814 if (stub != NULL) set_target(stub);
1887 } 1815 }
1888 1816
1889 #ifdef DEBUG 1817 TRACE_IC("KeyedStoreIC", key, state, target());
1890 TraceIC("KeyedStoreIC", key, state, target());
1891 #endif
1892 1818
1893 // Set the property. 1819 // Set the property.
1894 return Runtime::SetObjectProperty( 1820 return Runtime::SetObjectProperty(
1895 isolate(), object , key, value, NONE, strict_mode); 1821 isolate(), object , key, value, NONE, strict_mode);
1896 } 1822 }
1897 1823
1898 1824
1899 void KeyedStoreIC::UpdateCaches(LookupResult* lookup, 1825 void KeyedStoreIC::UpdateCaches(LookupResult* lookup,
1900 State state, 1826 State state,
1901 StrictModeFlag strict_mode, 1827 StrictModeFlag strict_mode,
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
1959 // sure to always rewrite from monomorphic to megamorphic. 1885 // sure to always rewrite from monomorphic to megamorphic.
1960 ASSERT(state != MONOMORPHIC_PROTOTYPE_FAILURE); 1886 ASSERT(state != MONOMORPHIC_PROTOTYPE_FAILURE);
1961 if (state == UNINITIALIZED || state == PREMONOMORPHIC) { 1887 if (state == UNINITIALIZED || state == PREMONOMORPHIC) {
1962 set_target(Code::cast(code)); 1888 set_target(Code::cast(code));
1963 } else if (state == MONOMORPHIC) { 1889 } else if (state == MONOMORPHIC) {
1964 set_target((strict_mode == kStrictMode) 1890 set_target((strict_mode == kStrictMode)
1965 ? megamorphic_stub_strict() 1891 ? megamorphic_stub_strict()
1966 : megamorphic_stub()); 1892 : megamorphic_stub());
1967 } 1893 }
1968 1894
1969 #ifdef DEBUG 1895 TRACE_IC("KeyedStoreIC", name, state, target());
1970 TraceIC("KeyedStoreIC", name, state, target());
1971 #endif
1972 } 1896 }
1973 1897
Vyacheslav Egorov (Chromium) 2011/10/20 10:12:23 add empty line
Kevin Millikin (Chromium) 2011/10/20 10:57:08 Done.
1898 #undef TRACE_IC
1899
1974 1900
1975 // ---------------------------------------------------------------------------- 1901 // ----------------------------------------------------------------------------
1976 // Static IC stub generators. 1902 // Static IC stub generators.
1977 // 1903 //
1978 1904
1979 // Used from ic-<arch>.cc. 1905 // Used from ic-<arch>.cc.
1980 RUNTIME_FUNCTION(MaybeObject*, CallIC_Miss) { 1906 RUNTIME_FUNCTION(MaybeObject*, CallIC_Miss) {
1981 HandleScope scope(isolate); 1907 HandleScope scope(isolate);
1982 ASSERT(args.length() == 2); 1908 ASSERT(args.length() == 2);
1983 CallIC ic(isolate); 1909 CallIC ic(isolate);
(...skipping 602 matching lines...) Expand 10 before | Expand all | Expand 10 after
2586 #undef ADDR 2512 #undef ADDR
2587 }; 2513 };
2588 2514
2589 2515
2590 Address IC::AddressFromUtilityId(IC::UtilityId id) { 2516 Address IC::AddressFromUtilityId(IC::UtilityId id) {
2591 return IC_utilities[id]; 2517 return IC_utilities[id];
2592 } 2518 }
2593 2519
2594 2520
2595 } } // namespace v8::internal 2521 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ic.h ('k') | src/objects.h » ('j') | src/stub-cache.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698