| OLD | NEW |
| 1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/ic/accessor-assembler.h" | 5 #include "src/ic/accessor-assembler.h" |
| 6 | 6 |
| 7 #include "src/code-factory.h" | 7 #include "src/code-factory.h" |
| 8 #include "src/code-stubs.h" | 8 #include "src/code-stubs.h" |
| 9 #include "src/ic/handler-configuration.h" | 9 #include "src/ic/handler-configuration.h" |
| 10 #include "src/ic/stub-cache.h" | 10 #include "src/ic/stub-cache.h" |
| (...skipping 1138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1149 Node* instance_type, Node* key, | 1149 Node* instance_type, Node* key, |
| 1150 const LoadICParameters* p, | 1150 const LoadICParameters* p, |
| 1151 Label* slow) { | 1151 Label* slow) { |
| 1152 Comment("key is unique name"); | 1152 Comment("key is unique name"); |
| 1153 Label if_found_on_receiver(this), if_property_dictionary(this), | 1153 Label if_found_on_receiver(this), if_property_dictionary(this), |
| 1154 lookup_prototype_chain(this); | 1154 lookup_prototype_chain(this); |
| 1155 Variable var_details(this, MachineRepresentation::kWord32); | 1155 Variable var_details(this, MachineRepresentation::kWord32); |
| 1156 Variable var_value(this, MachineRepresentation::kTagged); | 1156 Variable var_value(this, MachineRepresentation::kTagged); |
| 1157 | 1157 |
| 1158 // Receivers requiring non-standard accesses (interceptors, access | 1158 // Receivers requiring non-standard accesses (interceptors, access |
| 1159 // checks, string wrappers, proxies) are handled in the runtime. | 1159 // checks, strings and string wrappers, proxies) are handled in the runtime. |
| 1160 // We special-case strings here, to support loading <Symbol.split> etc. | 1160 GotoIf(Int32LessThanOrEqual(instance_type, |
| 1161 Variable var_receiver(this, MachineRepresentation::kTagged); | 1161 Int32Constant(LAST_SPECIAL_RECEIVER_TYPE)), |
| 1162 Variable var_receiver_map(this, MachineRepresentation::kTagged); | |
| 1163 Variable var_instance_type(this, MachineRepresentation::kWord32); | |
| 1164 var_receiver.Bind(receiver); | |
| 1165 var_receiver_map.Bind(receiver_map); | |
| 1166 var_instance_type.Bind(instance_type); | |
| 1167 Label normal_receiver(this); | |
| 1168 GotoIf(Int32GreaterThan(instance_type, | |
| 1169 Int32Constant(LAST_SPECIAL_RECEIVER_TYPE)), | |
| 1170 &normal_receiver); | |
| 1171 GotoIf(Int32GreaterThanOrEqual(instance_type, | |
| 1172 Int32Constant(FIRST_NONSTRING_TYPE)), | |
| 1173 slow); | 1162 slow); |
| 1174 CSA_ASSERT(this, WordEqual(LoadMapConstructorFunctionIndex(receiver_map), | |
| 1175 IntPtrConstant(Context::STRING_FUNCTION_INDEX))); | |
| 1176 Node* native_context = LoadNativeContext(p->context); | |
| 1177 Node* constructor_function = | |
| 1178 LoadContextElement(native_context, Context::STRING_FUNCTION_INDEX); | |
| 1179 Node* initial_map = LoadObjectField(constructor_function, | |
| 1180 JSFunction::kPrototypeOrInitialMapOffset); | |
| 1181 var_receiver.Bind(LoadMapPrototype(initial_map)); | |
| 1182 var_receiver_map.Bind(LoadMap(var_receiver.value())); | |
| 1183 var_instance_type.Bind(LoadMapInstanceType(var_receiver_map.value())); | |
| 1184 Goto(&normal_receiver); | |
| 1185 | 1163 |
| 1186 Bind(&normal_receiver); | |
| 1187 receiver = var_receiver.value(); | |
| 1188 receiver_map = var_receiver_map.value(); | |
| 1189 instance_type = var_instance_type.value(); | |
| 1190 // Check if the receiver has fast or slow properties. | 1164 // Check if the receiver has fast or slow properties. |
| 1191 Node* properties = LoadProperties(receiver); | 1165 Node* properties = LoadProperties(receiver); |
| 1192 Node* properties_map = LoadMap(properties); | 1166 Node* properties_map = LoadMap(properties); |
| 1193 GotoIf(WordEqual(properties_map, LoadRoot(Heap::kHashTableMapRootIndex)), | 1167 GotoIf(WordEqual(properties_map, LoadRoot(Heap::kHashTableMapRootIndex)), |
| 1194 &if_property_dictionary); | 1168 &if_property_dictionary); |
| 1195 | 1169 |
| 1196 // Try looking up the property on the receiver; if unsuccessful, look | 1170 // Try looking up the property on the receiver; if unsuccessful, look |
| 1197 // for a handler in the stub cache. | 1171 // for a handler in the stub cache. |
| 1198 Comment("DescriptorArray lookup"); | 1172 Comment("DescriptorArray lookup"); |
| 1199 | 1173 |
| 1200 // Skip linear search if there are too many descriptors. | 1174 // Skip linear search if there are too many descriptors. |
| 1201 // TODO(jkummerow): Consider implementing binary search. | 1175 // TODO(jkummerow): Consider implementing binary search. |
| 1202 // See also TryLookupProperty() which has the same limitation. | 1176 // See also TryLookupProperty() which has the same limitation. |
| 1203 const int32_t kMaxLinear = 210; | 1177 const int32_t kMaxLinear = 210; |
| 1204 Label stub_cache(this); | 1178 Label stub_cache(this); |
| 1205 Node* bitfield3 = LoadMapBitField3(var_receiver_map.value()); | 1179 Node* bitfield3 = LoadMapBitField3(receiver_map); |
| 1206 Node* nof = DecodeWordFromWord32<Map::NumberOfOwnDescriptorsBits>(bitfield3); | 1180 Node* nof = DecodeWordFromWord32<Map::NumberOfOwnDescriptorsBits>(bitfield3); |
| 1207 GotoIf(UintPtrLessThan(IntPtrConstant(kMaxLinear), nof), &stub_cache); | 1181 GotoIf(UintPtrLessThan(IntPtrConstant(kMaxLinear), nof), &stub_cache); |
| 1208 Node* descriptors = LoadMapDescriptors(var_receiver_map.value()); | 1182 Node* descriptors = LoadMapDescriptors(receiver_map); |
| 1209 Variable var_name_index(this, MachineType::PointerRepresentation()); | 1183 Variable var_name_index(this, MachineType::PointerRepresentation()); |
| 1210 Label if_descriptor_found(this); | 1184 Label if_descriptor_found(this); |
| 1211 DescriptorLookupLinear(key, descriptors, nof, &if_descriptor_found, | 1185 DescriptorLookupLinear(key, descriptors, nof, &if_descriptor_found, |
| 1212 &var_name_index, &stub_cache); | 1186 &var_name_index, &stub_cache); |
| 1213 | 1187 |
| 1214 Bind(&if_descriptor_found); | 1188 Bind(&if_descriptor_found); |
| 1215 { | 1189 { |
| 1216 LoadPropertyFromFastObject(receiver, var_receiver_map.value(), descriptors, | 1190 LoadPropertyFromFastObject(receiver, receiver_map, descriptors, |
| 1217 var_name_index.value(), &var_details, | 1191 var_name_index.value(), &var_details, |
| 1218 &var_value); | 1192 &var_value); |
| 1219 Goto(&if_found_on_receiver); | 1193 Goto(&if_found_on_receiver); |
| 1220 } | 1194 } |
| 1221 | 1195 |
| 1222 Bind(&stub_cache); | 1196 Bind(&stub_cache); |
| 1223 { | 1197 { |
| 1224 Comment("stub cache probe for fast property load"); | 1198 Comment("stub cache probe for fast property load"); |
| 1225 Variable var_handler(this, MachineRepresentation::kTagged); | 1199 Variable var_handler(this, MachineRepresentation::kTagged); |
| 1226 Label found_handler(this, &var_handler), stub_cache_miss(this); | 1200 Label found_handler(this, &var_handler), stub_cache_miss(this); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 1254 { | 1228 { |
| 1255 LoadPropertyFromNameDictionary(properties, var_name_index.value(), | 1229 LoadPropertyFromNameDictionary(properties, var_name_index.value(), |
| 1256 &var_details, &var_value); | 1230 &var_details, &var_value); |
| 1257 Goto(&if_found_on_receiver); | 1231 Goto(&if_found_on_receiver); |
| 1258 } | 1232 } |
| 1259 } | 1233 } |
| 1260 | 1234 |
| 1261 Bind(&if_found_on_receiver); | 1235 Bind(&if_found_on_receiver); |
| 1262 { | 1236 { |
| 1263 Node* value = CallGetterIfAccessor(var_value.value(), var_details.value(), | 1237 Node* value = CallGetterIfAccessor(var_value.value(), var_details.value(), |
| 1264 p->context, var_receiver.value(), slow); | 1238 p->context, receiver, slow); |
| 1265 IncrementCounter(isolate()->counters()->ic_keyed_load_generic_symbol(), 1); | 1239 IncrementCounter(isolate()->counters()->ic_keyed_load_generic_symbol(), 1); |
| 1266 Return(value); | 1240 Return(value); |
| 1267 } | 1241 } |
| 1268 | 1242 |
| 1269 Bind(&lookup_prototype_chain); | 1243 Bind(&lookup_prototype_chain); |
| 1270 { | 1244 { |
| 1271 Variable var_holder_map(this, MachineRepresentation::kTagged); | 1245 Variable var_holder_map(this, MachineRepresentation::kTagged); |
| 1272 Variable var_holder_instance_type(this, MachineRepresentation::kWord32); | 1246 Variable var_holder_instance_type(this, MachineRepresentation::kWord32); |
| 1273 Label return_undefined(this); | 1247 Label return_undefined(this); |
| 1274 Variable* merged_variables[] = {&var_holder_map, &var_holder_instance_type}; | 1248 Variable* merged_variables[] = {&var_holder_map, &var_holder_instance_type}; |
| 1275 Label loop(this, arraysize(merged_variables), merged_variables); | 1249 Label loop(this, arraysize(merged_variables), merged_variables); |
| 1276 | 1250 |
| 1277 var_holder_map.Bind(var_receiver_map.value()); | 1251 var_holder_map.Bind(receiver_map); |
| 1278 var_holder_instance_type.Bind(var_instance_type.value()); | 1252 var_holder_instance_type.Bind(instance_type); |
| 1279 // Private symbols must not be looked up on the prototype chain. | 1253 // Private symbols must not be looked up on the prototype chain. |
| 1280 GotoIf(IsPrivateSymbol(key), &return_undefined); | 1254 GotoIf(IsPrivateSymbol(key), &return_undefined); |
| 1281 Goto(&loop); | 1255 Goto(&loop); |
| 1282 Bind(&loop); | 1256 Bind(&loop); |
| 1283 { | 1257 { |
| 1284 // Bailout if it can be an integer indexed exotic case. | 1258 // Bailout if it can be an integer indexed exotic case. |
| 1285 GotoIf(Word32Equal(var_holder_instance_type.value(), | 1259 GotoIf(Word32Equal(var_holder_instance_type.value(), |
| 1286 Int32Constant(JS_TYPED_ARRAY_TYPE)), | 1260 Int32Constant(JS_TYPED_ARRAY_TYPE)), |
| 1287 slow); | 1261 slow); |
| 1288 Node* proto = LoadMapPrototype(var_holder_map.value()); | 1262 Node* proto = LoadMapPrototype(var_holder_map.value()); |
| 1289 GotoIf(WordEqual(proto, NullConstant()), &return_undefined); | 1263 GotoIf(WordEqual(proto, NullConstant()), &return_undefined); |
| 1290 Node* proto_map = LoadMap(proto); | 1264 Node* proto_map = LoadMap(proto); |
| 1291 Node* proto_instance_type = LoadMapInstanceType(proto_map); | 1265 Node* proto_instance_type = LoadMapInstanceType(proto_map); |
| 1292 var_holder_map.Bind(proto_map); | 1266 var_holder_map.Bind(proto_map); |
| 1293 var_holder_instance_type.Bind(proto_instance_type); | 1267 var_holder_instance_type.Bind(proto_instance_type); |
| 1294 Label next_proto(this), return_value(this, &var_value), goto_slow(this); | 1268 Label next_proto(this), return_value(this, &var_value), goto_slow(this); |
| 1295 TryGetOwnProperty(p->context, var_receiver.value(), proto, proto_map, | 1269 TryGetOwnProperty(p->context, receiver, proto, proto_map, |
| 1296 proto_instance_type, key, &return_value, &var_value, | 1270 proto_instance_type, key, &return_value, &var_value, |
| 1297 &next_proto, &goto_slow); | 1271 &next_proto, &goto_slow); |
| 1298 | 1272 |
| 1299 // This trampoline and the next are required to appease Turbofan's | 1273 // This trampoline and the next are required to appease Turbofan's |
| 1300 // variable merging. | 1274 // variable merging. |
| 1301 Bind(&next_proto); | 1275 Bind(&next_proto); |
| 1302 Goto(&loop); | 1276 Goto(&loop); |
| 1303 | 1277 |
| 1304 Bind(&goto_slow); | 1278 Bind(&goto_slow); |
| 1305 Goto(slow); | 1279 Goto(slow); |
| (...skipping 668 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1974 Node* slot = Parameter(Descriptor::kSlot); | 1948 Node* slot = Parameter(Descriptor::kSlot); |
| 1975 Node* context = Parameter(Descriptor::kContext); | 1949 Node* context = Parameter(Descriptor::kContext); |
| 1976 Node* vector = LoadTypeFeedbackVectorForStub(); | 1950 Node* vector = LoadTypeFeedbackVectorForStub(); |
| 1977 | 1951 |
| 1978 StoreICParameters p(context, receiver, name, value, slot, vector); | 1952 StoreICParameters p(context, receiver, name, value, slot, vector); |
| 1979 KeyedStoreIC(&p, language_mode); | 1953 KeyedStoreIC(&p, language_mode); |
| 1980 } | 1954 } |
| 1981 | 1955 |
| 1982 } // namespace internal | 1956 } // namespace internal |
| 1983 } // namespace v8 | 1957 } // namespace v8 |
| OLD | NEW |