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 627 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
638 if (can_do_fast_api_call) { | 638 if (can_do_fast_api_call) { |
639 __ IncrementCounter(counters->call_const_interceptor_fast_api(), 1); | 639 __ IncrementCounter(counters->call_const_interceptor_fast_api(), 1); |
640 ReserveSpaceForFastApiCall(masm, scratch1); | 640 ReserveSpaceForFastApiCall(masm, scratch1); |
641 } | 641 } |
642 | 642 |
643 // Check that the maps from receiver to interceptor's holder | 643 // Check that the maps from receiver to interceptor's holder |
644 // haven't changed and thus we can invoke interceptor. | 644 // haven't changed and thus we can invoke interceptor. |
645 Label miss_cleanup; | 645 Label miss_cleanup; |
646 Label* miss = can_do_fast_api_call ? &miss_cleanup : miss_label; | 646 Label* miss = can_do_fast_api_call ? &miss_cleanup : miss_label; |
647 Register holder = | 647 Register holder = |
648 stub_compiler_->CheckPrototypes(object, receiver, interceptor_holder, | 648 stub_compiler_->CheckPrototypes( |
649 scratch1, scratch2, scratch3, | 649 IC::CurrentTypeOf(object, masm->isolate()), receiver, |
650 name, depth1, miss); | 650 interceptor_holder, scratch1, scratch2, scratch3, |
| 651 name, depth1, miss); |
651 | 652 |
652 // Invoke an interceptor and if it provides a value, | 653 // Invoke an interceptor and if it provides a value, |
653 // branch to |regular_invoke|. | 654 // branch to |regular_invoke|. |
654 Label regular_invoke; | 655 Label regular_invoke; |
655 LoadWithInterceptor(masm, receiver, holder, interceptor_holder, | 656 LoadWithInterceptor(masm, receiver, holder, interceptor_holder, |
656 ®ular_invoke); | 657 ®ular_invoke); |
657 | 658 |
658 // Interceptor returned nothing for this property. Try to use cached | 659 // Interceptor returned nothing for this property. Try to use cached |
659 // constant function. | 660 // constant function. |
660 | 661 |
661 // Check that the maps from interceptor's holder to constant function's | 662 // Check that the maps from interceptor's holder to constant function's |
662 // holder haven't changed and thus we can use cached constant function. | 663 // holder haven't changed and thus we can use cached constant function. |
663 if (*interceptor_holder != lookup->holder()) { | 664 if (*interceptor_holder != lookup->holder()) { |
664 stub_compiler_->CheckPrototypes(interceptor_holder, receiver, | 665 stub_compiler_->CheckPrototypes( |
665 Handle<JSObject>(lookup->holder()), | 666 IC::CurrentTypeOf(interceptor_holder, masm->isolate()), receiver, |
666 scratch1, scratch2, scratch3, | 667 handle(lookup->holder()), scratch1, scratch2, scratch3, |
667 name, depth2, miss); | 668 name, depth2, miss); |
668 } else { | 669 } else { |
669 // CheckPrototypes has a side effect of fetching a 'holder' | 670 // CheckPrototypes has a side effect of fetching a 'holder' |
670 // for API (object which is instanceof for the signature). It's | 671 // for API (object which is instanceof for the signature). It's |
671 // safe to omit it here, as if present, it should be fetched | 672 // safe to omit it here, as if present, it should be fetched |
672 // by the previous CheckPrototypes. | 673 // by the previous CheckPrototypes. |
673 ASSERT(depth2 == kInvalidProtoDepth); | 674 ASSERT(depth2 == kInvalidProtoDepth); |
674 } | 675 } |
675 | 676 |
676 // Invoke function. | 677 // Invoke function. |
677 if (can_do_fast_api_call) { | 678 if (can_do_fast_api_call) { |
(...skipping 25 matching lines...) Expand all Loading... |
703 void CompileRegular(MacroAssembler* masm, | 704 void CompileRegular(MacroAssembler* masm, |
704 Handle<JSObject> object, | 705 Handle<JSObject> object, |
705 Register receiver, | 706 Register receiver, |
706 Register scratch1, | 707 Register scratch1, |
707 Register scratch2, | 708 Register scratch2, |
708 Register scratch3, | 709 Register scratch3, |
709 Handle<Name> name, | 710 Handle<Name> name, |
710 Handle<JSObject> interceptor_holder, | 711 Handle<JSObject> interceptor_holder, |
711 Label* miss_label) { | 712 Label* miss_label) { |
712 Register holder = | 713 Register holder = |
713 stub_compiler_->CheckPrototypes(object, receiver, interceptor_holder, | 714 stub_compiler_->CheckPrototypes( |
714 scratch1, scratch2, scratch3, | 715 IC::CurrentTypeOf(object, masm->isolate()), receiver, |
715 name, miss_label); | 716 interceptor_holder, scratch1, scratch2, scratch3, name, miss_label); |
716 | 717 |
717 FrameScope scope(masm, StackFrame::INTERNAL); | 718 FrameScope scope(masm, StackFrame::INTERNAL); |
718 // Save the name_ register across the call. | 719 // Save the name_ register across the call. |
719 __ push(name_); | 720 __ push(name_); |
720 | 721 |
721 PushInterceptorArguments(masm, receiver, holder, name_, interceptor_holder); | 722 PushInterceptorArguments(masm, receiver, holder, name_, interceptor_holder); |
722 | 723 |
723 __ CallExternalReference( | 724 __ CallExternalReference( |
724 ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorForCall), | 725 ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorForCall), |
725 masm->isolate()), | 726 masm->isolate()), |
(...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1040 EMIT_REMEMBERED_SET, smi_check); | 1041 EMIT_REMEMBERED_SET, smi_check); |
1041 } | 1042 } |
1042 } | 1043 } |
1043 | 1044 |
1044 // Return the value (register rax). | 1045 // Return the value (register rax). |
1045 ASSERT(value_reg.is(rax)); | 1046 ASSERT(value_reg.is(rax)); |
1046 __ ret(0); | 1047 __ ret(0); |
1047 } | 1048 } |
1048 | 1049 |
1049 | 1050 |
1050 void StubCompiler::GenerateCheckPropertyCells(MacroAssembler* masm, | |
1051 Handle<JSObject> object, | |
1052 Handle<JSObject> holder, | |
1053 Handle<Name> name, | |
1054 Register scratch, | |
1055 Label* miss) { | |
1056 Handle<JSObject> current = object; | |
1057 while (!current.is_identical_to(holder)) { | |
1058 if (current->IsJSGlobalObject()) { | |
1059 GenerateCheckPropertyCell(masm, | |
1060 Handle<JSGlobalObject>::cast(current), | |
1061 name, | |
1062 scratch, | |
1063 miss); | |
1064 } | |
1065 current = Handle<JSObject>(JSObject::cast(current->GetPrototype())); | |
1066 } | |
1067 } | |
1068 | |
1069 | |
1070 void StubCompiler::GenerateTailCall(MacroAssembler* masm, Handle<Code> code) { | 1051 void StubCompiler::GenerateTailCall(MacroAssembler* masm, Handle<Code> code) { |
1071 __ jmp(code, RelocInfo::CODE_TARGET); | 1052 __ jmp(code, RelocInfo::CODE_TARGET); |
1072 } | 1053 } |
1073 | 1054 |
1074 | 1055 |
1075 #undef __ | 1056 #undef __ |
1076 #define __ ACCESS_MASM((masm())) | 1057 #define __ ACCESS_MASM((masm())) |
1077 | 1058 |
1078 | 1059 |
1079 Register StubCompiler::CheckPrototypes(Handle<JSObject> object, | 1060 Register StubCompiler::CheckPrototypes(Handle<Type> type, |
1080 Register object_reg, | 1061 Register object_reg, |
1081 Handle<JSObject> holder, | 1062 Handle<JSObject> holder, |
1082 Register holder_reg, | 1063 Register holder_reg, |
1083 Register scratch1, | 1064 Register scratch1, |
1084 Register scratch2, | 1065 Register scratch2, |
1085 Handle<Name> name, | 1066 Handle<Name> name, |
1086 int save_at_depth, | 1067 int save_at_depth, |
1087 Label* miss, | 1068 Label* miss, |
1088 PrototypeCheckType check) { | 1069 PrototypeCheckType check) { |
| 1070 Handle<Map> receiver_map(IC::TypeToMap(*type, isolate())); |
1089 // Make sure that the type feedback oracle harvests the receiver map. | 1071 // Make sure that the type feedback oracle harvests the receiver map. |
1090 // TODO(svenpanne) Remove this hack when all ICs are reworked. | 1072 // TODO(svenpanne) Remove this hack when all ICs are reworked. |
1091 __ Move(scratch1, Handle<Map>(object->map())); | 1073 __ Move(scratch1, receiver_map); |
1092 | 1074 |
1093 Handle<JSObject> first = object; | |
1094 // Make sure there's no overlap between holder and object registers. | 1075 // Make sure there's no overlap between holder and object registers. |
1095 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); | 1076 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); |
1096 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg) | 1077 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg) |
1097 && !scratch2.is(scratch1)); | 1078 && !scratch2.is(scratch1)); |
1098 | 1079 |
1099 // Keep track of the current object in register reg. On the first | 1080 // Keep track of the current object in register reg. On the first |
1100 // iteration, reg is an alias for object_reg, on later iterations, | 1081 // iteration, reg is an alias for object_reg, on later iterations, |
1101 // it is an alias for holder_reg. | 1082 // it is an alias for holder_reg. |
1102 Register reg = object_reg; | 1083 Register reg = object_reg; |
1103 int depth = 0; | 1084 int depth = 0; |
1104 | 1085 |
1105 StackArgumentsAccessor args(rsp, kFastApiCallArguments, | 1086 StackArgumentsAccessor args(rsp, kFastApiCallArguments, |
1106 ARGUMENTS_DONT_CONTAIN_RECEIVER); | 1087 ARGUMENTS_DONT_CONTAIN_RECEIVER); |
1107 const int kHolderIndex = kFastApiCallArguments - 1 - | 1088 const int kHolderIndex = kFastApiCallArguments - 1 - |
1108 FunctionCallbackArguments::kHolderIndex; | 1089 FunctionCallbackArguments::kHolderIndex; |
1109 | 1090 |
1110 if (save_at_depth == depth) { | 1091 if (save_at_depth == depth) { |
1111 __ movq(args.GetArgumentOperand(kHolderIndex), object_reg); | 1092 __ movq(args.GetArgumentOperand(kHolderIndex), object_reg); |
1112 } | 1093 } |
1113 | 1094 |
1114 // Check the maps in the prototype chain. | 1095 Handle<JSObject> current = Handle<JSObject>::null(); |
1115 // Traverse the prototype chain from the object and do map checks. | 1096 if (type->IsConstant()) current = Handle<JSObject>::cast(type->AsConstant()); |
1116 Handle<JSObject> current = object; | 1097 Handle<JSObject> prototype = Handle<JSObject>::null(); |
1117 while (!current.is_identical_to(holder)) { | 1098 Handle<Map> current_map = receiver_map; |
| 1099 Handle<Map> holder_map(holder->map()); |
| 1100 // Traverse the prototype chain and check the maps in the prototype chain for |
| 1101 // fast and global objects or do negative lookup for normal objects. |
| 1102 while (!current_map.is_identical_to(holder_map)) { |
1118 ++depth; | 1103 ++depth; |
1119 | 1104 |
1120 // Only global objects and objects that do not require access | 1105 // Only global objects and objects that do not require access |
1121 // checks are allowed in stubs. | 1106 // checks are allowed in stubs. |
1122 ASSERT(current->IsJSGlobalProxy() || !current->IsAccessCheckNeeded()); | 1107 ASSERT(current_map->IsJSGlobalProxyMap() || |
| 1108 !current_map->is_access_check_needed()); |
1123 | 1109 |
1124 Handle<JSObject> prototype(JSObject::cast(current->GetPrototype())); | 1110 prototype = handle(JSObject::cast(current_map->prototype())); |
1125 if (!current->HasFastProperties() && | 1111 if (current_map->is_dictionary_map() && |
1126 !current->IsJSGlobalObject() && | 1112 !current_map->IsJSGlobalObjectMap() && |
1127 !current->IsJSGlobalProxy()) { | 1113 !current_map->IsJSGlobalProxyMap()) { |
1128 if (!name->IsUniqueName()) { | 1114 if (!name->IsUniqueName()) { |
1129 ASSERT(name->IsString()); | 1115 ASSERT(name->IsString()); |
1130 name = factory()->InternalizeString(Handle<String>::cast(name)); | 1116 name = factory()->InternalizeString(Handle<String>::cast(name)); |
1131 } | 1117 } |
1132 ASSERT(current->property_dictionary()->FindEntry(*name) == | 1118 ASSERT(current.is_null() || |
| 1119 current->property_dictionary()->FindEntry(*name) == |
1133 NameDictionary::kNotFound); | 1120 NameDictionary::kNotFound); |
1134 | 1121 |
1135 GenerateDictionaryNegativeLookup(masm(), miss, reg, name, | 1122 GenerateDictionaryNegativeLookup(masm(), miss, reg, name, |
1136 scratch1, scratch2); | 1123 scratch1, scratch2); |
1137 | 1124 |
1138 __ movq(scratch1, FieldOperand(reg, HeapObject::kMapOffset)); | 1125 __ movq(scratch1, FieldOperand(reg, HeapObject::kMapOffset)); |
1139 reg = holder_reg; // From now on the object will be in holder_reg. | 1126 reg = holder_reg; // From now on the object will be in holder_reg. |
1140 __ movq(reg, FieldOperand(scratch1, Map::kPrototypeOffset)); | 1127 __ movq(reg, FieldOperand(scratch1, Map::kPrototypeOffset)); |
1141 } else { | 1128 } else { |
1142 bool in_new_space = heap()->InNewSpace(*prototype); | 1129 bool in_new_space = heap()->InNewSpace(*prototype); |
1143 Handle<Map> current_map(current->map()); | |
1144 if (in_new_space) { | 1130 if (in_new_space) { |
1145 // Save the map in scratch1 for later. | 1131 // Save the map in scratch1 for later. |
1146 __ movq(scratch1, FieldOperand(reg, HeapObject::kMapOffset)); | 1132 __ movq(scratch1, FieldOperand(reg, HeapObject::kMapOffset)); |
1147 } | 1133 } |
1148 if (!current.is_identical_to(first) || check == CHECK_ALL_MAPS) { | 1134 if (depth != 1 || check == CHECK_ALL_MAPS) { |
1149 __ CheckMap(reg, current_map, miss, DONT_DO_SMI_CHECK); | 1135 __ CheckMap(reg, current_map, miss, DONT_DO_SMI_CHECK); |
1150 } | 1136 } |
1151 | 1137 |
1152 // Check access rights to the global object. This has to happen after | 1138 // Check access rights to the global object. This has to happen after |
1153 // the map check so that we know that the object is actually a global | 1139 // the map check so that we know that the object is actually a global |
1154 // object. | 1140 // object. |
1155 if (current->IsJSGlobalProxy()) { | 1141 if (current_map->IsJSGlobalProxyMap()) { |
1156 __ CheckAccessGlobalProxy(reg, scratch2, miss); | 1142 __ CheckAccessGlobalProxy(reg, scratch2, miss); |
| 1143 } else if (current_map->IsJSGlobalObjectMap()) { |
| 1144 GenerateCheckPropertyCell( |
| 1145 masm(), Handle<JSGlobalObject>::cast(current), name, |
| 1146 scratch2, miss); |
1157 } | 1147 } |
1158 reg = holder_reg; // From now on the object will be in holder_reg. | 1148 reg = holder_reg; // From now on the object will be in holder_reg. |
1159 | 1149 |
1160 if (in_new_space) { | 1150 if (in_new_space) { |
1161 // The prototype is in new space; we cannot store a reference to it | 1151 // The prototype is in new space; we cannot store a reference to it |
1162 // in the code. Load it from the map. | 1152 // in the code. Load it from the map. |
1163 __ movq(reg, FieldOperand(scratch1, Map::kPrototypeOffset)); | 1153 __ movq(reg, FieldOperand(scratch1, Map::kPrototypeOffset)); |
1164 } else { | 1154 } else { |
1165 // The prototype is in old space; load it directly. | 1155 // The prototype is in old space; load it directly. |
1166 __ Move(reg, prototype); | 1156 __ Move(reg, prototype); |
1167 } | 1157 } |
1168 } | 1158 } |
1169 | 1159 |
1170 if (save_at_depth == depth) { | 1160 if (save_at_depth == depth) { |
1171 __ movq(args.GetArgumentOperand(kHolderIndex), reg); | 1161 __ movq(args.GetArgumentOperand(kHolderIndex), reg); |
1172 } | 1162 } |
1173 | 1163 |
1174 // Go to the next object in the prototype chain. | 1164 // Go to the next object in the prototype chain. |
1175 current = prototype; | 1165 current = prototype; |
| 1166 current_map = handle(current->map()); |
1176 } | 1167 } |
1177 ASSERT(current.is_identical_to(holder)); | |
1178 | 1168 |
1179 // Log the check depth. | 1169 // Log the check depth. |
1180 LOG(isolate(), IntEvent("check-maps-depth", depth + 1)); | 1170 LOG(isolate(), IntEvent("check-maps-depth", depth + 1)); |
1181 | 1171 |
1182 if (!holder.is_identical_to(first) || check == CHECK_ALL_MAPS) { | 1172 if (depth != 0 || check == CHECK_ALL_MAPS) { |
1183 // Check the holder map. | 1173 // Check the holder map. |
1184 __ CheckMap(reg, Handle<Map>(holder->map()), miss, DONT_DO_SMI_CHECK); | 1174 __ CheckMap(reg, current_map, miss, DONT_DO_SMI_CHECK); |
1185 } | 1175 } |
1186 | 1176 |
1187 // Perform security check for access to the global object. | 1177 // Perform security check for access to the global object. |
1188 ASSERT(current->IsJSGlobalProxy() || !current->IsAccessCheckNeeded()); | 1178 ASSERT(current_map->IsJSGlobalProxyMap() || |
1189 if (current->IsJSGlobalProxy()) { | 1179 !current_map->is_access_check_needed()); |
| 1180 if (current_map->IsJSGlobalProxyMap()) { |
1190 __ CheckAccessGlobalProxy(reg, scratch1, miss); | 1181 __ CheckAccessGlobalProxy(reg, scratch1, miss); |
1191 } | 1182 } |
1192 | 1183 |
1193 // If we've skipped any global objects, it's not enough to verify that | |
1194 // their maps haven't changed. We also need to check that the property | |
1195 // cell for the property is still empty. | |
1196 GenerateCheckPropertyCells(masm(), object, holder, name, scratch1, miss); | |
1197 | |
1198 // Return the register containing the holder. | 1184 // Return the register containing the holder. |
1199 return reg; | 1185 return reg; |
1200 } | 1186 } |
1201 | 1187 |
1202 | 1188 |
1203 void LoadStubCompiler::HandlerFrontendFooter(Handle<Name> name, Label* miss) { | 1189 void LoadStubCompiler::HandlerFrontendFooter(Handle<Name> name, Label* miss) { |
1204 if (!miss->is_unused()) { | 1190 if (!miss->is_unused()) { |
1205 Label success; | 1191 Label success; |
1206 __ jmp(&success); | 1192 __ jmp(&success); |
1207 __ bind(miss); | 1193 __ bind(miss); |
(...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1492 Handle<Name> name, | 1478 Handle<Name> name, |
1493 Label* miss) { | 1479 Label* miss) { |
1494 ASSERT(holder->IsGlobalObject()); | 1480 ASSERT(holder->IsGlobalObject()); |
1495 | 1481 |
1496 StackArgumentsAccessor args(rsp, arguments()); | 1482 StackArgumentsAccessor args(rsp, arguments()); |
1497 __ movq(rdx, args.GetReceiverOperand()); | 1483 __ movq(rdx, args.GetReceiverOperand()); |
1498 | 1484 |
1499 | 1485 |
1500 // Check that the maps haven't changed. | 1486 // Check that the maps haven't changed. |
1501 __ JumpIfSmi(rdx, miss); | 1487 __ JumpIfSmi(rdx, miss); |
1502 CheckPrototypes(object, rdx, holder, rbx, rax, rdi, name, miss); | 1488 CheckPrototypes(IC::CurrentTypeOf(object, isolate()), rdx, holder, |
| 1489 rbx, rax, rdi, name, miss); |
1503 } | 1490 } |
1504 | 1491 |
1505 | 1492 |
1506 void CallStubCompiler::GenerateLoadFunctionFromCell( | 1493 void CallStubCompiler::GenerateLoadFunctionFromCell( |
1507 Handle<Cell> cell, | 1494 Handle<Cell> cell, |
1508 Handle<JSFunction> function, | 1495 Handle<JSFunction> function, |
1509 Label* miss) { | 1496 Label* miss) { |
1510 // Get the value from the cell. | 1497 // Get the value from the cell. |
1511 __ Move(rdi, cell); | 1498 __ Move(rdi, cell); |
1512 __ movq(rdi, FieldOperand(rdi, Cell::kValueOffset)); | 1499 __ movq(rdi, FieldOperand(rdi, Cell::kValueOffset)); |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1558 | 1545 |
1559 GenerateNameCheck(name, &miss); | 1546 GenerateNameCheck(name, &miss); |
1560 | 1547 |
1561 StackArgumentsAccessor args(rsp, arguments()); | 1548 StackArgumentsAccessor args(rsp, arguments()); |
1562 __ movq(rdx, args.GetReceiverOperand()); | 1549 __ movq(rdx, args.GetReceiverOperand()); |
1563 | 1550 |
1564 // Check that the receiver isn't a smi. | 1551 // Check that the receiver isn't a smi. |
1565 __ JumpIfSmi(rdx, &miss); | 1552 __ JumpIfSmi(rdx, &miss); |
1566 | 1553 |
1567 // Do the right check and compute the holder register. | 1554 // Do the right check and compute the holder register. |
1568 Register reg = CheckPrototypes(object, rdx, holder, rbx, rax, rdi, | 1555 Register reg = CheckPrototypes(IC::CurrentTypeOf(object, isolate()), rdx, |
1569 name, &miss); | 1556 holder, rbx, rax, rdi, name, &miss); |
1570 | 1557 |
1571 GenerateFastPropertyLoad(masm(), rdi, reg, index.is_inobject(holder), | 1558 GenerateFastPropertyLoad(masm(), rdi, reg, index.is_inobject(holder), |
1572 index.translate(holder), Representation::Tagged()); | 1559 index.translate(holder), Representation::Tagged()); |
1573 | 1560 |
1574 // Check that the function really is a function. | 1561 // Check that the function really is a function. |
1575 __ JumpIfSmi(rdi, &miss); | 1562 __ JumpIfSmi(rdi, &miss); |
1576 __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rbx); | 1563 __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rbx); |
1577 __ j(not_equal, &miss); | 1564 __ j(not_equal, &miss); |
1578 | 1565 |
1579 // Patch the receiver on the stack with the global proxy if | 1566 // Patch the receiver on the stack with the global proxy if |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1611 // Check that function is still array | 1598 // Check that function is still array |
1612 const int argc = arguments().immediate(); | 1599 const int argc = arguments().immediate(); |
1613 StackArgumentsAccessor args(rsp, argc); | 1600 StackArgumentsAccessor args(rsp, argc); |
1614 GenerateNameCheck(name, &miss); | 1601 GenerateNameCheck(name, &miss); |
1615 | 1602 |
1616 if (cell.is_null()) { | 1603 if (cell.is_null()) { |
1617 __ movq(rdx, args.GetReceiverOperand()); | 1604 __ movq(rdx, args.GetReceiverOperand()); |
1618 | 1605 |
1619 // Check that the receiver isn't a smi. | 1606 // Check that the receiver isn't a smi. |
1620 __ JumpIfSmi(rdx, &miss); | 1607 __ JumpIfSmi(rdx, &miss); |
1621 CheckPrototypes(Handle<JSObject>::cast(object), rdx, holder, rbx, rax, rdi, | 1608 CheckPrototypes(IC::CurrentTypeOf(object, isolate()), rdx, holder, |
1622 name, &miss); | 1609 rbx, rax, rdi, name, &miss); |
1623 } else { | 1610 } else { |
1624 ASSERT(cell->value() == *function); | 1611 ASSERT(cell->value() == *function); |
1625 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name, | 1612 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name, |
1626 &miss); | 1613 &miss); |
1627 GenerateLoadFunctionFromCell(cell, function, &miss); | 1614 GenerateLoadFunctionFromCell(cell, function, &miss); |
1628 } | 1615 } |
1629 | 1616 |
1630 Handle<AllocationSite> site = isolate()->factory()->NewAllocationSite(); | 1617 Handle<AllocationSite> site = isolate()->factory()->NewAllocationSite(); |
1631 site->SetElementsKind(GetInitialFastElementsKind()); | 1618 site->SetElementsKind(GetInitialFastElementsKind()); |
1632 Handle<Cell> site_feedback_cell = isolate()->factory()->NewCell(site); | 1619 Handle<Cell> site_feedback_cell = isolate()->factory()->NewCell(site); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1670 Label miss; | 1657 Label miss; |
1671 GenerateNameCheck(name, &miss); | 1658 GenerateNameCheck(name, &miss); |
1672 | 1659 |
1673 const int argc = arguments().immediate(); | 1660 const int argc = arguments().immediate(); |
1674 StackArgumentsAccessor args(rsp, argc); | 1661 StackArgumentsAccessor args(rsp, argc); |
1675 __ movq(rdx, args.GetReceiverOperand()); | 1662 __ movq(rdx, args.GetReceiverOperand()); |
1676 | 1663 |
1677 // Check that the receiver isn't a smi. | 1664 // Check that the receiver isn't a smi. |
1678 __ JumpIfSmi(rdx, &miss); | 1665 __ JumpIfSmi(rdx, &miss); |
1679 | 1666 |
1680 CheckPrototypes(Handle<JSObject>::cast(object), rdx, holder, rbx, rax, rdi, | 1667 CheckPrototypes(IC::CurrentTypeOf(object, isolate()), rdx, holder, |
1681 name, &miss); | 1668 rbx, rax, rdi, name, &miss); |
1682 | 1669 |
1683 if (argc == 0) { | 1670 if (argc == 0) { |
1684 // Noop, return the length. | 1671 // Noop, return the length. |
1685 __ movq(rax, FieldOperand(rdx, JSArray::kLengthOffset)); | 1672 __ movq(rax, FieldOperand(rdx, JSArray::kLengthOffset)); |
1686 __ ret((argc + 1) * kPointerSize); | 1673 __ ret((argc + 1) * kPointerSize); |
1687 } else { | 1674 } else { |
1688 Label call_builtin; | 1675 Label call_builtin; |
1689 | 1676 |
1690 if (argc == 1) { // Otherwise fall through to call builtin. | 1677 if (argc == 1) { // Otherwise fall through to call builtin. |
1691 Label attempt_to_grow_elements, with_write_barrier, check_double; | 1678 Label attempt_to_grow_elements, with_write_barrier, check_double; |
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1925 Label miss, return_undefined, call_builtin; | 1912 Label miss, return_undefined, call_builtin; |
1926 GenerateNameCheck(name, &miss); | 1913 GenerateNameCheck(name, &miss); |
1927 | 1914 |
1928 const int argc = arguments().immediate(); | 1915 const int argc = arguments().immediate(); |
1929 StackArgumentsAccessor args(rsp, argc); | 1916 StackArgumentsAccessor args(rsp, argc); |
1930 __ movq(rdx, args.GetReceiverOperand()); | 1917 __ movq(rdx, args.GetReceiverOperand()); |
1931 | 1918 |
1932 // Check that the receiver isn't a smi. | 1919 // Check that the receiver isn't a smi. |
1933 __ JumpIfSmi(rdx, &miss); | 1920 __ JumpIfSmi(rdx, &miss); |
1934 | 1921 |
1935 CheckPrototypes(Handle<JSObject>::cast(object), rdx, holder, rbx, rax, rdi, | 1922 CheckPrototypes(IC::CurrentTypeOf(object, isolate()), rdx, holder, |
1936 name, &miss); | 1923 rbx, rax, rdi, name, &miss); |
1937 | 1924 |
1938 // Get the elements array of the object. | 1925 // Get the elements array of the object. |
1939 __ movq(rbx, FieldOperand(rdx, JSArray::kElementsOffset)); | 1926 __ movq(rbx, FieldOperand(rdx, JSArray::kElementsOffset)); |
1940 | 1927 |
1941 // Check that the elements are in fast mode and writable. | 1928 // Check that the elements are in fast mode and writable. |
1942 __ CompareRoot(FieldOperand(rbx, HeapObject::kMapOffset), | 1929 __ CompareRoot(FieldOperand(rbx, HeapObject::kMapOffset), |
1943 Heap::kFixedArrayMapRootIndex); | 1930 Heap::kFixedArrayMapRootIndex); |
1944 __ j(not_equal, &call_builtin); | 1931 __ j(not_equal, &call_builtin); |
1945 | 1932 |
1946 // Get the array's length into rcx and calculate new length. | 1933 // Get the array's length into rcx and calculate new length. |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2017 index_out_of_range_label = &miss; | 2004 index_out_of_range_label = &miss; |
2018 } | 2005 } |
2019 GenerateNameCheck(name, &name_miss); | 2006 GenerateNameCheck(name, &name_miss); |
2020 | 2007 |
2021 // Check that the maps starting from the prototype haven't changed. | 2008 // Check that the maps starting from the prototype haven't changed. |
2022 GenerateDirectLoadGlobalFunctionPrototype(masm(), | 2009 GenerateDirectLoadGlobalFunctionPrototype(masm(), |
2023 Context::STRING_FUNCTION_INDEX, | 2010 Context::STRING_FUNCTION_INDEX, |
2024 rax, | 2011 rax, |
2025 &miss); | 2012 &miss); |
2026 ASSERT(!object.is_identical_to(holder)); | 2013 ASSERT(!object.is_identical_to(holder)); |
| 2014 Handle<Object> prototype(object->GetPrototype(isolate()), isolate()); |
2027 CheckPrototypes( | 2015 CheckPrototypes( |
2028 Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))), | 2016 IC::CurrentTypeOf(prototype, isolate()), |
2029 rax, holder, rbx, rdx, rdi, name, &miss); | 2017 rax, holder, rbx, rdx, rdi, name, &miss); |
2030 | 2018 |
2031 Register receiver = rbx; | 2019 Register receiver = rbx; |
2032 Register index = rdi; | 2020 Register index = rdi; |
2033 Register result = rax; | 2021 Register result = rax; |
2034 __ movq(receiver, args.GetReceiverOperand()); | 2022 __ movq(receiver, args.GetReceiverOperand()); |
2035 if (argc > 0) { | 2023 if (argc > 0) { |
2036 __ movq(index, args.GetArgumentOperand(1)); | 2024 __ movq(index, args.GetArgumentOperand(1)); |
2037 } else { | 2025 } else { |
2038 __ LoadRoot(index, Heap::kUndefinedValueRootIndex); | 2026 __ LoadRoot(index, Heap::kUndefinedValueRootIndex); |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2099 index_out_of_range_label = &miss; | 2087 index_out_of_range_label = &miss; |
2100 } | 2088 } |
2101 GenerateNameCheck(name, &name_miss); | 2089 GenerateNameCheck(name, &name_miss); |
2102 | 2090 |
2103 // Check that the maps starting from the prototype haven't changed. | 2091 // Check that the maps starting from the prototype haven't changed. |
2104 GenerateDirectLoadGlobalFunctionPrototype(masm(), | 2092 GenerateDirectLoadGlobalFunctionPrototype(masm(), |
2105 Context::STRING_FUNCTION_INDEX, | 2093 Context::STRING_FUNCTION_INDEX, |
2106 rax, | 2094 rax, |
2107 &miss); | 2095 &miss); |
2108 ASSERT(!object.is_identical_to(holder)); | 2096 ASSERT(!object.is_identical_to(holder)); |
| 2097 Handle<Object> prototype(object->GetPrototype(isolate()), isolate()); |
2109 CheckPrototypes( | 2098 CheckPrototypes( |
2110 Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))), | 2099 IC::CurrentTypeOf(prototype, isolate()), |
2111 rax, holder, rbx, rdx, rdi, name, &miss); | 2100 rax, holder, rbx, rdx, rdi, name, &miss); |
2112 | 2101 |
2113 Register receiver = rax; | 2102 Register receiver = rax; |
2114 Register index = rdi; | 2103 Register index = rdi; |
2115 Register scratch = rdx; | 2104 Register scratch = rdx; |
2116 Register result = rax; | 2105 Register result = rax; |
2117 __ movq(receiver, args.GetReceiverOperand()); | 2106 __ movq(receiver, args.GetReceiverOperand()); |
2118 if (argc > 0) { | 2107 if (argc > 0) { |
2119 __ movq(index, args.GetArgumentOperand(1)); | 2108 __ movq(index, args.GetArgumentOperand(1)); |
2120 } else { | 2109 } else { |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2171 const int argc = arguments().immediate(); | 2160 const int argc = arguments().immediate(); |
2172 StackArgumentsAccessor args(rsp, argc); | 2161 StackArgumentsAccessor args(rsp, argc); |
2173 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null(); | 2162 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null(); |
2174 | 2163 |
2175 Label miss; | 2164 Label miss; |
2176 GenerateNameCheck(name, &miss); | 2165 GenerateNameCheck(name, &miss); |
2177 | 2166 |
2178 if (cell.is_null()) { | 2167 if (cell.is_null()) { |
2179 __ movq(rdx, args.GetReceiverOperand()); | 2168 __ movq(rdx, args.GetReceiverOperand()); |
2180 __ JumpIfSmi(rdx, &miss); | 2169 __ JumpIfSmi(rdx, &miss); |
2181 CheckPrototypes(Handle<JSObject>::cast(object), rdx, holder, rbx, rax, rdi, | 2170 CheckPrototypes(IC::CurrentTypeOf(object, isolate()), rdx, holder, |
2182 name, &miss); | 2171 rbx, rax, rdi, name, &miss); |
2183 } else { | 2172 } else { |
2184 ASSERT(cell->value() == *function); | 2173 ASSERT(cell->value() == *function); |
2185 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name, | 2174 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name, |
2186 &miss); | 2175 &miss); |
2187 GenerateLoadFunctionFromCell(cell, function, &miss); | 2176 GenerateLoadFunctionFromCell(cell, function, &miss); |
2188 } | 2177 } |
2189 | 2178 |
2190 // Load the char code argument. | 2179 // Load the char code argument. |
2191 Register code = rbx; | 2180 Register code = rbx; |
2192 __ movq(code, args.GetArgumentOperand(1)); | 2181 __ movq(code, args.GetArgumentOperand(1)); |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2249 | 2238 |
2250 Label miss; | 2239 Label miss; |
2251 GenerateNameCheck(name, &miss); | 2240 GenerateNameCheck(name, &miss); |
2252 | 2241 |
2253 if (cell.is_null()) { | 2242 if (cell.is_null()) { |
2254 __ movq(rdx, args.GetReceiverOperand()); | 2243 __ movq(rdx, args.GetReceiverOperand()); |
2255 | 2244 |
2256 STATIC_ASSERT(kSmiTag == 0); | 2245 STATIC_ASSERT(kSmiTag == 0); |
2257 __ JumpIfSmi(rdx, &miss); | 2246 __ JumpIfSmi(rdx, &miss); |
2258 | 2247 |
2259 CheckPrototypes(Handle<JSObject>::cast(object), rdx, holder, rbx, rax, rdi, | 2248 CheckPrototypes(IC::CurrentTypeOf(object, isolate()), rdx, holder, |
2260 name, &miss); | 2249 rbx, rax, rdi, name, &miss); |
2261 } else { | 2250 } else { |
2262 ASSERT(cell->value() == *function); | 2251 ASSERT(cell->value() == *function); |
2263 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name, | 2252 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name, |
2264 &miss); | 2253 &miss); |
2265 GenerateLoadFunctionFromCell(cell, function, &miss); | 2254 GenerateLoadFunctionFromCell(cell, function, &miss); |
2266 } | 2255 } |
2267 | 2256 |
2268 // Load the (only) argument into rax. | 2257 // Load the (only) argument into rax. |
2269 __ movq(rax, args.GetArgumentOperand(1)); | 2258 __ movq(rax, args.GetArgumentOperand(1)); |
2270 | 2259 |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2372 const int argc = arguments().immediate(); | 2361 const int argc = arguments().immediate(); |
2373 StackArgumentsAccessor args(rsp, argc); | 2362 StackArgumentsAccessor args(rsp, argc); |
2374 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null(); | 2363 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null(); |
2375 | 2364 |
2376 Label miss; | 2365 Label miss; |
2377 GenerateNameCheck(name, &miss); | 2366 GenerateNameCheck(name, &miss); |
2378 | 2367 |
2379 if (cell.is_null()) { | 2368 if (cell.is_null()) { |
2380 __ movq(rdx, args.GetReceiverOperand()); | 2369 __ movq(rdx, args.GetReceiverOperand()); |
2381 __ JumpIfSmi(rdx, &miss); | 2370 __ JumpIfSmi(rdx, &miss); |
2382 CheckPrototypes(Handle<JSObject>::cast(object), rdx, holder, rbx, rax, rdi, | 2371 CheckPrototypes(IC::CurrentTypeOf(object, isolate()), rdx, holder, |
2383 name, &miss); | 2372 rbx, rax, rdi, name, &miss); |
2384 } else { | 2373 } else { |
2385 ASSERT(cell->value() == *function); | 2374 ASSERT(cell->value() == *function); |
2386 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name, | 2375 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name, |
2387 &miss); | 2376 &miss); |
2388 GenerateLoadFunctionFromCell(cell, function, &miss); | 2377 GenerateLoadFunctionFromCell(cell, function, &miss); |
2389 } | 2378 } |
2390 // Load the (only) argument into rax. | 2379 // Load the (only) argument into rax. |
2391 __ movq(rax, args.GetArgumentOperand(1)); | 2380 __ movq(rax, args.GetArgumentOperand(1)); |
2392 | 2381 |
2393 // Check if the argument is a smi. | 2382 // Check if the argument is a smi. |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2486 | 2475 |
2487 Counters* counters = isolate()->counters(); | 2476 Counters* counters = isolate()->counters(); |
2488 __ IncrementCounter(counters->call_const(), 1); | 2477 __ IncrementCounter(counters->call_const(), 1); |
2489 __ IncrementCounter(counters->call_const_fast_api(), 1); | 2478 __ IncrementCounter(counters->call_const_fast_api(), 1); |
2490 | 2479 |
2491 // Allocate space for v8::Arguments implicit values. Must be initialized | 2480 // Allocate space for v8::Arguments implicit values. Must be initialized |
2492 // before calling any runtime function. | 2481 // before calling any runtime function. |
2493 __ subq(rsp, Immediate(kFastApiCallArguments * kPointerSize)); | 2482 __ subq(rsp, Immediate(kFastApiCallArguments * kPointerSize)); |
2494 | 2483 |
2495 // Check that the maps haven't changed and find a Holder as a side effect. | 2484 // Check that the maps haven't changed and find a Holder as a side effect. |
2496 CheckPrototypes(Handle<JSObject>::cast(object), rdx, holder, rbx, rax, rdi, | 2485 CheckPrototypes(IC::CurrentTypeOf(object, isolate()), rdx, holder, |
2497 name, depth, &miss); | 2486 rbx, rax, rdi, name, depth, &miss); |
2498 | 2487 |
2499 // Move the return address on top of the stack. | 2488 // Move the return address on top of the stack. |
2500 __ movq(rax, | 2489 __ movq(rax, |
2501 StackOperandForReturnAddress(kFastApiCallArguments * kPointerSize)); | 2490 StackOperandForReturnAddress(kFastApiCallArguments * kPointerSize)); |
2502 __ movq(StackOperandForReturnAddress(0), rax); | 2491 __ movq(StackOperandForReturnAddress(0), rax); |
2503 | 2492 |
2504 GenerateFastApiCall(masm(), optimization, argc, false); | 2493 GenerateFastApiCall(masm(), optimization, argc, false); |
2505 | 2494 |
2506 __ bind(&miss); | 2495 __ bind(&miss); |
2507 __ addq(rsp, Immediate(kFastApiCallArguments * kPointerSize)); | 2496 __ addq(rsp, Immediate(kFastApiCallArguments * kPointerSize)); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2552 // Make sure that it's okay not to patch the on stack receiver | 2541 // Make sure that it's okay not to patch the on stack receiver |
2553 // unless we're doing a receiver map check. | 2542 // unless we're doing a receiver map check. |
2554 ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK); | 2543 ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK); |
2555 | 2544 |
2556 Counters* counters = isolate()->counters(); | 2545 Counters* counters = isolate()->counters(); |
2557 switch (check) { | 2546 switch (check) { |
2558 case RECEIVER_MAP_CHECK: | 2547 case RECEIVER_MAP_CHECK: |
2559 __ IncrementCounter(counters->call_const(), 1); | 2548 __ IncrementCounter(counters->call_const(), 1); |
2560 | 2549 |
2561 // Check that the maps haven't changed. | 2550 // Check that the maps haven't changed. |
2562 CheckPrototypes(Handle<JSObject>::cast(object), rdx, holder, rbx, rax, | 2551 CheckPrototypes(IC::CurrentTypeOf(object, isolate()), rdx, holder, |
2563 rdi, name, &miss); | 2552 rbx, rax, rdi, name, &miss); |
2564 | 2553 |
2565 // Patch the receiver on the stack with the global proxy if | 2554 // Patch the receiver on the stack with the global proxy if |
2566 // necessary. | 2555 // necessary. |
2567 if (object->IsGlobalObject()) { | 2556 if (object->IsGlobalObject()) { |
2568 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset)); | 2557 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset)); |
2569 __ movq(args.GetReceiverOperand(), rdx); | 2558 __ movq(args.GetReceiverOperand(), rdx); |
2570 } | 2559 } |
2571 break; | 2560 break; |
2572 | 2561 |
2573 case STRING_CHECK: | 2562 case STRING_CHECK: { |
2574 // Check that the object is a string. | 2563 // Check that the object is a string. |
2575 __ CmpObjectType(rdx, FIRST_NONSTRING_TYPE, rax); | 2564 __ CmpObjectType(rdx, FIRST_NONSTRING_TYPE, rax); |
2576 __ j(above_equal, &miss); | 2565 __ j(above_equal, &miss); |
2577 // Check that the maps starting from the prototype haven't changed. | 2566 // Check that the maps starting from the prototype haven't changed. |
2578 GenerateDirectLoadGlobalFunctionPrototype( | 2567 GenerateDirectLoadGlobalFunctionPrototype( |
2579 masm(), Context::STRING_FUNCTION_INDEX, rax, &miss); | 2568 masm(), Context::STRING_FUNCTION_INDEX, rax, &miss); |
| 2569 Handle<Object> prototype(object->GetPrototype(isolate()), isolate()); |
2580 CheckPrototypes( | 2570 CheckPrototypes( |
2581 Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))), | 2571 IC::CurrentTypeOf(prototype, isolate()), |
2582 rax, holder, rbx, rdx, rdi, name, &miss); | 2572 rax, holder, rbx, rdx, rdi, name, &miss); |
2583 break; | 2573 break; |
2584 | 2574 } |
2585 case SYMBOL_CHECK: | 2575 case SYMBOL_CHECK: { |
2586 // Check that the object is a symbol. | 2576 // Check that the object is a symbol. |
2587 __ CmpObjectType(rdx, SYMBOL_TYPE, rax); | 2577 __ CmpObjectType(rdx, SYMBOL_TYPE, rax); |
2588 __ j(not_equal, &miss); | 2578 __ j(not_equal, &miss); |
2589 // Check that the maps starting from the prototype haven't changed. | 2579 // Check that the maps starting from the prototype haven't changed. |
2590 GenerateDirectLoadGlobalFunctionPrototype( | 2580 GenerateDirectLoadGlobalFunctionPrototype( |
2591 masm(), Context::SYMBOL_FUNCTION_INDEX, rax, &miss); | 2581 masm(), Context::SYMBOL_FUNCTION_INDEX, rax, &miss); |
| 2582 Handle<Object> prototype(object->GetPrototype(isolate()), isolate()); |
2592 CheckPrototypes( | 2583 CheckPrototypes( |
2593 Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))), | 2584 IC::CurrentTypeOf(prototype, isolate()), |
2594 rax, holder, rbx, rdx, rdi, name, &miss); | 2585 rax, holder, rbx, rdx, rdi, name, &miss); |
2595 break; | 2586 break; |
2596 | 2587 } |
2597 case NUMBER_CHECK: { | 2588 case NUMBER_CHECK: { |
2598 Label fast; | 2589 Label fast; |
2599 // Check that the object is a smi or a heap number. | 2590 // Check that the object is a smi or a heap number. |
2600 __ JumpIfSmi(rdx, &fast); | 2591 __ JumpIfSmi(rdx, &fast); |
2601 __ CmpObjectType(rdx, HEAP_NUMBER_TYPE, rax); | 2592 __ CmpObjectType(rdx, HEAP_NUMBER_TYPE, rax); |
2602 __ j(not_equal, &miss); | 2593 __ j(not_equal, &miss); |
2603 __ bind(&fast); | 2594 __ bind(&fast); |
2604 // Check that the maps starting from the prototype haven't changed. | 2595 // Check that the maps starting from the prototype haven't changed. |
2605 GenerateDirectLoadGlobalFunctionPrototype( | 2596 GenerateDirectLoadGlobalFunctionPrototype( |
2606 masm(), Context::NUMBER_FUNCTION_INDEX, rax, &miss); | 2597 masm(), Context::NUMBER_FUNCTION_INDEX, rax, &miss); |
| 2598 Handle<Object> prototype(object->GetPrototype(isolate()), isolate()); |
2607 CheckPrototypes( | 2599 CheckPrototypes( |
2608 Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))), | 2600 IC::CurrentTypeOf(prototype, isolate()), |
2609 rax, holder, rbx, rdx, rdi, name, &miss); | 2601 rax, holder, rbx, rdx, rdi, name, &miss); |
2610 break; | 2602 break; |
2611 } | 2603 } |
2612 case BOOLEAN_CHECK: { | 2604 case BOOLEAN_CHECK: { |
2613 GenerateBooleanCheck(rdx, &miss); | 2605 GenerateBooleanCheck(rdx, &miss); |
2614 // Check that the maps starting from the prototype haven't changed. | 2606 // Check that the maps starting from the prototype haven't changed. |
2615 GenerateDirectLoadGlobalFunctionPrototype( | 2607 GenerateDirectLoadGlobalFunctionPrototype( |
2616 masm(), Context::BOOLEAN_FUNCTION_INDEX, rax, &miss); | 2608 masm(), Context::BOOLEAN_FUNCTION_INDEX, rax, &miss); |
| 2609 Handle<Object> prototype(object->GetPrototype(isolate()), isolate()); |
2617 CheckPrototypes( | 2610 CheckPrototypes( |
2618 Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))), | 2611 IC::CurrentTypeOf(prototype, isolate()), |
2619 rax, holder, rbx, rdx, rdi, name, &miss); | 2612 rax, holder, rbx, rdx, rdi, name, &miss); |
2620 break; | 2613 break; |
2621 } | 2614 } |
2622 } | 2615 } |
2623 | 2616 |
2624 Label success; | 2617 Label success; |
2625 __ jmp(&success); | 2618 __ jmp(&success); |
2626 | 2619 |
2627 // Handle call cache miss. | 2620 // Handle call cache miss. |
2628 __ bind(&miss); | 2621 __ bind(&miss); |
(...skipping 528 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3157 // ----------------------------------- | 3150 // ----------------------------------- |
3158 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); | 3151 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); |
3159 } | 3152 } |
3160 | 3153 |
3161 | 3154 |
3162 #undef __ | 3155 #undef __ |
3163 | 3156 |
3164 } } // namespace v8::internal | 3157 } } // namespace v8::internal |
3165 | 3158 |
3166 #endif // V8_TARGET_ARCH_X64 | 3159 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |