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

Side by Side Diff: src/mips/stub-cache-mips.cc

Issue 145853002: Merged r18783, r18784 into trunk branch. (Closed) Base URL: https://v8.googlecode.com/svn/trunk
Patch Set: Created 6 years, 11 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/mips/lithium-codegen-mips.cc ('k') | src/version.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 // 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 749 matching lines...) Expand 10 before | Expand all | Expand 10 after
760 IC::UtilityId id) { 760 IC::UtilityId id) {
761 PushInterceptorArguments(masm, receiver, holder, name, holder_obj); 761 PushInterceptorArguments(masm, receiver, holder, name, holder_obj);
762 __ CallExternalReference( 762 __ CallExternalReference(
763 ExternalReference(IC_Utility(id), masm->isolate()), 763 ExternalReference(IC_Utility(id), masm->isolate()),
764 StubCache::kInterceptorArgsLength); 764 StubCache::kInterceptorArgsLength);
765 } 765 }
766 766
767 767
768 static const int kFastApiCallArguments = FunctionCallbackArguments::kArgsLength; 768 static const int kFastApiCallArguments = FunctionCallbackArguments::kArgsLength;
769 769
770 // Reserves space for the extra arguments to API function in the
771 // caller's frame.
772 //
773 // These arguments are set by CheckPrototypes and GenerateFastApiDirectCall.
774 static void ReserveSpaceForFastApiCall(MacroAssembler* masm,
775 Register scratch) {
776 ASSERT(Smi::FromInt(0) == 0);
777 for (int i = 0; i < kFastApiCallArguments; i++) {
778 __ push(zero_reg);
779 }
780 }
781 770
771 static void GenerateFastApiCallBody(MacroAssembler* masm,
772 const CallOptimization& optimization,
773 int argc,
774 Register holder,
775 Register scratch1,
776 Register scratch2,
777 Register scratch3,
778 bool restore_context) {
779 // ----------- S t a t e -------------
780 // -- sp[0] : last JS argument
781 // -- ...
782 // -- sp[(argc - 1) * 4] : first JS argument
783 // -- sp[argc * 4] : receiver
784 // -----------------------------------
785 ASSERT(optimization.is_simple_api_call());
782 786
783 // Undoes the effects of ReserveSpaceForFastApiCall. 787 typedef FunctionCallbackArguments FCA;
784 static void FreeSpaceForFastApiCall(MacroAssembler* masm) {
785 __ Drop(kFastApiCallArguments);
786 }
787 788
789 STATIC_ASSERT(FCA::kHolderIndex == 0);
790 STATIC_ASSERT(FCA::kIsolateIndex == 1);
791 STATIC_ASSERT(FCA::kReturnValueDefaultValueIndex == 2);
792 STATIC_ASSERT(FCA::kReturnValueOffset == 3);
793 STATIC_ASSERT(FCA::kDataIndex == 4);
794 STATIC_ASSERT(FCA::kCalleeIndex == 5);
795 STATIC_ASSERT(FCA::kContextSaveIndex == 6);
796 STATIC_ASSERT(FCA::kArgsLength == 7);
788 797
789 static void GenerateFastApiDirectCall(MacroAssembler* masm, 798 ASSERT(!holder.is(cp));
790 const CallOptimization& optimization, 799
791 int argc,
792 bool restore_context) {
793 // ----------- S t a t e -------------
794 // -- sp[0] - sp[24] : FunctionCallbackInfo, incl.
795 // : holder (set by CheckPrototypes)
796 // -- sp[28] : last JS argument
797 // -- ...
798 // -- sp[(argc + 6) * 4] : first JS argument
799 // -- sp[(argc + 7) * 4] : receiver
800 // -----------------------------------
801 typedef FunctionCallbackArguments FCA;
802 // Save calling context. 800 // Save calling context.
803 __ sw(cp, MemOperand(sp, FCA::kContextSaveIndex * kPointerSize)); 801 __ push(cp);
804 // Get the function and setup the context. 802 // Get the function and setup the context.
805 Handle<JSFunction> function = optimization.constant_function(); 803 Handle<JSFunction> function = optimization.constant_function();
806 __ li(t1, function); 804 __ li(scratch1, function);
807 __ lw(cp, FieldMemOperand(t1, JSFunction::kContextOffset)); 805 __ lw(cp, FieldMemOperand(scratch1, JSFunction::kContextOffset));
808 __ sw(t1, MemOperand(sp, FCA::kCalleeIndex * kPointerSize)); 806 __ push(scratch1);
809 807
810 // Construct the FunctionCallbackInfo. 808 // Construct the FunctionCallbackInfo.
811 Handle<CallHandlerInfo> api_call_info = optimization.api_call_info(); 809 Handle<CallHandlerInfo> api_call_info = optimization.api_call_info();
812 Handle<Object> call_data(api_call_info->data(), masm->isolate()); 810 Handle<Object> call_data(api_call_info->data(), masm->isolate());
811 bool call_data_undefined = false;
813 if (masm->isolate()->heap()->InNewSpace(*call_data)) { 812 if (masm->isolate()->heap()->InNewSpace(*call_data)) {
814 __ li(a0, api_call_info); 813 __ li(scratch1, api_call_info);
815 __ lw(t2, FieldMemOperand(a0, CallHandlerInfo::kDataOffset)); 814 __ lw(scratch1, FieldMemOperand(scratch1, CallHandlerInfo::kDataOffset));
815 } else if (call_data->IsUndefined()) {
816 call_data_undefined = true;
817 __ LoadRoot(scratch3, Heap::kUndefinedValueRootIndex);
816 } else { 818 } else {
817 __ li(t2, call_data); 819 __ li(scratch1, call_data);
818 } 820 }
819 // Store call data. 821 // Store call data.
820 __ sw(t2, MemOperand(sp, FCA::kDataIndex * kPointerSize)); 822 __ push(scratch1);
823 if (!call_data_undefined) {
824 __ LoadRoot(scratch1, Heap::kUndefinedValueRootIndex);
825 }
826 // Store ReturnValue default and ReturnValue.
827 __ LoadRoot(scratch1, Heap::kUndefinedValueRootIndex);
828 __ Push(scratch1, scratch1);
821 // Store isolate. 829 // Store isolate.
822 __ li(t3, Operand(ExternalReference::isolate_address(masm->isolate()))); 830 __ li(scratch1, Operand(ExternalReference::isolate_address(masm->isolate())));
823 __ sw(t3, MemOperand(sp, FCA::kIsolateIndex * kPointerSize)); 831 __ push(scratch1);
824 // Store ReturnValue default and ReturnValue. 832 // Store holder.
825 __ LoadRoot(t1, Heap::kUndefinedValueRootIndex); 833 __ push(holder);
826 __ sw(t1, MemOperand(sp, FCA::kReturnValueOffset * kPointerSize));
827 __ sw(t1, MemOperand(sp, FCA::kReturnValueDefaultValueIndex * kPointerSize));
828 834
829 // Prepare arguments. 835 // Prepare arguments.
830 __ Move(a2, sp); 836 __ Move(a2, sp);
831 837
832 // Allocate the v8::Arguments structure in the arguments' space since 838 // Allocate the v8::Arguments structure in the arguments' space since
833 // it's not controlled by GC. 839 // it's not controlled by GC.
834 const int kApiStackSpace = 4; 840 const int kApiStackSpace = 4;
835 841
836 FrameScope frame_scope(masm, StackFrame::MANUAL); 842 FrameScope frame_scope(masm, StackFrame::MANUAL);
837 __ EnterExitFrame(false, kApiStackSpace); 843 __ EnterExitFrame(false, kApiStackSpace);
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
874 function_address, 880 function_address,
875 thunk_ref, 881 thunk_ref,
876 a1, 882 a1,
877 kStackUnwindSpace, 883 kStackUnwindSpace,
878 return_value_operand, 884 return_value_operand,
879 restore_context ? 885 restore_context ?
880 &context_restore_operand : NULL); 886 &context_restore_operand : NULL);
881 } 887 }
882 888
883 889
890 // Generates call to API function.
891 static void GenerateFastApiCall(MacroAssembler* masm,
892 const CallOptimization& optimization,
893 int argc,
894 Handle<Map> map_to_holder,
895 CallOptimization::HolderLookup holder_lookup) {
896 Counters* counters = masm->isolate()->counters();
897 __ IncrementCounter(counters->call_const_fast_api(), 1, a0, a1);
898
899 // Move holder to a register.
900 Register holder_reg = a0;
901 switch (holder_lookup) {
902 case CallOptimization::kHolderIsReceiver:
903 {
904 ASSERT(map_to_holder.is_null());
905 __ lw(holder_reg, MemOperand(sp, argc * kPointerSize));
906 }
907 break;
908 case CallOptimization::kHolderIsPrototypeOfMap:
909 {
910 Handle<JSObject> holder(JSObject::cast(map_to_holder->prototype()));
911 if (!masm->isolate()->heap()->InNewSpace(*holder)) {
912 __ li(holder_reg, holder);
913 } else {
914 __ li(holder_reg, map_to_holder);
915 __ lw(holder_reg,
916 FieldMemOperand(holder_reg, Map::kPrototypeOffset));
917 }
918 }
919 break;
920 case CallOptimization::kHolderNotFound:
921 UNREACHABLE();
922 }
923 GenerateFastApiCallBody(masm,
924 optimization,
925 argc,
926 holder_reg,
927 a1,
928 a2,
929 a3,
930 false);
931 }
932
933
884 // Generate call to api function. 934 // Generate call to api function.
885 static void GenerateFastApiCall(MacroAssembler* masm, 935 static void GenerateFastApiCall(MacroAssembler* masm,
886 const CallOptimization& optimization, 936 const CallOptimization& optimization,
887 Register receiver, 937 Register receiver,
888 Register scratch, 938 Register scratch,
889 int argc, 939 int argc,
890 Register* values) { 940 Register* values) {
891 ASSERT(optimization.is_simple_api_call());
892 ASSERT(!receiver.is(scratch)); 941 ASSERT(!receiver.is(scratch));
893 942 __ push(receiver);
894 typedef FunctionCallbackArguments FCA;
895 const int stack_space = kFastApiCallArguments + argc + 1;
896 // Assign stack space for the call arguments.
897 __ Subu(sp, sp, Operand(stack_space * kPointerSize));
898 // Write holder to stack frame.
899 __ sw(receiver, MemOperand(sp, FCA::kHolderIndex * kPointerSize));
900 // Write receiver to stack frame.
901 int index = stack_space - 1;
902 __ sw(receiver, MemOperand(sp, index-- * kPointerSize));
903 // Write the arguments to stack frame. 943 // Write the arguments to stack frame.
904 for (int i = 0; i < argc; i++) { 944 for (int i = 0; i < argc; i++) {
905 ASSERT(!receiver.is(values[i])); 945 Register arg = values[argc-1-i];
906 ASSERT(!scratch.is(values[i])); 946 ASSERT(!receiver.is(arg));
907 __ sw(values[i], MemOperand(sp, index-- * kPointerSize)); 947 ASSERT(!scratch.is(arg));
948 __ push(arg);
908 } 949 }
909 950
910 GenerateFastApiDirectCall(masm, optimization, argc, true); 951 Register scratch1 = a0;
952 Register scratch2 = a1;
953 Register scratch3 = a2;
954 if (!a3.is(receiver)) {
955 __ mov(a3, receiver);
956 receiver = a3;
957 }
958 // Stack now matches JSFunction abi.
959 GenerateFastApiCallBody(masm,
960 optimization,
961 argc,
962 receiver,
963 scratch1,
964 scratch2,
965 scratch3,
966 true);
911 } 967 }
912 968
913 969
914 class CallInterceptorCompiler BASE_EMBEDDED { 970 class CallInterceptorCompiler BASE_EMBEDDED {
915 public: 971 public:
916 CallInterceptorCompiler(CallStubCompiler* stub_compiler, 972 CallInterceptorCompiler(CallStubCompiler* stub_compiler,
917 const ParameterCount& arguments, 973 const ParameterCount& arguments,
918 Register name) 974 Register name)
919 : stub_compiler_(stub_compiler), 975 : stub_compiler_(stub_compiler),
920 arguments_(arguments), 976 arguments_(arguments),
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
953 Register scratch2, 1009 Register scratch2,
954 Register scratch3, 1010 Register scratch3,
955 Handle<JSObject> interceptor_holder, 1011 Handle<JSObject> interceptor_holder,
956 LookupResult* lookup, 1012 LookupResult* lookup,
957 Handle<Name> name, 1013 Handle<Name> name,
958 const CallOptimization& optimization, 1014 const CallOptimization& optimization,
959 Label* miss_label) { 1015 Label* miss_label) {
960 ASSERT(optimization.is_constant_call()); 1016 ASSERT(optimization.is_constant_call());
961 ASSERT(!lookup->holder()->IsGlobalObject()); 1017 ASSERT(!lookup->holder()->IsGlobalObject());
962 Counters* counters = masm->isolate()->counters(); 1018 Counters* counters = masm->isolate()->counters();
963 int depth1 = kInvalidProtoDepth;
964 int depth2 = kInvalidProtoDepth;
965 bool can_do_fast_api_call = false;
966 if (optimization.is_simple_api_call() &&
967 !lookup->holder()->IsGlobalObject()) {
968 depth1 = optimization.GetPrototypeDepthOfExpectedType(
969 object, interceptor_holder);
970 if (depth1 == kInvalidProtoDepth) {
971 depth2 = optimization.GetPrototypeDepthOfExpectedType(
972 interceptor_holder, Handle<JSObject>(lookup->holder()));
973 }
974 can_do_fast_api_call =
975 depth1 != kInvalidProtoDepth || depth2 != kInvalidProtoDepth;
976 }
977
978 __ IncrementCounter(counters->call_const_interceptor(), 1, 1019 __ IncrementCounter(counters->call_const_interceptor(), 1,
979 scratch1, scratch2); 1020 scratch1, scratch2);
980 1021
981 if (can_do_fast_api_call) {
982 __ IncrementCounter(counters->call_const_interceptor_fast_api(), 1,
983 scratch1, scratch2);
984 ReserveSpaceForFastApiCall(masm, scratch1);
985 }
986
987 // Check that the maps from receiver to interceptor's holder 1022 // Check that the maps from receiver to interceptor's holder
988 // haven't changed and thus we can invoke interceptor. 1023 // haven't changed and thus we can invoke interceptor.
989 Label miss_cleanup; 1024 Label miss_cleanup;
990 Label* miss = can_do_fast_api_call ? &miss_cleanup : miss_label;
991 Register holder = 1025 Register holder =
992 stub_compiler_->CheckPrototypes( 1026 stub_compiler_->CheckPrototypes(
993 IC::CurrentTypeOf(object, masm->isolate()), receiver, 1027 IC::CurrentTypeOf(object, masm->isolate()), receiver,
994 interceptor_holder, scratch1, scratch2, scratch3, 1028 interceptor_holder, scratch1, scratch2, scratch3,
995 name, depth1, miss); 1029 name, miss_label);
996 1030
997 // Invoke an interceptor and if it provides a value, 1031 // Invoke an interceptor and if it provides a value,
998 // branch to |regular_invoke|. 1032 // branch to |regular_invoke|.
999 Label regular_invoke; 1033 Label regular_invoke;
1000 LoadWithInterceptor(masm, receiver, holder, interceptor_holder, scratch2, 1034 LoadWithInterceptor(masm, receiver, holder, interceptor_holder, scratch2,
1001 &regular_invoke); 1035 &regular_invoke);
1002 1036
1003 // Interceptor returned nothing for this property. Try to use cached 1037 // Interceptor returned nothing for this property. Try to use cached
1004 // constant function. 1038 // constant function.
1005 1039
1006 // Check that the maps from interceptor's holder to constant function's 1040 // Check that the maps from interceptor's holder to constant function's
1007 // holder haven't changed and thus we can use cached constant function. 1041 // holder haven't changed and thus we can use cached constant function.
1008 if (*interceptor_holder != lookup->holder()) { 1042 if (*interceptor_holder != lookup->holder()) {
1009 stub_compiler_->CheckPrototypes( 1043 stub_compiler_->CheckPrototypes(
1010 IC::CurrentTypeOf(interceptor_holder, masm->isolate()), holder, 1044 IC::CurrentTypeOf(interceptor_holder, masm->isolate()), holder,
1011 handle(lookup->holder()), scratch1, scratch2, scratch3, 1045 handle(lookup->holder()), scratch1, scratch2, scratch3,
1012 name, depth2, miss); 1046 name, miss_label);
1013 } else { 1047 }
1014 // CheckPrototypes has a side effect of fetching a 'holder' 1048
1015 // for API (object which is instanceof for the signature). It's 1049 Handle<Map> lookup_map;
1016 // safe to omit it here, as if present, it should be fetched 1050 CallOptimization::HolderLookup holder_lookup =
1017 // by the previous CheckPrototypes. 1051 CallOptimization::kHolderNotFound;
1018 ASSERT(depth2 == kInvalidProtoDepth); 1052 if (optimization.is_simple_api_call() &&
1053 !lookup->holder()->IsGlobalObject()) {
1054 lookup_map = optimization.LookupHolderOfExpectedType(
1055 object, object, interceptor_holder, &holder_lookup);
1056 if (holder_lookup == CallOptimization::kHolderNotFound) {
1057 lookup_map =
1058 optimization.LookupHolderOfExpectedType(
1059 object,
1060 interceptor_holder,
1061 Handle<JSObject>(lookup->holder()),
1062 &holder_lookup);
1063 }
1019 } 1064 }
1020 1065
1021 // Invoke function. 1066 // Invoke function.
1022 if (can_do_fast_api_call) { 1067 if (holder_lookup != CallOptimization::kHolderNotFound) {
1023 GenerateFastApiDirectCall( 1068 int argc = arguments_.immediate();
1024 masm, optimization, arguments_.immediate(), false); 1069 GenerateFastApiCall(masm,
1070 optimization,
1071 argc,
1072 lookup_map,
1073 holder_lookup);
1025 } else { 1074 } else {
1026 Handle<JSFunction> function = optimization.constant_function(); 1075 Handle<JSFunction> function = optimization.constant_function();
1027 __ Move(a0, receiver); 1076 __ Move(a0, receiver);
1028 stub_compiler_->GenerateJumpFunction(object, function); 1077 stub_compiler_->GenerateJumpFunction(object, function);
1029 } 1078 }
1030 1079
1031 // Deferred code for fast API call case---clean preallocated space.
1032 if (can_do_fast_api_call) {
1033 __ bind(&miss_cleanup);
1034 FreeSpaceForFastApiCall(masm);
1035 __ Branch(miss_label);
1036 }
1037
1038 // Invoke a regular function. 1080 // Invoke a regular function.
1039 __ bind(&regular_invoke); 1081 __ bind(&regular_invoke);
1040 if (can_do_fast_api_call) {
1041 FreeSpaceForFastApiCall(masm);
1042 }
1043 } 1082 }
1044 1083
1045 void CompileRegular(MacroAssembler* masm, 1084 void CompileRegular(MacroAssembler* masm,
1046 Handle<JSObject> object, 1085 Handle<JSObject> object,
1047 Register receiver, 1086 Register receiver,
1048 Register scratch1, 1087 Register scratch1,
1049 Register scratch2, 1088 Register scratch2,
1050 Register scratch3, 1089 Register scratch3,
1051 Handle<Name> name, 1090 Handle<Name> name,
1052 Handle<JSObject> interceptor_holder, 1091 Handle<JSObject> interceptor_holder,
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
1107 #define __ ACCESS_MASM(masm()) 1146 #define __ ACCESS_MASM(masm())
1108 1147
1109 1148
1110 Register StubCompiler::CheckPrototypes(Handle<HeapType> type, 1149 Register StubCompiler::CheckPrototypes(Handle<HeapType> type,
1111 Register object_reg, 1150 Register object_reg,
1112 Handle<JSObject> holder, 1151 Handle<JSObject> holder,
1113 Register holder_reg, 1152 Register holder_reg,
1114 Register scratch1, 1153 Register scratch1,
1115 Register scratch2, 1154 Register scratch2,
1116 Handle<Name> name, 1155 Handle<Name> name,
1117 int save_at_depth,
1118 Label* miss, 1156 Label* miss,
1119 PrototypeCheckType check) { 1157 PrototypeCheckType check) {
1120 Handle<Map> receiver_map(IC::TypeToMap(*type, isolate())); 1158 Handle<Map> receiver_map(IC::TypeToMap(*type, isolate()));
1121 // Make sure that the type feedback oracle harvests the receiver map. 1159 // Make sure that the type feedback oracle harvests the receiver map.
1122 // TODO(svenpanne) Remove this hack when all ICs are reworked. 1160 // TODO(svenpanne) Remove this hack when all ICs are reworked.
1123 __ li(scratch1, Operand(receiver_map)); 1161 __ li(scratch1, Operand(receiver_map));
1124 1162
1125 // Make sure there's no overlap between holder and object registers. 1163 // Make sure there's no overlap between holder and object registers.
1126 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); 1164 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg));
1127 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg) 1165 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg)
1128 && !scratch2.is(scratch1)); 1166 && !scratch2.is(scratch1));
1129 1167
1130 // Keep track of the current object in register reg. 1168 // Keep track of the current object in register reg.
1131 Register reg = object_reg; 1169 Register reg = object_reg;
1132 int depth = 0; 1170 int depth = 0;
1133 1171
1134 typedef FunctionCallbackArguments FCA;
1135 if (save_at_depth == depth) {
1136 __ sw(reg, MemOperand(sp, FCA::kHolderIndex * kPointerSize));
1137 }
1138
1139 Handle<JSObject> current = Handle<JSObject>::null(); 1172 Handle<JSObject> current = Handle<JSObject>::null();
1140 if (type->IsConstant()) current = Handle<JSObject>::cast(type->AsConstant()); 1173 if (type->IsConstant()) current = Handle<JSObject>::cast(type->AsConstant());
1141 Handle<JSObject> prototype = Handle<JSObject>::null(); 1174 Handle<JSObject> prototype = Handle<JSObject>::null();
1142 Handle<Map> current_map = receiver_map; 1175 Handle<Map> current_map = receiver_map;
1143 Handle<Map> holder_map(holder->map()); 1176 Handle<Map> holder_map(holder->map());
1144 // Traverse the prototype chain and check the maps in the prototype chain for 1177 // Traverse the prototype chain and check the maps in the prototype chain for
1145 // fast and global objects or do negative lookup for normal objects. 1178 // fast and global objects or do negative lookup for normal objects.
1146 while (!current_map.is_identical_to(holder_map)) { 1179 while (!current_map.is_identical_to(holder_map)) {
1147 ++depth; 1180 ++depth;
1148 1181
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
1194 if (heap()->InNewSpace(*prototype)) { 1227 if (heap()->InNewSpace(*prototype)) {
1195 // The prototype is in new space; we cannot store a reference to it 1228 // The prototype is in new space; we cannot store a reference to it
1196 // in the code. Load it from the map. 1229 // in the code. Load it from the map.
1197 __ lw(reg, FieldMemOperand(map_reg, Map::kPrototypeOffset)); 1230 __ lw(reg, FieldMemOperand(map_reg, Map::kPrototypeOffset));
1198 } else { 1231 } else {
1199 // The prototype is in old space; load it directly. 1232 // The prototype is in old space; load it directly.
1200 __ li(reg, Operand(prototype)); 1233 __ li(reg, Operand(prototype));
1201 } 1234 }
1202 } 1235 }
1203 1236
1204 if (save_at_depth == depth) {
1205 __ sw(reg, MemOperand(sp, FCA::kHolderIndex * kPointerSize));
1206 }
1207
1208 // Go to the next object in the prototype chain. 1237 // Go to the next object in the prototype chain.
1209 current = prototype; 1238 current = prototype;
1210 current_map = handle(current->map()); 1239 current_map = handle(current->map());
1211 } 1240 }
1212 1241
1213 // Log the check depth. 1242 // Log the check depth.
1214 LOG(isolate(), IntEvent("check-maps-depth", depth + 1)); 1243 LOG(isolate(), IntEvent("check-maps-depth", depth + 1));
1215 1244
1216 if (depth != 0 || check == CHECK_ALL_MAPS) { 1245 if (depth != 0 || check == CHECK_ALL_MAPS) {
1217 // Check the holder map. 1246 // Check the holder map.
(...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after
1565 Handle<String> name) { 1594 Handle<String> name) {
1566 1595
1567 Counters* counters = isolate()->counters(); 1596 Counters* counters = isolate()->counters();
1568 1597
1569 ASSERT(optimization.is_simple_api_call()); 1598 ASSERT(optimization.is_simple_api_call());
1570 // Bail out if object is a global object as we don't want to 1599 // Bail out if object is a global object as we don't want to
1571 // repatch it to global receiver. 1600 // repatch it to global receiver.
1572 if (object->IsGlobalObject()) return Handle<Code>::null(); 1601 if (object->IsGlobalObject()) return Handle<Code>::null();
1573 if (!cell.is_null()) return Handle<Code>::null(); 1602 if (!cell.is_null()) return Handle<Code>::null();
1574 if (!object->IsJSObject()) return Handle<Code>::null(); 1603 if (!object->IsJSObject()) return Handle<Code>::null();
1575 int depth = optimization.GetPrototypeDepthOfExpectedType( 1604 Handle<JSObject> receiver = Handle<JSObject>::cast(object);
1576 Handle<JSObject>::cast(object), holder); 1605 CallOptimization::HolderLookup holder_lookup =
1577 if (depth == kInvalidProtoDepth) return Handle<Code>::null(); 1606 CallOptimization::kHolderNotFound;
1607 Handle<Map> lookup_map = optimization.LookupHolderOfExpectedType(
1608 receiver, receiver, holder, &holder_lookup);
1609 if (holder_lookup == CallOptimization::kHolderNotFound) {
1610 return Handle<Code>::null();
1611 }
1578 1612
1579 Label miss, miss_before_stack_reserved; 1613 Label miss;
1580 1614 GenerateNameCheck(name, &miss);
1581 GenerateNameCheck(name, &miss_before_stack_reserved);
1582 1615
1583 // Get the receiver from the stack. 1616 // Get the receiver from the stack.
1584 const int argc = arguments().immediate(); 1617 const int argc = arguments().immediate();
1585 __ lw(a1, MemOperand(sp, argc * kPointerSize)); 1618 __ lw(a1, MemOperand(sp, argc * kPointerSize));
1586 1619
1587 // Check that the receiver isn't a smi. 1620 // Check that the receiver isn't a smi.
1588 __ JumpIfSmi(a1, &miss_before_stack_reserved); 1621 __ JumpIfSmi(a1, &miss);
1589 1622
1590 __ IncrementCounter(counters->call_const(), 1, a0, a3); 1623 __ IncrementCounter(counters->call_const(), 1, a0, a3);
1591 __ IncrementCounter(counters->call_const_fast_api(), 1, a0, a3);
1592
1593 ReserveSpaceForFastApiCall(masm(), a0);
1594 1624
1595 // Check that the maps haven't changed and find a Holder as a side effect. 1625 // Check that the maps haven't changed and find a Holder as a side effect.
1596 CheckPrototypes( 1626 CheckPrototypes(
1597 IC::CurrentTypeOf(object, isolate()), 1627 IC::CurrentTypeOf(object, isolate()),
1598 a1, holder, a0, a3, t0, name, depth, &miss); 1628 a1, holder, a0, a3, t0, name, &miss);
1599 1629
1600 GenerateFastApiDirectCall(masm(), optimization, argc, false); 1630 GenerateFastApiCall(
1631 masm(), optimization, argc, lookup_map, holder_lookup);
1601 1632
1602 __ bind(&miss); 1633 HandlerFrontendFooter(&miss);
1603 FreeSpaceForFastApiCall(masm());
1604
1605 HandlerFrontendFooter(&miss_before_stack_reserved);
1606 1634
1607 // Return the generated code. 1635 // Return the generated code.
1608 return GetCode(function); 1636 return GetCode(function);
1609 } 1637 }
1610 1638
1611 1639
1612 void StubCompiler::GenerateBooleanCheck(Register object, Label* miss) { 1640 void StubCompiler::GenerateBooleanCheck(Register object, Label* miss) {
1613 Label success; 1641 Label success;
1614 // Check that the object is a boolean. 1642 // Check that the object is a boolean.
1615 __ LoadRoot(at, Heap::kTrueValueRootIndex); 1643 __ LoadRoot(at, Heap::kTrueValueRootIndex);
(...skipping 539 matching lines...) Expand 10 before | Expand all | Expand 10 after
2155 // ----------------------------------- 2183 // -----------------------------------
2156 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); 2184 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss);
2157 } 2185 }
2158 2186
2159 2187
2160 #undef __ 2188 #undef __
2161 2189
2162 } } // namespace v8::internal 2190 } } // namespace v8::internal
2163 2191
2164 #endif // V8_TARGET_ARCH_MIPS 2192 #endif // V8_TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « src/mips/lithium-codegen-mips.cc ('k') | src/version.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698