| 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 1020 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1031 __ IncrementCounter(counters->call_const_interceptor_fast_api(), 1, | 1031 __ IncrementCounter(counters->call_const_interceptor_fast_api(), 1, |
| 1032 scratch1, scratch2); | 1032 scratch1, scratch2); |
| 1033 ReserveSpaceForFastApiCall(masm, scratch1); | 1033 ReserveSpaceForFastApiCall(masm, scratch1); |
| 1034 } | 1034 } |
| 1035 | 1035 |
| 1036 // Check that the maps from receiver to interceptor's holder | 1036 // Check that the maps from receiver to interceptor's holder |
| 1037 // haven't changed and thus we can invoke interceptor. | 1037 // haven't changed and thus we can invoke interceptor. |
| 1038 Label miss_cleanup; | 1038 Label miss_cleanup; |
| 1039 Label* miss = can_do_fast_api_call ? &miss_cleanup : miss_label; | 1039 Label* miss = can_do_fast_api_call ? &miss_cleanup : miss_label; |
| 1040 Register holder = | 1040 Register holder = |
| 1041 stub_compiler_->CheckPrototypes(object, receiver, interceptor_holder, | 1041 stub_compiler_->CheckPrototypes( |
| 1042 scratch1, scratch2, scratch3, | 1042 IC::CurrentTypeOf(object, masm->isolate()), receiver, |
| 1043 name, depth1, miss); | 1043 interceptor_holder, scratch1, scratch2, scratch3, |
| 1044 name, depth1, miss); |
| 1044 | 1045 |
| 1045 // Invoke an interceptor and if it provides a value, | 1046 // Invoke an interceptor and if it provides a value, |
| 1046 // branch to |regular_invoke|. | 1047 // branch to |regular_invoke|. |
| 1047 Label regular_invoke; | 1048 Label regular_invoke; |
| 1048 LoadWithInterceptor(masm, receiver, holder, interceptor_holder, scratch2, | 1049 LoadWithInterceptor(masm, receiver, holder, interceptor_holder, scratch2, |
| 1049 ®ular_invoke); | 1050 ®ular_invoke); |
| 1050 | 1051 |
| 1051 // Interceptor returned nothing for this property. Try to use cached | 1052 // Interceptor returned nothing for this property. Try to use cached |
| 1052 // constant function. | 1053 // constant function. |
| 1053 | 1054 |
| 1054 // Check that the maps from interceptor's holder to constant function's | 1055 // Check that the maps from interceptor's holder to constant function's |
| 1055 // holder haven't changed and thus we can use cached constant function. | 1056 // holder haven't changed and thus we can use cached constant function. |
| 1056 if (*interceptor_holder != lookup->holder()) { | 1057 if (*interceptor_holder != lookup->holder()) { |
| 1057 stub_compiler_->CheckPrototypes(interceptor_holder, receiver, | 1058 stub_compiler_->CheckPrototypes( |
| 1058 Handle<JSObject>(lookup->holder()), | 1059 IC::CurrentTypeOf(interceptor_holder, masm->isolate()), receiver, |
| 1059 scratch1, scratch2, scratch3, | 1060 handle(lookup->holder()), scratch1, scratch2, scratch3, |
| 1060 name, depth2, miss); | 1061 name, depth2, miss); |
| 1061 } else { | 1062 } else { |
| 1062 // CheckPrototypes has a side effect of fetching a 'holder' | 1063 // CheckPrototypes has a side effect of fetching a 'holder' |
| 1063 // for API (object which is instanceof for the signature). It's | 1064 // for API (object which is instanceof for the signature). It's |
| 1064 // safe to omit it here, as if present, it should be fetched | 1065 // safe to omit it here, as if present, it should be fetched |
| 1065 // by the previous CheckPrototypes. | 1066 // by the previous CheckPrototypes. |
| 1066 ASSERT(depth2 == kInvalidProtoDepth); | 1067 ASSERT(depth2 == kInvalidProtoDepth); |
| 1067 } | 1068 } |
| 1068 | 1069 |
| 1069 // Invoke function. | 1070 // Invoke function. |
| 1070 if (can_do_fast_api_call) { | 1071 if (can_do_fast_api_call) { |
| (...skipping 26 matching lines...) Expand all Loading... |
| 1097 void CompileRegular(MacroAssembler* masm, | 1098 void CompileRegular(MacroAssembler* masm, |
| 1098 Handle<JSObject> object, | 1099 Handle<JSObject> object, |
| 1099 Register receiver, | 1100 Register receiver, |
| 1100 Register scratch1, | 1101 Register scratch1, |
| 1101 Register scratch2, | 1102 Register scratch2, |
| 1102 Register scratch3, | 1103 Register scratch3, |
| 1103 Handle<Name> name, | 1104 Handle<Name> name, |
| 1104 Handle<JSObject> interceptor_holder, | 1105 Handle<JSObject> interceptor_holder, |
| 1105 Label* miss_label) { | 1106 Label* miss_label) { |
| 1106 Register holder = | 1107 Register holder = |
| 1107 stub_compiler_->CheckPrototypes(object, receiver, interceptor_holder, | 1108 stub_compiler_->CheckPrototypes( |
| 1108 scratch1, scratch2, scratch3, | 1109 IC::CurrentTypeOf(object, masm->isolate()), receiver, |
| 1109 name, miss_label); | 1110 interceptor_holder, scratch1, scratch2, scratch3, name, miss_label); |
| 1110 | 1111 |
| 1111 // Call a runtime function to load the interceptor property. | 1112 // Call a runtime function to load the interceptor property. |
| 1112 FrameScope scope(masm, StackFrame::INTERNAL); | 1113 FrameScope scope(masm, StackFrame::INTERNAL); |
| 1113 // Save the name_ register across the call. | 1114 // Save the name_ register across the call. |
| 1114 __ push(name_); | 1115 __ push(name_); |
| 1115 PushInterceptorArguments(masm, receiver, holder, name_, interceptor_holder); | 1116 PushInterceptorArguments(masm, receiver, holder, name_, interceptor_holder); |
| 1116 __ CallExternalReference( | 1117 __ CallExternalReference( |
| 1117 ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorForCall), | 1118 ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorForCall), |
| 1118 masm->isolate()), | 1119 masm->isolate()), |
| 1119 StubCache::kInterceptorArgsLength); | 1120 StubCache::kInterceptorArgsLength); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 1145 __ b(ne, interceptor_succeeded); | 1146 __ b(ne, interceptor_succeeded); |
| 1146 } | 1147 } |
| 1147 | 1148 |
| 1148 StubCompiler* stub_compiler_; | 1149 StubCompiler* stub_compiler_; |
| 1149 const ParameterCount& arguments_; | 1150 const ParameterCount& arguments_; |
| 1150 Register name_; | 1151 Register name_; |
| 1151 Code::ExtraICState extra_ic_state_; | 1152 Code::ExtraICState extra_ic_state_; |
| 1152 }; | 1153 }; |
| 1153 | 1154 |
| 1154 | 1155 |
| 1155 void StubCompiler::GenerateCheckPropertyCells(MacroAssembler* masm, | |
| 1156 Handle<JSObject> object, | |
| 1157 Handle<JSObject> holder, | |
| 1158 Handle<Name> name, | |
| 1159 Register scratch, | |
| 1160 Label* miss) { | |
| 1161 Handle<JSObject> current = object; | |
| 1162 while (!current.is_identical_to(holder)) { | |
| 1163 if (current->IsJSGlobalObject()) { | |
| 1164 GenerateCheckPropertyCell(masm, | |
| 1165 Handle<JSGlobalObject>::cast(current), | |
| 1166 name, | |
| 1167 scratch, | |
| 1168 miss); | |
| 1169 } | |
| 1170 current = Handle<JSObject>(JSObject::cast(current->GetPrototype())); | |
| 1171 } | |
| 1172 } | |
| 1173 | |
| 1174 | |
| 1175 void StubCompiler::GenerateTailCall(MacroAssembler* masm, Handle<Code> code) { | 1156 void StubCompiler::GenerateTailCall(MacroAssembler* masm, Handle<Code> code) { |
| 1176 __ Jump(code, RelocInfo::CODE_TARGET); | 1157 __ Jump(code, RelocInfo::CODE_TARGET); |
| 1177 } | 1158 } |
| 1178 | 1159 |
| 1179 | 1160 |
| 1180 #undef __ | 1161 #undef __ |
| 1181 #define __ ACCESS_MASM(masm()) | 1162 #define __ ACCESS_MASM(masm()) |
| 1182 | 1163 |
| 1183 | 1164 |
| 1184 Register StubCompiler::CheckPrototypes(Handle<JSObject> object, | 1165 Register StubCompiler::CheckPrototypes(Handle<Type> type, |
| 1185 Register object_reg, | 1166 Register object_reg, |
| 1186 Handle<JSObject> holder, | 1167 Handle<JSObject> holder, |
| 1187 Register holder_reg, | 1168 Register holder_reg, |
| 1188 Register scratch1, | 1169 Register scratch1, |
| 1189 Register scratch2, | 1170 Register scratch2, |
| 1190 Handle<Name> name, | 1171 Handle<Name> name, |
| 1191 int save_at_depth, | 1172 int save_at_depth, |
| 1192 Label* miss, | 1173 Label* miss, |
| 1193 PrototypeCheckType check) { | 1174 PrototypeCheckType check) { |
| 1175 Handle<Map> receiver_map(IC::TypeToMap(*type, isolate())); |
| 1194 // Make sure that the type feedback oracle harvests the receiver map. | 1176 // Make sure that the type feedback oracle harvests the receiver map. |
| 1195 // TODO(svenpanne) Remove this hack when all ICs are reworked. | 1177 // TODO(svenpanne) Remove this hack when all ICs are reworked. |
| 1196 __ mov(scratch1, Operand(Handle<Map>(object->map()))); | 1178 __ mov(scratch1, Operand(receiver_map)); |
| 1197 | 1179 |
| 1198 Handle<JSObject> first = object; | |
| 1199 // Make sure there's no overlap between holder and object registers. | 1180 // Make sure there's no overlap between holder and object registers. |
| 1200 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); | 1181 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); |
| 1201 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg) | 1182 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg) |
| 1202 && !scratch2.is(scratch1)); | 1183 && !scratch2.is(scratch1)); |
| 1203 | 1184 |
| 1204 // Keep track of the current object in register reg. | 1185 // Keep track of the current object in register reg. |
| 1205 Register reg = object_reg; | 1186 Register reg = object_reg; |
| 1206 int depth = 0; | 1187 int depth = 0; |
| 1207 | 1188 |
| 1208 typedef FunctionCallbackArguments FCA; | 1189 typedef FunctionCallbackArguments FCA; |
| 1209 if (save_at_depth == depth) { | 1190 if (save_at_depth == depth) { |
| 1210 __ str(reg, MemOperand(sp, FCA::kHolderIndex * kPointerSize)); | 1191 __ str(reg, MemOperand(sp, FCA::kHolderIndex * kPointerSize)); |
| 1211 } | 1192 } |
| 1212 | 1193 |
| 1213 // Check the maps in the prototype chain. | 1194 Handle<JSObject> current = Handle<JSObject>::null(); |
| 1214 // Traverse the prototype chain from the object and do map checks. | 1195 if (type->IsConstant()) current = Handle<JSObject>::cast(type->AsConstant()); |
| 1215 Handle<JSObject> current = object; | 1196 Handle<JSObject> prototype = Handle<JSObject>::null(); |
| 1216 while (!current.is_identical_to(holder)) { | 1197 Handle<Map> current_map = receiver_map; |
| 1198 Handle<Map> holder_map(holder->map()); |
| 1199 // Traverse the prototype chain and check the maps in the prototype chain for |
| 1200 // fast and global objects or do negative lookup for normal objects. |
| 1201 while (!current_map.is_identical_to(holder_map)) { |
| 1217 ++depth; | 1202 ++depth; |
| 1218 | 1203 |
| 1219 // Only global objects and objects that do not require access | 1204 // Only global objects and objects that do not require access |
| 1220 // checks are allowed in stubs. | 1205 // checks are allowed in stubs. |
| 1221 ASSERT(current->IsJSGlobalProxy() || !current->IsAccessCheckNeeded()); | 1206 ASSERT(current_map->IsJSGlobalProxyMap() || |
| 1207 !current_map->is_access_check_needed()); |
| 1222 | 1208 |
| 1223 Handle<JSObject> prototype(JSObject::cast(current->GetPrototype())); | 1209 prototype = handle(JSObject::cast(current_map->prototype())); |
| 1224 if (!current->HasFastProperties() && | 1210 if (current_map->is_dictionary_map() && |
| 1225 !current->IsJSGlobalObject() && | 1211 !current_map->IsJSGlobalObjectMap() && |
| 1226 !current->IsJSGlobalProxy()) { | 1212 !current_map->IsJSGlobalProxyMap()) { |
| 1227 if (!name->IsUniqueName()) { | 1213 if (!name->IsUniqueName()) { |
| 1228 ASSERT(name->IsString()); | 1214 ASSERT(name->IsString()); |
| 1229 name = factory()->InternalizeString(Handle<String>::cast(name)); | 1215 name = factory()->InternalizeString(Handle<String>::cast(name)); |
| 1230 } | 1216 } |
| 1231 ASSERT(current->property_dictionary()->FindEntry(*name) == | 1217 ASSERT(current.is_null() || |
| 1218 current->property_dictionary()->FindEntry(*name) == |
| 1232 NameDictionary::kNotFound); | 1219 NameDictionary::kNotFound); |
| 1233 | 1220 |
| 1234 GenerateDictionaryNegativeLookup(masm(), miss, reg, name, | 1221 GenerateDictionaryNegativeLookup(masm(), miss, reg, name, |
| 1235 scratch1, scratch2); | 1222 scratch1, scratch2); |
| 1236 | 1223 |
| 1237 __ ldr(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset)); | 1224 __ ldr(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset)); |
| 1238 reg = holder_reg; // From now on the object will be in holder_reg. | 1225 reg = holder_reg; // From now on the object will be in holder_reg. |
| 1239 __ ldr(reg, FieldMemOperand(scratch1, Map::kPrototypeOffset)); | 1226 __ ldr(reg, FieldMemOperand(scratch1, Map::kPrototypeOffset)); |
| 1240 } else { | 1227 } else { |
| 1241 Register map_reg = scratch1; | 1228 Register map_reg = scratch1; |
| 1242 if (!current.is_identical_to(first) || check == CHECK_ALL_MAPS) { | 1229 if (depth != 1 || check == CHECK_ALL_MAPS) { |
| 1243 Handle<Map> current_map(current->map()); | |
| 1244 // CheckMap implicitly loads the map of |reg| into |map_reg|. | 1230 // CheckMap implicitly loads the map of |reg| into |map_reg|. |
| 1245 __ CheckMap(reg, map_reg, current_map, miss, DONT_DO_SMI_CHECK); | 1231 __ CheckMap(reg, map_reg, current_map, miss, DONT_DO_SMI_CHECK); |
| 1246 } else { | 1232 } else { |
| 1247 __ ldr(map_reg, FieldMemOperand(reg, HeapObject::kMapOffset)); | 1233 __ ldr(map_reg, FieldMemOperand(reg, HeapObject::kMapOffset)); |
| 1248 } | 1234 } |
| 1249 | 1235 |
| 1250 // Check access rights to the global object. This has to happen after | 1236 // Check access rights to the global object. This has to happen after |
| 1251 // the map check so that we know that the object is actually a global | 1237 // the map check so that we know that the object is actually a global |
| 1252 // object. | 1238 // object. |
| 1253 if (current->IsJSGlobalProxy()) { | 1239 if (current_map->IsJSGlobalProxyMap()) { |
| 1254 __ CheckAccessGlobalProxy(reg, scratch2, miss); | 1240 __ CheckAccessGlobalProxy(reg, scratch2, miss); |
| 1241 } else if (current_map->IsJSGlobalObjectMap()) { |
| 1242 GenerateCheckPropertyCell( |
| 1243 masm(), Handle<JSGlobalObject>::cast(current), name, |
| 1244 scratch2, miss); |
| 1255 } | 1245 } |
| 1246 |
| 1256 reg = holder_reg; // From now on the object will be in holder_reg. | 1247 reg = holder_reg; // From now on the object will be in holder_reg. |
| 1257 | 1248 |
| 1258 if (heap()->InNewSpace(*prototype)) { | 1249 if (heap()->InNewSpace(*prototype)) { |
| 1259 // The prototype is in new space; we cannot store a reference to it | 1250 // The prototype is in new space; we cannot store a reference to it |
| 1260 // in the code. Load it from the map. | 1251 // in the code. Load it from the map. |
| 1261 __ ldr(reg, FieldMemOperand(map_reg, Map::kPrototypeOffset)); | 1252 __ ldr(reg, FieldMemOperand(map_reg, Map::kPrototypeOffset)); |
| 1262 } else { | 1253 } else { |
| 1263 // The prototype is in old space; load it directly. | 1254 // The prototype is in old space; load it directly. |
| 1264 __ mov(reg, Operand(prototype)); | 1255 __ mov(reg, Operand(prototype)); |
| 1265 } | 1256 } |
| 1266 } | 1257 } |
| 1267 | 1258 |
| 1268 if (save_at_depth == depth) { | 1259 if (save_at_depth == depth) { |
| 1269 __ str(reg, MemOperand(sp, FCA::kHolderIndex * kPointerSize)); | 1260 __ str(reg, MemOperand(sp, FCA::kHolderIndex * kPointerSize)); |
| 1270 } | 1261 } |
| 1271 | 1262 |
| 1272 // Go to the next object in the prototype chain. | 1263 // Go to the next object in the prototype chain. |
| 1273 current = prototype; | 1264 current = prototype; |
| 1265 current_map = handle(current->map()); |
| 1274 } | 1266 } |
| 1275 | 1267 |
| 1276 // Log the check depth. | 1268 // Log the check depth. |
| 1277 LOG(isolate(), IntEvent("check-maps-depth", depth + 1)); | 1269 LOG(isolate(), IntEvent("check-maps-depth", depth + 1)); |
| 1278 | 1270 |
| 1279 if (!holder.is_identical_to(first) || check == CHECK_ALL_MAPS) { | 1271 if (depth != 0 || check == CHECK_ALL_MAPS) { |
| 1280 // Check the holder map. | 1272 // Check the holder map. |
| 1281 __ CheckMap(reg, scratch1, Handle<Map>(holder->map()), miss, | 1273 __ CheckMap(reg, scratch1, current_map, miss, DONT_DO_SMI_CHECK); |
| 1282 DONT_DO_SMI_CHECK); | |
| 1283 } | 1274 } |
| 1284 | 1275 |
| 1285 // Perform security check for access to the global object. | 1276 // Perform security check for access to the global object. |
| 1286 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded()); | 1277 ASSERT(current_map->IsJSGlobalProxyMap() || |
| 1287 if (holder->IsJSGlobalProxy()) { | 1278 !current_map->is_access_check_needed()); |
| 1279 if (current_map->IsJSGlobalProxyMap()) { |
| 1288 __ CheckAccessGlobalProxy(reg, scratch1, miss); | 1280 __ CheckAccessGlobalProxy(reg, scratch1, miss); |
| 1289 } | 1281 } |
| 1290 | 1282 |
| 1291 // If we've skipped any global objects, it's not enough to verify that | |
| 1292 // their maps haven't changed. We also need to check that the property | |
| 1293 // cell for the property is still empty. | |
| 1294 GenerateCheckPropertyCells(masm(), object, holder, name, scratch1, miss); | |
| 1295 | |
| 1296 // Return the register containing the holder. | 1283 // Return the register containing the holder. |
| 1297 return reg; | 1284 return reg; |
| 1298 } | 1285 } |
| 1299 | 1286 |
| 1300 | 1287 |
| 1301 void LoadStubCompiler::HandlerFrontendFooter(Handle<Name> name, Label* miss) { | 1288 void LoadStubCompiler::HandlerFrontendFooter(Handle<Name> name, Label* miss) { |
| 1302 if (!miss->is_unused()) { | 1289 if (!miss->is_unused()) { |
| 1303 Label success; | 1290 Label success; |
| 1304 __ b(&success); | 1291 __ b(&success); |
| 1305 __ bind(miss); | 1292 __ bind(miss); |
| (...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1569 ASSERT(holder->IsGlobalObject()); | 1556 ASSERT(holder->IsGlobalObject()); |
| 1570 | 1557 |
| 1571 // Get the number of arguments. | 1558 // Get the number of arguments. |
| 1572 const int argc = arguments().immediate(); | 1559 const int argc = arguments().immediate(); |
| 1573 | 1560 |
| 1574 // Get the receiver from the stack. | 1561 // Get the receiver from the stack. |
| 1575 __ ldr(r0, MemOperand(sp, argc * kPointerSize)); | 1562 __ ldr(r0, MemOperand(sp, argc * kPointerSize)); |
| 1576 | 1563 |
| 1577 // Check that the maps haven't changed. | 1564 // Check that the maps haven't changed. |
| 1578 __ JumpIfSmi(r0, miss); | 1565 __ JumpIfSmi(r0, miss); |
| 1579 CheckPrototypes(object, r0, holder, r3, r1, r4, name, miss); | 1566 CheckPrototypes( |
| 1567 IC::CurrentTypeOf(object, isolate()), r0, holder, r3, r1, r4, name, miss); |
| 1580 } | 1568 } |
| 1581 | 1569 |
| 1582 | 1570 |
| 1583 void CallStubCompiler::GenerateLoadFunctionFromCell( | 1571 void CallStubCompiler::GenerateLoadFunctionFromCell( |
| 1584 Handle<Cell> cell, | 1572 Handle<Cell> cell, |
| 1585 Handle<JSFunction> function, | 1573 Handle<JSFunction> function, |
| 1586 Label* miss) { | 1574 Label* miss) { |
| 1587 // Get the value from the cell. | 1575 // Get the value from the cell. |
| 1588 __ mov(r3, Operand(cell)); | 1576 __ mov(r3, Operand(cell)); |
| 1589 __ ldr(r1, FieldMemOperand(r3, Cell::kValueOffset)); | 1577 __ ldr(r1, FieldMemOperand(r3, Cell::kValueOffset)); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1632 GenerateNameCheck(name, &miss); | 1620 GenerateNameCheck(name, &miss); |
| 1633 | 1621 |
| 1634 const int argc = arguments().immediate(); | 1622 const int argc = arguments().immediate(); |
| 1635 | 1623 |
| 1636 // Get the receiver of the function from the stack into r0. | 1624 // Get the receiver of the function from the stack into r0. |
| 1637 __ ldr(r0, MemOperand(sp, argc * kPointerSize)); | 1625 __ ldr(r0, MemOperand(sp, argc * kPointerSize)); |
| 1638 // Check that the receiver isn't a smi. | 1626 // Check that the receiver isn't a smi. |
| 1639 __ JumpIfSmi(r0, &miss); | 1627 __ JumpIfSmi(r0, &miss); |
| 1640 | 1628 |
| 1641 // Do the right check and compute the holder register. | 1629 // Do the right check and compute the holder register. |
| 1642 Register reg = CheckPrototypes(object, r0, holder, r1, r3, r4, name, &miss); | 1630 Register reg = CheckPrototypes( |
| 1631 IC::CurrentTypeOf(object, isolate()), |
| 1632 r0, holder, r1, r3, r4, name, &miss); |
| 1643 GenerateFastPropertyLoad(masm(), r1, reg, index.is_inobject(holder), | 1633 GenerateFastPropertyLoad(masm(), r1, reg, index.is_inobject(holder), |
| 1644 index.translate(holder), Representation::Tagged()); | 1634 index.translate(holder), Representation::Tagged()); |
| 1645 | 1635 |
| 1646 GenerateCallFunction(masm(), object, arguments(), &miss, extra_state_); | 1636 GenerateCallFunction(masm(), object, arguments(), &miss, extra_state_); |
| 1647 | 1637 |
| 1648 // Handle call cache miss. | 1638 // Handle call cache miss. |
| 1649 __ bind(&miss); | 1639 __ bind(&miss); |
| 1650 GenerateMissBranch(); | 1640 GenerateMissBranch(); |
| 1651 | 1641 |
| 1652 // Return the generated code. | 1642 // Return the generated code. |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1668 GenerateNameCheck(name, &miss); | 1658 GenerateNameCheck(name, &miss); |
| 1669 Register receiver = r1; | 1659 Register receiver = r1; |
| 1670 | 1660 |
| 1671 if (cell.is_null()) { | 1661 if (cell.is_null()) { |
| 1672 __ ldr(receiver, MemOperand(sp, argc * kPointerSize)); | 1662 __ ldr(receiver, MemOperand(sp, argc * kPointerSize)); |
| 1673 | 1663 |
| 1674 // Check that the receiver isn't a smi. | 1664 // Check that the receiver isn't a smi. |
| 1675 __ JumpIfSmi(receiver, &miss); | 1665 __ JumpIfSmi(receiver, &miss); |
| 1676 | 1666 |
| 1677 // Check that the maps haven't changed. | 1667 // Check that the maps haven't changed. |
| 1678 CheckPrototypes(Handle<JSObject>::cast(object), receiver, holder, r3, r0, | 1668 CheckPrototypes( |
| 1679 r4, name, &miss); | 1669 IC::CurrentTypeOf(object, isolate()), receiver, holder, |
| 1670 r3, r0, r4, name, &miss); |
| 1680 } else { | 1671 } else { |
| 1681 ASSERT(cell->value() == *function); | 1672 ASSERT(cell->value() == *function); |
| 1682 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name, | 1673 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name, |
| 1683 &miss); | 1674 &miss); |
| 1684 GenerateLoadFunctionFromCell(cell, function, &miss); | 1675 GenerateLoadFunctionFromCell(cell, function, &miss); |
| 1685 } | 1676 } |
| 1686 | 1677 |
| 1687 Handle<AllocationSite> site = isolate()->factory()->NewAllocationSite(); | 1678 Handle<AllocationSite> site = isolate()->factory()->NewAllocationSite(); |
| 1688 site->SetElementsKind(GetInitialFastElementsKind()); | 1679 site->SetElementsKind(GetInitialFastElementsKind()); |
| 1689 Handle<Cell> site_feedback_cell = isolate()->factory()->NewCell(site); | 1680 Handle<Cell> site_feedback_cell = isolate()->factory()->NewCell(site); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1729 | 1720 |
| 1730 Register receiver = r1; | 1721 Register receiver = r1; |
| 1731 // Get the receiver from the stack | 1722 // Get the receiver from the stack |
| 1732 const int argc = arguments().immediate(); | 1723 const int argc = arguments().immediate(); |
| 1733 __ ldr(receiver, MemOperand(sp, argc * kPointerSize)); | 1724 __ ldr(receiver, MemOperand(sp, argc * kPointerSize)); |
| 1734 | 1725 |
| 1735 // Check that the receiver isn't a smi. | 1726 // Check that the receiver isn't a smi. |
| 1736 __ JumpIfSmi(receiver, &miss); | 1727 __ JumpIfSmi(receiver, &miss); |
| 1737 | 1728 |
| 1738 // Check that the maps haven't changed. | 1729 // Check that the maps haven't changed. |
| 1739 CheckPrototypes(Handle<JSObject>::cast(object), receiver, holder, r3, r0, r4, | 1730 CheckPrototypes( |
| 1740 name, &miss); | 1731 IC::CurrentTypeOf(object, isolate()), receiver, holder, |
| 1732 r3, r0, r4, name, &miss); |
| 1741 | 1733 |
| 1742 if (argc == 0) { | 1734 if (argc == 0) { |
| 1743 // Nothing to do, just return the length. | 1735 // Nothing to do, just return the length. |
| 1744 __ ldr(r0, FieldMemOperand(receiver, JSArray::kLengthOffset)); | 1736 __ ldr(r0, FieldMemOperand(receiver, JSArray::kLengthOffset)); |
| 1745 __ Drop(argc + 1); | 1737 __ Drop(argc + 1); |
| 1746 __ Ret(); | 1738 __ Ret(); |
| 1747 } else { | 1739 } else { |
| 1748 Label call_builtin; | 1740 Label call_builtin; |
| 1749 | 1741 |
| 1750 if (argc == 1) { // Otherwise fall through to call the builtin. | 1742 if (argc == 1) { // Otherwise fall through to call the builtin. |
| (...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1987 Register elements = r3; | 1979 Register elements = r3; |
| 1988 GenerateNameCheck(name, &miss); | 1980 GenerateNameCheck(name, &miss); |
| 1989 | 1981 |
| 1990 // Get the receiver from the stack | 1982 // Get the receiver from the stack |
| 1991 const int argc = arguments().immediate(); | 1983 const int argc = arguments().immediate(); |
| 1992 __ ldr(receiver, MemOperand(sp, argc * kPointerSize)); | 1984 __ ldr(receiver, MemOperand(sp, argc * kPointerSize)); |
| 1993 // Check that the receiver isn't a smi. | 1985 // Check that the receiver isn't a smi. |
| 1994 __ JumpIfSmi(receiver, &miss); | 1986 __ JumpIfSmi(receiver, &miss); |
| 1995 | 1987 |
| 1996 // Check that the maps haven't changed. | 1988 // Check that the maps haven't changed. |
| 1997 CheckPrototypes(Handle<JSObject>::cast(object), receiver, holder, elements, | 1989 CheckPrototypes(IC::CurrentTypeOf(object, isolate()), receiver, holder, |
| 1998 r4, r0, name, &miss); | 1990 elements, r4, r0, name, &miss); |
| 1999 | 1991 |
| 2000 // Get the elements array of the object. | 1992 // Get the elements array of the object. |
| 2001 __ ldr(elements, FieldMemOperand(receiver, JSArray::kElementsOffset)); | 1993 __ ldr(elements, FieldMemOperand(receiver, JSArray::kElementsOffset)); |
| 2002 | 1994 |
| 2003 // Check that the elements are in fast mode and writable. | 1995 // Check that the elements are in fast mode and writable. |
| 2004 __ CheckMap(elements, | 1996 __ CheckMap(elements, |
| 2005 r0, | 1997 r0, |
| 2006 Heap::kFixedArrayMapRootIndex, | 1998 Heap::kFixedArrayMapRootIndex, |
| 2007 &call_builtin, | 1999 &call_builtin, |
| 2008 DONT_DO_SMI_CHECK); | 2000 DONT_DO_SMI_CHECK); |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2077 index_out_of_range_label = &miss; | 2069 index_out_of_range_label = &miss; |
| 2078 } | 2070 } |
| 2079 GenerateNameCheck(name, &name_miss); | 2071 GenerateNameCheck(name, &name_miss); |
| 2080 | 2072 |
| 2081 // Check that the maps starting from the prototype haven't changed. | 2073 // Check that the maps starting from the prototype haven't changed. |
| 2082 GenerateDirectLoadGlobalFunctionPrototype(masm(), | 2074 GenerateDirectLoadGlobalFunctionPrototype(masm(), |
| 2083 Context::STRING_FUNCTION_INDEX, | 2075 Context::STRING_FUNCTION_INDEX, |
| 2084 r0, | 2076 r0, |
| 2085 &miss); | 2077 &miss); |
| 2086 ASSERT(!object.is_identical_to(holder)); | 2078 ASSERT(!object.is_identical_to(holder)); |
| 2079 Handle<JSObject> prototype(JSObject::cast(object->GetPrototype(isolate()))); |
| 2087 CheckPrototypes( | 2080 CheckPrototypes( |
| 2088 Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))), | 2081 IC::CurrentTypeOf(prototype, isolate()), |
| 2089 r0, holder, r1, r3, r4, name, &miss); | 2082 r0, holder, r1, r3, r4, name, &miss); |
| 2090 | 2083 |
| 2091 Register receiver = r1; | 2084 Register receiver = r1; |
| 2092 Register index = r4; | 2085 Register index = r4; |
| 2093 Register result = r0; | 2086 Register result = r0; |
| 2094 __ ldr(receiver, MemOperand(sp, argc * kPointerSize)); | 2087 __ ldr(receiver, MemOperand(sp, argc * kPointerSize)); |
| 2095 if (argc > 0) { | 2088 if (argc > 0) { |
| 2096 __ ldr(index, MemOperand(sp, (argc - 1) * kPointerSize)); | 2089 __ ldr(index, MemOperand(sp, (argc - 1) * kPointerSize)); |
| 2097 } else { | 2090 } else { |
| 2098 __ LoadRoot(index, Heap::kUndefinedValueRootIndex); | 2091 __ LoadRoot(index, Heap::kUndefinedValueRootIndex); |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2159 index_out_of_range_label = &miss; | 2152 index_out_of_range_label = &miss; |
| 2160 } | 2153 } |
| 2161 GenerateNameCheck(name, &name_miss); | 2154 GenerateNameCheck(name, &name_miss); |
| 2162 | 2155 |
| 2163 // Check that the maps starting from the prototype haven't changed. | 2156 // Check that the maps starting from the prototype haven't changed. |
| 2164 GenerateDirectLoadGlobalFunctionPrototype(masm(), | 2157 GenerateDirectLoadGlobalFunctionPrototype(masm(), |
| 2165 Context::STRING_FUNCTION_INDEX, | 2158 Context::STRING_FUNCTION_INDEX, |
| 2166 r0, | 2159 r0, |
| 2167 &miss); | 2160 &miss); |
| 2168 ASSERT(!object.is_identical_to(holder)); | 2161 ASSERT(!object.is_identical_to(holder)); |
| 2162 Handle<JSObject> prototype(JSObject::cast(object->GetPrototype(isolate()))); |
| 2169 CheckPrototypes( | 2163 CheckPrototypes( |
| 2170 Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))), | 2164 IC::CurrentTypeOf(prototype, isolate()), |
| 2171 r0, holder, r1, r3, r4, name, &miss); | 2165 r0, holder, r1, r3, r4, name, &miss); |
| 2172 | 2166 |
| 2173 Register receiver = r0; | 2167 Register receiver = r0; |
| 2174 Register index = r4; | 2168 Register index = r4; |
| 2175 Register scratch = r3; | 2169 Register scratch = r3; |
| 2176 Register result = r0; | 2170 Register result = r0; |
| 2177 __ ldr(receiver, MemOperand(sp, argc * kPointerSize)); | 2171 __ ldr(receiver, MemOperand(sp, argc * kPointerSize)); |
| 2178 if (argc > 0) { | 2172 if (argc > 0) { |
| 2179 __ ldr(index, MemOperand(sp, (argc - 1) * kPointerSize)); | 2173 __ ldr(index, MemOperand(sp, (argc - 1) * kPointerSize)); |
| 2180 } else { | 2174 } else { |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2236 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null(); | 2230 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null(); |
| 2237 | 2231 |
| 2238 Label miss; | 2232 Label miss; |
| 2239 GenerateNameCheck(name, &miss); | 2233 GenerateNameCheck(name, &miss); |
| 2240 | 2234 |
| 2241 if (cell.is_null()) { | 2235 if (cell.is_null()) { |
| 2242 __ ldr(r1, MemOperand(sp, 1 * kPointerSize)); | 2236 __ ldr(r1, MemOperand(sp, 1 * kPointerSize)); |
| 2243 | 2237 |
| 2244 __ JumpIfSmi(r1, &miss); | 2238 __ JumpIfSmi(r1, &miss); |
| 2245 | 2239 |
| 2246 CheckPrototypes(Handle<JSObject>::cast(object), r1, holder, r0, r3, r4, | 2240 CheckPrototypes( |
| 2247 name, &miss); | 2241 IC::CurrentTypeOf(object, isolate()), |
| 2242 r1, holder, r0, r3, r4, name, &miss); |
| 2248 } else { | 2243 } else { |
| 2249 ASSERT(cell->value() == *function); | 2244 ASSERT(cell->value() == *function); |
| 2250 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name, | 2245 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name, |
| 2251 &miss); | 2246 &miss); |
| 2252 GenerateLoadFunctionFromCell(cell, function, &miss); | 2247 GenerateLoadFunctionFromCell(cell, function, &miss); |
| 2253 } | 2248 } |
| 2254 | 2249 |
| 2255 // Load the char code argument. | 2250 // Load the char code argument. |
| 2256 Register code = r1; | 2251 Register code = r1; |
| 2257 __ ldr(code, MemOperand(sp, 0 * kPointerSize)); | 2252 __ ldr(code, MemOperand(sp, 0 * kPointerSize)); |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2306 // If the object is not a JSObject or we got an unexpected number of | 2301 // If the object is not a JSObject or we got an unexpected number of |
| 2307 // arguments, bail out to the regular call. | 2302 // arguments, bail out to the regular call. |
| 2308 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null(); | 2303 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null(); |
| 2309 | 2304 |
| 2310 Label miss, slow; | 2305 Label miss, slow; |
| 2311 GenerateNameCheck(name, &miss); | 2306 GenerateNameCheck(name, &miss); |
| 2312 | 2307 |
| 2313 if (cell.is_null()) { | 2308 if (cell.is_null()) { |
| 2314 __ ldr(r1, MemOperand(sp, 1 * kPointerSize)); | 2309 __ ldr(r1, MemOperand(sp, 1 * kPointerSize)); |
| 2315 __ JumpIfSmi(r1, &miss); | 2310 __ JumpIfSmi(r1, &miss); |
| 2316 CheckPrototypes(Handle<JSObject>::cast(object), r1, holder, r0, r3, r4, | 2311 CheckPrototypes( |
| 2317 name, &miss); | 2312 IC::CurrentTypeOf(object, isolate()), |
| 2313 r1, holder, r0, r3, r4, name, &miss); |
| 2318 } else { | 2314 } else { |
| 2319 ASSERT(cell->value() == *function); | 2315 ASSERT(cell->value() == *function); |
| 2320 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name, | 2316 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name, |
| 2321 &miss); | 2317 &miss); |
| 2322 GenerateLoadFunctionFromCell(cell, function, &miss); | 2318 GenerateLoadFunctionFromCell(cell, function, &miss); |
| 2323 } | 2319 } |
| 2324 | 2320 |
| 2325 // Load the (only) argument into r0. | 2321 // Load the (only) argument into r0. |
| 2326 __ ldr(r0, MemOperand(sp, 0 * kPointerSize)); | 2322 __ ldr(r0, MemOperand(sp, 0 * kPointerSize)); |
| 2327 | 2323 |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2414 const int argc = arguments().immediate(); | 2410 const int argc = arguments().immediate(); |
| 2415 // If the object is not a JSObject or we got an unexpected number of | 2411 // If the object is not a JSObject or we got an unexpected number of |
| 2416 // arguments, bail out to the regular call. | 2412 // arguments, bail out to the regular call. |
| 2417 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null(); | 2413 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null(); |
| 2418 | 2414 |
| 2419 Label miss; | 2415 Label miss; |
| 2420 GenerateNameCheck(name, &miss); | 2416 GenerateNameCheck(name, &miss); |
| 2421 if (cell.is_null()) { | 2417 if (cell.is_null()) { |
| 2422 __ ldr(r1, MemOperand(sp, 1 * kPointerSize)); | 2418 __ ldr(r1, MemOperand(sp, 1 * kPointerSize)); |
| 2423 __ JumpIfSmi(r1, &miss); | 2419 __ JumpIfSmi(r1, &miss); |
| 2424 CheckPrototypes(Handle<JSObject>::cast(object), r1, holder, r0, r3, r4, | 2420 CheckPrototypes( |
| 2425 name, &miss); | 2421 IC::CurrentTypeOf(object, isolate()), |
| 2422 r1, holder, r0, r3, r4, name, &miss); |
| 2426 } else { | 2423 } else { |
| 2427 ASSERT(cell->value() == *function); | 2424 ASSERT(cell->value() == *function); |
| 2428 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name, | 2425 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name, |
| 2429 &miss); | 2426 &miss); |
| 2430 GenerateLoadFunctionFromCell(cell, function, &miss); | 2427 GenerateLoadFunctionFromCell(cell, function, &miss); |
| 2431 } | 2428 } |
| 2432 | 2429 |
| 2433 // Load the (only) argument into r0. | 2430 // Load the (only) argument into r0. |
| 2434 __ ldr(r0, MemOperand(sp, 0 * kPointerSize)); | 2431 __ ldr(r0, MemOperand(sp, 0 * kPointerSize)); |
| 2435 | 2432 |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2523 | 2520 |
| 2524 // Check that the receiver isn't a smi. | 2521 // Check that the receiver isn't a smi. |
| 2525 __ JumpIfSmi(r1, &miss_before_stack_reserved); | 2522 __ JumpIfSmi(r1, &miss_before_stack_reserved); |
| 2526 | 2523 |
| 2527 __ IncrementCounter(counters->call_const(), 1, r0, r3); | 2524 __ IncrementCounter(counters->call_const(), 1, r0, r3); |
| 2528 __ IncrementCounter(counters->call_const_fast_api(), 1, r0, r3); | 2525 __ IncrementCounter(counters->call_const_fast_api(), 1, r0, r3); |
| 2529 | 2526 |
| 2530 ReserveSpaceForFastApiCall(masm(), r0); | 2527 ReserveSpaceForFastApiCall(masm(), r0); |
| 2531 | 2528 |
| 2532 // Check that the maps haven't changed and find a Holder as a side effect. | 2529 // Check that the maps haven't changed and find a Holder as a side effect. |
| 2533 CheckPrototypes(Handle<JSObject>::cast(object), r1, holder, r0, r3, r4, name, | 2530 CheckPrototypes( |
| 2534 depth, &miss); | 2531 IC::CurrentTypeOf(object, isolate()), |
| 2532 r1, holder, r0, r3, r4, name, depth, &miss); |
| 2535 | 2533 |
| 2536 GenerateFastApiDirectCall(masm(), optimization, argc, false); | 2534 GenerateFastApiDirectCall(masm(), optimization, argc, false); |
| 2537 | 2535 |
| 2538 __ bind(&miss); | 2536 __ bind(&miss); |
| 2539 FreeSpaceForFastApiCall(masm()); | 2537 FreeSpaceForFastApiCall(masm()); |
| 2540 | 2538 |
| 2541 __ bind(&miss_before_stack_reserved); | 2539 __ bind(&miss_before_stack_reserved); |
| 2542 GenerateMissBranch(); | 2540 GenerateMissBranch(); |
| 2543 | 2541 |
| 2544 // Return the generated code. | 2542 // Return the generated code. |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2580 } | 2578 } |
| 2581 | 2579 |
| 2582 // 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 |
| 2583 // unless we're doing a receiver map check. | 2581 // unless we're doing a receiver map check. |
| 2584 ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK); | 2582 ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK); |
| 2585 switch (check) { | 2583 switch (check) { |
| 2586 case RECEIVER_MAP_CHECK: | 2584 case RECEIVER_MAP_CHECK: |
| 2587 __ IncrementCounter(isolate()->counters()->call_const(), 1, r0, r3); | 2585 __ IncrementCounter(isolate()->counters()->call_const(), 1, r0, r3); |
| 2588 | 2586 |
| 2589 // Check that the maps haven't changed. | 2587 // Check that the maps haven't changed. |
| 2590 CheckPrototypes(Handle<JSObject>::cast(object), r1, holder, r0, r3, r4, | 2588 CheckPrototypes( |
| 2591 name, &miss); | 2589 IC::CurrentTypeOf(object, isolate()), |
| 2590 r1, holder, r0, r3, r4, name, &miss); |
| 2592 | 2591 |
| 2593 // Patch the receiver on the stack with the global proxy if | 2592 // Patch the receiver on the stack with the global proxy if |
| 2594 // necessary. | 2593 // necessary. |
| 2595 if (object->IsGlobalObject()) { | 2594 if (object->IsGlobalObject()) { |
| 2596 __ ldr(r3, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset)); | 2595 __ ldr(r3, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset)); |
| 2597 __ str(r3, MemOperand(sp, argc * kPointerSize)); | 2596 __ str(r3, MemOperand(sp, argc * kPointerSize)); |
| 2598 } | 2597 } |
| 2599 break; | 2598 break; |
| 2600 | 2599 |
| 2601 case STRING_CHECK: | 2600 case STRING_CHECK: { |
| 2602 // Check that the object is a string. | 2601 // Check that the object is a string. |
| 2603 __ CompareObjectType(r1, r3, r3, FIRST_NONSTRING_TYPE); | 2602 __ CompareObjectType(r1, r3, r3, FIRST_NONSTRING_TYPE); |
| 2604 __ b(ge, &miss); | 2603 __ b(ge, &miss); |
| 2605 // Check that the maps starting from the prototype haven't changed. | 2604 // Check that the maps starting from the prototype haven't changed. |
| 2606 GenerateDirectLoadGlobalFunctionPrototype( | 2605 GenerateDirectLoadGlobalFunctionPrototype( |
| 2607 masm(), Context::STRING_FUNCTION_INDEX, r0, &miss); | 2606 masm(), Context::STRING_FUNCTION_INDEX, r0, &miss); |
| 2607 Handle<Object> prototype(object->GetPrototype(isolate()), isolate()); |
| 2608 CheckPrototypes( | 2608 CheckPrototypes( |
| 2609 Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))), | 2609 IC::CurrentTypeOf(prototype, isolate()), |
| 2610 r0, holder, r3, r1, r4, name, &miss); | 2610 r0, holder, r3, r1, r4, name, &miss); |
| 2611 break; | 2611 break; |
| 2612 | 2612 } |
| 2613 case SYMBOL_CHECK: | 2613 case SYMBOL_CHECK: { |
| 2614 // Check that the object is a symbol. | 2614 // Check that the object is a symbol. |
| 2615 __ CompareObjectType(r1, r1, r3, SYMBOL_TYPE); | 2615 __ CompareObjectType(r1, r1, r3, SYMBOL_TYPE); |
| 2616 __ b(ne, &miss); | 2616 __ b(ne, &miss); |
| 2617 // Check that the maps starting from the prototype haven't changed. | 2617 // Check that the maps starting from the prototype haven't changed. |
| 2618 GenerateDirectLoadGlobalFunctionPrototype( | 2618 GenerateDirectLoadGlobalFunctionPrototype( |
| 2619 masm(), Context::SYMBOL_FUNCTION_INDEX, r0, &miss); | 2619 masm(), Context::SYMBOL_FUNCTION_INDEX, r0, &miss); |
| 2620 Handle<Object> prototype(object->GetPrototype(isolate()), isolate()); |
| 2620 CheckPrototypes( | 2621 CheckPrototypes( |
| 2621 Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))), | 2622 IC::CurrentTypeOf(prototype, isolate()), |
| 2622 r0, holder, r3, r1, r4, name, &miss); | 2623 r0, holder, r3, r1, r4, name, &miss); |
| 2623 break; | 2624 break; |
| 2624 | 2625 } |
| 2625 case NUMBER_CHECK: { | 2626 case NUMBER_CHECK: { |
| 2626 Label fast; | 2627 Label fast; |
| 2627 // Check that the object is a smi or a heap number. | 2628 // Check that the object is a smi or a heap number. |
| 2628 __ JumpIfSmi(r1, &fast); | 2629 __ JumpIfSmi(r1, &fast); |
| 2629 __ CompareObjectType(r1, r0, r0, HEAP_NUMBER_TYPE); | 2630 __ CompareObjectType(r1, r0, r0, HEAP_NUMBER_TYPE); |
| 2630 __ b(ne, &miss); | 2631 __ b(ne, &miss); |
| 2631 __ bind(&fast); | 2632 __ bind(&fast); |
| 2632 // Check that the maps starting from the prototype haven't changed. | 2633 // Check that the maps starting from the prototype haven't changed. |
| 2633 GenerateDirectLoadGlobalFunctionPrototype( | 2634 GenerateDirectLoadGlobalFunctionPrototype( |
| 2634 masm(), Context::NUMBER_FUNCTION_INDEX, r0, &miss); | 2635 masm(), Context::NUMBER_FUNCTION_INDEX, r0, &miss); |
| 2636 Handle<Object> prototype(object->GetPrototype(isolate()), isolate()); |
| 2635 CheckPrototypes( | 2637 CheckPrototypes( |
| 2636 Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))), | 2638 IC::CurrentTypeOf(prototype, isolate()), |
| 2637 r0, holder, r3, r1, r4, name, &miss); | 2639 r0, holder, r3, r1, r4, name, &miss); |
| 2638 break; | 2640 break; |
| 2639 } | 2641 } |
| 2640 case BOOLEAN_CHECK: { | 2642 case BOOLEAN_CHECK: { |
| 2641 GenerateBooleanCheck(r1, &miss); | 2643 GenerateBooleanCheck(r1, &miss); |
| 2642 | 2644 |
| 2643 // Check that the maps starting from the prototype haven't changed. | 2645 // Check that the maps starting from the prototype haven't changed. |
| 2644 GenerateDirectLoadGlobalFunctionPrototype( | 2646 GenerateDirectLoadGlobalFunctionPrototype( |
| 2645 masm(), Context::BOOLEAN_FUNCTION_INDEX, r0, &miss); | 2647 masm(), Context::BOOLEAN_FUNCTION_INDEX, r0, &miss); |
| 2648 Handle<Object> prototype(object->GetPrototype(isolate()), isolate()); |
| 2646 CheckPrototypes( | 2649 CheckPrototypes( |
| 2647 Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))), | 2650 IC::CurrentTypeOf(prototype, isolate()), |
| 2648 r0, holder, r3, r1, r4, name, &miss); | 2651 r0, holder, r3, r1, r4, name, &miss); |
| 2649 break; | 2652 break; |
| 2650 } | 2653 } |
| 2651 } | 2654 } |
| 2652 | 2655 |
| 2653 Label success; | 2656 Label success; |
| 2654 __ b(&success); | 2657 __ b(&success); |
| 2655 | 2658 |
| 2656 // Handle call cache miss. | 2659 // Handle call cache miss. |
| 2657 __ bind(&miss); | 2660 __ bind(&miss); |
| (...skipping 514 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3172 // ----------------------------------- | 3175 // ----------------------------------- |
| 3173 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); | 3176 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); |
| 3174 } | 3177 } |
| 3175 | 3178 |
| 3176 | 3179 |
| 3177 #undef __ | 3180 #undef __ |
| 3178 | 3181 |
| 3179 } } // namespace v8::internal | 3182 } } // namespace v8::internal |
| 3180 | 3183 |
| 3181 #endif // V8_TARGET_ARCH_ARM | 3184 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |