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 |