| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 686 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 697 void StoreStubCompiler::GenerateRestoreName(MacroAssembler* masm, | 697 void StoreStubCompiler::GenerateRestoreName(MacroAssembler* masm, |
| 698 Label* label, | 698 Label* label, |
| 699 Handle<Name> name) { | 699 Handle<Name> name) { |
| 700 if (!label->is_unused()) { | 700 if (!label->is_unused()) { |
| 701 __ Bind(label); | 701 __ Bind(label); |
| 702 __ Mov(this->name(), Operand(name)); | 702 __ Mov(this->name(), Operand(name)); |
| 703 } | 703 } |
| 704 } | 704 } |
| 705 | 705 |
| 706 | 706 |
| 707 void StubCompiler::GenerateCheckPropertyCells(MacroAssembler* masm, | |
| 708 Handle<JSObject> object, | |
| 709 Handle<JSObject> holder, | |
| 710 Handle<Name> name, | |
| 711 Register scratch1, | |
| 712 Label* miss) { | |
| 713 Handle<JSObject> current = object; | |
| 714 while (!current.is_identical_to(holder)) { | |
| 715 if (current->IsJSGlobalObject()) { | |
| 716 // TODO(all): GenerateCheckPropertyCell loads the hole (root value) every | |
| 717 // time. Hoist that out, and load it once at the start. | |
| 718 GenerateCheckPropertyCell(masm, | |
| 719 Handle<JSGlobalObject>::cast(current), | |
| 720 name, | |
| 721 scratch1, | |
| 722 miss); | |
| 723 } | |
| 724 current = Handle<JSObject>(JSObject::cast(current->GetPrototype())); | |
| 725 } | |
| 726 } | |
| 727 | |
| 728 | |
| 729 // The function to called must be passed in x1. | 707 // The function to called must be passed in x1. |
| 730 static void GenerateCallFunction(MacroAssembler* masm, | 708 static void GenerateCallFunction(MacroAssembler* masm, |
| 731 Handle<Object> object, | 709 Handle<Object> object, |
| 732 const ParameterCount& arguments, | 710 const ParameterCount& arguments, |
| 733 Label* miss, | 711 Label* miss, |
| 734 Code::ExtraICState extra_ic_state, | 712 Code::ExtraICState extra_ic_state, |
| 735 Register function, | 713 Register function, |
| 736 Register receiver, | 714 Register receiver, |
| 737 Register scratch) { | 715 Register scratch) { |
| 738 ASSERT(!AreAliased(function, receiver, scratch)); | 716 ASSERT(!AreAliased(function, receiver, scratch)); |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 776 __ Mov(scratch, Operand(interceptor)); | 754 __ Mov(scratch, Operand(interceptor)); |
| 777 __ Push(scratch, receiver, holder); | 755 __ Push(scratch, receiver, holder); |
| 778 } | 756 } |
| 779 | 757 |
| 780 | 758 |
| 781 static void CompileCallLoadPropertyWithInterceptor( | 759 static void CompileCallLoadPropertyWithInterceptor( |
| 782 MacroAssembler* masm, | 760 MacroAssembler* masm, |
| 783 Register receiver, | 761 Register receiver, |
| 784 Register holder, | 762 Register holder, |
| 785 Register name, | 763 Register name, |
| 786 Handle<JSObject> holder_obj) { | 764 Handle<JSObject> holder_obj, |
| 765 IC::UtilityId id) { |
| 787 PushInterceptorArguments(masm, receiver, holder, name, holder_obj); | 766 PushInterceptorArguments(masm, receiver, holder, name, holder_obj); |
| 788 | 767 |
| 789 ExternalReference ref = | 768 __ CallExternalReference( |
| 790 ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorOnly), | 769 ExternalReference(IC_Utility(id), masm->isolate()), |
| 791 masm->isolate()); | 770 StubCache::kInterceptorArgsLength); |
| 792 // Put the number of on-stack arguments for runtime call in x0. | |
| 793 // These arguemnts have been pushed by PushInterceptorArguments. | |
| 794 __ Mov(x0, StubCache::kInterceptorArgsLength); | |
| 795 __ Mov(x1, Operand(ref)); | |
| 796 | |
| 797 CEntryStub stub(1); | |
| 798 __ CallStub(&stub); | |
| 799 } | 771 } |
| 800 | 772 |
| 801 | 773 |
| 802 static const int kFastApiCallArguments = FunctionCallbackArguments::kArgsLength; | 774 static const int kFastApiCallArguments = FunctionCallbackArguments::kArgsLength; |
| 803 | 775 |
| 804 // Reserves space for the extra arguments to API function in the | 776 // Reserves space for the extra arguments to API function in the |
| 805 // caller's frame. | 777 // caller's frame. |
| 806 // | 778 // |
| 807 // These arguments are set by CheckPrototypes and GenerateFastApiDirectCall. | 779 // These arguments are set by CheckPrototypes and GenerateFastApiDirectCall. |
| 808 static void ReserveSpaceForFastApiCall(MacroAssembler* masm, | 780 static void ReserveSpaceForFastApiCall(MacroAssembler* masm, |
| (...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1039 __ IncrementCounter(counters->call_const_interceptor_fast_api(), 1, | 1011 __ IncrementCounter(counters->call_const_interceptor_fast_api(), 1, |
| 1040 scratch1, scratch2); | 1012 scratch1, scratch2); |
| 1041 ReserveSpaceForFastApiCall(masm, scratch1); | 1013 ReserveSpaceForFastApiCall(masm, scratch1); |
| 1042 } | 1014 } |
| 1043 | 1015 |
| 1044 // Check that the maps from receiver to interceptor's holder | 1016 // Check that the maps from receiver to interceptor's holder |
| 1045 // haven't changed and thus we can invoke interceptor. | 1017 // haven't changed and thus we can invoke interceptor. |
| 1046 Label miss_cleanup; | 1018 Label miss_cleanup; |
| 1047 Label* miss = can_do_fast_api_call ? &miss_cleanup : miss_label; | 1019 Label* miss = can_do_fast_api_call ? &miss_cleanup : miss_label; |
| 1048 Register holder = | 1020 Register holder = |
| 1049 stub_compiler_->CheckPrototypes(object, receiver, interceptor_holder, | 1021 stub_compiler_->CheckPrototypes( |
| 1050 scratch1, scratch2, scratch3, | 1022 IC::CurrentTypeOf(object, masm->isolate()), receiver, |
| 1051 name, depth1, miss); | 1023 interceptor_holder, scratch1, scratch2, scratch3, |
| 1024 name, depth1, miss); |
| 1052 | 1025 |
| 1053 // Invoke an interceptor and if it provides a value, | 1026 // Invoke an interceptor and if it provides a value, |
| 1054 // branch to |regular_invoke|. | 1027 // branch to |regular_invoke|. |
| 1055 Label regular_invoke; | 1028 Label regular_invoke; |
| 1056 LoadWithInterceptor(masm, receiver, holder, interceptor_holder, scratch2, | 1029 LoadWithInterceptor(masm, receiver, holder, interceptor_holder, scratch2, |
| 1057 ®ular_invoke); | 1030 ®ular_invoke); |
| 1058 | 1031 |
| 1059 // Interceptor returned nothing for this property. Try to use cached | 1032 // Interceptor returned nothing for this property. Try to use cached |
| 1060 // constant function. | 1033 // constant function. |
| 1061 | 1034 |
| 1062 // Check that the maps from interceptor's holder to constant function's | 1035 // Check that the maps from interceptor's holder to constant function's |
| 1063 // holder haven't changed and thus we can use cached constant function. | 1036 // holder haven't changed and thus we can use cached constant function. |
| 1064 if (*interceptor_holder != lookup->holder()) { | 1037 if (*interceptor_holder != lookup->holder()) { |
| 1065 stub_compiler_->CheckPrototypes(interceptor_holder, receiver, | 1038 stub_compiler_->CheckPrototypes( |
| 1066 Handle<JSObject>(lookup->holder()), | 1039 IC::CurrentTypeOf(interceptor_holder, masm->isolate()), receiver, |
| 1067 scratch1, scratch2, scratch3, | 1040 handle(lookup->holder()), scratch1, scratch2, scratch3, |
| 1068 name, depth2, miss); | 1041 name, depth2, miss); |
| 1069 } else { | 1042 } else { |
| 1070 // CheckPrototypes has a side effect of fetching a 'holder' | 1043 // CheckPrototypes has a side effect of fetching a 'holder' |
| 1071 // for API (object which is instanceof for the signature). It's | 1044 // for API (object which is instanceof for the signature). It's |
| 1072 // safe to omit it here, as if present, it should be fetched | 1045 // safe to omit it here, as if present, it should be fetched |
| 1073 // by the previous CheckPrototypes. | 1046 // by the previous CheckPrototypes. |
| 1074 ASSERT(depth2 == kInvalidProtoDepth); | 1047 ASSERT(depth2 == kInvalidProtoDepth); |
| 1075 } | 1048 } |
| 1076 | 1049 |
| 1077 // Invoke function. | 1050 // Invoke function. |
| 1078 if (can_do_fast_api_call) { | 1051 if (can_do_fast_api_call) { |
| (...skipping 26 matching lines...) Expand all Loading... |
| 1105 void CompileRegular(MacroAssembler* masm, | 1078 void CompileRegular(MacroAssembler* masm, |
| 1106 Handle<JSObject> object, | 1079 Handle<JSObject> object, |
| 1107 Register receiver, | 1080 Register receiver, |
| 1108 Register scratch1, | 1081 Register scratch1, |
| 1109 Register scratch2, | 1082 Register scratch2, |
| 1110 Register scratch3, | 1083 Register scratch3, |
| 1111 Handle<Name> name, | 1084 Handle<Name> name, |
| 1112 Handle<JSObject> interceptor_holder, | 1085 Handle<JSObject> interceptor_holder, |
| 1113 Label* miss_label) { | 1086 Label* miss_label) { |
| 1114 Register holder = | 1087 Register holder = |
| 1115 stub_compiler_->CheckPrototypes(object, receiver, interceptor_holder, | 1088 stub_compiler_->CheckPrototypes( |
| 1116 scratch1, scratch2, scratch3, | 1089 IC::CurrentTypeOf(object, masm->isolate()), receiver, |
| 1117 name, miss_label); | 1090 interceptor_holder, scratch1, scratch2, scratch3, name, miss_label); |
| 1118 | 1091 |
| 1119 // Call a runtime function to load the interceptor property. | 1092 // Call a runtime function to load the interceptor property. |
| 1120 FrameScope scope(masm, StackFrame::INTERNAL); | 1093 FrameScope scope(masm, StackFrame::INTERNAL); |
| 1121 // The name_ register must be preserved across the call. | 1094 // The name_ register must be preserved across the call. |
| 1122 __ Push(name_); | 1095 __ Push(name_); |
| 1123 PushInterceptorArguments(masm, receiver, holder, name_, interceptor_holder); | 1096 |
| 1124 __ CallExternalReference( | 1097 CompileCallLoadPropertyWithInterceptor( |
| 1125 ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorForCall), | 1098 masm, receiver, holder, name_, interceptor_holder, |
| 1126 masm->isolate()), | 1099 IC::kLoadPropertyWithInterceptorForCall); |
| 1127 StubCache::kInterceptorArgsLength); | 1100 |
| 1128 __ Pop(name_); | 1101 __ Pop(name_); |
| 1129 } | 1102 } |
| 1130 | 1103 |
| 1131 | 1104 |
| 1132 void LoadWithInterceptor(MacroAssembler* masm, | 1105 void LoadWithInterceptor(MacroAssembler* masm, |
| 1133 Register receiver, | 1106 Register receiver, |
| 1134 Register holder, | 1107 Register holder, |
| 1135 Handle<JSObject> holder_obj, | 1108 Handle<JSObject> holder_obj, |
| 1136 Register scratch, | 1109 Register scratch, |
| 1137 Label* interceptor_succeeded) { | 1110 Label* interceptor_succeeded) { |
| 1138 { | 1111 { |
| 1139 FrameScope scope(masm, StackFrame::INTERNAL); | 1112 FrameScope scope(masm, StackFrame::INTERNAL); |
| 1140 __ Push(holder, name_); | 1113 __ Push(holder, name_); |
| 1141 CompileCallLoadPropertyWithInterceptor(masm, | 1114 CompileCallLoadPropertyWithInterceptor( |
| 1142 receiver, | 1115 masm, receiver, holder, name_, holder_obj, |
| 1143 holder, | 1116 IC::kLoadPropertyWithInterceptorOnly); |
| 1144 name_, | |
| 1145 holder_obj); | |
| 1146 __ Pop(name_, receiver); | 1117 __ Pop(name_, receiver); |
| 1147 } | 1118 } |
| 1148 | 1119 |
| 1149 // If interceptor returns no-result sentinel, call the constant function. | 1120 // If interceptor returns no-result sentinel, call the constant function. |
| 1150 __ JumpIfNotRoot(x0, | 1121 __ JumpIfNotRoot(x0, |
| 1151 Heap::kNoInterceptorResultSentinelRootIndex, | 1122 Heap::kNoInterceptorResultSentinelRootIndex, |
| 1152 interceptor_succeeded); | 1123 interceptor_succeeded); |
| 1153 } | 1124 } |
| 1154 | 1125 |
| 1155 StubCompiler* stub_compiler_; | 1126 StubCompiler* stub_compiler_; |
| 1156 const ParameterCount& arguments_; | 1127 const ParameterCount& arguments_; |
| 1157 Register name_; | 1128 Register name_; |
| 1158 Code::ExtraICState extra_ic_state_; | 1129 Code::ExtraICState extra_ic_state_; |
| 1159 }; | 1130 }; |
| 1160 | 1131 |
| 1161 | 1132 |
| 1162 void StubCompiler::GenerateTailCall(MacroAssembler* masm, Handle<Code> code) { | 1133 void StubCompiler::GenerateTailCall(MacroAssembler* masm, Handle<Code> code) { |
| 1163 __ Jump(code, RelocInfo::CODE_TARGET); | 1134 __ Jump(code, RelocInfo::CODE_TARGET); |
| 1164 } | 1135 } |
| 1165 | 1136 |
| 1166 | 1137 |
| 1167 #undef __ | 1138 #undef __ |
| 1168 #define __ ACCESS_MASM(masm()) | 1139 #define __ ACCESS_MASM(masm()) |
| 1169 | 1140 |
| 1170 | 1141 |
| 1171 Register StubCompiler::CheckPrototypes(Handle<JSObject> object, | 1142 Register StubCompiler::CheckPrototypes(Handle<Type> type, |
| 1172 Register object_reg, | 1143 Register object_reg, |
| 1173 Handle<JSObject> holder, | 1144 Handle<JSObject> holder, |
| 1174 Register holder_reg, | 1145 Register holder_reg, |
| 1175 Register scratch1, | 1146 Register scratch1, |
| 1176 Register scratch2, | 1147 Register scratch2, |
| 1177 Handle<Name> name, | 1148 Handle<Name> name, |
| 1178 int save_at_depth, | 1149 int save_at_depth, |
| 1179 Label* miss, | 1150 Label* miss, |
| 1180 PrototypeCheckType check) { | 1151 PrototypeCheckType check) { |
| 1152 Handle<Map> receiver_map(IC::TypeToMap(*type, isolate())); |
| 1181 // Make sure that the type feedback oracle harvests the receiver map. | 1153 // Make sure that the type feedback oracle harvests the receiver map. |
| 1182 // TODO(svenpanne) Remove this hack when all ICs are reworked. | 1154 // TODO(svenpanne) Remove this hack when all ICs are reworked. |
| 1183 __ Mov(scratch1, Operand(Handle<Map>(object->map()))); | 1155 __ Mov(scratch1, Operand(receiver_map)); |
| 1184 | |
| 1185 Handle<JSObject> first = object; | |
| 1186 | 1156 |
| 1187 // object_reg and holder_reg registers can alias. | 1157 // object_reg and holder_reg registers can alias. |
| 1188 ASSERT(!AreAliased(object_reg, scratch1, scratch2)); | 1158 ASSERT(!AreAliased(object_reg, scratch1, scratch2)); |
| 1189 ASSERT(!AreAliased(holder_reg, scratch1, scratch2)); | 1159 ASSERT(!AreAliased(holder_reg, scratch1, scratch2)); |
| 1190 | 1160 |
| 1191 // Keep track of the current object in register reg. | 1161 // Keep track of the current object in register reg. |
| 1192 Register reg = object_reg; | 1162 Register reg = object_reg; |
| 1193 int depth = 0; | 1163 int depth = 0; |
| 1194 | 1164 |
| 1195 typedef FunctionCallbackArguments FCA; | 1165 typedef FunctionCallbackArguments FCA; |
| 1196 if (save_at_depth == depth) { | 1166 if (save_at_depth == depth) { |
| 1197 __ Poke(reg, FCA::kHolderIndex * kPointerSize); | 1167 __ Poke(reg, FCA::kHolderIndex * kPointerSize); |
| 1198 } | 1168 } |
| 1199 | 1169 |
| 1200 // Check the maps in the prototype chain. | 1170 Handle<JSObject> current = Handle<JSObject>::null(); |
| 1201 // Traverse the prototype chain from the object and do map checks. | 1171 if (type->IsConstant()) { |
| 1202 Handle<JSObject> current = object; | 1172 current = Handle<JSObject>::cast(type->AsConstant()); |
| 1203 while (!current.is_identical_to(holder)) { | 1173 } |
| 1174 Handle<JSObject> prototype = Handle<JSObject>::null(); |
| 1175 Handle<Map> current_map = receiver_map; |
| 1176 Handle<Map> holder_map(holder->map()); |
| 1177 // Traverse the prototype chain and check the maps in the prototype chain for |
| 1178 // fast and global objects or do negative lookup for normal objects. |
| 1179 while (!current_map.is_identical_to(holder_map)) { |
| 1204 ++depth; | 1180 ++depth; |
| 1205 | 1181 |
| 1206 // Only global objects and objects that do not require access | 1182 // Only global objects and objects that do not require access |
| 1207 // checks are allowed in stubs. | 1183 // checks are allowed in stubs. |
| 1208 ASSERT(current->IsJSGlobalProxy() || !current->IsAccessCheckNeeded()); | 1184 ASSERT(current_map->IsJSGlobalProxyMap() || |
| 1185 !current_map->is_access_check_needed()); |
| 1209 | 1186 |
| 1210 Handle<JSObject> prototype(JSObject::cast(current->GetPrototype())); | 1187 prototype = handle(JSObject::cast(current_map->prototype())); |
| 1211 if (!current->HasFastProperties() && | 1188 if (current_map->is_dictionary_map() && |
| 1212 !current->IsJSGlobalObject() && | 1189 !current_map->IsJSGlobalObjectMap() && |
| 1213 !current->IsJSGlobalProxy()) { | 1190 !current_map->IsJSGlobalProxyMap()) { |
| 1214 if (!name->IsUniqueName()) { | 1191 if (!name->IsUniqueName()) { |
| 1215 ASSERT(name->IsString()); | 1192 ASSERT(name->IsString()); |
| 1216 name = factory()->InternalizeString(Handle<String>::cast(name)); | 1193 name = factory()->InternalizeString(Handle<String>::cast(name)); |
| 1217 } | 1194 } |
| 1218 ASSERT(current->property_dictionary()->FindEntry(*name) == | 1195 ASSERT(current.is_null() || |
| 1219 NameDictionary::kNotFound); | 1196 (current->property_dictionary()->FindEntry(*name) == |
| 1197 NameDictionary::kNotFound)); |
| 1220 | 1198 |
| 1221 GenerateDictionaryNegativeLookup(masm(), miss, reg, name, | 1199 GenerateDictionaryNegativeLookup(masm(), miss, reg, name, |
| 1222 scratch1, scratch2); | 1200 scratch1, scratch2); |
| 1223 | 1201 |
| 1224 __ Ldr(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset)); | 1202 __ Ldr(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset)); |
| 1225 reg = holder_reg; // From now on the object will be in holder_reg. | 1203 reg = holder_reg; // From now on the object will be in holder_reg. |
| 1226 __ Ldr(reg, FieldMemOperand(scratch1, Map::kPrototypeOffset)); | 1204 __ Ldr(reg, FieldMemOperand(scratch1, Map::kPrototypeOffset)); |
| 1227 } else { | 1205 } else { |
| 1228 Register map_reg = scratch1; | 1206 Register map_reg = scratch1; |
| 1229 // TODO(jbramley): Skip this load when we don't need the map. | 1207 // TODO(jbramley): Skip this load when we don't need the map. |
| 1230 __ Ldr(map_reg, FieldMemOperand(reg, HeapObject::kMapOffset)); | 1208 __ Ldr(map_reg, FieldMemOperand(reg, HeapObject::kMapOffset)); |
| 1231 | 1209 |
| 1232 if (!current.is_identical_to(first) || (check == CHECK_ALL_MAPS)) { | 1210 if (depth != 1 || check == CHECK_ALL_MAPS) { |
| 1233 Handle<Map> current_map(current->map()); | |
| 1234 __ CheckMap(map_reg, current_map, miss, DONT_DO_SMI_CHECK); | 1211 __ CheckMap(map_reg, current_map, miss, DONT_DO_SMI_CHECK); |
| 1235 } | 1212 } |
| 1236 | 1213 |
| 1237 // Check access rights to the global object. This has to happen after | 1214 // Check access rights to the global object. This has to happen after |
| 1238 // the map check so that we know that the object is actually a global | 1215 // the map check so that we know that the object is actually a global |
| 1239 // object. | 1216 // object. |
| 1240 if (current->IsJSGlobalProxy()) { | 1217 if (current_map->IsJSGlobalProxyMap()) { |
| 1241 __ CheckAccessGlobalProxy(reg, scratch2, miss); | 1218 __ CheckAccessGlobalProxy(reg, scratch2, miss); |
| 1219 } else if (current_map->IsJSGlobalObjectMap()) { |
| 1220 GenerateCheckPropertyCell( |
| 1221 masm(), Handle<JSGlobalObject>::cast(current), name, |
| 1222 scratch2, miss); |
| 1242 } | 1223 } |
| 1224 |
| 1243 reg = holder_reg; // From now on the object will be in holder_reg. | 1225 reg = holder_reg; // From now on the object will be in holder_reg. |
| 1244 | 1226 |
| 1245 if (heap()->InNewSpace(*prototype)) { | 1227 if (heap()->InNewSpace(*prototype)) { |
| 1246 // The prototype is in new space; we cannot store a reference to it | 1228 // The prototype is in new space; we cannot store a reference to it |
| 1247 // in the code. Load it from the map. | 1229 // in the code. Load it from the map. |
| 1248 __ Ldr(reg, FieldMemOperand(map_reg, Map::kPrototypeOffset)); | 1230 __ Ldr(reg, FieldMemOperand(map_reg, Map::kPrototypeOffset)); |
| 1249 } else { | 1231 } else { |
| 1250 // The prototype is in old space; load it directly. | 1232 // The prototype is in old space; load it directly. |
| 1251 __ Mov(reg, Operand(prototype)); | 1233 __ Mov(reg, Operand(prototype)); |
| 1252 } | 1234 } |
| 1253 } | 1235 } |
| 1254 | 1236 |
| 1255 if (save_at_depth == depth) { | 1237 if (save_at_depth == depth) { |
| 1256 __ Poke(reg, FCA::kHolderIndex * kPointerSize); | 1238 __ Poke(reg, FCA::kHolderIndex * kPointerSize); |
| 1257 } | 1239 } |
| 1258 | 1240 |
| 1259 // Go to the next object in the prototype chain. | 1241 // Go to the next object in the prototype chain. |
| 1260 current = prototype; | 1242 current = prototype; |
| 1243 current_map = handle(current->map()); |
| 1261 } | 1244 } |
| 1262 | 1245 |
| 1263 // Log the check depth. | 1246 // Log the check depth. |
| 1264 LOG(isolate(), IntEvent("check-maps-depth", depth + 1)); | 1247 LOG(isolate(), IntEvent("check-maps-depth", depth + 1)); |
| 1265 | 1248 |
| 1266 // Check the holder map. | 1249 // Check the holder map. |
| 1267 if (!holder.is_identical_to(first) || check == CHECK_ALL_MAPS) { | 1250 if (depth != 0 || check == CHECK_ALL_MAPS) { |
| 1268 // Check the holder map. | 1251 // Check the holder map. |
| 1269 __ CheckMap(reg, scratch1, Handle<Map>(current->map()), miss, | 1252 __ CheckMap(reg, scratch1, current_map, miss, DONT_DO_SMI_CHECK); |
| 1270 DONT_DO_SMI_CHECK); | |
| 1271 } | 1253 } |
| 1272 | 1254 |
| 1273 // Perform security check for access to the global object. | 1255 // Perform security check for access to the global object. |
| 1274 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded()); | 1256 ASSERT(current_map->IsJSGlobalProxyMap() || |
| 1275 if (holder->IsJSGlobalProxy()) { | 1257 !current_map->is_access_check_needed()); |
| 1258 if (current_map->IsJSGlobalProxyMap()) { |
| 1276 __ CheckAccessGlobalProxy(reg, scratch1, miss); | 1259 __ CheckAccessGlobalProxy(reg, scratch1, miss); |
| 1277 } | 1260 } |
| 1278 | 1261 |
| 1279 // If we've skipped any global objects, it's not enough to verify that | |
| 1280 // their maps haven't changed. We also need to check that the property | |
| 1281 // cell for the property is still empty. | |
| 1282 GenerateCheckPropertyCells(masm(), object, holder, name, scratch1, miss); | |
| 1283 | |
| 1284 // Return the register containing the holder. | 1262 // Return the register containing the holder. |
| 1285 return reg; | 1263 return reg; |
| 1286 } | 1264 } |
| 1287 | 1265 |
| 1288 | 1266 |
| 1289 void LoadStubCompiler::HandlerFrontendFooter(Handle<Name> name, Label* miss) { | 1267 void LoadStubCompiler::HandlerFrontendFooter(Handle<Name> name, Label* miss) { |
| 1290 if (!miss->is_unused()) { | 1268 if (!miss->is_unused()) { |
| 1291 Label success; | 1269 Label success; |
| 1292 __ B(&success); | 1270 __ B(&success); |
| 1293 | 1271 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1305 __ B(&success); | 1283 __ B(&success); |
| 1306 | 1284 |
| 1307 GenerateRestoreName(masm(), miss, name); | 1285 GenerateRestoreName(masm(), miss, name); |
| 1308 TailCallBuiltin(masm(), MissBuiltin(kind())); | 1286 TailCallBuiltin(masm(), MissBuiltin(kind())); |
| 1309 | 1287 |
| 1310 __ Bind(&success); | 1288 __ Bind(&success); |
| 1311 } | 1289 } |
| 1312 } | 1290 } |
| 1313 | 1291 |
| 1314 | 1292 |
| 1315 Register LoadStubCompiler::CallbackHandlerFrontend(Handle<Object> object, | 1293 Register LoadStubCompiler::CallbackHandlerFrontend(Handle<Type> type, |
| 1316 Register object_reg, | 1294 Register object_reg, |
| 1317 Handle<JSObject> holder, | 1295 Handle<JSObject> holder, |
| 1318 Handle<Name> name, | 1296 Handle<Name> name, |
| 1319 Handle<Object> callback) { | 1297 Handle<Object> callback) { |
| 1320 Label miss; | 1298 Label miss; |
| 1321 | 1299 |
| 1322 Register reg = HandlerFrontendHeader(object, object_reg, holder, name, &miss); | 1300 Register reg = HandlerFrontendHeader(type, object_reg, holder, name, &miss); |
| 1323 | 1301 |
| 1324 // TODO(jbramely): HandlerFrontendHeader returns its result in scratch1(), so | 1302 // TODO(jbramely): HandlerFrontendHeader returns its result in scratch1(), so |
| 1325 // we can't use it below, but that isn't very obvious. Is there a better way | 1303 // we can't use it below, but that isn't very obvious. Is there a better way |
| 1326 // of handling this? | 1304 // of handling this? |
| 1327 | 1305 |
| 1328 if (!holder->HasFastProperties() && !holder->IsJSGlobalObject()) { | 1306 if (!holder->HasFastProperties() && !holder->IsJSGlobalObject()) { |
| 1329 ASSERT(!AreAliased(reg, scratch2(), scratch3(), scratch4())); | 1307 ASSERT(!AreAliased(reg, scratch2(), scratch3(), scratch4())); |
| 1330 | 1308 |
| 1331 // Load the properties dictionary. | 1309 // Load the properties dictionary. |
| 1332 Register dictionary = scratch4(); | 1310 Register dictionary = scratch4(); |
| (...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1537 { | 1515 { |
| 1538 FrameScope frame_scope(masm(), StackFrame::INTERNAL); | 1516 FrameScope frame_scope(masm(), StackFrame::INTERNAL); |
| 1539 if (must_preserve_receiver_reg) { | 1517 if (must_preserve_receiver_reg) { |
| 1540 __ Push(receiver(), holder_reg, this->name()); | 1518 __ Push(receiver(), holder_reg, this->name()); |
| 1541 } else { | 1519 } else { |
| 1542 __ Push(holder_reg, this->name()); | 1520 __ Push(holder_reg, this->name()); |
| 1543 } | 1521 } |
| 1544 // Invoke an interceptor. Note: map checks from receiver to | 1522 // Invoke an interceptor. Note: map checks from receiver to |
| 1545 // interceptor's holder has been compiled before (see a caller | 1523 // interceptor's holder has been compiled before (see a caller |
| 1546 // of this method.) | 1524 // of this method.) |
| 1547 CompileCallLoadPropertyWithInterceptor(masm(), | 1525 CompileCallLoadPropertyWithInterceptor( |
| 1548 receiver(), | 1526 masm(), receiver(), holder_reg, this->name(), interceptor_holder, |
| 1549 holder_reg, | 1527 IC::kLoadPropertyWithInterceptorOnly); |
| 1550 this->name(), | 1528 |
| 1551 interceptor_holder); | |
| 1552 // Check if interceptor provided a value for property. If it's | 1529 // Check if interceptor provided a value for property. If it's |
| 1553 // the case, return immediately. | 1530 // the case, return immediately. |
| 1554 Label interceptor_failed; | 1531 Label interceptor_failed; |
| 1555 __ JumpIfRoot(x0, | 1532 __ JumpIfRoot(x0, |
| 1556 Heap::kNoInterceptorResultSentinelRootIndex, | 1533 Heap::kNoInterceptorResultSentinelRootIndex, |
| 1557 &interceptor_failed); | 1534 &interceptor_failed); |
| 1558 frame_scope.GenerateLeaveFrame(); | 1535 frame_scope.GenerateLeaveFrame(); |
| 1559 __ Ret(); | 1536 __ Ret(); |
| 1560 | 1537 |
| 1561 __ Bind(&interceptor_failed); | 1538 __ Bind(&interceptor_failed); |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1599 ASSERT(holder->IsGlobalObject()); | 1576 ASSERT(holder->IsGlobalObject()); |
| 1600 | 1577 |
| 1601 const int argc = arguments().immediate(); | 1578 const int argc = arguments().immediate(); |
| 1602 | 1579 |
| 1603 // Get the receiver from the stack. | 1580 // Get the receiver from the stack. |
| 1604 Register receiver = x0; | 1581 Register receiver = x0; |
| 1605 __ Peek(receiver, argc * kPointerSize); | 1582 __ Peek(receiver, argc * kPointerSize); |
| 1606 | 1583 |
| 1607 // Check that the maps haven't changed. | 1584 // Check that the maps haven't changed. |
| 1608 __ JumpIfSmi(receiver, miss); | 1585 __ JumpIfSmi(receiver, miss); |
| 1609 CheckPrototypes(object, receiver, holder, x3, x1, x4, name, miss); | 1586 CheckPrototypes(IC::CurrentTypeOf(object, isolate()), |
| 1587 receiver, holder, x3, x1, x4, name, miss); |
| 1610 } | 1588 } |
| 1611 | 1589 |
| 1612 | 1590 |
| 1613 // Load the function object into x1 register. | 1591 // Load the function object into x1 register. |
| 1614 void CallStubCompiler::GenerateLoadFunctionFromCell( | 1592 void CallStubCompiler::GenerateLoadFunctionFromCell( |
| 1615 Handle<Cell> cell, | 1593 Handle<Cell> cell, |
| 1616 Handle<JSFunction> function, | 1594 Handle<JSFunction> function, |
| 1617 Label* miss) { | 1595 Label* miss) { |
| 1618 // Get the value from the cell. | 1596 // Get the value from the cell. |
| 1619 __ Mov(x3, Operand(cell)); | 1597 __ Mov(x3, Operand(cell)); |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1665 GenerateNameCheck(name, &miss); | 1643 GenerateNameCheck(name, &miss); |
| 1666 | 1644 |
| 1667 // Get the receiver of the function from the stack. | 1645 // Get the receiver of the function from the stack. |
| 1668 Register receiver = x0; | 1646 Register receiver = x0; |
| 1669 __ Peek(receiver, argc * kXRegSizeInBytes); | 1647 __ Peek(receiver, argc * kXRegSizeInBytes); |
| 1670 // Check that the receiver isn't a smi. | 1648 // Check that the receiver isn't a smi. |
| 1671 __ JumpIfSmi(receiver, &miss); | 1649 __ JumpIfSmi(receiver, &miss); |
| 1672 | 1650 |
| 1673 // Do the right check and compute the holder register. | 1651 // Do the right check and compute the holder register. |
| 1674 Register holder_reg = CheckPrototypes( | 1652 Register holder_reg = CheckPrototypes( |
| 1675 object, receiver, holder, x1, x3, x4, name, &miss); | 1653 IC::CurrentTypeOf(object, isolate()), |
| 1654 receiver, holder, x1, x3, x4, name, &miss); |
| 1676 Register function = x1; | 1655 Register function = x1; |
| 1677 GenerateFastPropertyLoad(masm(), function, holder_reg, | 1656 GenerateFastPropertyLoad(masm(), function, holder_reg, |
| 1678 index.is_inobject(holder), | 1657 index.is_inobject(holder), |
| 1679 index.translate(holder), | 1658 index.translate(holder), |
| 1680 Representation::Tagged()); | 1659 Representation::Tagged()); |
| 1681 | 1660 |
| 1682 GenerateCallFunction( | 1661 GenerateCallFunction( |
| 1683 masm(), object, arguments(), &miss, extra_state_, function, receiver, x3); | 1662 masm(), object, arguments(), &miss, extra_state_, function, receiver, x3); |
| 1684 | 1663 |
| 1685 // Handle call cache miss. | 1664 // Handle call cache miss. |
| (...skipping 26 matching lines...) Expand all Loading... |
| 1712 GenerateNameCheck(name, &miss); | 1691 GenerateNameCheck(name, &miss); |
| 1713 | 1692 |
| 1714 Register receiver = x1; | 1693 Register receiver = x1; |
| 1715 if (cell.is_null()) { | 1694 if (cell.is_null()) { |
| 1716 __ Peek(receiver, argc * kPointerSize); | 1695 __ Peek(receiver, argc * kPointerSize); |
| 1717 | 1696 |
| 1718 // Check that the receiver isn't a smi. | 1697 // Check that the receiver isn't a smi. |
| 1719 __ JumpIfSmi(receiver, &miss); | 1698 __ JumpIfSmi(receiver, &miss); |
| 1720 | 1699 |
| 1721 // Check that the maps haven't changed. | 1700 // Check that the maps haven't changed. |
| 1722 CheckPrototypes(Handle<JSObject>::cast(object), receiver, holder, x3, x0, | 1701 CheckPrototypes(IC::CurrentTypeOf(object, isolate()), |
| 1723 x4, name, &miss); | 1702 receiver, holder, x3, x0, x4, name, &miss); |
| 1724 } else { | 1703 } else { |
| 1725 ASSERT(cell->value() == *function); | 1704 ASSERT(cell->value() == *function); |
| 1726 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name, | 1705 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name, |
| 1727 &miss); | 1706 &miss); |
| 1728 GenerateLoadFunctionFromCell(cell, function, &miss); | 1707 GenerateLoadFunctionFromCell(cell, function, &miss); |
| 1729 } | 1708 } |
| 1730 | 1709 |
| 1731 Handle<AllocationSite> site = isolate()->factory()->NewAllocationSite(); | 1710 Handle<AllocationSite> site = isolate()->factory()->NewAllocationSite(); |
| 1732 site->SetElementsKind(GetInitialFastElementsKind()); | 1711 site->SetElementsKind(GetInitialFastElementsKind()); |
| 1733 Handle<Cell> site_feedback_cell = isolate()->factory()->NewCell(site); | 1712 Handle<Cell> site_feedback_cell = isolate()->factory()->NewCell(site); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1775 GenerateNameCheck(name, &miss); | 1754 GenerateNameCheck(name, &miss); |
| 1776 | 1755 |
| 1777 // Get the receiver from the stack | 1756 // Get the receiver from the stack |
| 1778 Register receiver = x1; | 1757 Register receiver = x1; |
| 1779 __ Peek(receiver, argc * kPointerSize); | 1758 __ Peek(receiver, argc * kPointerSize); |
| 1780 | 1759 |
| 1781 // Check that the receiver isn't a smi. | 1760 // Check that the receiver isn't a smi. |
| 1782 __ JumpIfSmi(receiver, &miss); | 1761 __ JumpIfSmi(receiver, &miss); |
| 1783 | 1762 |
| 1784 // Check that the maps haven't changed. | 1763 // Check that the maps haven't changed. |
| 1785 CheckPrototypes(Handle<JSObject>::cast(object), receiver, holder, x3, x0, x4, | 1764 CheckPrototypes(IC::CurrentTypeOf(object, isolate()), |
| 1786 name, &miss); | 1765 receiver, holder, x3, x0, x4, name, &miss); |
| 1787 | 1766 |
| 1788 if (argc == 0) { | 1767 if (argc == 0) { |
| 1789 // Nothing to do, just return the length. | 1768 // Nothing to do, just return the length. |
| 1790 __ Ldr(result, FieldMemOperand(receiver, JSArray::kLengthOffset)); | 1769 __ Ldr(result, FieldMemOperand(receiver, JSArray::kLengthOffset)); |
| 1791 __ Drop(argc + 1); | 1770 __ Drop(argc + 1); |
| 1792 __ Ret(); | 1771 __ Ret(); |
| 1793 } else { | 1772 } else { |
| 1794 Label call_builtin; | 1773 Label call_builtin; |
| 1795 | 1774 |
| 1796 if (argc == 1) { // Otherwise fall through to call the builtin. | 1775 if (argc == 1) { // Otherwise fall through to call the builtin. |
| (...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2048 | 2027 |
| 2049 GenerateNameCheck(name, &miss); | 2028 GenerateNameCheck(name, &miss); |
| 2050 | 2029 |
| 2051 // Get the receiver from the stack | 2030 // Get the receiver from the stack |
| 2052 Register receiver = x1; | 2031 Register receiver = x1; |
| 2053 __ Peek(receiver, argc * kPointerSize); | 2032 __ Peek(receiver, argc * kPointerSize); |
| 2054 // Check that the receiver isn't a smi. | 2033 // Check that the receiver isn't a smi. |
| 2055 __ JumpIfSmi(receiver, &miss); | 2034 __ JumpIfSmi(receiver, &miss); |
| 2056 | 2035 |
| 2057 // Check that the maps haven't changed. | 2036 // Check that the maps haven't changed. |
| 2058 CheckPrototypes(Handle<JSObject>::cast(object), receiver, holder, | 2037 CheckPrototypes(IC::CurrentTypeOf(object, isolate()), |
| 2059 x3, x4, x0, name, &miss); | 2038 receiver, holder, x3, x4, x0, name, &miss); |
| 2060 | 2039 |
| 2061 // Get the elements array of the object. | 2040 // Get the elements array of the object. |
| 2062 Register elements = x3; | 2041 Register elements = x3; |
| 2063 __ Ldr(elements, FieldMemOperand(receiver, JSArray::kElementsOffset)); | 2042 __ Ldr(elements, FieldMemOperand(receiver, JSArray::kElementsOffset)); |
| 2064 | 2043 |
| 2065 // Check that the elements are in fast mode and writable. | 2044 // Check that the elements are in fast mode and writable. |
| 2066 __ CheckMap(elements, | 2045 __ CheckMap(elements, |
| 2067 x0, | 2046 x0, |
| 2068 Heap::kFixedArrayMapRootIndex, | 2047 Heap::kFixedArrayMapRootIndex, |
| 2069 &call_builtin, | 2048 &call_builtin, |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2134 Label* index_out_of_range_label = &index_out_of_range; | 2113 Label* index_out_of_range_label = &index_out_of_range; |
| 2135 | 2114 |
| 2136 if (kind_ == Code::CALL_IC && | 2115 if (kind_ == Code::CALL_IC && |
| 2137 (CallICBase::StringStubState::decode(extra_state_) == | 2116 (CallICBase::StringStubState::decode(extra_state_) == |
| 2138 DEFAULT_STRING_STUB)) { | 2117 DEFAULT_STRING_STUB)) { |
| 2139 index_out_of_range_label = &miss; | 2118 index_out_of_range_label = &miss; |
| 2140 } | 2119 } |
| 2141 GenerateNameCheck(name, &name_miss); | 2120 GenerateNameCheck(name, &name_miss); |
| 2142 | 2121 |
| 2143 // Check that the maps starting from the prototype haven't changed. | 2122 // Check that the maps starting from the prototype haven't changed. |
| 2144 Register prototype = x0; | 2123 Register prototype_reg = x0; |
| 2145 GenerateDirectLoadGlobalFunctionPrototype(masm(), | 2124 GenerateDirectLoadGlobalFunctionPrototype(masm(), |
| 2146 Context::STRING_FUNCTION_INDEX, | 2125 Context::STRING_FUNCTION_INDEX, |
| 2147 prototype, | 2126 prototype_reg, |
| 2148 &miss); | 2127 &miss); |
| 2149 ASSERT(!object.is_identical_to(holder)); | 2128 ASSERT(!object.is_identical_to(holder)); |
| 2150 CheckPrototypes( | 2129 Handle<JSObject> prototype(JSObject::cast(object->GetPrototype(isolate()))); |
| 2151 Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))), | 2130 CheckPrototypes(IC::CurrentTypeOf(prototype, isolate()), |
| 2152 prototype, holder, x1, x3, x4, name, &miss); | 2131 prototype_reg, holder, x1, x3, x4, name, &miss); |
| 2153 | 2132 |
| 2154 Register result = x0; | 2133 Register result = x0; |
| 2155 Register receiver = x1; | 2134 Register receiver = x1; |
| 2156 Register index = x4; | 2135 Register index = x4; |
| 2157 | 2136 |
| 2158 __ Peek(receiver, argc * kPointerSize); | 2137 __ Peek(receiver, argc * kPointerSize); |
| 2159 if (argc > 0) { | 2138 if (argc > 0) { |
| 2160 __ Peek(index, (argc - 1) * kPointerSize); | 2139 __ Peek(index, (argc - 1) * kPointerSize); |
| 2161 } else { | 2140 } else { |
| 2162 __ LoadRoot(index, Heap::kUndefinedValueRootIndex); | 2141 __ LoadRoot(index, Heap::kUndefinedValueRootIndex); |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2219 Label* index_out_of_range_label = &index_out_of_range; | 2198 Label* index_out_of_range_label = &index_out_of_range; |
| 2220 | 2199 |
| 2221 if (kind_ == Code::CALL_IC && | 2200 if (kind_ == Code::CALL_IC && |
| 2222 (CallICBase::StringStubState::decode(extra_state_) == | 2201 (CallICBase::StringStubState::decode(extra_state_) == |
| 2223 DEFAULT_STRING_STUB)) { | 2202 DEFAULT_STRING_STUB)) { |
| 2224 index_out_of_range_label = &miss; | 2203 index_out_of_range_label = &miss; |
| 2225 } | 2204 } |
| 2226 GenerateNameCheck(name, &name_miss); | 2205 GenerateNameCheck(name, &name_miss); |
| 2227 | 2206 |
| 2228 // Check that the maps starting from the prototype haven't changed. | 2207 // Check that the maps starting from the prototype haven't changed. |
| 2229 Register prototype = x0; | 2208 Register prototype_reg = x0; |
| 2230 GenerateDirectLoadGlobalFunctionPrototype(masm(), | 2209 GenerateDirectLoadGlobalFunctionPrototype(masm(), |
| 2231 Context::STRING_FUNCTION_INDEX, | 2210 Context::STRING_FUNCTION_INDEX, |
| 2232 prototype, | 2211 prototype_reg, |
| 2233 &miss); | 2212 &miss); |
| 2234 ASSERT(!object.is_identical_to(holder)); | 2213 ASSERT(!object.is_identical_to(holder)); |
| 2235 CheckPrototypes( | 2214 Handle<JSObject> prototype(JSObject::cast(object->GetPrototype(isolate()))); |
| 2236 Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))), | 2215 CheckPrototypes(IC::CurrentTypeOf(prototype, isolate()), |
| 2237 prototype, holder, x1, x3, x4, name, &miss); | 2216 prototype_reg, holder, x1, x3, x4, name, &miss); |
| 2238 | 2217 |
| 2239 Register receiver = x0; | 2218 Register receiver = x0; |
| 2240 Register index = x4; | 2219 Register index = x4; |
| 2241 Register scratch = x3; | 2220 Register scratch = x3; |
| 2242 Register result = x0; | 2221 Register result = x0; |
| 2243 | 2222 |
| 2244 __ Peek(receiver, argc * kPointerSize); | 2223 __ Peek(receiver, argc * kPointerSize); |
| 2245 if (argc > 0) { | 2224 if (argc > 0) { |
| 2246 __ Peek(index, (argc - 1) * kPointerSize); | 2225 __ Peek(index, (argc - 1) * kPointerSize); |
| 2247 } else { | 2226 } else { |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2302 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null(); | 2281 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null(); |
| 2303 | 2282 |
| 2304 Label miss; | 2283 Label miss; |
| 2305 GenerateNameCheck(name, &miss); | 2284 GenerateNameCheck(name, &miss); |
| 2306 | 2285 |
| 2307 if (cell.is_null()) { | 2286 if (cell.is_null()) { |
| 2308 Register receiver = x1; | 2287 Register receiver = x1; |
| 2309 __ Peek(receiver, kPointerSize); | 2288 __ Peek(receiver, kPointerSize); |
| 2310 __ JumpIfSmi(receiver, &miss); | 2289 __ JumpIfSmi(receiver, &miss); |
| 2311 | 2290 |
| 2312 CheckPrototypes(Handle<JSObject>::cast(object), receiver, holder, | 2291 CheckPrototypes(IC::CurrentTypeOf(object, isolate()), |
| 2313 x0, x3, x4, name, &miss); | 2292 receiver, holder, x0, x3, x4, name, &miss); |
| 2314 } else { | 2293 } else { |
| 2315 ASSERT(cell->value() == *function); | 2294 ASSERT(cell->value() == *function); |
| 2316 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name, | 2295 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name, |
| 2317 &miss); | 2296 &miss); |
| 2318 GenerateLoadFunctionFromCell(cell, function, &miss); | 2297 GenerateLoadFunctionFromCell(cell, function, &miss); |
| 2319 } | 2298 } |
| 2320 | 2299 |
| 2321 // Load the char code argument. | 2300 // Load the char code argument. |
| 2322 Register code = x1; | 2301 Register code = x1; |
| 2323 __ Peek(code, 0); | 2302 __ Peek(code, 0); |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2375 // If the object is not a JSObject or we got an unexpected number of | 2354 // If the object is not a JSObject or we got an unexpected number of |
| 2376 // arguments, bail out to the regular call. | 2355 // arguments, bail out to the regular call. |
| 2377 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null(); | 2356 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null(); |
| 2378 | 2357 |
| 2379 GenerateNameCheck(name, &miss); | 2358 GenerateNameCheck(name, &miss); |
| 2380 | 2359 |
| 2381 if (cell.is_null()) { | 2360 if (cell.is_null()) { |
| 2382 Register receiver = x1; | 2361 Register receiver = x1; |
| 2383 __ Peek(receiver, kPointerSize); | 2362 __ Peek(receiver, kPointerSize); |
| 2384 __ JumpIfSmi(receiver, &miss); | 2363 __ JumpIfSmi(receiver, &miss); |
| 2385 CheckPrototypes(Handle<JSObject>::cast(object), receiver, holder, | 2364 CheckPrototypes(IC::CurrentTypeOf(object, isolate()), |
| 2386 x0, x3, x4, name, &miss); | 2365 receiver, holder, x0, x3, x4, name, &miss); |
| 2387 } else { | 2366 } else { |
| 2388 ASSERT(cell->value() == *function); | 2367 ASSERT(cell->value() == *function); |
| 2389 GenerateGlobalReceiverCheck( | 2368 GenerateGlobalReceiverCheck( |
| 2390 Handle<JSObject>::cast(object), holder, name, &miss); | 2369 Handle<JSObject>::cast(object), holder, name, &miss); |
| 2391 GenerateLoadFunctionFromCell(cell, function, &miss); | 2370 GenerateLoadFunctionFromCell(cell, function, &miss); |
| 2392 } | 2371 } |
| 2393 | 2372 |
| 2394 // Load the (only) argument. | 2373 // Load the (only) argument. |
| 2395 Register arg = x0; | 2374 Register arg = x0; |
| 2396 __ Peek(arg, 0); | 2375 __ Peek(arg, 0); |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2491 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null(); | 2470 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null(); |
| 2492 | 2471 |
| 2493 Register result = x0; | 2472 Register result = x0; |
| 2494 Label miss, slow; | 2473 Label miss, slow; |
| 2495 GenerateNameCheck(name, &miss); | 2474 GenerateNameCheck(name, &miss); |
| 2496 | 2475 |
| 2497 if (cell.is_null()) { | 2476 if (cell.is_null()) { |
| 2498 Register receiver = x1; | 2477 Register receiver = x1; |
| 2499 __ Peek(receiver, kPointerSize); | 2478 __ Peek(receiver, kPointerSize); |
| 2500 __ JumpIfSmi(receiver, &miss); | 2479 __ JumpIfSmi(receiver, &miss); |
| 2501 CheckPrototypes(Handle<JSObject>::cast(object), receiver, holder, | 2480 CheckPrototypes(IC::CurrentTypeOf(object, isolate()), |
| 2502 x0, x3, x4, name, &miss); | 2481 receiver, holder, x0, x3, x4, name, &miss); |
| 2503 } else { | 2482 } else { |
| 2504 ASSERT(cell->value() == *function); | 2483 ASSERT(cell->value() == *function); |
| 2505 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name, | 2484 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name, |
| 2506 &miss); | 2485 &miss); |
| 2507 GenerateLoadFunctionFromCell(cell, function, &miss); | 2486 GenerateLoadFunctionFromCell(cell, function, &miss); |
| 2508 } | 2487 } |
| 2509 | 2488 |
| 2510 // Load the (only) argument. | 2489 // Load the (only) argument. |
| 2511 Register arg = x0; | 2490 Register arg = x0; |
| 2512 __ Peek(arg, 0); | 2491 __ Peek(arg, 0); |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2586 | 2565 |
| 2587 // Check that the receiver isn't a smi. | 2566 // Check that the receiver isn't a smi. |
| 2588 __ JumpIfSmi(receiver, &miss_before_stack_reserved); | 2567 __ JumpIfSmi(receiver, &miss_before_stack_reserved); |
| 2589 | 2568 |
| 2590 __ IncrementCounter(counters->call_const(), 1, x0, x3); | 2569 __ IncrementCounter(counters->call_const(), 1, x0, x3); |
| 2591 __ IncrementCounter(counters->call_const_fast_api(), 1, x0, x3); | 2570 __ IncrementCounter(counters->call_const_fast_api(), 1, x0, x3); |
| 2592 | 2571 |
| 2593 ReserveSpaceForFastApiCall(masm(), x0); | 2572 ReserveSpaceForFastApiCall(masm(), x0); |
| 2594 | 2573 |
| 2595 // Check that the maps haven't changed and find a Holder as a side effect. | 2574 // Check that the maps haven't changed and find a Holder as a side effect. |
| 2596 CheckPrototypes(Handle<JSObject>::cast(object), receiver, holder, x0, x3, x4, | 2575 CheckPrototypes(IC::CurrentTypeOf(object, isolate()), |
| 2597 name, depth, &miss); | 2576 receiver, holder, x0, x3, x4, name, depth, &miss); |
| 2598 | 2577 |
| 2599 GenerateFastApiDirectCall(masm(), optimization, argc, false); | 2578 GenerateFastApiDirectCall(masm(), optimization, argc, false); |
| 2600 | 2579 |
| 2601 __ Bind(&miss); | 2580 __ Bind(&miss); |
| 2602 FreeSpaceForFastApiCall(masm()); | 2581 FreeSpaceForFastApiCall(masm()); |
| 2603 | 2582 |
| 2604 __ Bind(&miss_before_stack_reserved); | 2583 __ Bind(&miss_before_stack_reserved); |
| 2605 GenerateMissBranch(); | 2584 GenerateMissBranch(); |
| 2606 | 2585 |
| 2607 // Return the generated code. | 2586 // Return the generated code. |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2642 | 2621 |
| 2643 // Make sure that it's okay not to patch the on stack receiver | 2622 // Make sure that it's okay not to patch the on stack receiver |
| 2644 // unless we're doing a receiver map check. | 2623 // unless we're doing a receiver map check. |
| 2645 ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK); | 2624 ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK); |
| 2646 | 2625 |
| 2647 switch (check) { | 2626 switch (check) { |
| 2648 case RECEIVER_MAP_CHECK: { | 2627 case RECEIVER_MAP_CHECK: { |
| 2649 __ IncrementCounter(isolate()->counters()->call_const(), 1, x0, x3); | 2628 __ IncrementCounter(isolate()->counters()->call_const(), 1, x0, x3); |
| 2650 | 2629 |
| 2651 // Check that the maps haven't changed. | 2630 // Check that the maps haven't changed. |
| 2652 CheckPrototypes(Handle<JSObject>::cast(object), receiver, holder, | 2631 CheckPrototypes(IC::CurrentTypeOf(object, isolate()), |
| 2653 x0, x3, x4, name, &miss); | 2632 receiver, holder, x0, x3, x4, name, &miss); |
| 2654 | 2633 |
| 2655 // Patch the receiver on the stack with the global proxy if necessary. | 2634 // Patch the receiver on the stack with the global proxy if necessary. |
| 2656 if (object->IsGlobalObject()) { | 2635 if (object->IsGlobalObject()) { |
| 2657 __ Ldr(x3, | 2636 __ Ldr(x3, |
| 2658 FieldMemOperand(receiver, GlobalObject::kGlobalReceiverOffset)); | 2637 FieldMemOperand(receiver, GlobalObject::kGlobalReceiverOffset)); |
| 2659 __ Poke(x3, argc * kPointerSize); | 2638 __ Poke(x3, argc * kPointerSize); |
| 2660 } | 2639 } |
| 2661 break; | 2640 break; |
| 2662 } | 2641 } |
| 2663 case STRING_CHECK: { | 2642 case STRING_CHECK: { |
| 2664 // Check that the object is a string. | 2643 // Check that the object is a string. |
| 2665 __ JumpIfObjectType(receiver, x3, x3, FIRST_NONSTRING_TYPE, &miss, ge); | 2644 __ JumpIfObjectType(receiver, x3, x3, FIRST_NONSTRING_TYPE, &miss, ge); |
| 2666 // Check that the maps starting from the prototype haven't changed. | 2645 // Check that the maps starting from the prototype haven't changed. |
| 2667 Register prototype = x0; | 2646 Register prototype_reg = x0; |
| 2668 GenerateDirectLoadGlobalFunctionPrototype( | 2647 GenerateDirectLoadGlobalFunctionPrototype( |
| 2669 masm(), Context::STRING_FUNCTION_INDEX, prototype, &miss); | 2648 masm(), Context::STRING_FUNCTION_INDEX, prototype_reg, &miss); |
| 2649 Handle<Object> prototype(object->GetPrototype(isolate()), isolate()); |
| 2670 CheckPrototypes( | 2650 CheckPrototypes( |
| 2671 Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))), | 2651 IC::CurrentTypeOf(prototype, isolate()), |
| 2672 prototype, holder, x3, x1, x4, name, &miss); | 2652 prototype_reg, holder, x3, x1, x4, name, &miss); |
| 2673 break; | 2653 break; |
| 2674 } | 2654 } |
| 2675 case SYMBOL_CHECK: { | 2655 case SYMBOL_CHECK: { |
| 2676 // Check that the object is a symbol. | 2656 // Check that the object is a symbol. |
| 2677 __ JumpIfNotObjectType(receiver, x3, x3, SYMBOL_TYPE, &miss); | 2657 __ JumpIfNotObjectType(receiver, x3, x3, SYMBOL_TYPE, &miss); |
| 2678 // Check that the maps starting from the prototype haven't changed. | 2658 // Check that the maps starting from the prototype haven't changed. |
| 2679 Register prototype = x0; | 2659 Register prototype_reg = x0; |
| 2680 GenerateDirectLoadGlobalFunctionPrototype( | 2660 GenerateDirectLoadGlobalFunctionPrototype( |
| 2681 masm(), Context::SYMBOL_FUNCTION_INDEX, prototype, &miss); | 2661 masm(), Context::SYMBOL_FUNCTION_INDEX, prototype_reg, &miss); |
| 2662 Handle<Object> prototype(object->GetPrototype(isolate()), isolate()); |
| 2682 CheckPrototypes( | 2663 CheckPrototypes( |
| 2683 Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))), | 2664 IC::CurrentTypeOf(prototype, isolate()), |
| 2684 prototype, holder, x3, x1, x4, name, &miss); | 2665 prototype_reg, holder, x3, x1, x4, name, &miss); |
| 2685 break; | 2666 break; |
| 2686 } | 2667 } |
| 2687 case NUMBER_CHECK: { | 2668 case NUMBER_CHECK: { |
| 2688 Label fast; | 2669 Label fast; |
| 2689 // Check that the object is a smi or a heap number. | 2670 // Check that the object is a smi or a heap number. |
| 2690 __ JumpIfSmi(receiver, &fast); | 2671 __ JumpIfSmi(receiver, &fast); |
| 2691 __ JumpIfNotObjectType(receiver, x0, x0, HEAP_NUMBER_TYPE, &miss); | 2672 __ JumpIfNotObjectType(receiver, x0, x0, HEAP_NUMBER_TYPE, &miss); |
| 2692 | 2673 |
| 2693 __ Bind(&fast); | 2674 __ Bind(&fast); |
| 2694 // Check that the maps starting from the prototype haven't changed. | 2675 // Check that the maps starting from the prototype haven't changed. |
| 2695 Register prototype = x0; | 2676 Register prototype_reg = x0; |
| 2696 GenerateDirectLoadGlobalFunctionPrototype( | 2677 GenerateDirectLoadGlobalFunctionPrototype( |
| 2697 masm(), Context::NUMBER_FUNCTION_INDEX, prototype, &miss); | 2678 masm(), Context::NUMBER_FUNCTION_INDEX, prototype_reg, &miss); |
| 2679 Handle<Object> prototype(object->GetPrototype(isolate()), isolate()); |
| 2698 CheckPrototypes( | 2680 CheckPrototypes( |
| 2699 Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))), | 2681 IC::CurrentTypeOf(prototype, isolate()), |
| 2700 prototype, holder, x3, x1, x4, name, &miss); | 2682 prototype_reg, holder, x3, x1, x4, name, &miss); |
| 2701 break; | 2683 break; |
| 2702 } | 2684 } |
| 2703 case BOOLEAN_CHECK: { | 2685 case BOOLEAN_CHECK: { |
| 2704 GenerateBooleanCheck(receiver, &miss); | 2686 GenerateBooleanCheck(receiver, &miss); |
| 2705 | 2687 |
| 2706 // Check that the maps starting from the prototype haven't changed. | 2688 // Check that the maps starting from the prototype haven't changed. |
| 2707 Register prototype = x0; | 2689 Register prototype_reg = x0; |
| 2708 GenerateDirectLoadGlobalFunctionPrototype( | 2690 GenerateDirectLoadGlobalFunctionPrototype( |
| 2709 masm(), Context::BOOLEAN_FUNCTION_INDEX, prototype, &miss); | 2691 masm(), Context::BOOLEAN_FUNCTION_INDEX, prototype_reg, &miss); |
| 2692 Handle<Object> prototype(object->GetPrototype(isolate()), isolate()); |
| 2710 CheckPrototypes( | 2693 CheckPrototypes( |
| 2711 Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))), | 2694 IC::CurrentTypeOf(prototype, isolate()), |
| 2712 prototype, holder, x3, x1, x4, name, &miss); | 2695 prototype_reg, holder, x3, x1, x4, name, &miss); |
| 2713 break; | 2696 break; |
| 2714 } | 2697 } |
| 2715 } | 2698 } |
| 2716 | 2699 |
| 2717 Label success; | 2700 Label success; |
| 2718 __ B(&success); | 2701 __ B(&success); |
| 2719 | 2702 |
| 2720 // Handle call cache miss. | 2703 // Handle call cache miss. |
| 2721 __ Bind(&miss); | 2704 __ Bind(&miss); |
| 2722 GenerateMissBranch(); | 2705 GenerateMissBranch(); |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2865 return GetCode(Code::NORMAL, name); | 2848 return GetCode(Code::NORMAL, name); |
| 2866 } | 2849 } |
| 2867 | 2850 |
| 2868 | 2851 |
| 2869 Handle<Code> StoreStubCompiler::CompileStoreCallback( | 2852 Handle<Code> StoreStubCompiler::CompileStoreCallback( |
| 2870 Handle<JSObject> object, | 2853 Handle<JSObject> object, |
| 2871 Handle<JSObject> holder, | 2854 Handle<JSObject> holder, |
| 2872 Handle<Name> name, | 2855 Handle<Name> name, |
| 2873 Handle<ExecutableAccessorInfo> callback) { | 2856 Handle<ExecutableAccessorInfo> callback) { |
| 2874 ASM_LOCATION("StoreStubCompiler::CompileStoreCallback"); | 2857 ASM_LOCATION("StoreStubCompiler::CompileStoreCallback"); |
| 2875 HandlerFrontend(object, receiver(), holder, name); | 2858 HandlerFrontend(IC::CurrentTypeOf(object, isolate()), |
| 2859 receiver(), holder, name); |
| 2876 | 2860 |
| 2877 // Stub never generated for non-global objects that require access checks. | 2861 // Stub never generated for non-global objects that require access checks. |
| 2878 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded()); | 2862 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded()); |
| 2879 | 2863 |
| 2880 __ Mov(scratch1(), Operand(callback)); | 2864 __ Mov(scratch1(), Operand(callback)); |
| 2881 __ Mov(scratch2(), Operand(name)); | 2865 __ Mov(scratch2(), Operand(name)); |
| 2882 __ Push(receiver(), scratch1(), scratch2(), value()); | 2866 __ Push(receiver(), scratch1(), scratch2(), value()); |
| 2883 | 2867 |
| 2884 // Do tail-call to the runtime system. | 2868 // Do tail-call to the runtime system. |
| 2885 ExternalReference store_callback_property = | 2869 ExternalReference store_callback_property = |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2970 | 2954 |
| 2971 // Handle store cache miss. | 2955 // Handle store cache miss. |
| 2972 __ Bind(&miss); | 2956 __ Bind(&miss); |
| 2973 TailCallBuiltin(masm(), MissBuiltin(kind())); | 2957 TailCallBuiltin(masm(), MissBuiltin(kind())); |
| 2974 | 2958 |
| 2975 // Return the generated code. | 2959 // Return the generated code. |
| 2976 return GetCode(kind(), Code::FAST, name); | 2960 return GetCode(kind(), Code::FAST, name); |
| 2977 } | 2961 } |
| 2978 | 2962 |
| 2979 | 2963 |
| 2980 Handle<Code> LoadStubCompiler::CompileLoadNonexistent( | 2964 Handle<Code> LoadStubCompiler::CompileLoadNonexistent(Handle<Type> type, |
| 2981 Handle<Object> object, | 2965 Handle<JSObject> last, |
| 2982 Handle<JSObject> last, | 2966 Handle<Name> name) { |
| 2983 Handle<Name> name, | 2967 NonexistentHandlerFrontend(type, last, name); |
| 2984 Handle<JSGlobalObject> global) { | |
| 2985 NonexistentHandlerFrontend(object, last, name, global); | |
| 2986 | 2968 |
| 2987 // Return undefined if maps of the full prototype chain are still the | 2969 // Return undefined if maps of the full prototype chain are still the |
| 2988 // same and no global property with this name contains a value. | 2970 // same and no global property with this name contains a value. |
| 2989 __ LoadRoot(x0, Heap::kUndefinedValueRootIndex); | 2971 __ LoadRoot(x0, Heap::kUndefinedValueRootIndex); |
| 2990 __ Ret(); | 2972 __ Ret(); |
| 2991 | 2973 |
| 2992 // Return the generated code. | 2974 // Return the generated code. |
| 2993 return GetCode(kind(), Code::FAST, name); | 2975 return GetCode(kind(), Code::FAST, name); |
| 2994 } | 2976 } |
| 2995 | 2977 |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3071 } | 3053 } |
| 3072 __ Ret(); | 3054 __ Ret(); |
| 3073 } | 3055 } |
| 3074 | 3056 |
| 3075 | 3057 |
| 3076 #undef __ | 3058 #undef __ |
| 3077 #define __ ACCESS_MASM(masm()) | 3059 #define __ ACCESS_MASM(masm()) |
| 3078 | 3060 |
| 3079 | 3061 |
| 3080 Handle<Code> LoadStubCompiler::CompileLoadGlobal( | 3062 Handle<Code> LoadStubCompiler::CompileLoadGlobal( |
| 3081 Handle<Object> object, | 3063 Handle<Type> type, |
| 3082 Handle<GlobalObject> global, | 3064 Handle<GlobalObject> global, |
| 3083 Handle<PropertyCell> cell, | 3065 Handle<PropertyCell> cell, |
| 3084 Handle<Name> name, | 3066 Handle<Name> name, |
| 3085 bool is_dont_delete) { | 3067 bool is_dont_delete) { |
| 3086 Label miss; | 3068 Label miss; |
| 3087 | 3069 |
| 3088 HandlerFrontendHeader(object, receiver(), global, name, &miss); | 3070 HandlerFrontendHeader(type, receiver(), global, name, &miss); |
| 3089 | 3071 |
| 3090 // Get the value from the cell. | 3072 // Get the value from the cell. |
| 3091 __ Mov(x3, Operand(cell)); | 3073 __ Mov(x3, Operand(cell)); |
| 3092 __ Ldr(x4, FieldMemOperand(x3, Cell::kValueOffset)); | 3074 __ Ldr(x4, FieldMemOperand(x3, Cell::kValueOffset)); |
| 3093 | 3075 |
| 3094 // Check for deleted property if property can actually be deleted. | 3076 // Check for deleted property if property can actually be deleted. |
| 3095 if (!is_dont_delete) { | 3077 if (!is_dont_delete) { |
| 3096 __ JumpIfRoot(x4, Heap::kTheHoleValueRootIndex, &miss); | 3078 __ JumpIfRoot(x4, Heap::kTheHoleValueRootIndex, &miss); |
| 3097 } | 3079 } |
| 3098 | 3080 |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3188 return GetICCode( | 3170 return GetICCode( |
| 3189 kind(), Code::NORMAL, factory()->empty_string(), POLYMORPHIC); | 3171 kind(), Code::NORMAL, factory()->empty_string(), POLYMORPHIC); |
| 3190 } | 3172 } |
| 3191 | 3173 |
| 3192 | 3174 |
| 3193 Handle<Code> StoreStubCompiler::CompileStoreCallback( | 3175 Handle<Code> StoreStubCompiler::CompileStoreCallback( |
| 3194 Handle<JSObject> object, | 3176 Handle<JSObject> object, |
| 3195 Handle<JSObject> holder, | 3177 Handle<JSObject> holder, |
| 3196 Handle<Name> name, | 3178 Handle<Name> name, |
| 3197 const CallOptimization& call_optimization) { | 3179 const CallOptimization& call_optimization) { |
| 3198 HandlerFrontend(object, receiver(), holder, name); | 3180 HandlerFrontend(IC::CurrentTypeOf(object, isolate()), |
| 3181 receiver(), holder, name); |
| 3199 | 3182 |
| 3200 Register values[] = { value() }; | 3183 Register values[] = { value() }; |
| 3201 GenerateFastApiCall( | 3184 GenerateFastApiCall( |
| 3202 masm(), call_optimization, receiver(), scratch3(), 1, values); | 3185 masm(), call_optimization, receiver(), scratch3(), 1, values); |
| 3203 | 3186 |
| 3204 // Return the generated code. | 3187 // Return the generated code. |
| 3205 return GetCode(kind(), Code::FAST, name); | 3188 return GetCode(kind(), Code::FAST, name); |
| 3206 } | 3189 } |
| 3207 | 3190 |
| 3208 | 3191 |
| (...skipping 25 matching lines...) Expand all Loading... |
| 3234 | 3217 |
| 3235 // Miss case, call the runtime. | 3218 // Miss case, call the runtime. |
| 3236 __ Bind(&miss); | 3219 __ Bind(&miss); |
| 3237 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); | 3220 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); |
| 3238 } | 3221 } |
| 3239 | 3222 |
| 3240 | 3223 |
| 3241 } } // namespace v8::internal | 3224 } } // namespace v8::internal |
| 3242 | 3225 |
| 3243 #endif // V8_TARGET_ARCH_A64 | 3226 #endif // V8_TARGET_ARCH_A64 |
| OLD | NEW |