| OLD | NEW |
| 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 767 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 778 __ li(scratch, Operand(interceptor)); | 778 __ li(scratch, Operand(interceptor)); |
| 779 __ Push(scratch, receiver, holder); | 779 __ Push(scratch, receiver, holder); |
| 780 } | 780 } |
| 781 | 781 |
| 782 | 782 |
| 783 static void CompileCallLoadPropertyWithInterceptor( | 783 static void CompileCallLoadPropertyWithInterceptor( |
| 784 MacroAssembler* masm, | 784 MacroAssembler* masm, |
| 785 Register receiver, | 785 Register receiver, |
| 786 Register holder, | 786 Register holder, |
| 787 Register name, | 787 Register name, |
| 788 Handle<JSObject> holder_obj) { | 788 Handle<JSObject> holder_obj, |
| 789 IC::UtilityId id) { |
| 789 PushInterceptorArguments(masm, receiver, holder, name, holder_obj); | 790 PushInterceptorArguments(masm, receiver, holder, name, holder_obj); |
| 790 | 791 __ CallExternalReference( |
| 791 ExternalReference ref = | 792 ExternalReference(IC_Utility(id), masm->isolate()), |
| 792 ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorOnly), | 793 StubCache::kInterceptorArgsLength); |
| 793 masm->isolate()); | |
| 794 __ PrepareCEntryArgs(StubCache::kInterceptorArgsLength); | |
| 795 __ PrepareCEntryFunction(ref); | |
| 796 | |
| 797 CEntryStub stub(1); | |
| 798 __ CallStub(&stub); | |
| 799 } | 794 } |
| 800 | 795 |
| 801 | 796 |
| 802 static const int kFastApiCallArguments = FunctionCallbackArguments::kArgsLength; | 797 static const int kFastApiCallArguments = FunctionCallbackArguments::kArgsLength; |
| 803 | 798 |
| 804 // Reserves space for the extra arguments to API function in the | 799 // Reserves space for the extra arguments to API function in the |
| 805 // caller's frame. | 800 // caller's frame. |
| 806 // | 801 // |
| 807 // These arguments are set by CheckPrototypes and GenerateFastApiDirectCall. | 802 // These arguments are set by CheckPrototypes and GenerateFastApiDirectCall. |
| 808 static void ReserveSpaceForFastApiCall(MacroAssembler* masm, | 803 static void ReserveSpaceForFastApiCall(MacroAssembler* masm, |
| (...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1018 __ IncrementCounter(counters->call_const_interceptor_fast_api(), 1, | 1013 __ IncrementCounter(counters->call_const_interceptor_fast_api(), 1, |
| 1019 scratch1, scratch2); | 1014 scratch1, scratch2); |
| 1020 ReserveSpaceForFastApiCall(masm, scratch1); | 1015 ReserveSpaceForFastApiCall(masm, scratch1); |
| 1021 } | 1016 } |
| 1022 | 1017 |
| 1023 // Check that the maps from receiver to interceptor's holder | 1018 // Check that the maps from receiver to interceptor's holder |
| 1024 // haven't changed and thus we can invoke interceptor. | 1019 // haven't changed and thus we can invoke interceptor. |
| 1025 Label miss_cleanup; | 1020 Label miss_cleanup; |
| 1026 Label* miss = can_do_fast_api_call ? &miss_cleanup : miss_label; | 1021 Label* miss = can_do_fast_api_call ? &miss_cleanup : miss_label; |
| 1027 Register holder = | 1022 Register holder = |
| 1028 stub_compiler_->CheckPrototypes(object, receiver, interceptor_holder, | 1023 stub_compiler_->CheckPrototypes( |
| 1029 scratch1, scratch2, scratch3, | 1024 IC::CurrentTypeOf(object, masm->isolate()), receiver, |
| 1030 name, depth1, miss); | 1025 interceptor_holder, scratch1, scratch2, scratch3, |
| 1026 name, depth1, miss); |
| 1031 | 1027 |
| 1032 // Invoke an interceptor and if it provides a value, | 1028 // Invoke an interceptor and if it provides a value, |
| 1033 // branch to |regular_invoke|. | 1029 // branch to |regular_invoke|. |
| 1034 Label regular_invoke; | 1030 Label regular_invoke; |
| 1035 LoadWithInterceptor(masm, receiver, holder, interceptor_holder, scratch2, | 1031 LoadWithInterceptor(masm, receiver, holder, interceptor_holder, scratch2, |
| 1036 ®ular_invoke); | 1032 ®ular_invoke); |
| 1037 | 1033 |
| 1038 // Interceptor returned nothing for this property. Try to use cached | 1034 // Interceptor returned nothing for this property. Try to use cached |
| 1039 // constant function. | 1035 // constant function. |
| 1040 | 1036 |
| 1041 // Check that the maps from interceptor's holder to constant function's | 1037 // Check that the maps from interceptor's holder to constant function's |
| 1042 // holder haven't changed and thus we can use cached constant function. | 1038 // holder haven't changed and thus we can use cached constant function. |
| 1043 if (*interceptor_holder != lookup->holder()) { | 1039 if (*interceptor_holder != lookup->holder()) { |
| 1044 stub_compiler_->CheckPrototypes(interceptor_holder, receiver, | 1040 stub_compiler_->CheckPrototypes( |
| 1045 Handle<JSObject>(lookup->holder()), | 1041 IC::CurrentTypeOf(interceptor_holder, masm->isolate()), receiver, |
| 1046 scratch1, scratch2, scratch3, | 1042 handle(lookup->holder()), scratch1, scratch2, scratch3, |
| 1047 name, depth2, miss); | 1043 name, depth2, miss); |
| 1048 } else { | 1044 } else { |
| 1049 // CheckPrototypes has a side effect of fetching a 'holder' | 1045 // CheckPrototypes has a side effect of fetching a 'holder' |
| 1050 // for API (object which is instanceof for the signature). It's | 1046 // for API (object which is instanceof for the signature). It's |
| 1051 // safe to omit it here, as if present, it should be fetched | 1047 // safe to omit it here, as if present, it should be fetched |
| 1052 // by the previous CheckPrototypes. | 1048 // by the previous CheckPrototypes. |
| 1053 ASSERT(depth2 == kInvalidProtoDepth); | 1049 ASSERT(depth2 == kInvalidProtoDepth); |
| 1054 } | 1050 } |
| 1055 | 1051 |
| 1056 // Invoke function. | 1052 // Invoke function. |
| 1057 if (can_do_fast_api_call) { | 1053 if (can_do_fast_api_call) { |
| (...skipping 26 matching lines...) Expand all Loading... |
| 1084 void CompileRegular(MacroAssembler* masm, | 1080 void CompileRegular(MacroAssembler* masm, |
| 1085 Handle<JSObject> object, | 1081 Handle<JSObject> object, |
| 1086 Register receiver, | 1082 Register receiver, |
| 1087 Register scratch1, | 1083 Register scratch1, |
| 1088 Register scratch2, | 1084 Register scratch2, |
| 1089 Register scratch3, | 1085 Register scratch3, |
| 1090 Handle<Name> name, | 1086 Handle<Name> name, |
| 1091 Handle<JSObject> interceptor_holder, | 1087 Handle<JSObject> interceptor_holder, |
| 1092 Label* miss_label) { | 1088 Label* miss_label) { |
| 1093 Register holder = | 1089 Register holder = |
| 1094 stub_compiler_->CheckPrototypes(object, receiver, interceptor_holder, | 1090 stub_compiler_->CheckPrototypes( |
| 1095 scratch1, scratch2, scratch3, | 1091 IC::CurrentTypeOf(object, masm->isolate()), receiver, |
| 1096 name, miss_label); | 1092 interceptor_holder, scratch1, scratch2, scratch3, name, miss_label); |
| 1097 | 1093 |
| 1098 // Call a runtime function to load the interceptor property. | 1094 // Call a runtime function to load the interceptor property. |
| 1099 FrameScope scope(masm, StackFrame::INTERNAL); | 1095 FrameScope scope(masm, StackFrame::INTERNAL); |
| 1100 // Save the name_ register across the call. | 1096 // Save the name_ register across the call. |
| 1101 __ push(name_); | 1097 __ push(name_); |
| 1102 | 1098 |
| 1103 PushInterceptorArguments(masm, receiver, holder, name_, interceptor_holder); | 1099 CompileCallLoadPropertyWithInterceptor( |
| 1100 masm, receiver, holder, name_, interceptor_holder, |
| 1101 IC::kLoadPropertyWithInterceptorForCall); |
| 1104 | 1102 |
| 1105 __ CallExternalReference( | |
| 1106 ExternalReference( | |
| 1107 IC_Utility(IC::kLoadPropertyWithInterceptorForCall), | |
| 1108 masm->isolate()), | |
| 1109 StubCache::kInterceptorArgsLength); | |
| 1110 // Restore the name_ register. | 1103 // Restore the name_ register. |
| 1111 __ pop(name_); | 1104 __ pop(name_); |
| 1112 // Leave the internal frame. | 1105 // Leave the internal frame. |
| 1113 } | 1106 } |
| 1114 | 1107 |
| 1115 void LoadWithInterceptor(MacroAssembler* masm, | 1108 void LoadWithInterceptor(MacroAssembler* masm, |
| 1116 Register receiver, | 1109 Register receiver, |
| 1117 Register holder, | 1110 Register holder, |
| 1118 Handle<JSObject> holder_obj, | 1111 Handle<JSObject> holder_obj, |
| 1119 Register scratch, | 1112 Register scratch, |
| 1120 Label* interceptor_succeeded) { | 1113 Label* interceptor_succeeded) { |
| 1121 { | 1114 { |
| 1122 FrameScope scope(masm, StackFrame::INTERNAL); | 1115 FrameScope scope(masm, StackFrame::INTERNAL); |
| 1123 | 1116 |
| 1124 __ Push(holder, name_); | 1117 __ Push(holder, name_); |
| 1125 CompileCallLoadPropertyWithInterceptor(masm, | 1118 CompileCallLoadPropertyWithInterceptor( |
| 1126 receiver, | 1119 masm, receiver, holder, name_, holder_obj, |
| 1127 holder, | 1120 IC::kLoadPropertyWithInterceptorOnly); |
| 1128 name_, | |
| 1129 holder_obj); | |
| 1130 __ pop(name_); // Restore the name. | 1121 __ pop(name_); // Restore the name. |
| 1131 __ pop(receiver); // Restore the holder. | 1122 __ pop(receiver); // Restore the holder. |
| 1132 } | 1123 } |
| 1133 // If interceptor returns no-result sentinel, call the constant function. | 1124 // If interceptor returns no-result sentinel, call the constant function. |
| 1134 __ LoadRoot(scratch, Heap::kNoInterceptorResultSentinelRootIndex); | 1125 __ LoadRoot(scratch, Heap::kNoInterceptorResultSentinelRootIndex); |
| 1135 __ Branch(interceptor_succeeded, ne, v0, Operand(scratch)); | 1126 __ Branch(interceptor_succeeded, ne, v0, Operand(scratch)); |
| 1136 } | 1127 } |
| 1137 | 1128 |
| 1138 StubCompiler* stub_compiler_; | 1129 StubCompiler* stub_compiler_; |
| 1139 const ParameterCount& arguments_; | 1130 const ParameterCount& arguments_; |
| 1140 Register name_; | 1131 Register name_; |
| 1141 Code::ExtraICState extra_ic_state_; | 1132 Code::ExtraICState extra_ic_state_; |
| 1142 }; | 1133 }; |
| 1143 | 1134 |
| 1144 | 1135 |
| 1145 void StubCompiler::GenerateCheckPropertyCells(MacroAssembler* masm, | |
| 1146 Handle<JSObject> object, | |
| 1147 Handle<JSObject> holder, | |
| 1148 Handle<Name> name, | |
| 1149 Register scratch, | |
| 1150 Label* miss) { | |
| 1151 Handle<JSObject> current = object; | |
| 1152 while (!current.is_identical_to(holder)) { | |
| 1153 if (current->IsJSGlobalObject()) { | |
| 1154 GenerateCheckPropertyCell(masm, | |
| 1155 Handle<JSGlobalObject>::cast(current), | |
| 1156 name, | |
| 1157 scratch, | |
| 1158 miss); | |
| 1159 } | |
| 1160 current = Handle<JSObject>(JSObject::cast(current->GetPrototype())); | |
| 1161 } | |
| 1162 } | |
| 1163 | |
| 1164 | |
| 1165 void StubCompiler::GenerateTailCall(MacroAssembler* masm, Handle<Code> code) { | 1136 void StubCompiler::GenerateTailCall(MacroAssembler* masm, Handle<Code> code) { |
| 1166 __ Jump(code, RelocInfo::CODE_TARGET); | 1137 __ Jump(code, RelocInfo::CODE_TARGET); |
| 1167 } | 1138 } |
| 1168 | 1139 |
| 1169 | 1140 |
| 1170 #undef __ | 1141 #undef __ |
| 1171 #define __ ACCESS_MASM(masm()) | 1142 #define __ ACCESS_MASM(masm()) |
| 1172 | 1143 |
| 1173 | 1144 |
| 1174 Register StubCompiler::CheckPrototypes(Handle<JSObject> object, | 1145 Register StubCompiler::CheckPrototypes(Handle<Type> type, |
| 1175 Register object_reg, | 1146 Register object_reg, |
| 1176 Handle<JSObject> holder, | 1147 Handle<JSObject> holder, |
| 1177 Register holder_reg, | 1148 Register holder_reg, |
| 1178 Register scratch1, | 1149 Register scratch1, |
| 1179 Register scratch2, | 1150 Register scratch2, |
| 1180 Handle<Name> name, | 1151 Handle<Name> name, |
| 1181 int save_at_depth, | 1152 int save_at_depth, |
| 1182 Label* miss, | 1153 Label* miss, |
| 1183 PrototypeCheckType check) { | 1154 PrototypeCheckType check) { |
| 1155 Handle<Map> receiver_map(IC::TypeToMap(*type, isolate())); |
| 1184 // Make sure that the type feedback oracle harvests the receiver map. | 1156 // Make sure that the type feedback oracle harvests the receiver map. |
| 1185 // TODO(svenpanne) Remove this hack when all ICs are reworked. | 1157 // TODO(svenpanne) Remove this hack when all ICs are reworked. |
| 1186 __ li(scratch1, Operand(Handle<Map>(object->map()))); | 1158 __ li(scratch1, Operand(receiver_map)); |
| 1187 | 1159 |
| 1188 Handle<JSObject> first = object; | |
| 1189 // Make sure there's no overlap between holder and object registers. | 1160 // Make sure there's no overlap between holder and object registers. |
| 1190 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); | 1161 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); |
| 1191 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg) | 1162 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg) |
| 1192 && !scratch2.is(scratch1)); | 1163 && !scratch2.is(scratch1)); |
| 1193 | 1164 |
| 1194 // Keep track of the current object in register reg. | 1165 // Keep track of the current object in register reg. |
| 1195 Register reg = object_reg; | 1166 Register reg = object_reg; |
| 1196 int depth = 0; | 1167 int depth = 0; |
| 1197 | 1168 |
| 1198 typedef FunctionCallbackArguments FCA; | 1169 typedef FunctionCallbackArguments FCA; |
| 1199 if (save_at_depth == depth) { | 1170 if (save_at_depth == depth) { |
| 1200 __ sw(reg, MemOperand(sp, FCA::kHolderIndex * kPointerSize)); | 1171 __ sw(reg, MemOperand(sp, FCA::kHolderIndex * kPointerSize)); |
| 1201 } | 1172 } |
| 1202 | 1173 |
| 1203 // Check the maps in the prototype chain. | 1174 Handle<JSObject> current = Handle<JSObject>::null(); |
| 1204 // Traverse the prototype chain from the object and do map checks. | 1175 if (type->IsConstant()) current = Handle<JSObject>::cast(type->AsConstant()); |
| 1205 Handle<JSObject> current = object; | 1176 Handle<JSObject> prototype = Handle<JSObject>::null(); |
| 1206 while (!current.is_identical_to(holder)) { | 1177 Handle<Map> current_map = receiver_map; |
| 1178 Handle<Map> holder_map(holder->map()); |
| 1179 // Traverse the prototype chain and check the maps in the prototype chain for |
| 1180 // fast and global objects or do negative lookup for normal objects. |
| 1181 while (!current_map.is_identical_to(holder_map)) { |
| 1207 ++depth; | 1182 ++depth; |
| 1208 | 1183 |
| 1209 // Only global objects and objects that do not require access | 1184 // Only global objects and objects that do not require access |
| 1210 // checks are allowed in stubs. | 1185 // checks are allowed in stubs. |
| 1211 ASSERT(current->IsJSGlobalProxy() || !current->IsAccessCheckNeeded()); | 1186 ASSERT(current_map->IsJSGlobalProxyMap() || |
| 1187 !current_map->is_access_check_needed()); |
| 1212 | 1188 |
| 1213 Handle<JSObject> prototype(JSObject::cast(current->GetPrototype())); | 1189 prototype = handle(JSObject::cast(current_map->prototype())); |
| 1214 if (!current->HasFastProperties() && | 1190 if (current_map->is_dictionary_map() && |
| 1215 !current->IsJSGlobalObject() && | 1191 !current_map->IsJSGlobalObjectMap() && |
| 1216 !current->IsJSGlobalProxy()) { | 1192 !current_map->IsJSGlobalProxyMap()) { |
| 1217 if (!name->IsUniqueName()) { | 1193 if (!name->IsUniqueName()) { |
| 1218 ASSERT(name->IsString()); | 1194 ASSERT(name->IsString()); |
| 1219 name = factory()->InternalizeString(Handle<String>::cast(name)); | 1195 name = factory()->InternalizeString(Handle<String>::cast(name)); |
| 1220 } | 1196 } |
| 1221 ASSERT(current->property_dictionary()->FindEntry(*name) == | 1197 ASSERT(current.is_null() || |
| 1198 current->property_dictionary()->FindEntry(*name) == |
| 1222 NameDictionary::kNotFound); | 1199 NameDictionary::kNotFound); |
| 1223 | 1200 |
| 1224 GenerateDictionaryNegativeLookup(masm(), miss, reg, name, | 1201 GenerateDictionaryNegativeLookup(masm(), miss, reg, name, |
| 1225 scratch1, scratch2); | 1202 scratch1, scratch2); |
| 1226 | 1203 |
| 1227 __ lw(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset)); | 1204 __ lw(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset)); |
| 1228 reg = holder_reg; // From now on the object will be in holder_reg. | 1205 reg = holder_reg; // From now on the object will be in holder_reg. |
| 1229 __ lw(reg, FieldMemOperand(scratch1, Map::kPrototypeOffset)); | 1206 __ lw(reg, FieldMemOperand(scratch1, Map::kPrototypeOffset)); |
| 1230 } else { | 1207 } else { |
| 1231 Register map_reg = scratch1; | 1208 Register map_reg = scratch1; |
| 1232 if (!current.is_identical_to(first) || check == CHECK_ALL_MAPS) { | 1209 if (depth != 1 || check == CHECK_ALL_MAPS) { |
| 1233 Handle<Map> current_map(current->map()); | |
| 1234 // CheckMap implicitly loads the map of |reg| into |map_reg|. | 1210 // CheckMap implicitly loads the map of |reg| into |map_reg|. |
| 1235 __ CheckMap(reg, map_reg, current_map, miss, DONT_DO_SMI_CHECK); | 1211 __ CheckMap(reg, map_reg, current_map, miss, DONT_DO_SMI_CHECK); |
| 1236 } else { | 1212 } else { |
| 1237 __ lw(map_reg, FieldMemOperand(reg, HeapObject::kMapOffset)); | 1213 __ lw(map_reg, FieldMemOperand(reg, HeapObject::kMapOffset)); |
| 1238 } | 1214 } |
| 1215 |
| 1239 // Check access rights to the global object. This has to happen after | 1216 // Check access rights to the global object. This has to happen after |
| 1240 // the map check so that we know that the object is actually a global | 1217 // the map check so that we know that the object is actually a global |
| 1241 // object. | 1218 // object. |
| 1242 if (current->IsJSGlobalProxy()) { | 1219 if (current_map->IsJSGlobalProxyMap()) { |
| 1243 __ CheckAccessGlobalProxy(reg, scratch2, miss); | 1220 __ CheckAccessGlobalProxy(reg, scratch2, miss); |
| 1221 } else if (current_map->IsJSGlobalObjectMap()) { |
| 1222 GenerateCheckPropertyCell( |
| 1223 masm(), Handle<JSGlobalObject>::cast(current), name, |
| 1224 scratch2, miss); |
| 1244 } | 1225 } |
| 1226 |
| 1245 reg = holder_reg; // From now on the object will be in holder_reg. | 1227 reg = holder_reg; // From now on the object will be in holder_reg. |
| 1246 | 1228 |
| 1247 if (heap()->InNewSpace(*prototype)) { | 1229 if (heap()->InNewSpace(*prototype)) { |
| 1248 // The prototype is in new space; we cannot store a reference to it | 1230 // The prototype is in new space; we cannot store a reference to it |
| 1249 // in the code. Load it from the map. | 1231 // in the code. Load it from the map. |
| 1250 __ lw(reg, FieldMemOperand(map_reg, Map::kPrototypeOffset)); | 1232 __ lw(reg, FieldMemOperand(map_reg, Map::kPrototypeOffset)); |
| 1251 } else { | 1233 } else { |
| 1252 // The prototype is in old space; load it directly. | 1234 // The prototype is in old space; load it directly. |
| 1253 __ li(reg, Operand(prototype)); | 1235 __ li(reg, Operand(prototype)); |
| 1254 } | 1236 } |
| 1255 } | 1237 } |
| 1256 | 1238 |
| 1257 if (save_at_depth == depth) { | 1239 if (save_at_depth == depth) { |
| 1258 __ sw(reg, MemOperand(sp, FCA::kHolderIndex * kPointerSize)); | 1240 __ sw(reg, MemOperand(sp, FCA::kHolderIndex * kPointerSize)); |
| 1259 } | 1241 } |
| 1260 | 1242 |
| 1261 // Go to the next object in the prototype chain. | 1243 // Go to the next object in the prototype chain. |
| 1262 current = prototype; | 1244 current = prototype; |
| 1245 current_map = handle(current->map()); |
| 1263 } | 1246 } |
| 1264 | 1247 |
| 1265 // Log the check depth. | 1248 // Log the check depth. |
| 1266 LOG(isolate(), IntEvent("check-maps-depth", depth + 1)); | 1249 LOG(isolate(), IntEvent("check-maps-depth", depth + 1)); |
| 1267 | 1250 |
| 1268 if (!holder.is_identical_to(first) || check == CHECK_ALL_MAPS) { | 1251 if (depth != 0 || check == CHECK_ALL_MAPS) { |
| 1269 // Check the holder map. | 1252 // Check the holder map. |
| 1270 __ CheckMap(reg, scratch1, Handle<Map>(holder->map()), miss, | 1253 __ CheckMap(reg, scratch1, current_map, miss, DONT_DO_SMI_CHECK); |
| 1271 DONT_DO_SMI_CHECK); | |
| 1272 } | 1254 } |
| 1273 | 1255 |
| 1274 // Perform security check for access to the global object. | 1256 // Perform security check for access to the global object. |
| 1275 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded()); | 1257 ASSERT(current_map->IsJSGlobalProxyMap() || |
| 1276 if (holder->IsJSGlobalProxy()) { | 1258 !current_map->is_access_check_needed()); |
| 1259 if (current_map->IsJSGlobalProxyMap()) { |
| 1277 __ CheckAccessGlobalProxy(reg, scratch1, miss); | 1260 __ CheckAccessGlobalProxy(reg, scratch1, miss); |
| 1278 } | 1261 } |
| 1279 | 1262 |
| 1280 // If we've skipped any global objects, it's not enough to verify that | |
| 1281 // their maps haven't changed. We also need to check that the property | |
| 1282 // cell for the property is still empty. | |
| 1283 GenerateCheckPropertyCells(masm(), object, holder, name, scratch1, miss); | |
| 1284 | |
| 1285 // Return the register containing the holder. | 1263 // Return the register containing the holder. |
| 1286 return reg; | 1264 return reg; |
| 1287 } | 1265 } |
| 1288 | 1266 |
| 1289 | 1267 |
| 1290 void LoadStubCompiler::HandlerFrontendFooter(Handle<Name> name, Label* miss) { | 1268 void LoadStubCompiler::HandlerFrontendFooter(Handle<Name> name, Label* miss) { |
| 1291 if (!miss->is_unused()) { | 1269 if (!miss->is_unused()) { |
| 1292 Label success; | 1270 Label success; |
| 1293 __ Branch(&success); | 1271 __ Branch(&success); |
| 1294 __ bind(miss); | 1272 __ bind(miss); |
| 1295 TailCallBuiltin(masm(), MissBuiltin(kind())); | 1273 TailCallBuiltin(masm(), MissBuiltin(kind())); |
| 1296 __ bind(&success); | 1274 __ bind(&success); |
| 1297 } | 1275 } |
| 1298 } | 1276 } |
| 1299 | 1277 |
| 1300 | 1278 |
| 1301 void StoreStubCompiler::HandlerFrontendFooter(Handle<Name> name, Label* miss) { | 1279 void StoreStubCompiler::HandlerFrontendFooter(Handle<Name> name, Label* miss) { |
| 1302 if (!miss->is_unused()) { | 1280 if (!miss->is_unused()) { |
| 1303 Label success; | 1281 Label success; |
| 1304 __ Branch(&success); | 1282 __ Branch(&success); |
| 1305 GenerateRestoreName(masm(), miss, name); | 1283 GenerateRestoreName(masm(), miss, name); |
| 1306 TailCallBuiltin(masm(), MissBuiltin(kind())); | 1284 TailCallBuiltin(masm(), MissBuiltin(kind())); |
| 1307 __ bind(&success); | 1285 __ bind(&success); |
| 1308 } | 1286 } |
| 1309 } | 1287 } |
| 1310 | 1288 |
| 1311 | 1289 |
| 1312 Register LoadStubCompiler::CallbackHandlerFrontend( | 1290 Register LoadStubCompiler::CallbackHandlerFrontend( |
| 1313 Handle<Object> object, | 1291 Handle<Type> type, |
| 1314 Register object_reg, | 1292 Register object_reg, |
| 1315 Handle<JSObject> holder, | 1293 Handle<JSObject> holder, |
| 1316 Handle<Name> name, | 1294 Handle<Name> name, |
| 1317 Handle<Object> callback) { | 1295 Handle<Object> callback) { |
| 1318 Label miss; | 1296 Label miss; |
| 1319 | 1297 |
| 1320 Register reg = HandlerFrontendHeader(object, object_reg, holder, name, &miss); | 1298 Register reg = HandlerFrontendHeader(type, object_reg, holder, name, &miss); |
| 1321 | 1299 |
| 1322 if (!holder->HasFastProperties() && !holder->IsJSGlobalObject()) { | 1300 if (!holder->HasFastProperties() && !holder->IsJSGlobalObject()) { |
| 1323 ASSERT(!reg.is(scratch2())); | 1301 ASSERT(!reg.is(scratch2())); |
| 1324 ASSERT(!reg.is(scratch3())); | 1302 ASSERT(!reg.is(scratch3())); |
| 1325 ASSERT(!reg.is(scratch4())); | 1303 ASSERT(!reg.is(scratch4())); |
| 1326 | 1304 |
| 1327 // Load the properties dictionary. | 1305 // Load the properties dictionary. |
| 1328 Register dictionary = scratch4(); | 1306 Register dictionary = scratch4(); |
| 1329 __ lw(dictionary, FieldMemOperand(reg, JSObject::kPropertiesOffset)); | 1307 __ lw(dictionary, FieldMemOperand(reg, JSObject::kPropertiesOffset)); |
| 1330 | 1308 |
| (...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1501 { | 1479 { |
| 1502 FrameScope frame_scope(masm(), StackFrame::INTERNAL); | 1480 FrameScope frame_scope(masm(), StackFrame::INTERNAL); |
| 1503 if (must_preserve_receiver_reg) { | 1481 if (must_preserve_receiver_reg) { |
| 1504 __ Push(receiver(), holder_reg, this->name()); | 1482 __ Push(receiver(), holder_reg, this->name()); |
| 1505 } else { | 1483 } else { |
| 1506 __ Push(holder_reg, this->name()); | 1484 __ Push(holder_reg, this->name()); |
| 1507 } | 1485 } |
| 1508 // Invoke an interceptor. Note: map checks from receiver to | 1486 // Invoke an interceptor. Note: map checks from receiver to |
| 1509 // interceptor's holder has been compiled before (see a caller | 1487 // interceptor's holder has been compiled before (see a caller |
| 1510 // of this method). | 1488 // of this method). |
| 1511 CompileCallLoadPropertyWithInterceptor(masm(), | 1489 CompileCallLoadPropertyWithInterceptor( |
| 1512 receiver(), | 1490 masm(), receiver(), holder_reg, this->name(), interceptor_holder, |
| 1513 holder_reg, | 1491 IC::kLoadPropertyWithInterceptorOnly); |
| 1514 this->name(), | 1492 |
| 1515 interceptor_holder); | |
| 1516 // Check if interceptor provided a value for property. If it's | 1493 // Check if interceptor provided a value for property. If it's |
| 1517 // the case, return immediately. | 1494 // the case, return immediately. |
| 1518 Label interceptor_failed; | 1495 Label interceptor_failed; |
| 1519 __ LoadRoot(scratch1(), Heap::kNoInterceptorResultSentinelRootIndex); | 1496 __ LoadRoot(scratch1(), Heap::kNoInterceptorResultSentinelRootIndex); |
| 1520 __ Branch(&interceptor_failed, eq, v0, Operand(scratch1())); | 1497 __ Branch(&interceptor_failed, eq, v0, Operand(scratch1())); |
| 1521 frame_scope.GenerateLeaveFrame(); | 1498 frame_scope.GenerateLeaveFrame(); |
| 1522 __ Ret(); | 1499 __ Ret(); |
| 1523 | 1500 |
| 1524 __ bind(&interceptor_failed); | 1501 __ bind(&interceptor_failed); |
| 1525 __ pop(this->name()); | 1502 __ pop(this->name()); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1557 ASSERT(holder->IsGlobalObject()); | 1534 ASSERT(holder->IsGlobalObject()); |
| 1558 | 1535 |
| 1559 // Get the number of arguments. | 1536 // Get the number of arguments. |
| 1560 const int argc = arguments().immediate(); | 1537 const int argc = arguments().immediate(); |
| 1561 | 1538 |
| 1562 // Get the receiver from the stack. | 1539 // Get the receiver from the stack. |
| 1563 __ lw(a0, MemOperand(sp, argc * kPointerSize)); | 1540 __ lw(a0, MemOperand(sp, argc * kPointerSize)); |
| 1564 | 1541 |
| 1565 // Check that the maps haven't changed. | 1542 // Check that the maps haven't changed. |
| 1566 __ JumpIfSmi(a0, miss); | 1543 __ JumpIfSmi(a0, miss); |
| 1567 CheckPrototypes(object, a0, holder, a3, a1, t0, name, miss); | 1544 CheckPrototypes( |
| 1545 IC::CurrentTypeOf(object, isolate()), a0, holder, a3, a1, t0, name, miss); |
| 1568 } | 1546 } |
| 1569 | 1547 |
| 1570 | 1548 |
| 1571 void CallStubCompiler::GenerateLoadFunctionFromCell( | 1549 void CallStubCompiler::GenerateLoadFunctionFromCell( |
| 1572 Handle<Cell> cell, | 1550 Handle<Cell> cell, |
| 1573 Handle<JSFunction> function, | 1551 Handle<JSFunction> function, |
| 1574 Label* miss) { | 1552 Label* miss) { |
| 1575 // Get the value from the cell. | 1553 // Get the value from the cell. |
| 1576 __ li(a3, Operand(cell)); | 1554 __ li(a3, Operand(cell)); |
| 1577 __ lw(a1, FieldMemOperand(a3, Cell::kValueOffset)); | 1555 __ lw(a1, FieldMemOperand(a3, Cell::kValueOffset)); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1619 GenerateNameCheck(name, &miss); | 1597 GenerateNameCheck(name, &miss); |
| 1620 | 1598 |
| 1621 const int argc = arguments().immediate(); | 1599 const int argc = arguments().immediate(); |
| 1622 | 1600 |
| 1623 // Get the receiver of the function from the stack into a0. | 1601 // Get the receiver of the function from the stack into a0. |
| 1624 __ lw(a0, MemOperand(sp, argc * kPointerSize)); | 1602 __ lw(a0, MemOperand(sp, argc * kPointerSize)); |
| 1625 // Check that the receiver isn't a smi. | 1603 // Check that the receiver isn't a smi. |
| 1626 __ JumpIfSmi(a0, &miss, t0); | 1604 __ JumpIfSmi(a0, &miss, t0); |
| 1627 | 1605 |
| 1628 // Do the right check and compute the holder register. | 1606 // Do the right check and compute the holder register. |
| 1629 Register reg = CheckPrototypes(object, a0, holder, a1, a3, t0, name, &miss); | 1607 Register reg = CheckPrototypes( |
| 1608 IC::CurrentTypeOf(object, isolate()), |
| 1609 a0, holder, a1, a3, t0, name, &miss); |
| 1630 GenerateFastPropertyLoad(masm(), a1, reg, index.is_inobject(holder), | 1610 GenerateFastPropertyLoad(masm(), a1, reg, index.is_inobject(holder), |
| 1631 index.translate(holder), Representation::Tagged()); | 1611 index.translate(holder), Representation::Tagged()); |
| 1632 | 1612 |
| 1633 GenerateCallFunction(masm(), object, arguments(), &miss, extra_state_); | 1613 GenerateCallFunction(masm(), object, arguments(), &miss, extra_state_); |
| 1634 | 1614 |
| 1635 // Handle call cache miss. | 1615 // Handle call cache miss. |
| 1636 __ bind(&miss); | 1616 __ bind(&miss); |
| 1637 GenerateMissBranch(); | 1617 GenerateMissBranch(); |
| 1638 | 1618 |
| 1639 // Return the generated code. | 1619 // Return the generated code. |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1655 GenerateNameCheck(name, &miss); | 1635 GenerateNameCheck(name, &miss); |
| 1656 Register receiver = a1; | 1636 Register receiver = a1; |
| 1657 | 1637 |
| 1658 if (cell.is_null()) { | 1638 if (cell.is_null()) { |
| 1659 __ lw(receiver, MemOperand(sp, argc * kPointerSize)); | 1639 __ lw(receiver, MemOperand(sp, argc * kPointerSize)); |
| 1660 | 1640 |
| 1661 // Check that the receiver isn't a smi. | 1641 // Check that the receiver isn't a smi. |
| 1662 __ JumpIfSmi(receiver, &miss); | 1642 __ JumpIfSmi(receiver, &miss); |
| 1663 | 1643 |
| 1664 // Check that the maps haven't changed. | 1644 // Check that the maps haven't changed. |
| 1665 CheckPrototypes(Handle<JSObject>::cast(object), receiver, holder, a3, a0, | 1645 CheckPrototypes( |
| 1666 t0, name, &miss); | 1646 IC::CurrentTypeOf(object, isolate()), receiver, holder, |
| 1647 a3, a0, t0, name, &miss); |
| 1667 } else { | 1648 } else { |
| 1668 ASSERT(cell->value() == *function); | 1649 ASSERT(cell->value() == *function); |
| 1669 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name, | 1650 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name, |
| 1670 &miss); | 1651 &miss); |
| 1671 GenerateLoadFunctionFromCell(cell, function, &miss); | 1652 GenerateLoadFunctionFromCell(cell, function, &miss); |
| 1672 } | 1653 } |
| 1673 | 1654 |
| 1674 Handle<AllocationSite> site = isolate()->factory()->NewAllocationSite(); | 1655 Handle<AllocationSite> site = isolate()->factory()->NewAllocationSite(); |
| 1675 site->SetElementsKind(GetInitialFastElementsKind()); | 1656 site->SetElementsKind(GetInitialFastElementsKind()); |
| 1676 Handle<Cell> site_feedback_cell = isolate()->factory()->NewCell(site); | 1657 Handle<Cell> site_feedback_cell = isolate()->factory()->NewCell(site); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1718 Register receiver = a1; | 1699 Register receiver = a1; |
| 1719 | 1700 |
| 1720 // Get the receiver from the stack. | 1701 // Get the receiver from the stack. |
| 1721 const int argc = arguments().immediate(); | 1702 const int argc = arguments().immediate(); |
| 1722 __ lw(receiver, MemOperand(sp, argc * kPointerSize)); | 1703 __ lw(receiver, MemOperand(sp, argc * kPointerSize)); |
| 1723 | 1704 |
| 1724 // Check that the receiver isn't a smi. | 1705 // Check that the receiver isn't a smi. |
| 1725 __ JumpIfSmi(receiver, &miss); | 1706 __ JumpIfSmi(receiver, &miss); |
| 1726 | 1707 |
| 1727 // Check that the maps haven't changed. | 1708 // Check that the maps haven't changed. |
| 1728 CheckPrototypes(Handle<JSObject>::cast(object), receiver, holder, a3, v0, t0, | 1709 CheckPrototypes( |
| 1729 name, &miss); | 1710 IC::CurrentTypeOf(object, isolate()), receiver, holder, |
| 1711 a3, v0, t0, name, &miss); |
| 1730 | 1712 |
| 1731 if (argc == 0) { | 1713 if (argc == 0) { |
| 1732 // Nothing to do, just return the length. | 1714 // Nothing to do, just return the length. |
| 1733 __ lw(v0, FieldMemOperand(receiver, JSArray::kLengthOffset)); | 1715 __ lw(v0, FieldMemOperand(receiver, JSArray::kLengthOffset)); |
| 1734 __ DropAndRet(argc + 1); | 1716 __ DropAndRet(argc + 1); |
| 1735 } else { | 1717 } else { |
| 1736 Label call_builtin; | 1718 Label call_builtin; |
| 1737 if (argc == 1) { // Otherwise fall through to call the builtin. | 1719 if (argc == 1) { // Otherwise fall through to call the builtin. |
| 1738 Label attempt_to_grow_elements, with_write_barrier, check_double; | 1720 Label attempt_to_grow_elements, with_write_barrier, check_double; |
| 1739 | 1721 |
| (...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1975 Register elements = a3; | 1957 Register elements = a3; |
| 1976 GenerateNameCheck(name, &miss); | 1958 GenerateNameCheck(name, &miss); |
| 1977 | 1959 |
| 1978 // Get the receiver from the stack. | 1960 // Get the receiver from the stack. |
| 1979 const int argc = arguments().immediate(); | 1961 const int argc = arguments().immediate(); |
| 1980 __ lw(receiver, MemOperand(sp, argc * kPointerSize)); | 1962 __ lw(receiver, MemOperand(sp, argc * kPointerSize)); |
| 1981 // Check that the receiver isn't a smi. | 1963 // Check that the receiver isn't a smi. |
| 1982 __ JumpIfSmi(receiver, &miss); | 1964 __ JumpIfSmi(receiver, &miss); |
| 1983 | 1965 |
| 1984 // Check that the maps haven't changed. | 1966 // Check that the maps haven't changed. |
| 1985 CheckPrototypes(Handle<JSObject>::cast(object), receiver, holder, elements, | 1967 CheckPrototypes( |
| 1986 t0, v0, name, &miss); | 1968 IC::CurrentTypeOf(object, isolate()), receiver, holder, |
| 1969 elements, t0, v0, name, &miss); |
| 1987 | 1970 |
| 1988 // Get the elements array of the object. | 1971 // Get the elements array of the object. |
| 1989 __ lw(elements, FieldMemOperand(receiver, JSArray::kElementsOffset)); | 1972 __ lw(elements, FieldMemOperand(receiver, JSArray::kElementsOffset)); |
| 1990 | 1973 |
| 1991 // Check that the elements are in fast mode and writable. | 1974 // Check that the elements are in fast mode and writable. |
| 1992 __ CheckMap(elements, | 1975 __ CheckMap(elements, |
| 1993 v0, | 1976 v0, |
| 1994 Heap::kFixedArrayMapRootIndex, | 1977 Heap::kFixedArrayMapRootIndex, |
| 1995 &call_builtin, | 1978 &call_builtin, |
| 1996 DONT_DO_SMI_CHECK); | 1979 DONT_DO_SMI_CHECK); |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2067 } | 2050 } |
| 2068 | 2051 |
| 2069 GenerateNameCheck(name, &name_miss); | 2052 GenerateNameCheck(name, &name_miss); |
| 2070 | 2053 |
| 2071 // Check that the maps starting from the prototype haven't changed. | 2054 // Check that the maps starting from the prototype haven't changed. |
| 2072 GenerateDirectLoadGlobalFunctionPrototype(masm(), | 2055 GenerateDirectLoadGlobalFunctionPrototype(masm(), |
| 2073 Context::STRING_FUNCTION_INDEX, | 2056 Context::STRING_FUNCTION_INDEX, |
| 2074 v0, | 2057 v0, |
| 2075 &miss); | 2058 &miss); |
| 2076 ASSERT(!object.is_identical_to(holder)); | 2059 ASSERT(!object.is_identical_to(holder)); |
| 2060 Handle<JSObject> prototype(JSObject::cast(object->GetPrototype(isolate()))); |
| 2077 CheckPrototypes( | 2061 CheckPrototypes( |
| 2078 Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))), | 2062 IC::CurrentTypeOf(prototype, isolate()), |
| 2079 v0, holder, a1, a3, t0, name, &miss); | 2063 v0, holder, a1, a3, t0, name, &miss); |
| 2080 | 2064 |
| 2081 Register receiver = a1; | 2065 Register receiver = a1; |
| 2082 Register index = t1; | 2066 Register index = t1; |
| 2083 Register result = v0; | 2067 Register result = v0; |
| 2084 __ lw(receiver, MemOperand(sp, argc * kPointerSize)); | 2068 __ lw(receiver, MemOperand(sp, argc * kPointerSize)); |
| 2085 if (argc > 0) { | 2069 if (argc > 0) { |
| 2086 __ lw(index, MemOperand(sp, (argc - 1) * kPointerSize)); | 2070 __ lw(index, MemOperand(sp, (argc - 1) * kPointerSize)); |
| 2087 } else { | 2071 } else { |
| 2088 __ LoadRoot(index, Heap::kUndefinedValueRootIndex); | 2072 __ LoadRoot(index, Heap::kUndefinedValueRootIndex); |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2147 index_out_of_range_label = &miss; | 2131 index_out_of_range_label = &miss; |
| 2148 } | 2132 } |
| 2149 GenerateNameCheck(name, &name_miss); | 2133 GenerateNameCheck(name, &name_miss); |
| 2150 | 2134 |
| 2151 // Check that the maps starting from the prototype haven't changed. | 2135 // Check that the maps starting from the prototype haven't changed. |
| 2152 GenerateDirectLoadGlobalFunctionPrototype(masm(), | 2136 GenerateDirectLoadGlobalFunctionPrototype(masm(), |
| 2153 Context::STRING_FUNCTION_INDEX, | 2137 Context::STRING_FUNCTION_INDEX, |
| 2154 v0, | 2138 v0, |
| 2155 &miss); | 2139 &miss); |
| 2156 ASSERT(!object.is_identical_to(holder)); | 2140 ASSERT(!object.is_identical_to(holder)); |
| 2141 Handle<JSObject> prototype(JSObject::cast(object->GetPrototype(isolate()))); |
| 2157 CheckPrototypes( | 2142 CheckPrototypes( |
| 2158 Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))), | 2143 IC::CurrentTypeOf(prototype, isolate()), |
| 2159 v0, holder, a1, a3, t0, name, &miss); | 2144 v0, holder, a1, a3, t0, name, &miss); |
| 2160 | 2145 |
| 2161 Register receiver = v0; | 2146 Register receiver = v0; |
| 2162 Register index = t1; | 2147 Register index = t1; |
| 2163 Register scratch = a3; | 2148 Register scratch = a3; |
| 2164 Register result = v0; | 2149 Register result = v0; |
| 2165 __ lw(receiver, MemOperand(sp, argc * kPointerSize)); | 2150 __ lw(receiver, MemOperand(sp, argc * kPointerSize)); |
| 2166 if (argc > 0) { | 2151 if (argc > 0) { |
| 2167 __ lw(index, MemOperand(sp, (argc - 1) * kPointerSize)); | 2152 __ lw(index, MemOperand(sp, (argc - 1) * kPointerSize)); |
| 2168 } else { | 2153 } else { |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2223 | 2208 |
| 2224 Label miss; | 2209 Label miss; |
| 2225 GenerateNameCheck(name, &miss); | 2210 GenerateNameCheck(name, &miss); |
| 2226 | 2211 |
| 2227 if (cell.is_null()) { | 2212 if (cell.is_null()) { |
| 2228 __ lw(a1, MemOperand(sp, 1 * kPointerSize)); | 2213 __ lw(a1, MemOperand(sp, 1 * kPointerSize)); |
| 2229 | 2214 |
| 2230 STATIC_ASSERT(kSmiTag == 0); | 2215 STATIC_ASSERT(kSmiTag == 0); |
| 2231 __ JumpIfSmi(a1, &miss); | 2216 __ JumpIfSmi(a1, &miss); |
| 2232 | 2217 |
| 2233 CheckPrototypes(Handle<JSObject>::cast(object), a1, holder, v0, a3, t0, | 2218 CheckPrototypes( |
| 2234 name, &miss); | 2219 IC::CurrentTypeOf(object, isolate()), |
| 2220 a1, holder, v0, a3, t0, name, &miss); |
| 2235 } else { | 2221 } else { |
| 2236 ASSERT(cell->value() == *function); | 2222 ASSERT(cell->value() == *function); |
| 2237 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name, | 2223 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name, |
| 2238 &miss); | 2224 &miss); |
| 2239 GenerateLoadFunctionFromCell(cell, function, &miss); | 2225 GenerateLoadFunctionFromCell(cell, function, &miss); |
| 2240 } | 2226 } |
| 2241 | 2227 |
| 2242 // Load the char code argument. | 2228 // Load the char code argument. |
| 2243 Register code = a1; | 2229 Register code = a1; |
| 2244 __ lw(code, MemOperand(sp, 0 * kPointerSize)); | 2230 __ lw(code, MemOperand(sp, 0 * kPointerSize)); |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2295 // arguments, bail out to the regular call. | 2281 // arguments, bail out to the regular call. |
| 2296 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null(); | 2282 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null(); |
| 2297 | 2283 |
| 2298 Label miss, slow; | 2284 Label miss, slow; |
| 2299 GenerateNameCheck(name, &miss); | 2285 GenerateNameCheck(name, &miss); |
| 2300 | 2286 |
| 2301 if (cell.is_null()) { | 2287 if (cell.is_null()) { |
| 2302 __ lw(a1, MemOperand(sp, 1 * kPointerSize)); | 2288 __ lw(a1, MemOperand(sp, 1 * kPointerSize)); |
| 2303 STATIC_ASSERT(kSmiTag == 0); | 2289 STATIC_ASSERT(kSmiTag == 0); |
| 2304 __ JumpIfSmi(a1, &miss); | 2290 __ JumpIfSmi(a1, &miss); |
| 2305 CheckPrototypes(Handle<JSObject>::cast(object), a1, holder, a0, a3, t0, | 2291 CheckPrototypes( |
| 2306 name, &miss); | 2292 IC::CurrentTypeOf(object, isolate()), |
| 2293 a1, holder, a0, a3, t0, name, &miss); |
| 2307 } else { | 2294 } else { |
| 2308 ASSERT(cell->value() == *function); | 2295 ASSERT(cell->value() == *function); |
| 2309 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name, | 2296 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name, |
| 2310 &miss); | 2297 &miss); |
| 2311 GenerateLoadFunctionFromCell(cell, function, &miss); | 2298 GenerateLoadFunctionFromCell(cell, function, &miss); |
| 2312 } | 2299 } |
| 2313 | 2300 |
| 2314 // Load the (only) argument into v0. | 2301 // Load the (only) argument into v0. |
| 2315 __ lw(v0, MemOperand(sp, 0 * kPointerSize)); | 2302 __ lw(v0, MemOperand(sp, 0 * kPointerSize)); |
| 2316 | 2303 |
| 2317 // If the argument is a smi, just return. | 2304 // If the argument is a smi, just return. |
| 2318 STATIC_ASSERT(kSmiTag == 0); | 2305 STATIC_ASSERT(kSmiTag == 0); |
| 2319 __ And(t0, v0, Operand(kSmiTagMask)); | 2306 __ SmiTst(v0, t0); |
| 2320 __ DropAndRet(argc + 1, eq, t0, Operand(zero_reg)); | 2307 __ DropAndRet(argc + 1, eq, t0, Operand(zero_reg)); |
| 2321 | 2308 |
| 2322 __ CheckMap(v0, a1, Heap::kHeapNumberMapRootIndex, &slow, DONT_DO_SMI_CHECK); | 2309 __ CheckMap(v0, a1, Heap::kHeapNumberMapRootIndex, &slow, DONT_DO_SMI_CHECK); |
| 2323 | 2310 |
| 2324 Label wont_fit_smi, no_fpu_error, restore_fcsr_and_return; | 2311 Label wont_fit_smi, no_fpu_error, restore_fcsr_and_return; |
| 2325 | 2312 |
| 2326 // If fpu is enabled, we use the floor instruction. | 2313 // If fpu is enabled, we use the floor instruction. |
| 2327 | 2314 |
| 2328 // Load the HeapNumber value. | 2315 // Load the HeapNumber value. |
| 2329 __ ldc1(f0, FieldMemOperand(v0, HeapNumber::kValueOffset)); | 2316 __ ldc1(f0, FieldMemOperand(v0, HeapNumber::kValueOffset)); |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2424 // arguments, bail out to the regular call. | 2411 // arguments, bail out to the regular call. |
| 2425 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null(); | 2412 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null(); |
| 2426 | 2413 |
| 2427 Label miss; | 2414 Label miss; |
| 2428 | 2415 |
| 2429 GenerateNameCheck(name, &miss); | 2416 GenerateNameCheck(name, &miss); |
| 2430 if (cell.is_null()) { | 2417 if (cell.is_null()) { |
| 2431 __ lw(a1, MemOperand(sp, 1 * kPointerSize)); | 2418 __ lw(a1, MemOperand(sp, 1 * kPointerSize)); |
| 2432 STATIC_ASSERT(kSmiTag == 0); | 2419 STATIC_ASSERT(kSmiTag == 0); |
| 2433 __ JumpIfSmi(a1, &miss); | 2420 __ JumpIfSmi(a1, &miss); |
| 2434 CheckPrototypes(Handle<JSObject>::cast(object), a1, holder, v0, a3, t0, | 2421 CheckPrototypes( |
| 2435 name, &miss); | 2422 IC::CurrentTypeOf(object, isolate()), |
| 2423 a1, holder, v0, a3, t0, name, &miss); |
| 2436 } else { | 2424 } else { |
| 2437 ASSERT(cell->value() == *function); | 2425 ASSERT(cell->value() == *function); |
| 2438 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name, | 2426 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name, |
| 2439 &miss); | 2427 &miss); |
| 2440 GenerateLoadFunctionFromCell(cell, function, &miss); | 2428 GenerateLoadFunctionFromCell(cell, function, &miss); |
| 2441 } | 2429 } |
| 2442 | 2430 |
| 2443 // Load the (only) argument into v0. | 2431 // Load the (only) argument into v0. |
| 2444 __ lw(v0, MemOperand(sp, 0 * kPointerSize)); | 2432 __ lw(v0, MemOperand(sp, 0 * kPointerSize)); |
| 2445 | 2433 |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2534 | 2522 |
| 2535 // Check that the receiver isn't a smi. | 2523 // Check that the receiver isn't a smi. |
| 2536 __ JumpIfSmi(a1, &miss_before_stack_reserved); | 2524 __ JumpIfSmi(a1, &miss_before_stack_reserved); |
| 2537 | 2525 |
| 2538 __ IncrementCounter(counters->call_const(), 1, a0, a3); | 2526 __ IncrementCounter(counters->call_const(), 1, a0, a3); |
| 2539 __ IncrementCounter(counters->call_const_fast_api(), 1, a0, a3); | 2527 __ IncrementCounter(counters->call_const_fast_api(), 1, a0, a3); |
| 2540 | 2528 |
| 2541 ReserveSpaceForFastApiCall(masm(), a0); | 2529 ReserveSpaceForFastApiCall(masm(), a0); |
| 2542 | 2530 |
| 2543 // Check that the maps haven't changed and find a Holder as a side effect. | 2531 // Check that the maps haven't changed and find a Holder as a side effect. |
| 2544 CheckPrototypes(Handle<JSObject>::cast(object), a1, holder, a0, a3, t0, name, | 2532 CheckPrototypes( |
| 2545 depth, &miss); | 2533 IC::CurrentTypeOf(object, isolate()), |
| 2534 a1, holder, a0, a3, t0, name, depth, &miss); |
| 2546 | 2535 |
| 2547 GenerateFastApiDirectCall(masm(), optimization, argc, false); | 2536 GenerateFastApiDirectCall(masm(), optimization, argc, false); |
| 2548 | 2537 |
| 2549 __ bind(&miss); | 2538 __ bind(&miss); |
| 2550 FreeSpaceForFastApiCall(masm()); | 2539 FreeSpaceForFastApiCall(masm()); |
| 2551 | 2540 |
| 2552 __ bind(&miss_before_stack_reserved); | 2541 __ bind(&miss_before_stack_reserved); |
| 2553 GenerateMissBranch(); | 2542 GenerateMissBranch(); |
| 2554 | 2543 |
| 2555 // Return the generated code. | 2544 // Return the generated code. |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2589 } | 2578 } |
| 2590 | 2579 |
| 2591 // Make sure that it's okay not to patch the on stack receiver | 2580 // Make sure that it's okay not to patch the on stack receiver |
| 2592 // unless we're doing a receiver map check. | 2581 // unless we're doing a receiver map check. |
| 2593 ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK); | 2582 ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK); |
| 2594 switch (check) { | 2583 switch (check) { |
| 2595 case RECEIVER_MAP_CHECK: | 2584 case RECEIVER_MAP_CHECK: |
| 2596 __ IncrementCounter(isolate()->counters()->call_const(), 1, a0, a3); | 2585 __ IncrementCounter(isolate()->counters()->call_const(), 1, a0, a3); |
| 2597 | 2586 |
| 2598 // Check that the maps haven't changed. | 2587 // Check that the maps haven't changed. |
| 2599 CheckPrototypes(Handle<JSObject>::cast(object), a1, holder, a0, a3, t0, | 2588 CheckPrototypes( |
| 2600 name, &miss); | 2589 IC::CurrentTypeOf(object, isolate()), |
| 2590 a1, holder, a0, a3, t0, name, &miss); |
| 2601 | 2591 |
| 2602 // Patch the receiver on the stack with the global proxy if | 2592 // Patch the receiver on the stack with the global proxy if |
| 2603 // necessary. | 2593 // necessary. |
| 2604 if (object->IsGlobalObject()) { | 2594 if (object->IsGlobalObject()) { |
| 2605 __ lw(a3, FieldMemOperand(a1, GlobalObject::kGlobalReceiverOffset)); | 2595 __ lw(a3, FieldMemOperand(a1, GlobalObject::kGlobalReceiverOffset)); |
| 2606 __ sw(a3, MemOperand(sp, argc * kPointerSize)); | 2596 __ sw(a3, MemOperand(sp, argc * kPointerSize)); |
| 2607 } | 2597 } |
| 2608 break; | 2598 break; |
| 2609 | 2599 |
| 2610 case STRING_CHECK: | 2600 case STRING_CHECK: { |
| 2611 // Check that the object is a string. | 2601 // Check that the object is a string. |
| 2612 __ GetObjectType(a1, a3, a3); | 2602 __ GetObjectType(a1, a3, a3); |
| 2613 __ Branch(&miss, Ugreater_equal, a3, Operand(FIRST_NONSTRING_TYPE)); | 2603 __ Branch(&miss, Ugreater_equal, a3, Operand(FIRST_NONSTRING_TYPE)); |
| 2614 // Check that the maps starting from the prototype haven't changed. | 2604 // Check that the maps starting from the prototype haven't changed. |
| 2615 GenerateDirectLoadGlobalFunctionPrototype( | 2605 GenerateDirectLoadGlobalFunctionPrototype( |
| 2616 masm(), Context::STRING_FUNCTION_INDEX, a0, &miss); | 2606 masm(), Context::STRING_FUNCTION_INDEX, a0, &miss); |
| 2607 Handle<Object> prototype(object->GetPrototype(isolate()), isolate()); |
| 2617 CheckPrototypes( | 2608 CheckPrototypes( |
| 2618 Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))), | 2609 IC::CurrentTypeOf(prototype, isolate()), |
| 2619 a0, holder, a3, a1, t0, name, &miss); | 2610 a0, holder, a3, a1, t0, name, &miss); |
| 2620 break; | 2611 break; |
| 2621 | 2612 } |
| 2622 case SYMBOL_CHECK: | 2613 case SYMBOL_CHECK: { |
| 2623 // Check that the object is a symbol. | 2614 // Check that the object is a symbol. |
| 2624 __ GetObjectType(a1, a1, a3); | 2615 __ GetObjectType(a1, a1, a3); |
| 2625 __ Branch(&miss, ne, a3, Operand(SYMBOL_TYPE)); | 2616 __ Branch(&miss, ne, a3, Operand(SYMBOL_TYPE)); |
| 2626 // Check that the maps starting from the prototype haven't changed. | 2617 // Check that the maps starting from the prototype haven't changed. |
| 2627 GenerateDirectLoadGlobalFunctionPrototype( | 2618 GenerateDirectLoadGlobalFunctionPrototype( |
| 2628 masm(), Context::SYMBOL_FUNCTION_INDEX, a0, &miss); | 2619 masm(), Context::SYMBOL_FUNCTION_INDEX, a0, &miss); |
| 2620 Handle<Object> prototype(object->GetPrototype(isolate()), isolate()); |
| 2629 CheckPrototypes( | 2621 CheckPrototypes( |
| 2630 Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))), | 2622 IC::CurrentTypeOf(prototype, isolate()), |
| 2631 a0, holder, a3, a1, t0, name, &miss); | 2623 a0, holder, a3, a1, t0, name, &miss); |
| 2632 break; | 2624 break; |
| 2633 | 2625 } |
| 2634 case NUMBER_CHECK: { | 2626 case NUMBER_CHECK: { |
| 2635 Label fast; | 2627 Label fast; |
| 2636 // Check that the object is a smi or a heap number. | 2628 // Check that the object is a smi or a heap number. |
| 2637 __ JumpIfSmi(a1, &fast); | 2629 __ JumpIfSmi(a1, &fast); |
| 2638 __ GetObjectType(a1, a0, a0); | 2630 __ GetObjectType(a1, a0, a0); |
| 2639 __ Branch(&miss, ne, a0, Operand(HEAP_NUMBER_TYPE)); | 2631 __ Branch(&miss, ne, a0, Operand(HEAP_NUMBER_TYPE)); |
| 2640 __ bind(&fast); | 2632 __ bind(&fast); |
| 2641 // Check that the maps starting from the prototype haven't changed. | 2633 // Check that the maps starting from the prototype haven't changed. |
| 2642 GenerateDirectLoadGlobalFunctionPrototype( | 2634 GenerateDirectLoadGlobalFunctionPrototype( |
| 2643 masm(), Context::NUMBER_FUNCTION_INDEX, a0, &miss); | 2635 masm(), Context::NUMBER_FUNCTION_INDEX, a0, &miss); |
| 2636 Handle<Object> prototype(object->GetPrototype(isolate()), isolate()); |
| 2644 CheckPrototypes( | 2637 CheckPrototypes( |
| 2645 Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))), | 2638 IC::CurrentTypeOf(prototype, isolate()), |
| 2646 a0, holder, a3, a1, t0, name, &miss); | 2639 a0, holder, a3, a1, t0, name, &miss); |
| 2647 break; | 2640 break; |
| 2648 } | 2641 } |
| 2649 case BOOLEAN_CHECK: { | 2642 case BOOLEAN_CHECK: { |
| 2650 GenerateBooleanCheck(a1, &miss); | 2643 GenerateBooleanCheck(a1, &miss); |
| 2651 | 2644 |
| 2652 // Check that the maps starting from the prototype haven't changed. | 2645 // Check that the maps starting from the prototype haven't changed. |
| 2653 GenerateDirectLoadGlobalFunctionPrototype( | 2646 GenerateDirectLoadGlobalFunctionPrototype( |
| 2654 masm(), Context::BOOLEAN_FUNCTION_INDEX, a0, &miss); | 2647 masm(), Context::BOOLEAN_FUNCTION_INDEX, a0, &miss); |
| 2648 Handle<Object> prototype(object->GetPrototype(isolate()), isolate()); |
| 2655 CheckPrototypes( | 2649 CheckPrototypes( |
| 2656 Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))), | 2650 IC::CurrentTypeOf(prototype, isolate()), |
| 2657 a0, holder, a3, a1, t0, name, &miss); | 2651 a0, holder, a3, a1, t0, name, &miss); |
| 2658 break; | 2652 break; |
| 2659 } | 2653 } |
| 2660 } | 2654 } |
| 2661 | 2655 |
| 2662 Label success; | 2656 Label success; |
| 2663 __ Branch(&success); | 2657 __ Branch(&success); |
| 2664 | 2658 |
| 2665 // Handle call cache miss. | 2659 // Handle call cache miss. |
| 2666 __ bind(&miss); | 2660 __ bind(&miss); |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2803 // Return the generated code. | 2797 // Return the generated code. |
| 2804 return GetCode(Code::NORMAL, name); | 2798 return GetCode(Code::NORMAL, name); |
| 2805 } | 2799 } |
| 2806 | 2800 |
| 2807 | 2801 |
| 2808 Handle<Code> StoreStubCompiler::CompileStoreCallback( | 2802 Handle<Code> StoreStubCompiler::CompileStoreCallback( |
| 2809 Handle<JSObject> object, | 2803 Handle<JSObject> object, |
| 2810 Handle<JSObject> holder, | 2804 Handle<JSObject> holder, |
| 2811 Handle<Name> name, | 2805 Handle<Name> name, |
| 2812 Handle<ExecutableAccessorInfo> callback) { | 2806 Handle<ExecutableAccessorInfo> callback) { |
| 2813 HandlerFrontend(object, receiver(), holder, name); | 2807 HandlerFrontend(IC::CurrentTypeOf(object, isolate()), |
| 2808 receiver(), holder, name); |
| 2814 | 2809 |
| 2815 // Stub never generated for non-global objects that require access | 2810 // Stub never generated for non-global objects that require access |
| 2816 // checks. | 2811 // checks. |
| 2817 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded()); | 2812 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded()); |
| 2818 | 2813 |
| 2819 __ push(receiver()); // Receiver. | 2814 __ push(receiver()); // Receiver. |
| 2820 __ li(at, Operand(callback)); // Callback info. | 2815 __ li(at, Operand(callback)); // Callback info. |
| 2821 __ push(at); | 2816 __ push(at); |
| 2822 __ li(at, Operand(name)); | 2817 __ li(at, Operand(name)); |
| 2823 __ Push(at, value()); | 2818 __ Push(at, value()); |
| 2824 | 2819 |
| 2825 // Do tail-call to the runtime system. | 2820 // Do tail-call to the runtime system. |
| 2826 ExternalReference store_callback_property = | 2821 ExternalReference store_callback_property = |
| 2827 ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate()); | 2822 ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate()); |
| 2828 __ TailCallExternalReference(store_callback_property, 4, 1); | 2823 __ TailCallExternalReference(store_callback_property, 4, 1); |
| 2829 | 2824 |
| 2830 // Return the generated code. | 2825 // Return the generated code. |
| 2831 return GetCode(kind(), Code::FAST, name); | 2826 return GetCode(kind(), Code::FAST, name); |
| 2832 } | 2827 } |
| 2833 | 2828 |
| 2834 | 2829 |
| 2835 Handle<Code> StoreStubCompiler::CompileStoreCallback( | 2830 Handle<Code> StoreStubCompiler::CompileStoreCallback( |
| 2836 Handle<JSObject> object, | 2831 Handle<JSObject> object, |
| 2837 Handle<JSObject> holder, | 2832 Handle<JSObject> holder, |
| 2838 Handle<Name> name, | 2833 Handle<Name> name, |
| 2839 const CallOptimization& call_optimization) { | 2834 const CallOptimization& call_optimization) { |
| 2840 HandlerFrontend(object, receiver(), holder, name); | 2835 HandlerFrontend(IC::CurrentTypeOf(object, isolate()), |
| 2836 receiver(), holder, name); |
| 2841 | 2837 |
| 2842 Register values[] = { value() }; | 2838 Register values[] = { value() }; |
| 2843 GenerateFastApiCall( | 2839 GenerateFastApiCall( |
| 2844 masm(), call_optimization, receiver(), scratch3(), 1, values); | 2840 masm(), call_optimization, receiver(), scratch3(), 1, values); |
| 2845 | 2841 |
| 2846 // Return the generated code. | 2842 // Return the generated code. |
| 2847 return GetCode(kind(), Code::FAST, name); | 2843 return GetCode(kind(), Code::FAST, name); |
| 2848 } | 2844 } |
| 2849 | 2845 |
| 2850 | 2846 |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2925 | 2921 |
| 2926 // Handle store cache miss. | 2922 // Handle store cache miss. |
| 2927 __ bind(&miss); | 2923 __ bind(&miss); |
| 2928 TailCallBuiltin(masm(), MissBuiltin(kind())); | 2924 TailCallBuiltin(masm(), MissBuiltin(kind())); |
| 2929 | 2925 |
| 2930 // Return the generated code. | 2926 // Return the generated code. |
| 2931 return GetCode(kind(), Code::FAST, name); | 2927 return GetCode(kind(), Code::FAST, name); |
| 2932 } | 2928 } |
| 2933 | 2929 |
| 2934 | 2930 |
| 2935 Handle<Code> LoadStubCompiler::CompileLoadNonexistent( | 2931 Handle<Code> LoadStubCompiler::CompileLoadNonexistent(Handle<Type> type, |
| 2936 Handle<Object> object, | 2932 Handle<JSObject> last, |
| 2937 Handle<JSObject> last, | 2933 Handle<Name> name) { |
| 2938 Handle<Name> name, | 2934 NonexistentHandlerFrontend(type, last, name); |
| 2939 Handle<JSGlobalObject> global) { | |
| 2940 NonexistentHandlerFrontend(object, last, name, global); | |
| 2941 | 2935 |
| 2942 // Return undefined if maps of the full prototype chain is still the same. | 2936 // Return undefined if maps of the full prototype chain is still the same. |
| 2943 __ LoadRoot(v0, Heap::kUndefinedValueRootIndex); | 2937 __ LoadRoot(v0, Heap::kUndefinedValueRootIndex); |
| 2944 __ Ret(); | 2938 __ Ret(); |
| 2945 | 2939 |
| 2946 // Return the generated code. | 2940 // Return the generated code. |
| 2947 return GetCode(kind(), Code::FAST, name); | 2941 return GetCode(kind(), Code::FAST, name); |
| 2948 } | 2942 } |
| 2949 | 2943 |
| 2950 | 2944 |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3023 } | 3017 } |
| 3024 __ Ret(); | 3018 __ Ret(); |
| 3025 } | 3019 } |
| 3026 | 3020 |
| 3027 | 3021 |
| 3028 #undef __ | 3022 #undef __ |
| 3029 #define __ ACCESS_MASM(masm()) | 3023 #define __ ACCESS_MASM(masm()) |
| 3030 | 3024 |
| 3031 | 3025 |
| 3032 Handle<Code> LoadStubCompiler::CompileLoadGlobal( | 3026 Handle<Code> LoadStubCompiler::CompileLoadGlobal( |
| 3033 Handle<Object> object, | 3027 Handle<Type> type, |
| 3034 Handle<GlobalObject> global, | 3028 Handle<GlobalObject> global, |
| 3035 Handle<PropertyCell> cell, | 3029 Handle<PropertyCell> cell, |
| 3036 Handle<Name> name, | 3030 Handle<Name> name, |
| 3037 bool is_dont_delete) { | 3031 bool is_dont_delete) { |
| 3038 Label miss; | 3032 Label miss; |
| 3039 | 3033 |
| 3040 HandlerFrontendHeader(object, receiver(), global, name, &miss); | 3034 HandlerFrontendHeader(type, receiver(), global, name, &miss); |
| 3041 | 3035 |
| 3042 // Get the value from the cell. | 3036 // Get the value from the cell. |
| 3043 __ li(a3, Operand(cell)); | 3037 __ li(a3, Operand(cell)); |
| 3044 __ lw(t0, FieldMemOperand(a3, Cell::kValueOffset)); | 3038 __ lw(t0, FieldMemOperand(a3, Cell::kValueOffset)); |
| 3045 | 3039 |
| 3046 // Check for deleted property if property can actually be deleted. | 3040 // Check for deleted property if property can actually be deleted. |
| 3047 if (!is_dont_delete) { | 3041 if (!is_dont_delete) { |
| 3048 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); | 3042 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); |
| 3049 __ Branch(&miss, eq, t0, Operand(at)); | 3043 __ Branch(&miss, eq, t0, Operand(at)); |
| 3050 } | 3044 } |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3183 // ----------------------------------- | 3177 // ----------------------------------- |
| 3184 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); | 3178 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); |
| 3185 } | 3179 } |
| 3186 | 3180 |
| 3187 | 3181 |
| 3188 #undef __ | 3182 #undef __ |
| 3189 | 3183 |
| 3190 } } // namespace v8::internal | 3184 } } // namespace v8::internal |
| 3191 | 3185 |
| 3192 #endif // V8_TARGET_ARCH_MIPS | 3186 #endif // V8_TARGET_ARCH_MIPS |
| OLD | NEW |