OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 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 <ostream> | 5 #include <ostream> |
6 | 6 |
7 #include "src/accessors.h" | 7 #include "src/accessors.h" |
8 #include "src/compilation-dependencies.h" | 8 #include "src/compilation-dependencies.h" |
9 #include "src/compiler/access-info.h" | 9 #include "src/compiler/access-info.h" |
10 #include "src/compiler/type-cache.h" | 10 #include "src/compiler/type-cache.h" |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
54 return os << "Store"; | 54 return os << "Store"; |
55 case AccessMode::kStoreInLiteral: | 55 case AccessMode::kStoreInLiteral: |
56 return os << "StoreInLiteral"; | 56 return os << "StoreInLiteral"; |
57 } | 57 } |
58 UNREACHABLE(); | 58 UNREACHABLE(); |
59 return os; | 59 return os; |
60 } | 60 } |
61 | 61 |
62 ElementAccessInfo::ElementAccessInfo() {} | 62 ElementAccessInfo::ElementAccessInfo() {} |
63 | 63 |
64 ElementAccessInfo::ElementAccessInfo(MapList const& receiver_maps, | 64 ElementAccessInfo::ElementAccessInfo(MapHandles const& receiver_maps, |
65 ElementsKind elements_kind) | 65 ElementsKind elements_kind) |
66 : elements_kind_(elements_kind), receiver_maps_(receiver_maps) {} | 66 : elements_kind_(elements_kind), receiver_maps_(receiver_maps) {} |
67 | 67 |
68 // static | 68 // static |
69 PropertyAccessInfo PropertyAccessInfo::NotFound(MapList const& receiver_maps, | 69 PropertyAccessInfo PropertyAccessInfo::NotFound(MapHandles const& receiver_maps, |
70 MaybeHandle<JSObject> holder) { | 70 MaybeHandle<JSObject> holder) { |
71 return PropertyAccessInfo(holder, receiver_maps); | 71 return PropertyAccessInfo(holder, receiver_maps); |
72 } | 72 } |
73 | 73 |
74 // static | 74 // static |
75 PropertyAccessInfo PropertyAccessInfo::DataConstant( | 75 PropertyAccessInfo PropertyAccessInfo::DataConstant( |
76 MapList const& receiver_maps, Handle<Object> constant, | 76 MapHandles const& receiver_maps, Handle<Object> constant, |
77 MaybeHandle<JSObject> holder) { | 77 MaybeHandle<JSObject> holder) { |
78 return PropertyAccessInfo(kDataConstant, holder, constant, receiver_maps); | 78 return PropertyAccessInfo(kDataConstant, holder, constant, receiver_maps); |
79 } | 79 } |
80 | 80 |
81 // static | 81 // static |
82 PropertyAccessInfo PropertyAccessInfo::DataField( | 82 PropertyAccessInfo PropertyAccessInfo::DataField( |
83 PropertyConstness constness, MapList const& receiver_maps, | 83 PropertyConstness constness, MapHandles const& receiver_maps, |
84 FieldIndex field_index, MachineRepresentation field_representation, | 84 FieldIndex field_index, MachineRepresentation field_representation, |
85 Type* field_type, MaybeHandle<Map> field_map, MaybeHandle<JSObject> holder, | 85 Type* field_type, MaybeHandle<Map> field_map, MaybeHandle<JSObject> holder, |
86 MaybeHandle<Map> transition_map) { | 86 MaybeHandle<Map> transition_map) { |
87 Kind kind = constness == kConst ? kDataConstantField : kDataField; | 87 Kind kind = constness == kConst ? kDataConstantField : kDataField; |
88 return PropertyAccessInfo(kind, holder, transition_map, field_index, | 88 return PropertyAccessInfo(kind, holder, transition_map, field_index, |
89 field_representation, field_type, field_map, | 89 field_representation, field_type, field_map, |
90 receiver_maps); | 90 receiver_maps); |
91 } | 91 } |
92 | 92 |
93 // static | 93 // static |
94 PropertyAccessInfo PropertyAccessInfo::AccessorConstant( | 94 PropertyAccessInfo PropertyAccessInfo::AccessorConstant( |
95 MapList const& receiver_maps, Handle<Object> constant, | 95 MapHandles const& receiver_maps, Handle<Object> constant, |
96 MaybeHandle<JSObject> holder) { | 96 MaybeHandle<JSObject> holder) { |
97 return PropertyAccessInfo(kAccessorConstant, holder, constant, receiver_maps); | 97 return PropertyAccessInfo(kAccessorConstant, holder, constant, receiver_maps); |
98 } | 98 } |
99 | 99 |
100 PropertyAccessInfo::PropertyAccessInfo() | 100 PropertyAccessInfo::PropertyAccessInfo() |
101 : kind_(kInvalid), | 101 : kind_(kInvalid), |
102 field_representation_(MachineRepresentation::kNone), | 102 field_representation_(MachineRepresentation::kNone), |
103 field_type_(Type::None()) {} | 103 field_type_(Type::None()) {} |
104 | 104 |
105 PropertyAccessInfo::PropertyAccessInfo(MaybeHandle<JSObject> holder, | 105 PropertyAccessInfo::PropertyAccessInfo(MaybeHandle<JSObject> holder, |
106 MapList const& receiver_maps) | 106 MapHandles const& receiver_maps) |
107 : kind_(kNotFound), | 107 : kind_(kNotFound), |
108 receiver_maps_(receiver_maps), | 108 receiver_maps_(receiver_maps), |
109 holder_(holder), | 109 holder_(holder), |
110 field_representation_(MachineRepresentation::kNone), | 110 field_representation_(MachineRepresentation::kNone), |
111 field_type_(Type::None()) {} | 111 field_type_(Type::None()) {} |
112 | 112 |
113 PropertyAccessInfo::PropertyAccessInfo(Kind kind, MaybeHandle<JSObject> holder, | 113 PropertyAccessInfo::PropertyAccessInfo(Kind kind, MaybeHandle<JSObject> holder, |
114 Handle<Object> constant, | 114 Handle<Object> constant, |
115 MapList const& receiver_maps) | 115 MapHandles const& receiver_maps) |
116 : kind_(kind), | 116 : kind_(kind), |
117 receiver_maps_(receiver_maps), | 117 receiver_maps_(receiver_maps), |
118 constant_(constant), | 118 constant_(constant), |
119 holder_(holder), | 119 holder_(holder), |
120 field_representation_(MachineRepresentation::kNone), | 120 field_representation_(MachineRepresentation::kNone), |
121 field_type_(Type::Any()) {} | 121 field_type_(Type::Any()) {} |
122 | 122 |
123 PropertyAccessInfo::PropertyAccessInfo( | 123 PropertyAccessInfo::PropertyAccessInfo( |
124 Kind kind, MaybeHandle<JSObject> holder, MaybeHandle<Map> transition_map, | 124 Kind kind, MaybeHandle<JSObject> holder, MaybeHandle<Map> transition_map, |
125 FieldIndex field_index, MachineRepresentation field_representation, | 125 FieldIndex field_index, MachineRepresentation field_representation, |
126 Type* field_type, MaybeHandle<Map> field_map, MapList const& receiver_maps) | 126 Type* field_type, MaybeHandle<Map> field_map, |
| 127 MapHandles const& receiver_maps) |
127 : kind_(kind), | 128 : kind_(kind), |
128 receiver_maps_(receiver_maps), | 129 receiver_maps_(receiver_maps), |
129 transition_map_(transition_map), | 130 transition_map_(transition_map), |
130 holder_(holder), | 131 holder_(holder), |
131 field_index_(field_index), | 132 field_index_(field_index), |
132 field_representation_(field_representation), | 133 field_representation_(field_representation), |
133 field_type_(field_type), | 134 field_type_(field_type), |
134 field_map_(field_map) {} | 135 field_map_(field_map) {} |
135 | 136 |
136 bool PropertyAccessInfo::Merge(PropertyAccessInfo const* that, | 137 bool PropertyAccessInfo::Merge(PropertyAccessInfo const* that, |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
221 zone_(zone) { | 222 zone_(zone) { |
222 DCHECK(native_context->IsNativeContext()); | 223 DCHECK(native_context->IsNativeContext()); |
223 } | 224 } |
224 | 225 |
225 | 226 |
226 bool AccessInfoFactory::ComputeElementAccessInfo( | 227 bool AccessInfoFactory::ComputeElementAccessInfo( |
227 Handle<Map> map, AccessMode access_mode, ElementAccessInfo* access_info) { | 228 Handle<Map> map, AccessMode access_mode, ElementAccessInfo* access_info) { |
228 // Check if it is safe to inline element access for the {map}. | 229 // Check if it is safe to inline element access for the {map}. |
229 if (!CanInlineElementAccess(map)) return false; | 230 if (!CanInlineElementAccess(map)) return false; |
230 ElementsKind const elements_kind = map->elements_kind(); | 231 ElementsKind const elements_kind = map->elements_kind(); |
231 *access_info = ElementAccessInfo(MapList{map}, elements_kind); | 232 *access_info = ElementAccessInfo(MapHandles{map}, elements_kind); |
232 return true; | 233 return true; |
233 } | 234 } |
234 | 235 |
235 bool AccessInfoFactory::ComputeElementAccessInfos( | 236 bool AccessInfoFactory::ComputeElementAccessInfos( |
236 MapHandleList const& maps, AccessMode access_mode, | 237 MapHandles const& maps, AccessMode access_mode, |
237 ZoneVector<ElementAccessInfo>* access_infos) { | 238 ZoneVector<ElementAccessInfo>* access_infos) { |
238 if (access_mode == AccessMode::kLoad) { | 239 if (access_mode == AccessMode::kLoad) { |
239 // For polymorphic loads of similar elements kinds (i.e. all tagged or all | 240 // For polymorphic loads of similar elements kinds (i.e. all tagged or all |
240 // double), always use the "worst case" code without a transition. This is | 241 // double), always use the "worst case" code without a transition. This is |
241 // much faster than transitioning the elements to the worst case, trading a | 242 // much faster than transitioning the elements to the worst case, trading a |
242 // TransitionElementsKind for a CheckMaps, avoiding mutation of the array. | 243 // TransitionElementsKind for a CheckMaps, avoiding mutation of the array. |
243 ElementAccessInfo access_info; | 244 ElementAccessInfo access_info; |
244 if (ConsolidateElementLoad(maps, &access_info)) { | 245 if (ConsolidateElementLoad(maps, &access_info)) { |
245 access_infos->push_back(access_info); | 246 access_infos->push_back(access_info); |
246 return true; | 247 return true; |
247 } | 248 } |
248 } | 249 } |
249 | 250 |
250 // Collect possible transition targets. | 251 // Collect possible transition targets. |
251 MapHandleList possible_transition_targets(maps.length()); | 252 MapHandles possible_transition_targets; |
| 253 possible_transition_targets.reserve(maps.size()); |
252 for (Handle<Map> map : maps) { | 254 for (Handle<Map> map : maps) { |
253 if (Map::TryUpdate(map).ToHandle(&map)) { | 255 if (Map::TryUpdate(map).ToHandle(&map)) { |
254 if (CanInlineElementAccess(map) && | 256 if (CanInlineElementAccess(map) && |
255 IsFastElementsKind(map->elements_kind()) && | 257 IsFastElementsKind(map->elements_kind()) && |
256 GetInitialFastElementsKind() != map->elements_kind()) { | 258 GetInitialFastElementsKind() != map->elements_kind()) { |
257 possible_transition_targets.Add(map); | 259 possible_transition_targets.push_back(map); |
258 } | 260 } |
259 } | 261 } |
260 } | 262 } |
261 | 263 |
262 // Separate the actual receiver maps and the possible transition sources. | 264 // Separate the actual receiver maps and the possible transition sources. |
263 MapHandleList receiver_maps(maps.length()); | 265 MapHandles receiver_maps; |
264 MapTransitionList transitions(maps.length()); | 266 receiver_maps.reserve(maps.size()); |
| 267 MapTransitionList transitions(maps.size()); |
265 for (Handle<Map> map : maps) { | 268 for (Handle<Map> map : maps) { |
266 if (Map::TryUpdate(map).ToHandle(&map)) { | 269 if (Map::TryUpdate(map).ToHandle(&map)) { |
267 Map* transition_target = | 270 Map* transition_target = |
268 map->FindElementsKindTransitionedMap(&possible_transition_targets); | 271 map->FindElementsKindTransitionedMap(possible_transition_targets); |
269 if (transition_target == nullptr) { | 272 if (transition_target == nullptr) { |
270 receiver_maps.Add(map); | 273 receiver_maps.push_back(map); |
271 } else { | 274 } else { |
272 DCHECK(!map->is_stable()); | 275 DCHECK(!map->is_stable()); |
273 transitions.push_back(std::make_pair(map, handle(transition_target))); | 276 transitions.push_back(std::make_pair(map, handle(transition_target))); |
274 } | 277 } |
275 } | 278 } |
276 } | 279 } |
277 | 280 |
278 for (Handle<Map> receiver_map : receiver_maps) { | 281 for (Handle<Map> receiver_map : receiver_maps) { |
279 // Compute the element access information. | 282 // Compute the element access information. |
280 ElementAccessInfo access_info; | 283 ElementAccessInfo access_info; |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
368 Handle<Map> field_owner_map(map->FindFieldOwner(number), | 371 Handle<Map> field_owner_map(map->FindFieldOwner(number), |
369 isolate()); | 372 isolate()); |
370 dependencies()->AssumeFieldOwner(field_owner_map); | 373 dependencies()->AssumeFieldOwner(field_owner_map); |
371 | 374 |
372 // Remember the field map, and try to infer a useful type. | 375 // Remember the field map, and try to infer a useful type. |
373 field_type = Type::For(descriptors_field_type->AsClass()); | 376 field_type = Type::For(descriptors_field_type->AsClass()); |
374 field_map = descriptors_field_type->AsClass(); | 377 field_map = descriptors_field_type->AsClass(); |
375 } | 378 } |
376 } | 379 } |
377 *access_info = PropertyAccessInfo::DataField( | 380 *access_info = PropertyAccessInfo::DataField( |
378 details.constness(), MapList{receiver_map}, field_index, | 381 details.constness(), MapHandles{receiver_map}, field_index, |
379 field_representation, field_type, field_map, holder); | 382 field_representation, field_type, field_map, holder); |
380 return true; | 383 return true; |
381 } else { | 384 } else { |
382 DCHECK_EQ(kAccessor, details.kind()); | 385 DCHECK_EQ(kAccessor, details.kind()); |
383 // TODO(turbofan): Add support for general accessors? | 386 // TODO(turbofan): Add support for general accessors? |
384 return false; | 387 return false; |
385 } | 388 } |
386 | 389 |
387 } else { | 390 } else { |
388 DCHECK_EQ(kDescriptor, details.location()); | 391 DCHECK_EQ(kDescriptor, details.location()); |
389 if (details.kind() == kData) { | 392 if (details.kind() == kData) { |
390 DCHECK(!FLAG_track_constant_fields); | 393 DCHECK(!FLAG_track_constant_fields); |
391 *access_info = PropertyAccessInfo::DataConstant( | 394 *access_info = PropertyAccessInfo::DataConstant( |
392 MapList{receiver_map}, | 395 MapHandles{receiver_map}, |
393 handle(descriptors->GetValue(number), isolate()), holder); | 396 handle(descriptors->GetValue(number), isolate()), holder); |
394 return true; | 397 return true; |
395 } else { | 398 } else { |
396 DCHECK_EQ(kAccessor, details.kind()); | 399 DCHECK_EQ(kAccessor, details.kind()); |
397 Handle<Object> accessors(descriptors->GetValue(number), isolate()); | 400 Handle<Object> accessors(descriptors->GetValue(number), isolate()); |
398 if (!accessors->IsAccessorPair()) return false; | 401 if (!accessors->IsAccessorPair()) return false; |
399 Handle<Object> accessor( | 402 Handle<Object> accessor( |
400 access_mode == AccessMode::kLoad | 403 access_mode == AccessMode::kLoad |
401 ? Handle<AccessorPair>::cast(accessors)->getter() | 404 ? Handle<AccessorPair>::cast(accessors)->getter() |
402 : Handle<AccessorPair>::cast(accessors)->setter(), | 405 : Handle<AccessorPair>::cast(accessors)->setter(), |
(...skipping 10 matching lines...) Expand all Loading... |
413 if (FunctionTemplateInfo::TryGetCachedPropertyName(isolate(), | 416 if (FunctionTemplateInfo::TryGetCachedPropertyName(isolate(), |
414 accessor) | 417 accessor) |
415 .ToHandle(&cached_property_name)) { | 418 .ToHandle(&cached_property_name)) { |
416 if (ComputePropertyAccessInfo(map, cached_property_name, | 419 if (ComputePropertyAccessInfo(map, cached_property_name, |
417 access_mode, access_info)) { | 420 access_mode, access_info)) { |
418 return true; | 421 return true; |
419 } | 422 } |
420 } | 423 } |
421 } | 424 } |
422 *access_info = PropertyAccessInfo::AccessorConstant( | 425 *access_info = PropertyAccessInfo::AccessorConstant( |
423 MapList{receiver_map}, accessor, holder); | 426 MapHandles{receiver_map}, accessor, holder); |
424 return true; | 427 return true; |
425 } | 428 } |
426 } | 429 } |
427 UNREACHABLE(); | 430 UNREACHABLE(); |
428 return false; | 431 return false; |
429 } | 432 } |
430 | 433 |
431 // Don't search on the prototype chain for special indices in case of | 434 // Don't search on the prototype chain for special indices in case of |
432 // integer indexed exotic objects (see ES6 section 9.4.5). | 435 // integer indexed exotic objects (see ES6 section 9.4.5). |
433 if (map->IsJSTypedArrayMap() && name->IsString() && | 436 if (map->IsJSTypedArrayMap() && name->IsString() && |
(...skipping 22 matching lines...) Expand all Loading... |
456 // Store to property not found on the receiver or any prototype, we need | 459 // Store to property not found on the receiver or any prototype, we need |
457 // to transition to a new data property. | 460 // to transition to a new data property. |
458 // Implemented according to ES6 section 9.1.9 [[Set]] (P, V, Receiver) | 461 // Implemented according to ES6 section 9.1.9 [[Set]] (P, V, Receiver) |
459 if (access_mode == AccessMode::kStore) { | 462 if (access_mode == AccessMode::kStore) { |
460 return LookupTransition(receiver_map, name, holder, access_info); | 463 return LookupTransition(receiver_map, name, holder, access_info); |
461 } | 464 } |
462 // The property was not found, return undefined or throw depending | 465 // The property was not found, return undefined or throw depending |
463 // on the language mode of the load operation. | 466 // on the language mode of the load operation. |
464 // Implemented according to ES6 section 9.1.8 [[Get]] (P, Receiver) | 467 // Implemented according to ES6 section 9.1.8 [[Get]] (P, Receiver) |
465 *access_info = | 468 *access_info = |
466 PropertyAccessInfo::NotFound(MapList{receiver_map}, holder); | 469 PropertyAccessInfo::NotFound(MapHandles{receiver_map}, holder); |
467 return true; | 470 return true; |
468 } else { | 471 } else { |
469 return false; | 472 return false; |
470 } | 473 } |
471 } | 474 } |
472 Handle<JSObject> map_prototype(JSObject::cast(map->prototype()), isolate()); | 475 Handle<JSObject> map_prototype(JSObject::cast(map->prototype()), isolate()); |
473 if (map_prototype->map()->is_deprecated()) { | 476 if (map_prototype->map()->is_deprecated()) { |
474 // Try to migrate the prototype object so we don't embed the deprecated | 477 // Try to migrate the prototype object so we don't embed the deprecated |
475 // map into the optimized code. | 478 // map into the optimized code. |
476 JSObject::TryMigrateInstance(map_prototype); | 479 JSObject::TryMigrateInstance(map_prototype); |
477 } | 480 } |
478 map = handle(map_prototype->map(), isolate()); | 481 map = handle(map_prototype->map(), isolate()); |
479 holder = map_prototype; | 482 holder = map_prototype; |
480 } while (CanInlinePropertyAccess(map)); | 483 } while (CanInlinePropertyAccess(map)); |
481 return false; | 484 return false; |
482 } | 485 } |
483 | 486 |
484 bool AccessInfoFactory::ComputePropertyAccessInfos( | 487 bool AccessInfoFactory::ComputePropertyAccessInfos( |
485 MapHandleList const& maps, Handle<Name> name, AccessMode access_mode, | 488 MapHandles const& maps, Handle<Name> name, AccessMode access_mode, |
486 ZoneVector<PropertyAccessInfo>* access_infos) { | 489 ZoneVector<PropertyAccessInfo>* access_infos) { |
487 for (Handle<Map> map : maps) { | 490 for (Handle<Map> map : maps) { |
488 if (Map::TryUpdate(map).ToHandle(&map)) { | 491 if (Map::TryUpdate(map).ToHandle(&map)) { |
489 PropertyAccessInfo access_info; | 492 PropertyAccessInfo access_info; |
490 if (!ComputePropertyAccessInfo(map, name, access_mode, &access_info)) { | 493 if (!ComputePropertyAccessInfo(map, name, access_mode, &access_info)) { |
491 return false; | 494 return false; |
492 } | 495 } |
493 // Try to merge the {access_info} with an existing one. | 496 // Try to merge the {access_info} with an existing one. |
494 bool merged = false; | 497 bool merged = false; |
495 for (PropertyAccessInfo& other_info : *access_infos) { | 498 for (PropertyAccessInfo& other_info : *access_infos) { |
(...skipping 25 matching lines...) Expand all Loading... |
521 } | 524 } |
522 if (IsMoreGeneralElementsKindTransition(this_kind, that_kind)) { | 525 if (IsMoreGeneralElementsKindTransition(this_kind, that_kind)) { |
523 return Just(that_kind); | 526 return Just(that_kind); |
524 } | 527 } |
525 } | 528 } |
526 return Nothing<ElementsKind>(); | 529 return Nothing<ElementsKind>(); |
527 } | 530 } |
528 | 531 |
529 } // namespace | 532 } // namespace |
530 | 533 |
531 bool AccessInfoFactory::ConsolidateElementLoad(MapHandleList const& maps, | 534 bool AccessInfoFactory::ConsolidateElementLoad(MapHandles const& maps, |
532 ElementAccessInfo* access_info) { | 535 ElementAccessInfo* access_info) { |
533 if (maps.is_empty()) return false; | 536 if (maps.empty()) return false; |
534 InstanceType instance_type = maps.first()->instance_type(); | 537 InstanceType instance_type = maps.front()->instance_type(); |
535 ElementsKind elements_kind = maps.first()->elements_kind(); | 538 ElementsKind elements_kind = maps.front()->elements_kind(); |
536 MapList receiver_maps(maps.length()); | 539 for (Handle<Map> map : maps) { |
537 for (int i = 0; i < maps.length(); ++i) { | |
538 Handle<Map> map = maps[i]; | |
539 if (!CanInlineElementAccess(map) || map->instance_type() != instance_type) { | 540 if (!CanInlineElementAccess(map) || map->instance_type() != instance_type) { |
540 return false; | 541 return false; |
541 } | 542 } |
542 if (!GeneralizeElementsKind(elements_kind, map->elements_kind()) | 543 if (!GeneralizeElementsKind(elements_kind, map->elements_kind()) |
543 .To(&elements_kind)) { | 544 .To(&elements_kind)) { |
544 return false; | 545 return false; |
545 } | 546 } |
546 receiver_maps[i] = map; | |
547 } | 547 } |
548 *access_info = ElementAccessInfo(receiver_maps, elements_kind); | 548 *access_info = ElementAccessInfo(maps, elements_kind); |
549 return true; | 549 return true; |
550 } | 550 } |
551 | 551 |
552 bool AccessInfoFactory::LookupSpecialFieldAccessor( | 552 bool AccessInfoFactory::LookupSpecialFieldAccessor( |
553 Handle<Map> map, Handle<Name> name, PropertyAccessInfo* access_info) { | 553 Handle<Map> map, Handle<Name> name, PropertyAccessInfo* access_info) { |
554 // Check for special JSObject field accessors. | 554 // Check for special JSObject field accessors. |
555 int offset; | 555 int offset; |
556 if (Accessors::IsJSObjectFieldAccessor(map, name, &offset)) { | 556 if (Accessors::IsJSObjectFieldAccessor(map, name, &offset)) { |
557 FieldIndex field_index = FieldIndex::ForInObjectOffset(offset); | 557 FieldIndex field_index = FieldIndex::ForInObjectOffset(offset); |
558 Type* field_type = Type::NonInternal(); | 558 Type* field_type = Type::NonInternal(); |
(...skipping 15 matching lines...) Expand all Loading... |
574 field_type = type_cache_.kFixedDoubleArrayLengthType; | 574 field_type = type_cache_.kFixedDoubleArrayLengthType; |
575 field_representation = MachineRepresentation::kTaggedSigned; | 575 field_representation = MachineRepresentation::kTaggedSigned; |
576 } else if (IsFastElementsKind(map->elements_kind())) { | 576 } else if (IsFastElementsKind(map->elements_kind())) { |
577 field_type = type_cache_.kFixedArrayLengthType; | 577 field_type = type_cache_.kFixedArrayLengthType; |
578 field_representation = MachineRepresentation::kTaggedSigned; | 578 field_representation = MachineRepresentation::kTaggedSigned; |
579 } else { | 579 } else { |
580 field_type = type_cache_.kJSArrayLengthType; | 580 field_type = type_cache_.kJSArrayLengthType; |
581 } | 581 } |
582 } | 582 } |
583 // Special fields are always mutable. | 583 // Special fields are always mutable. |
584 *access_info = PropertyAccessInfo::DataField( | 584 *access_info = |
585 kMutable, MapList{map}, field_index, field_representation, field_type); | 585 PropertyAccessInfo::DataField(kMutable, MapHandles{map}, field_index, |
| 586 field_representation, field_type); |
586 return true; | 587 return true; |
587 } | 588 } |
588 return false; | 589 return false; |
589 } | 590 } |
590 | 591 |
591 | 592 |
592 bool AccessInfoFactory::LookupTransition(Handle<Map> map, Handle<Name> name, | 593 bool AccessInfoFactory::LookupTransition(Handle<Map> map, Handle<Name> name, |
593 MaybeHandle<JSObject> holder, | 594 MaybeHandle<JSObject> holder, |
594 PropertyAccessInfo* access_info) { | 595 PropertyAccessInfo* access_info) { |
595 // Check if the {map} has a data transition with the given {name}. | 596 // Check if the {map} has a data transition with the given {name}. |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
633 dependencies()->AssumeFieldOwner(field_owner_map); | 634 dependencies()->AssumeFieldOwner(field_owner_map); |
634 | 635 |
635 // Remember the field map, and try to infer a useful type. | 636 // Remember the field map, and try to infer a useful type. |
636 field_type = Type::For(descriptors_field_type->AsClass()); | 637 field_type = Type::For(descriptors_field_type->AsClass()); |
637 field_map = descriptors_field_type->AsClass(); | 638 field_map = descriptors_field_type->AsClass(); |
638 } | 639 } |
639 } | 640 } |
640 dependencies()->AssumeMapNotDeprecated(transition_map); | 641 dependencies()->AssumeMapNotDeprecated(transition_map); |
641 // Transitioning stores are never stores to constant fields. | 642 // Transitioning stores are never stores to constant fields. |
642 *access_info = PropertyAccessInfo::DataField( | 643 *access_info = PropertyAccessInfo::DataField( |
643 kMutable, MapList{map}, field_index, field_representation, field_type, | 644 kMutable, MapHandles{map}, field_index, field_representation, |
644 field_map, holder, transition_map); | 645 field_type, field_map, holder, transition_map); |
645 return true; | 646 return true; |
646 } | 647 } |
647 return false; | 648 return false; |
648 } | 649 } |
649 | 650 |
650 | 651 |
651 Factory* AccessInfoFactory::factory() const { return isolate()->factory(); } | 652 Factory* AccessInfoFactory::factory() const { return isolate()->factory(); } |
652 | 653 |
653 } // namespace compiler | 654 } // namespace compiler |
654 } // namespace internal | 655 } // namespace internal |
655 } // namespace v8 | 656 } // namespace v8 |
OLD | NEW |