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 639 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
650 if (can_do_fast_api_call) { | 650 if (can_do_fast_api_call) { |
651 __ IncrementCounter(counters->call_const_interceptor_fast_api(), 1); | 651 __ IncrementCounter(counters->call_const_interceptor_fast_api(), 1); |
652 ReserveSpaceForFastApiCall(masm, scratch1); | 652 ReserveSpaceForFastApiCall(masm, scratch1); |
653 } | 653 } |
654 | 654 |
655 // Check that the maps from receiver to interceptor's holder | 655 // Check that the maps from receiver to interceptor's holder |
656 // haven't changed and thus we can invoke interceptor. | 656 // haven't changed and thus we can invoke interceptor. |
657 Label miss_cleanup; | 657 Label miss_cleanup; |
658 Label* miss = can_do_fast_api_call ? &miss_cleanup : miss_label; | 658 Label* miss = can_do_fast_api_call ? &miss_cleanup : miss_label; |
659 Register holder = | 659 Register holder = |
660 stub_compiler_->CheckPrototypes(object, receiver, interceptor_holder, | 660 stub_compiler_->CheckPrototypes( |
661 scratch1, scratch2, scratch3, | 661 IC::CurrentTypeOf(object, masm->isolate()), receiver, |
662 name, depth1, miss); | 662 interceptor_holder, scratch1, scratch2, scratch3, |
| 663 name, depth1, miss); |
663 | 664 |
664 // Invoke an interceptor and if it provides a value, | 665 // Invoke an interceptor and if it provides a value, |
665 // branch to |regular_invoke|. | 666 // branch to |regular_invoke|. |
666 Label regular_invoke; | 667 Label regular_invoke; |
667 LoadWithInterceptor(masm, receiver, holder, interceptor_holder, | 668 LoadWithInterceptor(masm, receiver, holder, interceptor_holder, |
668 ®ular_invoke); | 669 ®ular_invoke); |
669 | 670 |
670 // Interceptor returned nothing for this property. Try to use cached | 671 // Interceptor returned nothing for this property. Try to use cached |
671 // constant function. | 672 // constant function. |
672 | 673 |
673 // Check that the maps from interceptor's holder to constant function's | 674 // Check that the maps from interceptor's holder to constant function's |
674 // holder haven't changed and thus we can use cached constant function. | 675 // holder haven't changed and thus we can use cached constant function. |
675 if (*interceptor_holder != lookup->holder()) { | 676 if (*interceptor_holder != lookup->holder()) { |
676 stub_compiler_->CheckPrototypes(interceptor_holder, receiver, | 677 stub_compiler_->CheckPrototypes( |
677 Handle<JSObject>(lookup->holder()), | 678 IC::CurrentTypeOf(interceptor_holder, masm->isolate()), receiver, |
678 scratch1, scratch2, scratch3, | 679 handle(lookup->holder()), scratch1, scratch2, scratch3, |
679 name, depth2, miss); | 680 name, depth2, miss); |
680 } else { | 681 } else { |
681 // CheckPrototypes has a side effect of fetching a 'holder' | 682 // CheckPrototypes has a side effect of fetching a 'holder' |
682 // for API (object which is instanceof for the signature). It's | 683 // for API (object which is instanceof for the signature). It's |
683 // safe to omit it here, as if present, it should be fetched | 684 // safe to omit it here, as if present, it should be fetched |
684 // by the previous CheckPrototypes. | 685 // by the previous CheckPrototypes. |
685 ASSERT(depth2 == kInvalidProtoDepth); | 686 ASSERT(depth2 == kInvalidProtoDepth); |
686 } | 687 } |
687 | 688 |
688 // Invoke function. | 689 // Invoke function. |
689 if (can_do_fast_api_call) { | 690 if (can_do_fast_api_call) { |
(...skipping 25 matching lines...) Expand all Loading... |
715 void CompileRegular(MacroAssembler* masm, | 716 void CompileRegular(MacroAssembler* masm, |
716 Handle<JSObject> object, | 717 Handle<JSObject> object, |
717 Register receiver, | 718 Register receiver, |
718 Register scratch1, | 719 Register scratch1, |
719 Register scratch2, | 720 Register scratch2, |
720 Register scratch3, | 721 Register scratch3, |
721 Handle<Name> name, | 722 Handle<Name> name, |
722 Handle<JSObject> interceptor_holder, | 723 Handle<JSObject> interceptor_holder, |
723 Label* miss_label) { | 724 Label* miss_label) { |
724 Register holder = | 725 Register holder = |
725 stub_compiler_->CheckPrototypes(object, receiver, interceptor_holder, | 726 stub_compiler_->CheckPrototypes( |
726 scratch1, scratch2, scratch3, | 727 IC::CurrentTypeOf(object, masm->isolate()), receiver, |
727 name, miss_label); | 728 interceptor_holder, scratch1, scratch2, scratch3, name, miss_label); |
728 | 729 |
729 FrameScope scope(masm, StackFrame::INTERNAL); | 730 FrameScope scope(masm, StackFrame::INTERNAL); |
730 // Save the name_ register across the call. | 731 // Save the name_ register across the call. |
731 __ push(name_); | 732 __ push(name_); |
732 | 733 |
733 PushInterceptorArguments(masm, receiver, holder, name_, interceptor_holder); | 734 PushInterceptorArguments(masm, receiver, holder, name_, interceptor_holder); |
734 | 735 |
735 __ CallExternalReference( | 736 __ CallExternalReference( |
736 ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorForCall), | 737 ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorForCall), |
737 masm->isolate()), | 738 masm->isolate()), |
(...skipping 373 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1111 smi_check); | 1112 smi_check); |
1112 } | 1113 } |
1113 } | 1114 } |
1114 | 1115 |
1115 // Return the value (register eax). | 1116 // Return the value (register eax). |
1116 ASSERT(value_reg.is(eax)); | 1117 ASSERT(value_reg.is(eax)); |
1117 __ ret(0); | 1118 __ ret(0); |
1118 } | 1119 } |
1119 | 1120 |
1120 | 1121 |
1121 void StubCompiler::GenerateCheckPropertyCells(MacroAssembler* masm, | |
1122 Handle<JSObject> object, | |
1123 Handle<JSObject> holder, | |
1124 Handle<Name> name, | |
1125 Register scratch, | |
1126 Label* miss) { | |
1127 Handle<JSObject> current = object; | |
1128 while (!current.is_identical_to(holder)) { | |
1129 if (current->IsJSGlobalObject()) { | |
1130 GenerateCheckPropertyCell(masm, | |
1131 Handle<JSGlobalObject>::cast(current), | |
1132 name, | |
1133 scratch, | |
1134 miss); | |
1135 } | |
1136 current = Handle<JSObject>(JSObject::cast(current->GetPrototype())); | |
1137 } | |
1138 } | |
1139 | |
1140 | |
1141 void StubCompiler::GenerateTailCall(MacroAssembler* masm, Handle<Code> code) { | 1122 void StubCompiler::GenerateTailCall(MacroAssembler* masm, Handle<Code> code) { |
1142 __ jmp(code, RelocInfo::CODE_TARGET); | 1123 __ jmp(code, RelocInfo::CODE_TARGET); |
1143 } | 1124 } |
1144 | 1125 |
1145 | 1126 |
1146 #undef __ | 1127 #undef __ |
1147 #define __ ACCESS_MASM(masm()) | 1128 #define __ ACCESS_MASM(masm()) |
1148 | 1129 |
1149 | 1130 |
1150 Register StubCompiler::CheckPrototypes(Handle<JSObject> object, | 1131 Register StubCompiler::CheckPrototypes(Handle<Type> type, |
1151 Register object_reg, | 1132 Register object_reg, |
1152 Handle<JSObject> holder, | 1133 Handle<JSObject> holder, |
1153 Register holder_reg, | 1134 Register holder_reg, |
1154 Register scratch1, | 1135 Register scratch1, |
1155 Register scratch2, | 1136 Register scratch2, |
1156 Handle<Name> name, | 1137 Handle<Name> name, |
1157 int save_at_depth, | 1138 int save_at_depth, |
1158 Label* miss, | 1139 Label* miss, |
1159 PrototypeCheckType check) { | 1140 PrototypeCheckType check) { |
1160 const int kHolderIndex = FunctionCallbackArguments::kHolderIndex + 1; | 1141 Handle<Map> receiver_map(IC::TypeToMap(*type, isolate())); |
1161 // Make sure that the type feedback oracle harvests the receiver map. | 1142 // Make sure that the type feedback oracle harvests the receiver map. |
1162 // TODO(svenpanne) Remove this hack when all ICs are reworked. | 1143 // TODO(svenpanne) Remove this hack when all ICs are reworked. |
1163 __ mov(scratch1, Handle<Map>(object->map())); | 1144 __ mov(scratch1, receiver_map); |
1164 | 1145 |
1165 Handle<JSObject> first = object; | |
1166 // Make sure there's no overlap between holder and object registers. | 1146 // Make sure there's no overlap between holder and object registers. |
1167 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); | 1147 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); |
1168 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg) | 1148 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg) |
1169 && !scratch2.is(scratch1)); | 1149 && !scratch2.is(scratch1)); |
1170 | 1150 |
1171 // Keep track of the current object in register reg. | 1151 // Keep track of the current object in register reg. |
1172 Register reg = object_reg; | 1152 Register reg = object_reg; |
1173 Handle<JSObject> current = object; | |
1174 int depth = 0; | 1153 int depth = 0; |
1175 | 1154 |
| 1155 const int kHolderIndex = FunctionCallbackArguments::kHolderIndex + 1; |
1176 if (save_at_depth == depth) { | 1156 if (save_at_depth == depth) { |
1177 __ mov(Operand(esp, kHolderIndex * kPointerSize), reg); | 1157 __ mov(Operand(esp, kHolderIndex * kPointerSize), reg); |
1178 } | 1158 } |
1179 | 1159 |
| 1160 Handle<JSObject> current = Handle<JSObject>::null(); |
| 1161 if (type->IsConstant()) current = Handle<JSObject>::cast(type->AsConstant()); |
| 1162 Handle<JSObject> prototype = Handle<JSObject>::null(); |
| 1163 Handle<Map> current_map = receiver_map; |
| 1164 Handle<Map> holder_map(holder->map()); |
1180 // Traverse the prototype chain and check the maps in the prototype chain for | 1165 // Traverse the prototype chain and check the maps in the prototype chain for |
1181 // fast and global objects or do negative lookup for normal objects. | 1166 // fast and global objects or do negative lookup for normal objects. |
1182 while (!current.is_identical_to(holder)) { | 1167 while (!current_map.is_identical_to(holder_map)) { |
1183 ++depth; | 1168 ++depth; |
1184 | 1169 |
1185 // Only global objects and objects that do not require access | 1170 // Only global objects and objects that do not require access |
1186 // checks are allowed in stubs. | 1171 // checks are allowed in stubs. |
1187 ASSERT(current->IsJSGlobalProxy() || !current->IsAccessCheckNeeded()); | 1172 ASSERT(current_map->IsJSGlobalProxyMap() || |
| 1173 !current_map->is_access_check_needed()); |
1188 | 1174 |
1189 Handle<JSObject> prototype(JSObject::cast(current->GetPrototype())); | 1175 prototype = handle(JSObject::cast(current_map->prototype())); |
1190 if (!current->HasFastProperties() && | 1176 if (current_map->is_dictionary_map() && |
1191 !current->IsJSGlobalObject() && | 1177 !current_map->IsJSGlobalObjectMap() && |
1192 !current->IsJSGlobalProxy()) { | 1178 !current_map->IsJSGlobalProxyMap()) { |
1193 if (!name->IsUniqueName()) { | 1179 if (!name->IsUniqueName()) { |
1194 ASSERT(name->IsString()); | 1180 ASSERT(name->IsString()); |
1195 name = factory()->InternalizeString(Handle<String>::cast(name)); | 1181 name = factory()->InternalizeString(Handle<String>::cast(name)); |
1196 } | 1182 } |
1197 ASSERT(current->property_dictionary()->FindEntry(*name) == | 1183 ASSERT(current.is_null() || |
| 1184 current->property_dictionary()->FindEntry(*name) == |
1198 NameDictionary::kNotFound); | 1185 NameDictionary::kNotFound); |
1199 | 1186 |
1200 GenerateDictionaryNegativeLookup(masm(), miss, reg, name, | 1187 GenerateDictionaryNegativeLookup(masm(), miss, reg, name, |
1201 scratch1, scratch2); | 1188 scratch1, scratch2); |
1202 | 1189 |
1203 __ mov(scratch1, FieldOperand(reg, HeapObject::kMapOffset)); | 1190 __ mov(scratch1, FieldOperand(reg, HeapObject::kMapOffset)); |
1204 reg = holder_reg; // From now on the object will be in holder_reg. | 1191 reg = holder_reg; // From now on the object will be in holder_reg. |
1205 __ mov(reg, FieldOperand(scratch1, Map::kPrototypeOffset)); | 1192 __ mov(reg, FieldOperand(scratch1, Map::kPrototypeOffset)); |
1206 } else { | 1193 } else { |
1207 bool in_new_space = heap()->InNewSpace(*prototype); | 1194 bool in_new_space = heap()->InNewSpace(*prototype); |
1208 Handle<Map> current_map(current->map()); | 1195 if (depth != 1 || check == CHECK_ALL_MAPS) { |
1209 if (!current.is_identical_to(first) || check == CHECK_ALL_MAPS) { | |
1210 __ CheckMap(reg, current_map, miss, DONT_DO_SMI_CHECK); | 1196 __ CheckMap(reg, current_map, miss, DONT_DO_SMI_CHECK); |
1211 } | 1197 } |
1212 | 1198 |
1213 // Check access rights to the global object. This has to happen after | 1199 // Check access rights to the global object. This has to happen after |
1214 // the map check so that we know that the object is actually a global | 1200 // the map check so that we know that the object is actually a global |
1215 // object. | 1201 // object. |
1216 if (current->IsJSGlobalProxy()) { | 1202 if (current_map->IsJSGlobalProxyMap()) { |
1217 __ CheckAccessGlobalProxy(reg, scratch1, scratch2, miss); | 1203 __ CheckAccessGlobalProxy(reg, scratch1, scratch2, miss); |
| 1204 } else if (current_map->IsJSGlobalObjectMap()) { |
| 1205 GenerateCheckPropertyCell( |
| 1206 masm(), Handle<JSGlobalObject>::cast(current), name, |
| 1207 scratch2, miss); |
1218 } | 1208 } |
1219 | 1209 |
1220 if (in_new_space) { | 1210 if (in_new_space) { |
1221 // Save the map in scratch1 for later. | 1211 // Save the map in scratch1 for later. |
1222 __ mov(scratch1, FieldOperand(reg, HeapObject::kMapOffset)); | 1212 __ mov(scratch1, FieldOperand(reg, HeapObject::kMapOffset)); |
1223 } | 1213 } |
1224 | 1214 |
1225 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. |
1226 | 1216 |
1227 if (in_new_space) { | 1217 if (in_new_space) { |
1228 // The prototype is in new space; we cannot store a reference to it | 1218 // The prototype is in new space; we cannot store a reference to it |
1229 // in the code. Load it from the map. | 1219 // in the code. Load it from the map. |
1230 __ mov(reg, FieldOperand(scratch1, Map::kPrototypeOffset)); | 1220 __ mov(reg, FieldOperand(scratch1, Map::kPrototypeOffset)); |
1231 } else { | 1221 } else { |
1232 // The prototype is in old space; load it directly. | 1222 // The prototype is in old space; load it directly. |
1233 __ mov(reg, prototype); | 1223 __ mov(reg, prototype); |
1234 } | 1224 } |
1235 } | 1225 } |
1236 | 1226 |
1237 if (save_at_depth == depth) { | 1227 if (save_at_depth == depth) { |
1238 __ mov(Operand(esp, kHolderIndex * kPointerSize), reg); | 1228 __ mov(Operand(esp, kHolderIndex * kPointerSize), reg); |
1239 } | 1229 } |
1240 | 1230 |
1241 // Go to the next object in the prototype chain. | 1231 // Go to the next object in the prototype chain. |
1242 current = prototype; | 1232 current = prototype; |
| 1233 current_map = handle(current->map()); |
1243 } | 1234 } |
1244 ASSERT(current.is_identical_to(holder)); | |
1245 | 1235 |
1246 // Log the check depth. | 1236 // Log the check depth. |
1247 LOG(isolate(), IntEvent("check-maps-depth", depth + 1)); | 1237 LOG(isolate(), IntEvent("check-maps-depth", depth + 1)); |
1248 | 1238 |
1249 if (!holder.is_identical_to(first) || check == CHECK_ALL_MAPS) { | 1239 if (depth != 0 || check == CHECK_ALL_MAPS) { |
1250 // Check the holder map. | 1240 // Check the holder map. |
1251 __ CheckMap(reg, Handle<Map>(holder->map()), miss, DONT_DO_SMI_CHECK); | 1241 __ CheckMap(reg, current_map, miss, DONT_DO_SMI_CHECK); |
1252 } | 1242 } |
1253 | 1243 |
1254 // Perform security check for access to the global object. | 1244 // Perform security check for access to the global object. |
1255 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded()); | 1245 ASSERT(current_map->IsJSGlobalProxyMap() || |
1256 if (holder->IsJSGlobalProxy()) { | 1246 !current_map->is_access_check_needed()); |
| 1247 if (current_map->IsJSGlobalProxyMap()) { |
1257 __ CheckAccessGlobalProxy(reg, scratch1, scratch2, miss); | 1248 __ CheckAccessGlobalProxy(reg, scratch1, scratch2, miss); |
1258 } | 1249 } |
1259 | 1250 |
1260 // If we've skipped any global objects, it's not enough to verify that | |
1261 // their maps haven't changed. We also need to check that the property | |
1262 // cell for the property is still empty. | |
1263 GenerateCheckPropertyCells(masm(), object, holder, name, scratch1, miss); | |
1264 | |
1265 // Return the register containing the holder. | 1251 // Return the register containing the holder. |
1266 return reg; | 1252 return reg; |
1267 } | 1253 } |
1268 | 1254 |
1269 | 1255 |
1270 void LoadStubCompiler::HandlerFrontendFooter(Handle<Name> name, Label* miss) { | 1256 void LoadStubCompiler::HandlerFrontendFooter(Handle<Name> name, Label* miss) { |
1271 if (!miss->is_unused()) { | 1257 if (!miss->is_unused()) { |
1272 Label success; | 1258 Label success; |
1273 __ jmp(&success); | 1259 __ jmp(&success); |
1274 __ bind(miss); | 1260 __ bind(miss); |
(...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1564 | 1550 |
1565 // Get the number of arguments. | 1551 // Get the number of arguments. |
1566 const int argc = arguments().immediate(); | 1552 const int argc = arguments().immediate(); |
1567 | 1553 |
1568 // Get the receiver from the stack. | 1554 // Get the receiver from the stack. |
1569 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); | 1555 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); |
1570 | 1556 |
1571 | 1557 |
1572 // Check that the maps haven't changed. | 1558 // Check that the maps haven't changed. |
1573 __ JumpIfSmi(edx, miss); | 1559 __ JumpIfSmi(edx, miss); |
1574 CheckPrototypes(object, edx, holder, ebx, eax, edi, name, miss); | 1560 CheckPrototypes(IC::CurrentTypeOf(object, isolate()), edx, holder, |
| 1561 ebx, eax, edi, name, miss); |
1575 } | 1562 } |
1576 | 1563 |
1577 | 1564 |
1578 void CallStubCompiler::GenerateLoadFunctionFromCell( | 1565 void CallStubCompiler::GenerateLoadFunctionFromCell( |
1579 Handle<Cell> cell, | 1566 Handle<Cell> cell, |
1580 Handle<JSFunction> function, | 1567 Handle<JSFunction> function, |
1581 Label* miss) { | 1568 Label* miss) { |
1582 // Get the value from the cell. | 1569 // Get the value from the cell. |
1583 if (Serializer::enabled()) { | 1570 if (Serializer::enabled()) { |
1584 __ mov(edi, Immediate(cell)); | 1571 __ mov(edi, Immediate(cell)); |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1633 GenerateNameCheck(name, &miss); | 1620 GenerateNameCheck(name, &miss); |
1634 | 1621 |
1635 // Get the receiver from the stack. | 1622 // Get the receiver from the stack. |
1636 const int argc = arguments().immediate(); | 1623 const int argc = arguments().immediate(); |
1637 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); | 1624 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); |
1638 | 1625 |
1639 // Check that the receiver isn't a smi. | 1626 // Check that the receiver isn't a smi. |
1640 __ JumpIfSmi(edx, &miss); | 1627 __ JumpIfSmi(edx, &miss); |
1641 | 1628 |
1642 // Do the right check and compute the holder register. | 1629 // Do the right check and compute the holder register. |
1643 Register reg = CheckPrototypes(object, edx, holder, ebx, eax, edi, | 1630 Register reg = CheckPrototypes(IC::CurrentTypeOf(object, isolate()), edx, |
1644 name, &miss); | 1631 holder, ebx, eax, edi, name, &miss); |
1645 | 1632 |
1646 GenerateFastPropertyLoad( | 1633 GenerateFastPropertyLoad( |
1647 masm(), edi, reg, index.is_inobject(holder), | 1634 masm(), edi, reg, index.is_inobject(holder), |
1648 index.translate(holder), Representation::Tagged()); | 1635 index.translate(holder), Representation::Tagged()); |
1649 | 1636 |
1650 // Check that the function really is a function. | 1637 // Check that the function really is a function. |
1651 __ JumpIfSmi(edi, &miss); | 1638 __ JumpIfSmi(edi, &miss); |
1652 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ebx); | 1639 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ebx); |
1653 __ j(not_equal, &miss); | 1640 __ j(not_equal, &miss); |
1654 | 1641 |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1687 // Check that function is still array | 1674 // Check that function is still array |
1688 const int argc = arguments().immediate(); | 1675 const int argc = arguments().immediate(); |
1689 GenerateNameCheck(name, &miss); | 1676 GenerateNameCheck(name, &miss); |
1690 | 1677 |
1691 if (cell.is_null()) { | 1678 if (cell.is_null()) { |
1692 // Get the receiver from the stack. | 1679 // Get the receiver from the stack. |
1693 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); | 1680 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); |
1694 | 1681 |
1695 // Check that the receiver isn't a smi. | 1682 // Check that the receiver isn't a smi. |
1696 __ JumpIfSmi(edx, &miss); | 1683 __ JumpIfSmi(edx, &miss); |
1697 CheckPrototypes(Handle<JSObject>::cast(object), edx, holder, ebx, eax, edi, | 1684 CheckPrototypes(IC::CurrentTypeOf(object, isolate()), edx, holder, |
1698 name, &miss); | 1685 ebx, eax, edi, name, &miss); |
1699 } else { | 1686 } else { |
1700 ASSERT(cell->value() == *function); | 1687 ASSERT(cell->value() == *function); |
1701 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name, | 1688 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name, |
1702 &miss); | 1689 &miss); |
1703 GenerateLoadFunctionFromCell(cell, function, &miss); | 1690 GenerateLoadFunctionFromCell(cell, function, &miss); |
1704 } | 1691 } |
1705 | 1692 |
1706 Handle<AllocationSite> site = isolate()->factory()->NewAllocationSite(); | 1693 Handle<AllocationSite> site = isolate()->factory()->NewAllocationSite(); |
1707 site->SetElementsKind(GetInitialFastElementsKind()); | 1694 site->SetElementsKind(GetInitialFastElementsKind()); |
1708 Handle<Cell> site_feedback_cell = isolate()->factory()->NewCell(site); | 1695 Handle<Cell> site_feedback_cell = isolate()->factory()->NewCell(site); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1747 | 1734 |
1748 GenerateNameCheck(name, &miss); | 1735 GenerateNameCheck(name, &miss); |
1749 | 1736 |
1750 // Get the receiver from the stack. | 1737 // Get the receiver from the stack. |
1751 const int argc = arguments().immediate(); | 1738 const int argc = arguments().immediate(); |
1752 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); | 1739 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); |
1753 | 1740 |
1754 // Check that the receiver isn't a smi. | 1741 // Check that the receiver isn't a smi. |
1755 __ JumpIfSmi(edx, &miss); | 1742 __ JumpIfSmi(edx, &miss); |
1756 | 1743 |
1757 CheckPrototypes(Handle<JSObject>::cast(object), edx, holder, ebx, eax, edi, | 1744 CheckPrototypes(IC::CurrentTypeOf(object, isolate()), edx, holder, |
1758 name, &miss); | 1745 ebx, eax, edi, name, &miss); |
1759 | 1746 |
1760 if (argc == 0) { | 1747 if (argc == 0) { |
1761 // Noop, return the length. | 1748 // Noop, return the length. |
1762 __ mov(eax, FieldOperand(edx, JSArray::kLengthOffset)); | 1749 __ mov(eax, FieldOperand(edx, JSArray::kLengthOffset)); |
1763 __ ret((argc + 1) * kPointerSize); | 1750 __ ret((argc + 1) * kPointerSize); |
1764 } else { | 1751 } else { |
1765 Label call_builtin; | 1752 Label call_builtin; |
1766 | 1753 |
1767 if (argc == 1) { // Otherwise fall through to call builtin. | 1754 if (argc == 1) { // Otherwise fall through to call builtin. |
1768 Label attempt_to_grow_elements, with_write_barrier, check_double; | 1755 Label attempt_to_grow_elements, with_write_barrier, check_double; |
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2007 Label miss, return_undefined, call_builtin; | 1994 Label miss, return_undefined, call_builtin; |
2008 | 1995 |
2009 GenerateNameCheck(name, &miss); | 1996 GenerateNameCheck(name, &miss); |
2010 | 1997 |
2011 // Get the receiver from the stack. | 1998 // Get the receiver from the stack. |
2012 const int argc = arguments().immediate(); | 1999 const int argc = arguments().immediate(); |
2013 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); | 2000 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); |
2014 | 2001 |
2015 // Check that the receiver isn't a smi. | 2002 // Check that the receiver isn't a smi. |
2016 __ JumpIfSmi(edx, &miss); | 2003 __ JumpIfSmi(edx, &miss); |
2017 CheckPrototypes(Handle<JSObject>::cast(object), edx, holder, ebx, eax, edi, | 2004 CheckPrototypes(IC::CurrentTypeOf(object, isolate()), edx, holder, |
2018 name, &miss); | 2005 ebx, eax, edi, name, &miss); |
2019 | 2006 |
2020 // Get the elements array of the object. | 2007 // Get the elements array of the object. |
2021 __ mov(ebx, FieldOperand(edx, JSArray::kElementsOffset)); | 2008 __ mov(ebx, FieldOperand(edx, JSArray::kElementsOffset)); |
2022 | 2009 |
2023 // Check that the elements are in fast mode and writable. | 2010 // Check that the elements are in fast mode and writable. |
2024 __ cmp(FieldOperand(ebx, HeapObject::kMapOffset), | 2011 __ cmp(FieldOperand(ebx, HeapObject::kMapOffset), |
2025 Immediate(factory()->fixed_array_map())); | 2012 Immediate(factory()->fixed_array_map())); |
2026 __ j(not_equal, &call_builtin); | 2013 __ j(not_equal, &call_builtin); |
2027 | 2014 |
2028 // Get the array's length into ecx and calculate new length. | 2015 // Get the array's length into ecx and calculate new length. |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2101 } | 2088 } |
2102 | 2089 |
2103 GenerateNameCheck(name, &name_miss); | 2090 GenerateNameCheck(name, &name_miss); |
2104 | 2091 |
2105 // Check that the maps starting from the prototype haven't changed. | 2092 // Check that the maps starting from the prototype haven't changed. |
2106 GenerateDirectLoadGlobalFunctionPrototype(masm(), | 2093 GenerateDirectLoadGlobalFunctionPrototype(masm(), |
2107 Context::STRING_FUNCTION_INDEX, | 2094 Context::STRING_FUNCTION_INDEX, |
2108 eax, | 2095 eax, |
2109 &miss); | 2096 &miss); |
2110 ASSERT(!object.is_identical_to(holder)); | 2097 ASSERT(!object.is_identical_to(holder)); |
| 2098 Handle<Object> prototype(object->GetPrototype(isolate()), isolate()); |
2111 CheckPrototypes( | 2099 CheckPrototypes( |
2112 Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))), | 2100 IC::CurrentTypeOf(prototype, isolate()), |
2113 eax, holder, ebx, edx, edi, name, &miss); | 2101 eax, holder, ebx, edx, edi, name, &miss); |
2114 | 2102 |
2115 Register receiver = ebx; | 2103 Register receiver = ebx; |
2116 Register index = edi; | 2104 Register index = edi; |
2117 Register result = eax; | 2105 Register result = eax; |
2118 __ mov(receiver, Operand(esp, (argc + 1) * kPointerSize)); | 2106 __ mov(receiver, Operand(esp, (argc + 1) * kPointerSize)); |
2119 if (argc > 0) { | 2107 if (argc > 0) { |
2120 __ mov(index, Operand(esp, (argc - 0) * kPointerSize)); | 2108 __ mov(index, Operand(esp, (argc - 0) * kPointerSize)); |
2121 } else { | 2109 } else { |
2122 __ Set(index, Immediate(factory()->undefined_value())); | 2110 __ Set(index, Immediate(factory()->undefined_value())); |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2186 } | 2174 } |
2187 | 2175 |
2188 GenerateNameCheck(name, &name_miss); | 2176 GenerateNameCheck(name, &name_miss); |
2189 | 2177 |
2190 // Check that the maps starting from the prototype haven't changed. | 2178 // Check that the maps starting from the prototype haven't changed. |
2191 GenerateDirectLoadGlobalFunctionPrototype(masm(), | 2179 GenerateDirectLoadGlobalFunctionPrototype(masm(), |
2192 Context::STRING_FUNCTION_INDEX, | 2180 Context::STRING_FUNCTION_INDEX, |
2193 eax, | 2181 eax, |
2194 &miss); | 2182 &miss); |
2195 ASSERT(!object.is_identical_to(holder)); | 2183 ASSERT(!object.is_identical_to(holder)); |
| 2184 Handle<Object> prototype(object->GetPrototype(isolate()), isolate()); |
2196 CheckPrototypes( | 2185 CheckPrototypes( |
2197 Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))), | 2186 IC::CurrentTypeOf(prototype, isolate()), |
2198 eax, holder, ebx, edx, edi, name, &miss); | 2187 eax, holder, ebx, edx, edi, name, &miss); |
2199 | 2188 |
2200 Register receiver = eax; | 2189 Register receiver = eax; |
2201 Register index = edi; | 2190 Register index = edi; |
2202 Register scratch = edx; | 2191 Register scratch = edx; |
2203 Register result = eax; | 2192 Register result = eax; |
2204 __ mov(receiver, Operand(esp, (argc + 1) * kPointerSize)); | 2193 __ mov(receiver, Operand(esp, (argc + 1) * kPointerSize)); |
2205 if (argc > 0) { | 2194 if (argc > 0) { |
2206 __ mov(index, Operand(esp, (argc - 0) * kPointerSize)); | 2195 __ mov(index, Operand(esp, (argc - 0) * kPointerSize)); |
2207 } else { | 2196 } else { |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2262 return Handle<Code>::null(); | 2251 return Handle<Code>::null(); |
2263 } | 2252 } |
2264 | 2253 |
2265 Label miss; | 2254 Label miss; |
2266 GenerateNameCheck(name, &miss); | 2255 GenerateNameCheck(name, &miss); |
2267 | 2256 |
2268 if (cell.is_null()) { | 2257 if (cell.is_null()) { |
2269 __ mov(edx, Operand(esp, 2 * kPointerSize)); | 2258 __ mov(edx, Operand(esp, 2 * kPointerSize)); |
2270 STATIC_ASSERT(kSmiTag == 0); | 2259 STATIC_ASSERT(kSmiTag == 0); |
2271 __ JumpIfSmi(edx, &miss); | 2260 __ JumpIfSmi(edx, &miss); |
2272 CheckPrototypes(Handle<JSObject>::cast(object), edx, holder, ebx, eax, edi, | 2261 CheckPrototypes(IC::CurrentTypeOf(object, isolate()), edx, holder, |
2273 name, &miss); | 2262 ebx, eax, edi, name, &miss); |
2274 } else { | 2263 } else { |
2275 ASSERT(cell->value() == *function); | 2264 ASSERT(cell->value() == *function); |
2276 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name, | 2265 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name, |
2277 &miss); | 2266 &miss); |
2278 GenerateLoadFunctionFromCell(cell, function, &miss); | 2267 GenerateLoadFunctionFromCell(cell, function, &miss); |
2279 } | 2268 } |
2280 | 2269 |
2281 // Load the char code argument. | 2270 // Load the char code argument. |
2282 Register code = ebx; | 2271 Register code = ebx; |
2283 __ mov(code, Operand(esp, 1 * kPointerSize)); | 2272 __ mov(code, Operand(esp, 1 * kPointerSize)); |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2347 | 2336 |
2348 Label miss; | 2337 Label miss; |
2349 GenerateNameCheck(name, &miss); | 2338 GenerateNameCheck(name, &miss); |
2350 | 2339 |
2351 if (cell.is_null()) { | 2340 if (cell.is_null()) { |
2352 __ mov(edx, Operand(esp, 2 * kPointerSize)); | 2341 __ mov(edx, Operand(esp, 2 * kPointerSize)); |
2353 | 2342 |
2354 STATIC_ASSERT(kSmiTag == 0); | 2343 STATIC_ASSERT(kSmiTag == 0); |
2355 __ JumpIfSmi(edx, &miss); | 2344 __ JumpIfSmi(edx, &miss); |
2356 | 2345 |
2357 CheckPrototypes(Handle<JSObject>::cast(object), edx, holder, ebx, eax, edi, | 2346 CheckPrototypes(IC::CurrentTypeOf(object, isolate()), edx, holder, |
2358 name, &miss); | 2347 ebx, eax, edi, name, &miss); |
2359 } else { | 2348 } else { |
2360 ASSERT(cell->value() == *function); | 2349 ASSERT(cell->value() == *function); |
2361 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name, | 2350 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name, |
2362 &miss); | 2351 &miss); |
2363 GenerateLoadFunctionFromCell(cell, function, &miss); | 2352 GenerateLoadFunctionFromCell(cell, function, &miss); |
2364 } | 2353 } |
2365 | 2354 |
2366 // Load the (only) argument into eax. | 2355 // Load the (only) argument into eax. |
2367 __ mov(eax, Operand(esp, 1 * kPointerSize)); | 2356 __ mov(eax, Operand(esp, 1 * kPointerSize)); |
2368 | 2357 |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2473 | 2462 |
2474 Label miss; | 2463 Label miss; |
2475 GenerateNameCheck(name, &miss); | 2464 GenerateNameCheck(name, &miss); |
2476 | 2465 |
2477 if (cell.is_null()) { | 2466 if (cell.is_null()) { |
2478 __ mov(edx, Operand(esp, 2 * kPointerSize)); | 2467 __ mov(edx, Operand(esp, 2 * kPointerSize)); |
2479 | 2468 |
2480 STATIC_ASSERT(kSmiTag == 0); | 2469 STATIC_ASSERT(kSmiTag == 0); |
2481 __ JumpIfSmi(edx, &miss); | 2470 __ JumpIfSmi(edx, &miss); |
2482 | 2471 |
2483 CheckPrototypes(Handle<JSObject>::cast(object), edx, holder, ebx, eax, edi, | 2472 CheckPrototypes(IC::CurrentTypeOf(object, isolate()), edx, holder, |
2484 name, &miss); | 2473 ebx, eax, edi, name, &miss); |
2485 } else { | 2474 } else { |
2486 ASSERT(cell->value() == *function); | 2475 ASSERT(cell->value() == *function); |
2487 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name, | 2476 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name, |
2488 &miss); | 2477 &miss); |
2489 GenerateLoadFunctionFromCell(cell, function, &miss); | 2478 GenerateLoadFunctionFromCell(cell, function, &miss); |
2490 } | 2479 } |
2491 | 2480 |
2492 // Load the (only) argument into eax. | 2481 // Load the (only) argument into eax. |
2493 __ mov(eax, Operand(esp, 1 * kPointerSize)); | 2482 __ mov(eax, Operand(esp, 1 * kPointerSize)); |
2494 | 2483 |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2587 | 2576 |
2588 Counters* counters = isolate()->counters(); | 2577 Counters* counters = isolate()->counters(); |
2589 __ IncrementCounter(counters->call_const(), 1); | 2578 __ IncrementCounter(counters->call_const(), 1); |
2590 __ IncrementCounter(counters->call_const_fast_api(), 1); | 2579 __ IncrementCounter(counters->call_const_fast_api(), 1); |
2591 | 2580 |
2592 // Allocate space for v8::Arguments implicit values. Must be initialized | 2581 // Allocate space for v8::Arguments implicit values. Must be initialized |
2593 // before calling any runtime function. | 2582 // before calling any runtime function. |
2594 __ sub(esp, Immediate(kFastApiCallArguments * kPointerSize)); | 2583 __ sub(esp, Immediate(kFastApiCallArguments * kPointerSize)); |
2595 | 2584 |
2596 // Check that the maps haven't changed and find a Holder as a side effect. | 2585 // Check that the maps haven't changed and find a Holder as a side effect. |
2597 CheckPrototypes(Handle<JSObject>::cast(object), edx, holder, ebx, eax, edi, | 2586 CheckPrototypes(IC::CurrentTypeOf(object, isolate()), edx, holder, |
2598 name, depth, &miss); | 2587 ebx, eax, edi, name, depth, &miss); |
2599 | 2588 |
2600 // Move the return address on top of the stack. | 2589 // Move the return address on top of the stack. |
2601 __ mov(eax, Operand(esp, kFastApiCallArguments * kPointerSize)); | 2590 __ mov(eax, Operand(esp, kFastApiCallArguments * kPointerSize)); |
2602 __ mov(Operand(esp, 0 * kPointerSize), eax); | 2591 __ mov(Operand(esp, 0 * kPointerSize), eax); |
2603 | 2592 |
2604 // esp[2 * kPointerSize] is uninitialized, esp[3 * kPointerSize] contains | 2593 // esp[2 * kPointerSize] is uninitialized, esp[3 * kPointerSize] contains |
2605 // duplicate of return address and will be overwritten. | 2594 // duplicate of return address and will be overwritten. |
2606 GenerateFastApiCall(masm(), optimization, argc, false); | 2595 GenerateFastApiCall(masm(), optimization, argc, false); |
2607 | 2596 |
2608 __ bind(&miss); | 2597 __ bind(&miss); |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2651 } | 2640 } |
2652 | 2641 |
2653 // Make sure that it's okay not to patch the on stack receiver | 2642 // Make sure that it's okay not to patch the on stack receiver |
2654 // unless we're doing a receiver map check. | 2643 // unless we're doing a receiver map check. |
2655 ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK); | 2644 ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK); |
2656 switch (check) { | 2645 switch (check) { |
2657 case RECEIVER_MAP_CHECK: | 2646 case RECEIVER_MAP_CHECK: |
2658 __ IncrementCounter(isolate()->counters()->call_const(), 1); | 2647 __ IncrementCounter(isolate()->counters()->call_const(), 1); |
2659 | 2648 |
2660 // Check that the maps haven't changed. | 2649 // Check that the maps haven't changed. |
2661 CheckPrototypes(Handle<JSObject>::cast(object), edx, holder, ebx, eax, | 2650 CheckPrototypes(IC::CurrentTypeOf(object, isolate()), edx, holder, |
2662 edi, name, &miss); | 2651 ebx, eax, edi, name, &miss); |
2663 | 2652 |
2664 // Patch the receiver on the stack with the global proxy if | 2653 // Patch the receiver on the stack with the global proxy if |
2665 // necessary. | 2654 // necessary. |
2666 if (object->IsGlobalObject()) { | 2655 if (object->IsGlobalObject()) { |
2667 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset)); | 2656 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset)); |
2668 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx); | 2657 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx); |
2669 } | 2658 } |
2670 break; | 2659 break; |
2671 | 2660 |
2672 case STRING_CHECK: | 2661 case STRING_CHECK: { |
2673 // Check that the object is a string. | 2662 // Check that the object is a string. |
2674 __ CmpObjectType(edx, FIRST_NONSTRING_TYPE, eax); | 2663 __ CmpObjectType(edx, FIRST_NONSTRING_TYPE, eax); |
2675 __ j(above_equal, &miss); | 2664 __ j(above_equal, &miss); |
2676 // Check that the maps starting from the prototype haven't changed. | 2665 // Check that the maps starting from the prototype haven't changed. |
2677 GenerateDirectLoadGlobalFunctionPrototype( | 2666 GenerateDirectLoadGlobalFunctionPrototype( |
2678 masm(), Context::STRING_FUNCTION_INDEX, eax, &miss); | 2667 masm(), Context::STRING_FUNCTION_INDEX, eax, &miss); |
| 2668 Handle<Object> prototype(object->GetPrototype(isolate()), isolate()); |
2679 CheckPrototypes( | 2669 CheckPrototypes( |
2680 Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))), | 2670 IC::CurrentTypeOf(prototype, isolate()), |
2681 eax, holder, ebx, edx, edi, name, &miss); | 2671 eax, holder, ebx, edx, edi, name, &miss); |
2682 break; | 2672 break; |
2683 | 2673 } |
2684 case SYMBOL_CHECK: | 2674 case SYMBOL_CHECK: { |
2685 // Check that the object is a symbol. | 2675 // Check that the object is a symbol. |
2686 __ CmpObjectType(edx, SYMBOL_TYPE, eax); | 2676 __ CmpObjectType(edx, SYMBOL_TYPE, eax); |
2687 __ j(not_equal, &miss); | 2677 __ j(not_equal, &miss); |
2688 // Check that the maps starting from the prototype haven't changed. | 2678 // Check that the maps starting from the prototype haven't changed. |
2689 GenerateDirectLoadGlobalFunctionPrototype( | 2679 GenerateDirectLoadGlobalFunctionPrototype( |
2690 masm(), Context::SYMBOL_FUNCTION_INDEX, eax, &miss); | 2680 masm(), Context::SYMBOL_FUNCTION_INDEX, eax, &miss); |
| 2681 Handle<Object> prototype(object->GetPrototype(isolate()), isolate()); |
2691 CheckPrototypes( | 2682 CheckPrototypes( |
2692 Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))), | 2683 IC::CurrentTypeOf(prototype, isolate()), |
2693 eax, holder, ebx, edx, edi, name, &miss); | 2684 eax, holder, ebx, edx, edi, name, &miss); |
2694 break; | 2685 break; |
2695 | 2686 } |
2696 case NUMBER_CHECK: { | 2687 case NUMBER_CHECK: { |
2697 Label fast; | 2688 Label fast; |
2698 // Check that the object is a smi or a heap number. | 2689 // Check that the object is a smi or a heap number. |
2699 __ JumpIfSmi(edx, &fast); | 2690 __ JumpIfSmi(edx, &fast); |
2700 __ CmpObjectType(edx, HEAP_NUMBER_TYPE, eax); | 2691 __ CmpObjectType(edx, HEAP_NUMBER_TYPE, eax); |
2701 __ j(not_equal, &miss); | 2692 __ j(not_equal, &miss); |
2702 __ bind(&fast); | 2693 __ bind(&fast); |
2703 // Check that the maps starting from the prototype haven't changed. | 2694 // Check that the maps starting from the prototype haven't changed. |
2704 GenerateDirectLoadGlobalFunctionPrototype( | 2695 GenerateDirectLoadGlobalFunctionPrototype( |
2705 masm(), Context::NUMBER_FUNCTION_INDEX, eax, &miss); | 2696 masm(), Context::NUMBER_FUNCTION_INDEX, eax, &miss); |
| 2697 Handle<Object> prototype(object->GetPrototype(isolate()), isolate()); |
2706 CheckPrototypes( | 2698 CheckPrototypes( |
2707 Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))), | 2699 IC::CurrentTypeOf(prototype, isolate()), |
2708 eax, holder, ebx, edx, edi, name, &miss); | 2700 eax, holder, ebx, edx, edi, name, &miss); |
2709 break; | 2701 break; |
2710 } | 2702 } |
2711 case BOOLEAN_CHECK: { | 2703 case BOOLEAN_CHECK: { |
2712 GenerateBooleanCheck(edx, &miss); | 2704 GenerateBooleanCheck(edx, &miss); |
2713 // Check that the maps starting from the prototype haven't changed. | 2705 // Check that the maps starting from the prototype haven't changed. |
2714 GenerateDirectLoadGlobalFunctionPrototype( | 2706 GenerateDirectLoadGlobalFunctionPrototype( |
2715 masm(), Context::BOOLEAN_FUNCTION_INDEX, eax, &miss); | 2707 masm(), Context::BOOLEAN_FUNCTION_INDEX, eax, &miss); |
| 2708 Handle<Object> prototype(object->GetPrototype(isolate()), isolate()); |
2716 CheckPrototypes( | 2709 CheckPrototypes( |
2717 Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))), | 2710 IC::CurrentTypeOf(prototype, isolate()), |
2718 eax, holder, ebx, edx, edi, name, &miss); | 2711 eax, holder, ebx, edx, edi, name, &miss); |
2719 break; | 2712 break; |
2720 } | 2713 } |
2721 } | 2714 } |
2722 | 2715 |
2723 Label success; | 2716 Label success; |
2724 __ jmp(&success); | 2717 __ jmp(&success); |
2725 | 2718 |
2726 // Handle call cache miss. | 2719 // Handle call cache miss. |
2727 __ bind(&miss); | 2720 __ bind(&miss); |
(...skipping 518 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3246 // ----------------------------------- | 3239 // ----------------------------------- |
3247 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); | 3240 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); |
3248 } | 3241 } |
3249 | 3242 |
3250 | 3243 |
3251 #undef __ | 3244 #undef __ |
3252 | 3245 |
3253 } } // namespace v8::internal | 3246 } } // namespace v8::internal |
3254 | 3247 |
3255 #endif // V8_TARGET_ARCH_IA32 | 3248 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |