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 1007 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1018 __ IncrementCounter(counters->call_const_interceptor_fast_api(), 1, | 1018 __ IncrementCounter(counters->call_const_interceptor_fast_api(), 1, |
1019 scratch1, scratch2); | 1019 scratch1, scratch2); |
1020 ReserveSpaceForFastApiCall(masm, scratch1); | 1020 ReserveSpaceForFastApiCall(masm, scratch1); |
1021 } | 1021 } |
1022 | 1022 |
1023 // Check that the maps from receiver to interceptor's holder | 1023 // Check that the maps from receiver to interceptor's holder |
1024 // haven't changed and thus we can invoke interceptor. | 1024 // haven't changed and thus we can invoke interceptor. |
1025 Label miss_cleanup; | 1025 Label miss_cleanup; |
1026 Label* miss = can_do_fast_api_call ? &miss_cleanup : miss_label; | 1026 Label* miss = can_do_fast_api_call ? &miss_cleanup : miss_label; |
1027 Register holder = | 1027 Register holder = |
1028 stub_compiler_->CheckPrototypes(object, receiver, interceptor_holder, | 1028 stub_compiler_->CheckPrototypes( |
1029 scratch1, scratch2, scratch3, | 1029 IC::CurrentTypeOf(object, masm->isolate()), receiver, |
1030 name, depth1, miss); | 1030 interceptor_holder, scratch1, scratch2, scratch3, |
| 1031 name, depth1, miss); |
1031 | 1032 |
1032 // Invoke an interceptor and if it provides a value, | 1033 // Invoke an interceptor and if it provides a value, |
1033 // branch to |regular_invoke|. | 1034 // branch to |regular_invoke|. |
1034 Label regular_invoke; | 1035 Label regular_invoke; |
1035 LoadWithInterceptor(masm, receiver, holder, interceptor_holder, scratch2, | 1036 LoadWithInterceptor(masm, receiver, holder, interceptor_holder, scratch2, |
1036 ®ular_invoke); | 1037 ®ular_invoke); |
1037 | 1038 |
1038 // Interceptor returned nothing for this property. Try to use cached | 1039 // Interceptor returned nothing for this property. Try to use cached |
1039 // constant function. | 1040 // constant function. |
1040 | 1041 |
1041 // Check that the maps from interceptor's holder to constant function's | 1042 // 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. | 1043 // holder haven't changed and thus we can use cached constant function. |
1043 if (*interceptor_holder != lookup->holder()) { | 1044 if (*interceptor_holder != lookup->holder()) { |
1044 stub_compiler_->CheckPrototypes(interceptor_holder, receiver, | 1045 stub_compiler_->CheckPrototypes( |
1045 Handle<JSObject>(lookup->holder()), | 1046 IC::CurrentTypeOf(interceptor_holder, masm->isolate()), receiver, |
1046 scratch1, scratch2, scratch3, | 1047 handle(lookup->holder()), scratch1, scratch2, scratch3, |
1047 name, depth2, miss); | 1048 name, depth2, miss); |
1048 } else { | 1049 } else { |
1049 // CheckPrototypes has a side effect of fetching a 'holder' | 1050 // CheckPrototypes has a side effect of fetching a 'holder' |
1050 // for API (object which is instanceof for the signature). It's | 1051 // for API (object which is instanceof for the signature). It's |
1051 // safe to omit it here, as if present, it should be fetched | 1052 // safe to omit it here, as if present, it should be fetched |
1052 // by the previous CheckPrototypes. | 1053 // by the previous CheckPrototypes. |
1053 ASSERT(depth2 == kInvalidProtoDepth); | 1054 ASSERT(depth2 == kInvalidProtoDepth); |
1054 } | 1055 } |
1055 | 1056 |
1056 // Invoke function. | 1057 // Invoke function. |
1057 if (can_do_fast_api_call) { | 1058 if (can_do_fast_api_call) { |
(...skipping 26 matching lines...) Expand all Loading... |
1084 void CompileRegular(MacroAssembler* masm, | 1085 void CompileRegular(MacroAssembler* masm, |
1085 Handle<JSObject> object, | 1086 Handle<JSObject> object, |
1086 Register receiver, | 1087 Register receiver, |
1087 Register scratch1, | 1088 Register scratch1, |
1088 Register scratch2, | 1089 Register scratch2, |
1089 Register scratch3, | 1090 Register scratch3, |
1090 Handle<Name> name, | 1091 Handle<Name> name, |
1091 Handle<JSObject> interceptor_holder, | 1092 Handle<JSObject> interceptor_holder, |
1092 Label* miss_label) { | 1093 Label* miss_label) { |
1093 Register holder = | 1094 Register holder = |
1094 stub_compiler_->CheckPrototypes(object, receiver, interceptor_holder, | 1095 stub_compiler_->CheckPrototypes( |
1095 scratch1, scratch2, scratch3, | 1096 IC::CurrentTypeOf(object, masm->isolate()), receiver, |
1096 name, miss_label); | 1097 interceptor_holder, scratch1, scratch2, scratch3, name, miss_label); |
1097 | 1098 |
1098 // Call a runtime function to load the interceptor property. | 1099 // Call a runtime function to load the interceptor property. |
1099 FrameScope scope(masm, StackFrame::INTERNAL); | 1100 FrameScope scope(masm, StackFrame::INTERNAL); |
1100 // Save the name_ register across the call. | 1101 // Save the name_ register across the call. |
1101 __ push(name_); | 1102 __ push(name_); |
1102 | 1103 |
1103 PushInterceptorArguments(masm, receiver, holder, name_, interceptor_holder); | 1104 PushInterceptorArguments(masm, receiver, holder, name_, interceptor_holder); |
1104 | 1105 |
1105 __ CallExternalReference( | 1106 __ CallExternalReference( |
1106 ExternalReference( | 1107 ExternalReference( |
(...skipping 28 matching lines...) Expand all Loading... |
1135 __ Branch(interceptor_succeeded, ne, v0, Operand(scratch)); | 1136 __ Branch(interceptor_succeeded, ne, v0, Operand(scratch)); |
1136 } | 1137 } |
1137 | 1138 |
1138 StubCompiler* stub_compiler_; | 1139 StubCompiler* stub_compiler_; |
1139 const ParameterCount& arguments_; | 1140 const ParameterCount& arguments_; |
1140 Register name_; | 1141 Register name_; |
1141 Code::ExtraICState extra_ic_state_; | 1142 Code::ExtraICState extra_ic_state_; |
1142 }; | 1143 }; |
1143 | 1144 |
1144 | 1145 |
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) { | 1146 void StubCompiler::GenerateTailCall(MacroAssembler* masm, Handle<Code> code) { |
1166 __ Jump(code, RelocInfo::CODE_TARGET); | 1147 __ Jump(code, RelocInfo::CODE_TARGET); |
1167 } | 1148 } |
1168 | 1149 |
1169 | 1150 |
1170 #undef __ | 1151 #undef __ |
1171 #define __ ACCESS_MASM(masm()) | 1152 #define __ ACCESS_MASM(masm()) |
1172 | 1153 |
1173 | 1154 |
1174 Register StubCompiler::CheckPrototypes(Handle<JSObject> object, | 1155 Register StubCompiler::CheckPrototypes(Handle<Type> type, |
1175 Register object_reg, | 1156 Register object_reg, |
1176 Handle<JSObject> holder, | 1157 Handle<JSObject> holder, |
1177 Register holder_reg, | 1158 Register holder_reg, |
1178 Register scratch1, | 1159 Register scratch1, |
1179 Register scratch2, | 1160 Register scratch2, |
1180 Handle<Name> name, | 1161 Handle<Name> name, |
1181 int save_at_depth, | 1162 int save_at_depth, |
1182 Label* miss, | 1163 Label* miss, |
1183 PrototypeCheckType check) { | 1164 PrototypeCheckType check) { |
| 1165 Handle<Map> receiver_map(IC::TypeToMap(*type, isolate())); |
1184 // Make sure that the type feedback oracle harvests the receiver map. | 1166 // Make sure that the type feedback oracle harvests the receiver map. |
1185 // TODO(svenpanne) Remove this hack when all ICs are reworked. | 1167 // TODO(svenpanne) Remove this hack when all ICs are reworked. |
1186 __ li(scratch1, Operand(Handle<Map>(object->map()))); | 1168 __ li(scratch1, Operand(receiver_map)); |
1187 | 1169 |
1188 Handle<JSObject> first = object; | |
1189 // Make sure there's no overlap between holder and object registers. | 1170 // Make sure there's no overlap between holder and object registers. |
1190 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); | 1171 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); |
1191 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg) | 1172 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg) |
1192 && !scratch2.is(scratch1)); | 1173 && !scratch2.is(scratch1)); |
1193 | 1174 |
1194 // Keep track of the current object in register reg. | 1175 // Keep track of the current object in register reg. |
1195 Register reg = object_reg; | 1176 Register reg = object_reg; |
1196 int depth = 0; | 1177 int depth = 0; |
1197 | 1178 |
1198 typedef FunctionCallbackArguments FCA; | 1179 typedef FunctionCallbackArguments FCA; |
1199 if (save_at_depth == depth) { | 1180 if (save_at_depth == depth) { |
1200 __ sw(reg, MemOperand(sp, FCA::kHolderIndex * kPointerSize)); | 1181 __ sw(reg, MemOperand(sp, FCA::kHolderIndex * kPointerSize)); |
1201 } | 1182 } |
1202 | 1183 |
1203 // Check the maps in the prototype chain. | 1184 Handle<JSObject> current = Handle<JSObject>::null(); |
1204 // Traverse the prototype chain from the object and do map checks. | 1185 if (type->IsConstant()) current = Handle<JSObject>::cast(type->AsConstant()); |
1205 Handle<JSObject> current = object; | 1186 Handle<JSObject> prototype = Handle<JSObject>::null(); |
1206 while (!current.is_identical_to(holder)) { | 1187 Handle<Map> current_map = receiver_map; |
| 1188 Handle<Map> holder_map(holder->map()); |
| 1189 // Traverse the prototype chain and check the maps in the prototype chain for |
| 1190 // fast and global objects or do negative lookup for normal objects. |
| 1191 while (!current_map.is_identical_to(holder_map)) { |
1207 ++depth; | 1192 ++depth; |
1208 | 1193 |
1209 // Only global objects and objects that do not require access | 1194 // Only global objects and objects that do not require access |
1210 // checks are allowed in stubs. | 1195 // checks are allowed in stubs. |
1211 ASSERT(current->IsJSGlobalProxy() || !current->IsAccessCheckNeeded()); | 1196 ASSERT(current_map->IsJSGlobalProxyMap() || |
| 1197 !current_map->is_access_check_needed()); |
1212 | 1198 |
1213 Handle<JSObject> prototype(JSObject::cast(current->GetPrototype())); | 1199 prototype = handle(JSObject::cast(current_map->prototype())); |
1214 if (!current->HasFastProperties() && | 1200 if (current_map->is_dictionary_map() && |
1215 !current->IsJSGlobalObject() && | 1201 !current_map->IsJSGlobalObjectMap() && |
1216 !current->IsJSGlobalProxy()) { | 1202 !current_map->IsJSGlobalProxyMap()) { |
1217 if (!name->IsUniqueName()) { | 1203 if (!name->IsUniqueName()) { |
1218 ASSERT(name->IsString()); | 1204 ASSERT(name->IsString()); |
1219 name = factory()->InternalizeString(Handle<String>::cast(name)); | 1205 name = factory()->InternalizeString(Handle<String>::cast(name)); |
1220 } | 1206 } |
1221 ASSERT(current->property_dictionary()->FindEntry(*name) == | 1207 ASSERT(current.is_null() || |
| 1208 current->property_dictionary()->FindEntry(*name) == |
1222 NameDictionary::kNotFound); | 1209 NameDictionary::kNotFound); |
1223 | 1210 |
1224 GenerateDictionaryNegativeLookup(masm(), miss, reg, name, | 1211 GenerateDictionaryNegativeLookup(masm(), miss, reg, name, |
1225 scratch1, scratch2); | 1212 scratch1, scratch2); |
1226 | 1213 |
1227 __ lw(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset)); | 1214 __ lw(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset)); |
1228 reg = holder_reg; // From now on the object will be in holder_reg. | 1215 reg = holder_reg; // From now on the object will be in holder_reg. |
1229 __ lw(reg, FieldMemOperand(scratch1, Map::kPrototypeOffset)); | 1216 __ lw(reg, FieldMemOperand(scratch1, Map::kPrototypeOffset)); |
1230 } else { | 1217 } else { |
1231 Register map_reg = scratch1; | 1218 Register map_reg = scratch1; |
1232 if (!current.is_identical_to(first) || check == CHECK_ALL_MAPS) { | 1219 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|. | 1220 // CheckMap implicitly loads the map of |reg| into |map_reg|. |
1235 __ CheckMap(reg, map_reg, current_map, miss, DONT_DO_SMI_CHECK); | 1221 __ CheckMap(reg, map_reg, current_map, miss, DONT_DO_SMI_CHECK); |
1236 } else { | 1222 } else { |
1237 __ lw(map_reg, FieldMemOperand(reg, HeapObject::kMapOffset)); | 1223 __ lw(map_reg, FieldMemOperand(reg, HeapObject::kMapOffset)); |
1238 } | 1224 } |
| 1225 |
1239 // Check access rights to the global object. This has to happen after | 1226 // 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 | 1227 // the map check so that we know that the object is actually a global |
1241 // object. | 1228 // object. |
1242 if (current->IsJSGlobalProxy()) { | 1229 if (current_map->IsJSGlobalProxyMap()) { |
1243 __ CheckAccessGlobalProxy(reg, scratch2, miss); | 1230 __ CheckAccessGlobalProxy(reg, scratch2, miss); |
| 1231 } else if (current_map->IsJSGlobalObjectMap()) { |
| 1232 GenerateCheckPropertyCell( |
| 1233 masm(), Handle<JSGlobalObject>::cast(current), name, |
| 1234 scratch2, miss); |
1244 } | 1235 } |
| 1236 |
1245 reg = holder_reg; // From now on the object will be in holder_reg. | 1237 reg = holder_reg; // From now on the object will be in holder_reg. |
1246 | 1238 |
1247 if (heap()->InNewSpace(*prototype)) { | 1239 if (heap()->InNewSpace(*prototype)) { |
1248 // The prototype is in new space; we cannot store a reference to it | 1240 // The prototype is in new space; we cannot store a reference to it |
1249 // in the code. Load it from the map. | 1241 // in the code. Load it from the map. |
1250 __ lw(reg, FieldMemOperand(map_reg, Map::kPrototypeOffset)); | 1242 __ lw(reg, FieldMemOperand(map_reg, Map::kPrototypeOffset)); |
1251 } else { | 1243 } else { |
1252 // The prototype is in old space; load it directly. | 1244 // The prototype is in old space; load it directly. |
1253 __ li(reg, Operand(prototype)); | 1245 __ li(reg, Operand(prototype)); |
1254 } | 1246 } |
1255 } | 1247 } |
1256 | 1248 |
1257 if (save_at_depth == depth) { | 1249 if (save_at_depth == depth) { |
1258 __ sw(reg, MemOperand(sp, FCA::kHolderIndex * kPointerSize)); | 1250 __ sw(reg, MemOperand(sp, FCA::kHolderIndex * kPointerSize)); |
1259 } | 1251 } |
1260 | 1252 |
1261 // Go to the next object in the prototype chain. | 1253 // Go to the next object in the prototype chain. |
1262 current = prototype; | 1254 current = prototype; |
| 1255 current_map = handle(current->map()); |
1263 } | 1256 } |
1264 | 1257 |
1265 // Log the check depth. | 1258 // Log the check depth. |
1266 LOG(isolate(), IntEvent("check-maps-depth", depth + 1)); | 1259 LOG(isolate(), IntEvent("check-maps-depth", depth + 1)); |
1267 | 1260 |
1268 if (!holder.is_identical_to(first) || check == CHECK_ALL_MAPS) { | 1261 if (depth != 0 || check == CHECK_ALL_MAPS) { |
1269 // Check the holder map. | 1262 // Check the holder map. |
1270 __ CheckMap(reg, scratch1, Handle<Map>(holder->map()), miss, | 1263 __ CheckMap(reg, scratch1, current_map, miss, DONT_DO_SMI_CHECK); |
1271 DONT_DO_SMI_CHECK); | |
1272 } | 1264 } |
1273 | 1265 |
1274 // Perform security check for access to the global object. | 1266 // Perform security check for access to the global object. |
1275 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded()); | 1267 ASSERT(current_map->IsJSGlobalProxyMap() || |
1276 if (holder->IsJSGlobalProxy()) { | 1268 !current_map->is_access_check_needed()); |
| 1269 if (current_map->IsJSGlobalProxyMap()) { |
1277 __ CheckAccessGlobalProxy(reg, scratch1, miss); | 1270 __ CheckAccessGlobalProxy(reg, scratch1, miss); |
1278 } | 1271 } |
1279 | 1272 |
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. | 1273 // Return the register containing the holder. |
1286 return reg; | 1274 return reg; |
1287 } | 1275 } |
1288 | 1276 |
1289 | 1277 |
1290 void LoadStubCompiler::HandlerFrontendFooter(Handle<Name> name, Label* miss) { | 1278 void LoadStubCompiler::HandlerFrontendFooter(Handle<Name> name, Label* miss) { |
1291 if (!miss->is_unused()) { | 1279 if (!miss->is_unused()) { |
1292 Label success; | 1280 Label success; |
1293 __ Branch(&success); | 1281 __ Branch(&success); |
1294 __ bind(miss); | 1282 __ bind(miss); |
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1557 ASSERT(holder->IsGlobalObject()); | 1545 ASSERT(holder->IsGlobalObject()); |
1558 | 1546 |
1559 // Get the number of arguments. | 1547 // Get the number of arguments. |
1560 const int argc = arguments().immediate(); | 1548 const int argc = arguments().immediate(); |
1561 | 1549 |
1562 // Get the receiver from the stack. | 1550 // Get the receiver from the stack. |
1563 __ lw(a0, MemOperand(sp, argc * kPointerSize)); | 1551 __ lw(a0, MemOperand(sp, argc * kPointerSize)); |
1564 | 1552 |
1565 // Check that the maps haven't changed. | 1553 // Check that the maps haven't changed. |
1566 __ JumpIfSmi(a0, miss); | 1554 __ JumpIfSmi(a0, miss); |
1567 CheckPrototypes(object, a0, holder, a3, a1, t0, name, miss); | 1555 CheckPrototypes( |
| 1556 IC::CurrentTypeOf(object, isolate()), a0, holder, a3, a1, t0, name, miss); |
1568 } | 1557 } |
1569 | 1558 |
1570 | 1559 |
1571 void CallStubCompiler::GenerateLoadFunctionFromCell( | 1560 void CallStubCompiler::GenerateLoadFunctionFromCell( |
1572 Handle<Cell> cell, | 1561 Handle<Cell> cell, |
1573 Handle<JSFunction> function, | 1562 Handle<JSFunction> function, |
1574 Label* miss) { | 1563 Label* miss) { |
1575 // Get the value from the cell. | 1564 // Get the value from the cell. |
1576 __ li(a3, Operand(cell)); | 1565 __ li(a3, Operand(cell)); |
1577 __ lw(a1, FieldMemOperand(a3, Cell::kValueOffset)); | 1566 __ lw(a1, FieldMemOperand(a3, Cell::kValueOffset)); |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1619 GenerateNameCheck(name, &miss); | 1608 GenerateNameCheck(name, &miss); |
1620 | 1609 |
1621 const int argc = arguments().immediate(); | 1610 const int argc = arguments().immediate(); |
1622 | 1611 |
1623 // Get the receiver of the function from the stack into a0. | 1612 // Get the receiver of the function from the stack into a0. |
1624 __ lw(a0, MemOperand(sp, argc * kPointerSize)); | 1613 __ lw(a0, MemOperand(sp, argc * kPointerSize)); |
1625 // Check that the receiver isn't a smi. | 1614 // Check that the receiver isn't a smi. |
1626 __ JumpIfSmi(a0, &miss, t0); | 1615 __ JumpIfSmi(a0, &miss, t0); |
1627 | 1616 |
1628 // Do the right check and compute the holder register. | 1617 // Do the right check and compute the holder register. |
1629 Register reg = CheckPrototypes(object, a0, holder, a1, a3, t0, name, &miss); | 1618 Register reg = CheckPrototypes( |
| 1619 IC::CurrentTypeOf(object, isolate()), |
| 1620 a0, holder, a1, a3, t0, name, &miss); |
1630 GenerateFastPropertyLoad(masm(), a1, reg, index.is_inobject(holder), | 1621 GenerateFastPropertyLoad(masm(), a1, reg, index.is_inobject(holder), |
1631 index.translate(holder), Representation::Tagged()); | 1622 index.translate(holder), Representation::Tagged()); |
1632 | 1623 |
1633 GenerateCallFunction(masm(), object, arguments(), &miss, extra_state_); | 1624 GenerateCallFunction(masm(), object, arguments(), &miss, extra_state_); |
1634 | 1625 |
1635 // Handle call cache miss. | 1626 // Handle call cache miss. |
1636 __ bind(&miss); | 1627 __ bind(&miss); |
1637 GenerateMissBranch(); | 1628 GenerateMissBranch(); |
1638 | 1629 |
1639 // Return the generated code. | 1630 // Return the generated code. |
(...skipping 15 matching lines...) Expand all Loading... |
1655 GenerateNameCheck(name, &miss); | 1646 GenerateNameCheck(name, &miss); |
1656 Register receiver = a1; | 1647 Register receiver = a1; |
1657 | 1648 |
1658 if (cell.is_null()) { | 1649 if (cell.is_null()) { |
1659 __ lw(receiver, MemOperand(sp, argc * kPointerSize)); | 1650 __ lw(receiver, MemOperand(sp, argc * kPointerSize)); |
1660 | 1651 |
1661 // Check that the receiver isn't a smi. | 1652 // Check that the receiver isn't a smi. |
1662 __ JumpIfSmi(receiver, &miss); | 1653 __ JumpIfSmi(receiver, &miss); |
1663 | 1654 |
1664 // Check that the maps haven't changed. | 1655 // Check that the maps haven't changed. |
1665 CheckPrototypes(Handle<JSObject>::cast(object), receiver, holder, a3, a0, | 1656 CheckPrototypes( |
1666 t0, name, &miss); | 1657 IC::CurrentTypeOf(object, isolate()), receiver, holder, |
| 1658 a3, a0, t0, name, &miss); |
1667 } else { | 1659 } else { |
1668 ASSERT(cell->value() == *function); | 1660 ASSERT(cell->value() == *function); |
1669 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name, | 1661 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name, |
1670 &miss); | 1662 &miss); |
1671 GenerateLoadFunctionFromCell(cell, function, &miss); | 1663 GenerateLoadFunctionFromCell(cell, function, &miss); |
1672 } | 1664 } |
1673 | 1665 |
1674 Handle<AllocationSite> site = isolate()->factory()->NewAllocationSite(); | 1666 Handle<AllocationSite> site = isolate()->factory()->NewAllocationSite(); |
1675 site->SetElementsKind(GetInitialFastElementsKind()); | 1667 site->SetElementsKind(GetInitialFastElementsKind()); |
1676 Handle<Cell> site_feedback_cell = isolate()->factory()->NewCell(site); | 1668 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; | 1710 Register receiver = a1; |
1719 | 1711 |
1720 // Get the receiver from the stack. | 1712 // Get the receiver from the stack. |
1721 const int argc = arguments().immediate(); | 1713 const int argc = arguments().immediate(); |
1722 __ lw(receiver, MemOperand(sp, argc * kPointerSize)); | 1714 __ lw(receiver, MemOperand(sp, argc * kPointerSize)); |
1723 | 1715 |
1724 // Check that the receiver isn't a smi. | 1716 // Check that the receiver isn't a smi. |
1725 __ JumpIfSmi(receiver, &miss); | 1717 __ JumpIfSmi(receiver, &miss); |
1726 | 1718 |
1727 // Check that the maps haven't changed. | 1719 // Check that the maps haven't changed. |
1728 CheckPrototypes(Handle<JSObject>::cast(object), receiver, holder, a3, v0, t0, | 1720 CheckPrototypes( |
1729 name, &miss); | 1721 IC::CurrentTypeOf(object, isolate()), receiver, holder, |
| 1722 a3, v0, t0, name, &miss); |
1730 | 1723 |
1731 if (argc == 0) { | 1724 if (argc == 0) { |
1732 // Nothing to do, just return the length. | 1725 // Nothing to do, just return the length. |
1733 __ lw(v0, FieldMemOperand(receiver, JSArray::kLengthOffset)); | 1726 __ lw(v0, FieldMemOperand(receiver, JSArray::kLengthOffset)); |
1734 __ DropAndRet(argc + 1); | 1727 __ DropAndRet(argc + 1); |
1735 } else { | 1728 } else { |
1736 Label call_builtin; | 1729 Label call_builtin; |
1737 if (argc == 1) { // Otherwise fall through to call the builtin. | 1730 if (argc == 1) { // Otherwise fall through to call the builtin. |
1738 Label attempt_to_grow_elements, with_write_barrier, check_double; | 1731 Label attempt_to_grow_elements, with_write_barrier, check_double; |
1739 | 1732 |
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1975 Register elements = a3; | 1968 Register elements = a3; |
1976 GenerateNameCheck(name, &miss); | 1969 GenerateNameCheck(name, &miss); |
1977 | 1970 |
1978 // Get the receiver from the stack. | 1971 // Get the receiver from the stack. |
1979 const int argc = arguments().immediate(); | 1972 const int argc = arguments().immediate(); |
1980 __ lw(receiver, MemOperand(sp, argc * kPointerSize)); | 1973 __ lw(receiver, MemOperand(sp, argc * kPointerSize)); |
1981 // Check that the receiver isn't a smi. | 1974 // Check that the receiver isn't a smi. |
1982 __ JumpIfSmi(receiver, &miss); | 1975 __ JumpIfSmi(receiver, &miss); |
1983 | 1976 |
1984 // Check that the maps haven't changed. | 1977 // Check that the maps haven't changed. |
1985 CheckPrototypes(Handle<JSObject>::cast(object), receiver, holder, elements, | 1978 CheckPrototypes( |
1986 t0, v0, name, &miss); | 1979 IC::CurrentTypeOf(object, isolate()), receiver, holder, |
| 1980 elements, t0, v0, name, &miss); |
1987 | 1981 |
1988 // Get the elements array of the object. | 1982 // Get the elements array of the object. |
1989 __ lw(elements, FieldMemOperand(receiver, JSArray::kElementsOffset)); | 1983 __ lw(elements, FieldMemOperand(receiver, JSArray::kElementsOffset)); |
1990 | 1984 |
1991 // Check that the elements are in fast mode and writable. | 1985 // Check that the elements are in fast mode and writable. |
1992 __ CheckMap(elements, | 1986 __ CheckMap(elements, |
1993 v0, | 1987 v0, |
1994 Heap::kFixedArrayMapRootIndex, | 1988 Heap::kFixedArrayMapRootIndex, |
1995 &call_builtin, | 1989 &call_builtin, |
1996 DONT_DO_SMI_CHECK); | 1990 DONT_DO_SMI_CHECK); |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2067 } | 2061 } |
2068 | 2062 |
2069 GenerateNameCheck(name, &name_miss); | 2063 GenerateNameCheck(name, &name_miss); |
2070 | 2064 |
2071 // Check that the maps starting from the prototype haven't changed. | 2065 // Check that the maps starting from the prototype haven't changed. |
2072 GenerateDirectLoadGlobalFunctionPrototype(masm(), | 2066 GenerateDirectLoadGlobalFunctionPrototype(masm(), |
2073 Context::STRING_FUNCTION_INDEX, | 2067 Context::STRING_FUNCTION_INDEX, |
2074 v0, | 2068 v0, |
2075 &miss); | 2069 &miss); |
2076 ASSERT(!object.is_identical_to(holder)); | 2070 ASSERT(!object.is_identical_to(holder)); |
| 2071 Handle<JSObject> prototype(JSObject::cast(object->GetPrototype(isolate()))); |
2077 CheckPrototypes( | 2072 CheckPrototypes( |
2078 Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))), | 2073 IC::CurrentTypeOf(prototype, isolate()), |
2079 v0, holder, a1, a3, t0, name, &miss); | 2074 v0, holder, a1, a3, t0, name, &miss); |
2080 | 2075 |
2081 Register receiver = a1; | 2076 Register receiver = a1; |
2082 Register index = t1; | 2077 Register index = t1; |
2083 Register result = v0; | 2078 Register result = v0; |
2084 __ lw(receiver, MemOperand(sp, argc * kPointerSize)); | 2079 __ lw(receiver, MemOperand(sp, argc * kPointerSize)); |
2085 if (argc > 0) { | 2080 if (argc > 0) { |
2086 __ lw(index, MemOperand(sp, (argc - 1) * kPointerSize)); | 2081 __ lw(index, MemOperand(sp, (argc - 1) * kPointerSize)); |
2087 } else { | 2082 } else { |
2088 __ LoadRoot(index, Heap::kUndefinedValueRootIndex); | 2083 __ LoadRoot(index, Heap::kUndefinedValueRootIndex); |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2147 index_out_of_range_label = &miss; | 2142 index_out_of_range_label = &miss; |
2148 } | 2143 } |
2149 GenerateNameCheck(name, &name_miss); | 2144 GenerateNameCheck(name, &name_miss); |
2150 | 2145 |
2151 // Check that the maps starting from the prototype haven't changed. | 2146 // Check that the maps starting from the prototype haven't changed. |
2152 GenerateDirectLoadGlobalFunctionPrototype(masm(), | 2147 GenerateDirectLoadGlobalFunctionPrototype(masm(), |
2153 Context::STRING_FUNCTION_INDEX, | 2148 Context::STRING_FUNCTION_INDEX, |
2154 v0, | 2149 v0, |
2155 &miss); | 2150 &miss); |
2156 ASSERT(!object.is_identical_to(holder)); | 2151 ASSERT(!object.is_identical_to(holder)); |
| 2152 Handle<JSObject> prototype(JSObject::cast(object->GetPrototype(isolate()))); |
2157 CheckPrototypes( | 2153 CheckPrototypes( |
2158 Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))), | 2154 IC::CurrentTypeOf(prototype, isolate()), |
2159 v0, holder, a1, a3, t0, name, &miss); | 2155 v0, holder, a1, a3, t0, name, &miss); |
2160 | 2156 |
2161 Register receiver = v0; | 2157 Register receiver = v0; |
2162 Register index = t1; | 2158 Register index = t1; |
2163 Register scratch = a3; | 2159 Register scratch = a3; |
2164 Register result = v0; | 2160 Register result = v0; |
2165 __ lw(receiver, MemOperand(sp, argc * kPointerSize)); | 2161 __ lw(receiver, MemOperand(sp, argc * kPointerSize)); |
2166 if (argc > 0) { | 2162 if (argc > 0) { |
2167 __ lw(index, MemOperand(sp, (argc - 1) * kPointerSize)); | 2163 __ lw(index, MemOperand(sp, (argc - 1) * kPointerSize)); |
2168 } else { | 2164 } else { |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2223 | 2219 |
2224 Label miss; | 2220 Label miss; |
2225 GenerateNameCheck(name, &miss); | 2221 GenerateNameCheck(name, &miss); |
2226 | 2222 |
2227 if (cell.is_null()) { | 2223 if (cell.is_null()) { |
2228 __ lw(a1, MemOperand(sp, 1 * kPointerSize)); | 2224 __ lw(a1, MemOperand(sp, 1 * kPointerSize)); |
2229 | 2225 |
2230 STATIC_ASSERT(kSmiTag == 0); | 2226 STATIC_ASSERT(kSmiTag == 0); |
2231 __ JumpIfSmi(a1, &miss); | 2227 __ JumpIfSmi(a1, &miss); |
2232 | 2228 |
2233 CheckPrototypes(Handle<JSObject>::cast(object), a1, holder, v0, a3, t0, | 2229 CheckPrototypes( |
2234 name, &miss); | 2230 IC::CurrentTypeOf(object, isolate()), |
| 2231 a1, holder, v0, a3, t0, name, &miss); |
2235 } else { | 2232 } else { |
2236 ASSERT(cell->value() == *function); | 2233 ASSERT(cell->value() == *function); |
2237 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name, | 2234 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name, |
2238 &miss); | 2235 &miss); |
2239 GenerateLoadFunctionFromCell(cell, function, &miss); | 2236 GenerateLoadFunctionFromCell(cell, function, &miss); |
2240 } | 2237 } |
2241 | 2238 |
2242 // Load the char code argument. | 2239 // Load the char code argument. |
2243 Register code = a1; | 2240 Register code = a1; |
2244 __ lw(code, MemOperand(sp, 0 * kPointerSize)); | 2241 __ 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. | 2292 // arguments, bail out to the regular call. |
2296 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null(); | 2293 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null(); |
2297 | 2294 |
2298 Label miss, slow; | 2295 Label miss, slow; |
2299 GenerateNameCheck(name, &miss); | 2296 GenerateNameCheck(name, &miss); |
2300 | 2297 |
2301 if (cell.is_null()) { | 2298 if (cell.is_null()) { |
2302 __ lw(a1, MemOperand(sp, 1 * kPointerSize)); | 2299 __ lw(a1, MemOperand(sp, 1 * kPointerSize)); |
2303 STATIC_ASSERT(kSmiTag == 0); | 2300 STATIC_ASSERT(kSmiTag == 0); |
2304 __ JumpIfSmi(a1, &miss); | 2301 __ JumpIfSmi(a1, &miss); |
2305 CheckPrototypes(Handle<JSObject>::cast(object), a1, holder, a0, a3, t0, | 2302 CheckPrototypes( |
2306 name, &miss); | 2303 IC::CurrentTypeOf(object, isolate()), |
| 2304 a1, holder, a0, a3, t0, name, &miss); |
2307 } else { | 2305 } else { |
2308 ASSERT(cell->value() == *function); | 2306 ASSERT(cell->value() == *function); |
2309 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name, | 2307 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name, |
2310 &miss); | 2308 &miss); |
2311 GenerateLoadFunctionFromCell(cell, function, &miss); | 2309 GenerateLoadFunctionFromCell(cell, function, &miss); |
2312 } | 2310 } |
2313 | 2311 |
2314 // Load the (only) argument into v0. | 2312 // Load the (only) argument into v0. |
2315 __ lw(v0, MemOperand(sp, 0 * kPointerSize)); | 2313 __ lw(v0, MemOperand(sp, 0 * kPointerSize)); |
2316 | 2314 |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2424 // arguments, bail out to the regular call. | 2422 // arguments, bail out to the regular call. |
2425 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null(); | 2423 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null(); |
2426 | 2424 |
2427 Label miss; | 2425 Label miss; |
2428 | 2426 |
2429 GenerateNameCheck(name, &miss); | 2427 GenerateNameCheck(name, &miss); |
2430 if (cell.is_null()) { | 2428 if (cell.is_null()) { |
2431 __ lw(a1, MemOperand(sp, 1 * kPointerSize)); | 2429 __ lw(a1, MemOperand(sp, 1 * kPointerSize)); |
2432 STATIC_ASSERT(kSmiTag == 0); | 2430 STATIC_ASSERT(kSmiTag == 0); |
2433 __ JumpIfSmi(a1, &miss); | 2431 __ JumpIfSmi(a1, &miss); |
2434 CheckPrototypes(Handle<JSObject>::cast(object), a1, holder, v0, a3, t0, | 2432 CheckPrototypes( |
2435 name, &miss); | 2433 IC::CurrentTypeOf(object, isolate()), |
| 2434 a1, holder, v0, a3, t0, name, &miss); |
2436 } else { | 2435 } else { |
2437 ASSERT(cell->value() == *function); | 2436 ASSERT(cell->value() == *function); |
2438 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name, | 2437 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name, |
2439 &miss); | 2438 &miss); |
2440 GenerateLoadFunctionFromCell(cell, function, &miss); | 2439 GenerateLoadFunctionFromCell(cell, function, &miss); |
2441 } | 2440 } |
2442 | 2441 |
2443 // Load the (only) argument into v0. | 2442 // Load the (only) argument into v0. |
2444 __ lw(v0, MemOperand(sp, 0 * kPointerSize)); | 2443 __ lw(v0, MemOperand(sp, 0 * kPointerSize)); |
2445 | 2444 |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2534 | 2533 |
2535 // Check that the receiver isn't a smi. | 2534 // Check that the receiver isn't a smi. |
2536 __ JumpIfSmi(a1, &miss_before_stack_reserved); | 2535 __ JumpIfSmi(a1, &miss_before_stack_reserved); |
2537 | 2536 |
2538 __ IncrementCounter(counters->call_const(), 1, a0, a3); | 2537 __ IncrementCounter(counters->call_const(), 1, a0, a3); |
2539 __ IncrementCounter(counters->call_const_fast_api(), 1, a0, a3); | 2538 __ IncrementCounter(counters->call_const_fast_api(), 1, a0, a3); |
2540 | 2539 |
2541 ReserveSpaceForFastApiCall(masm(), a0); | 2540 ReserveSpaceForFastApiCall(masm(), a0); |
2542 | 2541 |
2543 // Check that the maps haven't changed and find a Holder as a side effect. | 2542 // 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, | 2543 CheckPrototypes( |
2545 depth, &miss); | 2544 IC::CurrentTypeOf(object, isolate()), |
| 2545 a1, holder, a0, a3, t0, name, depth, &miss); |
2546 | 2546 |
2547 GenerateFastApiDirectCall(masm(), optimization, argc, false); | 2547 GenerateFastApiDirectCall(masm(), optimization, argc, false); |
2548 | 2548 |
2549 __ bind(&miss); | 2549 __ bind(&miss); |
2550 FreeSpaceForFastApiCall(masm()); | 2550 FreeSpaceForFastApiCall(masm()); |
2551 | 2551 |
2552 __ bind(&miss_before_stack_reserved); | 2552 __ bind(&miss_before_stack_reserved); |
2553 GenerateMissBranch(); | 2553 GenerateMissBranch(); |
2554 | 2554 |
2555 // Return the generated code. | 2555 // Return the generated code. |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2589 } | 2589 } |
2590 | 2590 |
2591 // Make sure that it's okay not to patch the on stack receiver | 2591 // Make sure that it's okay not to patch the on stack receiver |
2592 // unless we're doing a receiver map check. | 2592 // unless we're doing a receiver map check. |
2593 ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK); | 2593 ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK); |
2594 switch (check) { | 2594 switch (check) { |
2595 case RECEIVER_MAP_CHECK: | 2595 case RECEIVER_MAP_CHECK: |
2596 __ IncrementCounter(isolate()->counters()->call_const(), 1, a0, a3); | 2596 __ IncrementCounter(isolate()->counters()->call_const(), 1, a0, a3); |
2597 | 2597 |
2598 // Check that the maps haven't changed. | 2598 // Check that the maps haven't changed. |
2599 CheckPrototypes(Handle<JSObject>::cast(object), a1, holder, a0, a3, t0, | 2599 CheckPrototypes( |
2600 name, &miss); | 2600 IC::CurrentTypeOf(object, isolate()), |
| 2601 a1, holder, a0, a3, t0, name, &miss); |
2601 | 2602 |
2602 // Patch the receiver on the stack with the global proxy if | 2603 // Patch the receiver on the stack with the global proxy if |
2603 // necessary. | 2604 // necessary. |
2604 if (object->IsGlobalObject()) { | 2605 if (object->IsGlobalObject()) { |
2605 __ lw(a3, FieldMemOperand(a1, GlobalObject::kGlobalReceiverOffset)); | 2606 __ lw(a3, FieldMemOperand(a1, GlobalObject::kGlobalReceiverOffset)); |
2606 __ sw(a3, MemOperand(sp, argc * kPointerSize)); | 2607 __ sw(a3, MemOperand(sp, argc * kPointerSize)); |
2607 } | 2608 } |
2608 break; | 2609 break; |
2609 | 2610 |
2610 case STRING_CHECK: | 2611 case STRING_CHECK: { |
2611 // Check that the object is a string. | 2612 // Check that the object is a string. |
2612 __ GetObjectType(a1, a3, a3); | 2613 __ GetObjectType(a1, a3, a3); |
2613 __ Branch(&miss, Ugreater_equal, a3, Operand(FIRST_NONSTRING_TYPE)); | 2614 __ Branch(&miss, Ugreater_equal, a3, Operand(FIRST_NONSTRING_TYPE)); |
2614 // Check that the maps starting from the prototype haven't changed. | 2615 // Check that the maps starting from the prototype haven't changed. |
2615 GenerateDirectLoadGlobalFunctionPrototype( | 2616 GenerateDirectLoadGlobalFunctionPrototype( |
2616 masm(), Context::STRING_FUNCTION_INDEX, a0, &miss); | 2617 masm(), Context::STRING_FUNCTION_INDEX, a0, &miss); |
| 2618 Handle<Object> prototype(object->GetPrototype(isolate()), isolate()); |
2617 CheckPrototypes( | 2619 CheckPrototypes( |
2618 Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))), | 2620 IC::CurrentTypeOf(prototype, isolate()), |
2619 a0, holder, a3, a1, t0, name, &miss); | 2621 a0, holder, a3, a1, t0, name, &miss); |
2620 break; | 2622 break; |
2621 | 2623 } |
2622 case SYMBOL_CHECK: | 2624 case SYMBOL_CHECK: { |
2623 // Check that the object is a symbol. | 2625 // Check that the object is a symbol. |
2624 __ GetObjectType(a1, a1, a3); | 2626 __ GetObjectType(a1, a1, a3); |
2625 __ Branch(&miss, ne, a3, Operand(SYMBOL_TYPE)); | 2627 __ Branch(&miss, ne, a3, Operand(SYMBOL_TYPE)); |
2626 // Check that the maps starting from the prototype haven't changed. | 2628 // Check that the maps starting from the prototype haven't changed. |
2627 GenerateDirectLoadGlobalFunctionPrototype( | 2629 GenerateDirectLoadGlobalFunctionPrototype( |
2628 masm(), Context::SYMBOL_FUNCTION_INDEX, a0, &miss); | 2630 masm(), Context::SYMBOL_FUNCTION_INDEX, a0, &miss); |
| 2631 Handle<Object> prototype(object->GetPrototype(isolate()), isolate()); |
2629 CheckPrototypes( | 2632 CheckPrototypes( |
2630 Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))), | 2633 IC::CurrentTypeOf(prototype, isolate()), |
2631 a0, holder, a3, a1, t0, name, &miss); | 2634 a0, holder, a3, a1, t0, name, &miss); |
2632 break; | 2635 break; |
2633 | 2636 } |
2634 case NUMBER_CHECK: { | 2637 case NUMBER_CHECK: { |
2635 Label fast; | 2638 Label fast; |
2636 // Check that the object is a smi or a heap number. | 2639 // Check that the object is a smi or a heap number. |
2637 __ JumpIfSmi(a1, &fast); | 2640 __ JumpIfSmi(a1, &fast); |
2638 __ GetObjectType(a1, a0, a0); | 2641 __ GetObjectType(a1, a0, a0); |
2639 __ Branch(&miss, ne, a0, Operand(HEAP_NUMBER_TYPE)); | 2642 __ Branch(&miss, ne, a0, Operand(HEAP_NUMBER_TYPE)); |
2640 __ bind(&fast); | 2643 __ bind(&fast); |
2641 // Check that the maps starting from the prototype haven't changed. | 2644 // Check that the maps starting from the prototype haven't changed. |
2642 GenerateDirectLoadGlobalFunctionPrototype( | 2645 GenerateDirectLoadGlobalFunctionPrototype( |
2643 masm(), Context::NUMBER_FUNCTION_INDEX, a0, &miss); | 2646 masm(), Context::NUMBER_FUNCTION_INDEX, a0, &miss); |
| 2647 Handle<Object> prototype(object->GetPrototype(isolate()), isolate()); |
2644 CheckPrototypes( | 2648 CheckPrototypes( |
2645 Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))), | 2649 IC::CurrentTypeOf(prototype, isolate()), |
2646 a0, holder, a3, a1, t0, name, &miss); | 2650 a0, holder, a3, a1, t0, name, &miss); |
2647 break; | 2651 break; |
2648 } | 2652 } |
2649 case BOOLEAN_CHECK: { | 2653 case BOOLEAN_CHECK: { |
2650 GenerateBooleanCheck(a1, &miss); | 2654 GenerateBooleanCheck(a1, &miss); |
2651 | 2655 |
2652 // Check that the maps starting from the prototype haven't changed. | 2656 // Check that the maps starting from the prototype haven't changed. |
2653 GenerateDirectLoadGlobalFunctionPrototype( | 2657 GenerateDirectLoadGlobalFunctionPrototype( |
2654 masm(), Context::BOOLEAN_FUNCTION_INDEX, a0, &miss); | 2658 masm(), Context::BOOLEAN_FUNCTION_INDEX, a0, &miss); |
| 2659 Handle<Object> prototype(object->GetPrototype(isolate()), isolate()); |
2655 CheckPrototypes( | 2660 CheckPrototypes( |
2656 Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))), | 2661 IC::CurrentTypeOf(prototype, isolate()), |
2657 a0, holder, a3, a1, t0, name, &miss); | 2662 a0, holder, a3, a1, t0, name, &miss); |
2658 break; | 2663 break; |
2659 } | 2664 } |
2660 } | 2665 } |
2661 | 2666 |
2662 Label success; | 2667 Label success; |
2663 __ Branch(&success); | 2668 __ Branch(&success); |
2664 | 2669 |
2665 // Handle call cache miss. | 2670 // Handle call cache miss. |
2666 __ bind(&miss); | 2671 __ bind(&miss); |
(...skipping 516 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3183 // ----------------------------------- | 3188 // ----------------------------------- |
3184 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); | 3189 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); |
3185 } | 3190 } |
3186 | 3191 |
3187 | 3192 |
3188 #undef __ | 3193 #undef __ |
3189 | 3194 |
3190 } } // namespace v8::internal | 3195 } } // namespace v8::internal |
3191 | 3196 |
3192 #endif // V8_TARGET_ARCH_MIPS | 3197 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |