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

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

Issue 12560004: MIPS: Polymorphism support for load IC. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 9 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/ic-mips.cc ('k') | no next file » | 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 297 matching lines...) Expand 10 before | Expand all | Expand 10 after
308 308
309 309
310 // Load a fast property out of a holder object (src). In-object properties 310 // Load a fast property out of a holder object (src). In-object properties
311 // are loaded directly otherwise the property is loaded from the properties 311 // are loaded directly otherwise the property is loaded from the properties
312 // fixed array. 312 // fixed array.
313 void StubCompiler::GenerateFastPropertyLoad(MacroAssembler* masm, 313 void StubCompiler::GenerateFastPropertyLoad(MacroAssembler* masm,
314 Register dst, 314 Register dst,
315 Register src, 315 Register src,
316 Handle<JSObject> holder, 316 Handle<JSObject> holder,
317 PropertyIndex index) { 317 PropertyIndex index) {
318 if (index.is_header_index()) { 318 DoGenerateFastPropertyLoad(
319 int offset = index.header_index() * kPointerSize; 319 masm, dst, src, index.is_inobject(holder), index.translate(holder));
320 __ lw(dst, FieldMemOperand(src, offset));
321 } else {
322 // Adjust for the number of properties stored in the holder.
323 int slot = index.field_index() - holder->map()->inobject_properties();
324 if (slot < 0) {
325 // Get the property straight out of the holder.
326 int offset = holder->map()->instance_size() + (slot * kPointerSize);
327 __ lw(dst, FieldMemOperand(src, offset));
328 } else {
329 // Calculate the offset into the properties array.
330 int offset = slot * kPointerSize + FixedArray::kHeaderSize;
331 __ lw(dst, FieldMemOperand(src, JSObject::kPropertiesOffset));
332 __ lw(dst, FieldMemOperand(dst, offset));
333 }
334 }
335 } 320 }
336 321
337 322
323 void StubCompiler::DoGenerateFastPropertyLoad(MacroAssembler* masm,
324 Register dst,
325 Register src,
326 bool inobject,
327 int index) {
328 int offset = index * kPointerSize;
329 if (!inobject) {
330 // Calculate the offset into the properties array.
331 offset = offset + FixedArray::kHeaderSize;
332 __ lw(dst, FieldMemOperand(src, JSObject::kPropertiesOffset));
333 src = dst;
334 }
335 __ lw(dst, FieldMemOperand(src, offset));
336 }
337
338
338 void StubCompiler::GenerateLoadArrayLength(MacroAssembler* masm, 339 void StubCompiler::GenerateLoadArrayLength(MacroAssembler* masm,
339 Register receiver, 340 Register receiver,
340 Register scratch, 341 Register scratch,
341 Label* miss_label) { 342 Label* miss_label) {
342 // Check that the receiver isn't a smi. 343 // Check that the receiver isn't a smi.
343 __ JumpIfSmi(receiver, miss_label); 344 __ JumpIfSmi(receiver, miss_label);
344 345
345 // Check that the object is a JS array. 346 // Check that the object is a JS array.
346 __ GetObjectType(receiver, scratch, scratch); 347 __ GetObjectType(receiver, scratch, scratch);
347 __ Branch(miss_label, ne, scratch, Operand(JS_ARRAY_TYPE)); 348 __ Branch(miss_label, ne, scratch, Operand(JS_ARRAY_TYPE));
(...skipping 712 matching lines...) Expand 10 before | Expand all | Expand 10 after
1060 __ addu(scratch1, dst, scratch1); 1061 __ addu(scratch1, dst, scratch1);
1061 __ sw(fval, MemOperand(scratch1, 0)); 1062 __ sw(fval, MemOperand(scratch1, 0));
1062 } 1063 }
1063 } 1064 }
1064 1065
1065 1066
1066 #undef __ 1067 #undef __
1067 #define __ ACCESS_MASM(masm()) 1068 #define __ ACCESS_MASM(masm())
1068 1069
1069 1070
1071 void StubCompiler::GenerateTailCall(Handle<Code> code) {
1072 __ Jump(code, RelocInfo::CODE_TARGET);
1073 }
1074
1075
1070 Register StubCompiler::CheckPrototypes(Handle<JSObject> object, 1076 Register StubCompiler::CheckPrototypes(Handle<JSObject> object,
1071 Register object_reg, 1077 Register object_reg,
1072 Handle<JSObject> holder, 1078 Handle<JSObject> holder,
1073 Register holder_reg, 1079 Register holder_reg,
1074 Register scratch1, 1080 Register scratch1,
1075 Register scratch2, 1081 Register scratch2,
1076 Handle<String> name, 1082 Handle<String> name,
1077 int save_at_depth, 1083 int save_at_depth,
1078 Label* miss) { 1084 Label* miss,
1085 PrototypeCheckType check) {
1086 Handle<JSObject> first = object;
1079 // Make sure there's no overlap between holder and object registers. 1087 // Make sure there's no overlap between holder and object registers.
1080 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); 1088 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg));
1081 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg) 1089 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg)
1082 && !scratch2.is(scratch1)); 1090 && !scratch2.is(scratch1));
1083 1091
1084 // Keep track of the current object in register reg. 1092 // Keep track of the current object in register reg.
1085 Register reg = object_reg; 1093 Register reg = object_reg;
1086 int depth = 0; 1094 int depth = 0;
1087 1095
1088 if (save_at_depth == depth) { 1096 if (save_at_depth == depth) {
(...skipping 20 matching lines...) Expand all
1109 ASSERT(current->property_dictionary()->FindEntry(*name) == 1117 ASSERT(current->property_dictionary()->FindEntry(*name) ==
1110 StringDictionary::kNotFound); 1118 StringDictionary::kNotFound);
1111 1119
1112 GenerateDictionaryNegativeLookup(masm(), miss, reg, name, 1120 GenerateDictionaryNegativeLookup(masm(), miss, reg, name,
1113 scratch1, scratch2); 1121 scratch1, scratch2);
1114 1122
1115 __ lw(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset)); 1123 __ lw(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset));
1116 reg = holder_reg; // From now on the object will be in holder_reg. 1124 reg = holder_reg; // From now on the object will be in holder_reg.
1117 __ lw(reg, FieldMemOperand(scratch1, Map::kPrototypeOffset)); 1125 __ lw(reg, FieldMemOperand(scratch1, Map::kPrototypeOffset));
1118 } else { 1126 } else {
1119 Handle<Map> current_map(current->map()); 1127 Register map_reg = scratch1;
1120 __ CheckMap(reg, scratch1, current_map, miss, DONT_DO_SMI_CHECK, 1128 if (!current.is_identical_to(first) || check == CHECK_ALL_MAPS) {
1121 ALLOW_ELEMENT_TRANSITION_MAPS); 1129 Handle<Map> current_map(current->map());
1130 // CheckMap implicitly loads the map of |reg| into |map_reg|.
1131 __ CheckMap(reg, map_reg, current_map, miss, DONT_DO_SMI_CHECK,
1132 ALLOW_ELEMENT_TRANSITION_MAPS);
1133 } else {
1134 __ lw(map_reg, FieldMemOperand(reg, HeapObject::kMapOffset));
1135 }
1122 // Check access rights to the global object. This has to happen after 1136 // Check access rights to the global object. This has to happen after
1123 // the map check so that we know that the object is actually a global 1137 // the map check so that we know that the object is actually a global
1124 // object. 1138 // object.
1125 if (current->IsJSGlobalProxy()) { 1139 if (current->IsJSGlobalProxy()) {
1126 __ CheckAccessGlobalProxy(reg, scratch2, miss); 1140 __ CheckAccessGlobalProxy(reg, scratch2, miss);
1127 } 1141 }
1128 reg = holder_reg; // From now on the object will be in holder_reg. 1142 reg = holder_reg; // From now on the object will be in holder_reg.
1129 1143
1130 if (heap()->InNewSpace(*prototype)) { 1144 if (heap()->InNewSpace(*prototype)) {
1131 // The prototype is in new space; we cannot store a reference to it 1145 // The prototype is in new space; we cannot store a reference to it
1132 // in the code. Load it from the map. 1146 // in the code. Load it from the map.
1133 __ lw(reg, FieldMemOperand(scratch1, Map::kPrototypeOffset)); 1147 __ lw(reg, FieldMemOperand(map_reg, Map::kPrototypeOffset));
1134 } else { 1148 } else {
1135 // The prototype is in old space; load it directly. 1149 // The prototype is in old space; load it directly.
1136 __ li(reg, Operand(prototype)); 1150 __ li(reg, Operand(prototype));
1137 } 1151 }
1138 } 1152 }
1139 1153
1140 if (save_at_depth == depth) { 1154 if (save_at_depth == depth) {
1141 __ sw(reg, MemOperand(sp)); 1155 __ sw(reg, MemOperand(sp));
1142 } 1156 }
1143 1157
1144 // Go to the next object in the prototype chain. 1158 // Go to the next object in the prototype chain.
1145 current = prototype; 1159 current = prototype;
1146 } 1160 }
1147 1161
1148 // Log the check depth. 1162 // Log the check depth.
1149 LOG(masm()->isolate(), IntEvent("check-maps-depth", depth + 1)); 1163 LOG(masm()->isolate(), IntEvent("check-maps-depth", depth + 1));
1150 1164
1151 // Check the holder map. 1165 if (!holder.is_identical_to(first) || check == CHECK_ALL_MAPS) {
1152 __ CheckMap(reg, scratch1, Handle<Map>(current->map()), miss, 1166 // Check the holder map.
1153 DONT_DO_SMI_CHECK, ALLOW_ELEMENT_TRANSITION_MAPS); 1167 __ CheckMap(reg, scratch1, Handle<Map>(holder->map()), miss,
1168 DONT_DO_SMI_CHECK, ALLOW_ELEMENT_TRANSITION_MAPS);
1169 }
1154 1170
1155 // Perform security check for access to the global object. 1171 // Perform security check for access to the global object.
1156 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded()); 1172 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded());
1157 if (holder->IsJSGlobalProxy()) { 1173 if (holder->IsJSGlobalProxy()) {
1158 __ CheckAccessGlobalProxy(reg, scratch1, miss); 1174 __ CheckAccessGlobalProxy(reg, scratch1, miss);
1159 } 1175 }
1160 1176
1161 // If we've skipped any global objects, it's not enough to verify that 1177 // If we've skipped any global objects, it's not enough to verify that
1162 // their maps haven't changed. We also need to check that the property 1178 // their maps haven't changed. We also need to check that the property
1163 // cell for the property is still empty. 1179 // cell for the property is still empty.
1164 GenerateCheckPropertyCells(masm(), object, holder, name, scratch1, miss); 1180 GenerateCheckPropertyCells(masm(), object, holder, name, scratch1, miss);
1165 1181
1166 // Return the register containing the holder. 1182 // Return the register containing the holder.
1167 return reg; 1183 return reg;
1168 } 1184 }
1169 1185
1170 1186
1171 void BaseLoadStubCompiler::HandlerFrontendFooter(Label* success, 1187 void BaseLoadStubCompiler::HandlerFrontendFooter(Label* success,
1172 Label* miss) { 1188 Label* miss) {
1173 __ Branch(success); 1189 if (!miss->is_unused()) {
1174 __ bind(miss); 1190 __ Branch(success);
1175 GenerateLoadMiss(masm(), kind()); 1191 __ bind(miss);
1192 GenerateLoadMiss(masm(), kind());
1193 }
1176 } 1194 }
1177 1195
1178 1196
1179 Register BaseLoadStubCompiler::CallbackHandlerFrontend( 1197 Register BaseLoadStubCompiler::CallbackHandlerFrontend(
1180 Handle<JSObject> object, 1198 Handle<JSObject> object,
1181 Register object_reg, 1199 Register object_reg,
1182 Handle<JSObject> holder, 1200 Handle<JSObject> holder,
1183 Handle<String> name, 1201 Handle<String> name,
1184 Label* success, 1202 Label* success,
1185 FrontendCheckType check,
1186 Handle<ExecutableAccessorInfo> callback) { 1203 Handle<ExecutableAccessorInfo> callback) {
1187 Label miss; 1204 Label miss;
1188 1205
1189 Register reg = HandlerFrontendHeader( 1206 Register reg = HandlerFrontendHeader(object, object_reg, holder, name, &miss);
1190 object, object_reg, holder, name, &miss, check);
1191 1207
1192 if (!holder->HasFastProperties() && !holder->IsJSGlobalObject()) { 1208 if (!holder->HasFastProperties() && !holder->IsJSGlobalObject()) {
1193 ASSERT(!reg.is(scratch2())); 1209 ASSERT(!reg.is(scratch2()));
1194 ASSERT(!reg.is(scratch3())); 1210 ASSERT(!reg.is(scratch3()));
1195 ASSERT(!reg.is(scratch4())); 1211 ASSERT(!reg.is(scratch4()));
1196 1212
1197 // Load the properties dictionary. 1213 // Load the properties dictionary.
1198 Register dictionary = scratch4(); 1214 Register dictionary = scratch4();
1199 __ lw(dictionary, FieldMemOperand(reg, JSObject::kPropertiesOffset)); 1215 __ lw(dictionary, FieldMemOperand(reg, JSObject::kPropertiesOffset));
1200 1216
(...skipping 24 matching lines...) Expand all
1225 1241
1226 1242
1227 void BaseLoadStubCompiler::NonexistentHandlerFrontend( 1243 void BaseLoadStubCompiler::NonexistentHandlerFrontend(
1228 Handle<JSObject> object, 1244 Handle<JSObject> object,
1229 Handle<JSObject> last, 1245 Handle<JSObject> last,
1230 Handle<String> name, 1246 Handle<String> name,
1231 Label* success, 1247 Label* success,
1232 Handle<GlobalObject> global) { 1248 Handle<GlobalObject> global) {
1233 Label miss; 1249 Label miss;
1234 1250
1235 Register reg = HandlerFrontendHeader( 1251 Register reg = HandlerFrontendHeader(object, receiver(), last, name, &miss);
1236 object, receiver(), last, name, &miss, PERFORM_INITIAL_CHECKS);
1237 1252
1238 // If the last object in the prototype chain is a global object, 1253 // If the last object in the prototype chain is a global object,
1239 // check that the global property cell is empty. 1254 // check that the global property cell is empty.
1240 if (!global.is_null()) { 1255 if (!global.is_null()) {
1241 GenerateCheckPropertyCell(masm(), global, name, scratch2(), &miss); 1256 GenerateCheckPropertyCell(masm(), global, name, scratch2(), &miss);
1242 } 1257 }
1243 1258
1244 if (!last->HasFastProperties()) { 1259 if (!last->HasFastProperties()) {
1245 __ lw(scratch2(), FieldMemOperand(reg, HeapObject::kMapOffset)); 1260 __ lw(scratch2(), FieldMemOperand(reg, HeapObject::kMapOffset));
1246 __ lw(scratch2(), FieldMemOperand(scratch2(), Map::kPrototypeOffset)); 1261 __ lw(scratch2(), FieldMemOperand(scratch2(), Map::kPrototypeOffset));
(...skipping 1603 matching lines...) Expand 10 before | Expand all | Expand 10 after
2850 Label success; 2865 Label success;
2851 2866
2852 NonexistentHandlerFrontend(object, last, name, &success, global); 2867 NonexistentHandlerFrontend(object, last, name, &success, global);
2853 2868
2854 __ bind(&success); 2869 __ bind(&success);
2855 // Return undefined if maps of the full prototype chain is still the same. 2870 // Return undefined if maps of the full prototype chain is still the same.
2856 __ LoadRoot(v0, Heap::kUndefinedValueRootIndex); 2871 __ LoadRoot(v0, Heap::kUndefinedValueRootIndex);
2857 __ Ret(); 2872 __ Ret();
2858 2873
2859 // Return the generated code. 2874 // Return the generated code.
2860 return GetCode(Code::NONEXISTENT, factory()->empty_string()); 2875 return GetCode(Code::HANDLER_FRAGMENT, Code::NONEXISTENT, name);
2861 } 2876 }
2862 2877
2863 2878
2864 Register* LoadStubCompiler::registers() { 2879 Register* LoadStubCompiler::registers() {
2865 // receiver, name, scratch1, scratch2, scratch3, scratch4. 2880 // receiver, name, scratch1, scratch2, scratch3, scratch4.
2866 static Register registers[] = { a0, a2, a3, a1, t0, t1 }; 2881 static Register registers[] = { a0, a2, a3, a1, t0, t1 };
2867 return registers; 2882 return registers;
2868 } 2883 }
2869 2884
2870 2885
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
2920 2935
2921 2936
2922 Handle<Code> LoadStubCompiler::CompileLoadGlobal( 2937 Handle<Code> LoadStubCompiler::CompileLoadGlobal(
2923 Handle<JSObject> object, 2938 Handle<JSObject> object,
2924 Handle<GlobalObject> global, 2939 Handle<GlobalObject> global,
2925 Handle<JSGlobalPropertyCell> cell, 2940 Handle<JSGlobalPropertyCell> cell,
2926 Handle<String> name, 2941 Handle<String> name,
2927 bool is_dont_delete) { 2942 bool is_dont_delete) {
2928 Label success, miss; 2943 Label success, miss;
2929 2944
2930 HandlerFrontendHeader(object, receiver(), Handle<JSObject>::cast(global), 2945 __ CheckMap(
2931 name, &miss, PERFORM_INITIAL_CHECKS); 2946 receiver(), scratch1(), Handle<Map>(object->map()), &miss, DO_SMI_CHECK);
2947 HandlerFrontendHeader(
2948 object, receiver(), Handle<JSObject>::cast(global), name, &miss);
2932 2949
2933 // Get the value from the cell. 2950 // Get the value from the cell.
2934 __ li(a3, Operand(cell)); 2951 __ li(a3, Operand(cell));
2935 __ lw(t0, FieldMemOperand(a3, JSGlobalPropertyCell::kValueOffset)); 2952 __ lw(t0, FieldMemOperand(a3, JSGlobalPropertyCell::kValueOffset));
2936 2953
2937 // Check for deleted property if property can actually be deleted. 2954 // Check for deleted property if property can actually be deleted.
2938 if (!is_dont_delete) { 2955 if (!is_dont_delete) {
2939 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); 2956 __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
2940 __ Branch(&miss, eq, t0, Operand(at)); 2957 __ Branch(&miss, eq, t0, Operand(at));
2941 } 2958 }
2942 2959
2943 HandlerFrontendFooter(&success, &miss); 2960 HandlerFrontendFooter(&success, &miss);
2944 __ bind(&success); 2961 __ bind(&success);
2945 2962
2946 Counters* counters = masm()->isolate()->counters(); 2963 Counters* counters = masm()->isolate()->counters();
2947 __ IncrementCounter(counters->named_load_global_stub(), 1, a1, a3); 2964 __ IncrementCounter(counters->named_load_global_stub(), 1, a1, a3);
2948 __ mov(v0, t0); 2965 __ mov(v0, t0);
2949 __ Ret(); 2966 __ Ret();
2950 2967
2951 // Return the generated code. 2968 // Return the generated code.
2952 return GetCode(Code::NORMAL, name); 2969 return GetCode(Code::IC_FRAGMENT, Code::NORMAL, name);
2953 } 2970 }
2954 2971
2955 2972
2956 Handle<Code> KeyedLoadStubCompiler::CompileLoadElement( 2973 Handle<Code> KeyedLoadStubCompiler::CompileLoadElement(
2957 Handle<Map> receiver_map) { 2974 Handle<Map> receiver_map) {
2958 // ----------- S t a t e ------------- 2975 // ----------- S t a t e -------------
2959 // -- ra : return address 2976 // -- ra : return address
2960 // -- a0 : key 2977 // -- a0 : key
2961 // -- a1 : receiver 2978 // -- a1 : receiver
2962 // ----------------------------------- 2979 // -----------------------------------
2963 ElementsKind elements_kind = receiver_map->elements_kind(); 2980 ElementsKind elements_kind = receiver_map->elements_kind();
2964 if (receiver_map->has_fast_elements() || 2981 if (receiver_map->has_fast_elements() ||
2965 receiver_map->has_external_array_elements()) { 2982 receiver_map->has_external_array_elements()) {
2966 Handle<Code> stub = KeyedLoadFastElementStub( 2983 Handle<Code> stub = KeyedLoadFastElementStub(
2967 receiver_map->instance_type() == JS_ARRAY_TYPE, 2984 receiver_map->instance_type() == JS_ARRAY_TYPE,
2968 elements_kind).GetCode(isolate()); 2985 elements_kind).GetCode(isolate());
2969 __ DispatchMap(a1, a2, receiver_map, stub, DO_SMI_CHECK); 2986 __ DispatchMap(a1, a2, receiver_map, stub, DO_SMI_CHECK);
2970 } else { 2987 } else {
2971 Handle<Code> stub = 2988 Handle<Code> stub =
2972 KeyedLoadDictionaryElementStub().GetCode(isolate()); 2989 KeyedLoadDictionaryElementStub().GetCode(isolate());
2973 __ DispatchMap(a1, a2, receiver_map, stub, DO_SMI_CHECK); 2990 __ DispatchMap(a1, a2, receiver_map, stub, DO_SMI_CHECK);
2974 } 2991 }
2975 2992
2976 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Miss(); 2993 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Miss();
2977 __ Jump(ic, RelocInfo::CODE_TARGET); 2994 __ Jump(ic, RelocInfo::CODE_TARGET);
2978 2995
2979 // Return the generated code. 2996 // Return the generated code.
2980 return GetCode(Code::NORMAL, factory()->empty_string()); 2997 return GetCode(Code::IC_FRAGMENT, Code::NORMAL, factory()->empty_string());
2981 } 2998 }
2982 2999
2983 3000
2984 Handle<Code> BaseLoadStubCompiler::CompilePolymorphicIC( 3001 Handle<Code> BaseLoadStubCompiler::CompilePolymorphicIC(
2985 MapHandleList* receiver_maps, 3002 MapHandleList* receiver_maps,
2986 CodeHandleList* handlers) { 3003 CodeHandleList* handlers,
2987 // ----------- S t a t e ------------- 3004 Handle<String> name,
2988 // -- ra : return address 3005 Code::StubType type,
2989 // -- a0 : key 3006 IcCheckType check) {
2990 // -- a1 : receiver
2991 // -----------------------------------
2992 Label miss; 3007 Label miss;
2993 __ JumpIfSmi(a1, &miss); 3008
3009 if (check == PROPERTY) {
3010 GenerateNameCheck(name, this->name(), &miss);
3011 }
3012
3013 __ JumpIfSmi(receiver(), &miss);
3014 Register map_reg = scratch1();
2994 3015
2995 int receiver_count = receiver_maps->length(); 3016 int receiver_count = receiver_maps->length();
2996 __ lw(a2, FieldMemOperand(a1, HeapObject::kMapOffset)); 3017 __ lw(map_reg, FieldMemOperand(receiver(), HeapObject::kMapOffset));
2997 for (int current = 0; current < receiver_count; ++current) { 3018 for (int current = 0; current < receiver_count; ++current) {
2998 __ Jump(handlers->at(current), RelocInfo::CODE_TARGET, 3019 __ Jump(handlers->at(current), RelocInfo::CODE_TARGET,
2999 eq, a2, Operand(receiver_maps->at(current))); 3020 eq, map_reg, Operand(receiver_maps->at(current)));
3000 } 3021 }
3001 3022
3002 __ bind(&miss); 3023 __ bind(&miss);
3003 GenerateLoadMiss(masm(), kind()); 3024 GenerateLoadMiss(masm(), kind());
3004 3025
3005 // Return the generated code. 3026 // Return the generated code.
3006 return GetCode(Code::NORMAL, factory()->empty_string(), POLYMORPHIC); 3027 InlineCacheState state =
3028 receiver_maps->length() > 1 ? POLYMORPHIC : MONOMORPHIC;
3029 return GetCode(Code::IC_FRAGMENT, type, name, state);
3007 } 3030 }
3008 3031
3009 3032
3010 Handle<Code> KeyedStoreStubCompiler::CompileStoreField(Handle<JSObject> object, 3033 Handle<Code> KeyedStoreStubCompiler::CompileStoreField(Handle<JSObject> object,
3011 int index, 3034 int index,
3012 Handle<Map> transition, 3035 Handle<Map> transition,
3013 Handle<String> name) { 3036 Handle<String> name) {
3014 // ----------- S t a t e ------------- 3037 // ----------- S t a t e -------------
3015 // -- a0 : value 3038 // -- a0 : value
3016 // -- a1 : key 3039 // -- a1 : key
(...skipping 1094 matching lines...) Expand 10 before | Expand all | Expand 10 after
4111 __ Jump(ic_slow, RelocInfo::CODE_TARGET); 4134 __ Jump(ic_slow, RelocInfo::CODE_TARGET);
4112 } 4135 }
4113 } 4136 }
4114 4137
4115 4138
4116 #undef __ 4139 #undef __
4117 4140
4118 } } // namespace v8::internal 4141 } } // namespace v8::internal
4119 4142
4120 #endif // V8_TARGET_ARCH_MIPS 4143 #endif // V8_TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « src/mips/ic-mips.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698