Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(69)

Side by Side Diff: src/compiler/access-info.cc

Issue 2290233002: [turbofan] Introduce MachineRepresentation to PropertyAccessInfo. (Closed)
Patch Set: REBASE and comments. Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/compiler/access-info.h ('k') | src/compiler/js-native-context-specialization.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
72 72
73 // static 73 // static
74 PropertyAccessInfo PropertyAccessInfo::DataConstant( 74 PropertyAccessInfo PropertyAccessInfo::DataConstant(
75 MapList const& receiver_maps, Handle<Object> constant, 75 MapList const& receiver_maps, Handle<Object> constant,
76 MaybeHandle<JSObject> holder) { 76 MaybeHandle<JSObject> holder) {
77 return PropertyAccessInfo(kDataConstant, holder, constant, receiver_maps); 77 return PropertyAccessInfo(kDataConstant, holder, constant, receiver_maps);
78 } 78 }
79 79
80 // static 80 // static
81 PropertyAccessInfo PropertyAccessInfo::DataField( 81 PropertyAccessInfo PropertyAccessInfo::DataField(
82 MapList const& receiver_maps, FieldIndex field_index, Type* field_type, 82 MapList const& receiver_maps, FieldIndex field_index,
83 MachineRepresentation field_representation, Type* field_type,
83 MaybeHandle<JSObject> holder, MaybeHandle<Map> transition_map) { 84 MaybeHandle<JSObject> holder, MaybeHandle<Map> transition_map) {
84 return PropertyAccessInfo(holder, transition_map, field_index, field_type, 85 return PropertyAccessInfo(holder, transition_map, field_index,
85 receiver_maps); 86 field_representation, field_type, receiver_maps);
86 } 87 }
87 88
88 // static 89 // static
89 PropertyAccessInfo PropertyAccessInfo::AccessorConstant( 90 PropertyAccessInfo PropertyAccessInfo::AccessorConstant(
90 MapList const& receiver_maps, Handle<Object> constant, 91 MapList const& receiver_maps, Handle<Object> constant,
91 MaybeHandle<JSObject> holder) { 92 MaybeHandle<JSObject> holder) {
92 return PropertyAccessInfo(kAccessorConstant, holder, constant, receiver_maps); 93 return PropertyAccessInfo(kAccessorConstant, holder, constant, receiver_maps);
93 } 94 }
94 95
95 PropertyAccessInfo::PropertyAccessInfo() 96 PropertyAccessInfo::PropertyAccessInfo()
96 : kind_(kInvalid), field_type_(Type::None()) {} 97 : kind_(kInvalid),
98 field_representation_(MachineRepresentation::kNone),
99 field_type_(Type::None()) {}
97 100
98 PropertyAccessInfo::PropertyAccessInfo(MaybeHandle<JSObject> holder, 101 PropertyAccessInfo::PropertyAccessInfo(MaybeHandle<JSObject> holder,
99 MapList const& receiver_maps) 102 MapList const& receiver_maps)
100 : kind_(kNotFound), 103 : kind_(kNotFound),
101 receiver_maps_(receiver_maps), 104 receiver_maps_(receiver_maps),
102 holder_(holder), 105 holder_(holder),
106 field_representation_(MachineRepresentation::kNone),
103 field_type_(Type::None()) {} 107 field_type_(Type::None()) {}
104 108
105 PropertyAccessInfo::PropertyAccessInfo(Kind kind, MaybeHandle<JSObject> holder, 109 PropertyAccessInfo::PropertyAccessInfo(Kind kind, MaybeHandle<JSObject> holder,
106 Handle<Object> constant, 110 Handle<Object> constant,
107 MapList const& receiver_maps) 111 MapList const& receiver_maps)
108 : kind_(kind), 112 : kind_(kind),
109 receiver_maps_(receiver_maps), 113 receiver_maps_(receiver_maps),
110 constant_(constant), 114 constant_(constant),
111 holder_(holder), 115 holder_(holder),
116 field_representation_(MachineRepresentation::kNone),
112 field_type_(Type::Any()) {} 117 field_type_(Type::Any()) {}
113 118
114 PropertyAccessInfo::PropertyAccessInfo(MaybeHandle<JSObject> holder, 119 PropertyAccessInfo::PropertyAccessInfo(
115 MaybeHandle<Map> transition_map, 120 MaybeHandle<JSObject> holder, MaybeHandle<Map> transition_map,
116 FieldIndex field_index, Type* field_type, 121 FieldIndex field_index, MachineRepresentation field_representation,
117 MapList const& receiver_maps) 122 Type* field_type, MapList const& receiver_maps)
118 : kind_(kDataField), 123 : kind_(kDataField),
119 receiver_maps_(receiver_maps), 124 receiver_maps_(receiver_maps),
120 transition_map_(transition_map), 125 transition_map_(transition_map),
121 holder_(holder), 126 holder_(holder),
122 field_index_(field_index), 127 field_index_(field_index),
128 field_representation_(field_representation),
123 field_type_(field_type) {} 129 field_type_(field_type) {}
124 130
125 bool PropertyAccessInfo::Merge(PropertyAccessInfo const* that) { 131 bool PropertyAccessInfo::Merge(PropertyAccessInfo const* that) {
126 if (this->kind_ != that->kind_) return false; 132 if (this->kind_ != that->kind_) return false;
127 if (this->holder_.address() != that->holder_.address()) return false; 133 if (this->holder_.address() != that->holder_.address()) return false;
128 134
129 switch (this->kind_) { 135 switch (this->kind_) {
130 case kInvalid: 136 case kInvalid:
131 break; 137 break;
132 138
133 case kNotFound: 139 case kNotFound:
134 return true; 140 return true;
135 141
136 case kDataField: { 142 case kDataField: {
137 // Check if we actually access the same field. 143 // Check if we actually access the same field.
138 if (this->transition_map_.address() == that->transition_map_.address() && 144 if (this->transition_map_.address() == that->transition_map_.address() &&
139 this->field_index_ == that->field_index_ && 145 this->field_index_ == that->field_index_ &&
140 this->field_type_->Is(that->field_type_) && 146 this->field_type_->Is(that->field_type_) &&
141 that->field_type_->Is(this->field_type_)) { 147 that->field_type_->Is(this->field_type_) &&
148 this->field_representation_ == that->field_representation_) {
142 this->receiver_maps_.insert(this->receiver_maps_.end(), 149 this->receiver_maps_.insert(this->receiver_maps_.end(),
143 that->receiver_maps_.begin(), 150 that->receiver_maps_.begin(),
144 that->receiver_maps_.end()); 151 that->receiver_maps_.end());
145 return true; 152 return true;
146 } 153 }
147 return false; 154 return false;
148 } 155 }
149 156
150 case kDataConstant: 157 case kDataConstant:
151 case kAccessorConstant: { 158 case kAccessorConstant: {
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
276 } 283 }
277 switch (details.type()) { 284 switch (details.type()) {
278 case DATA_CONSTANT: { 285 case DATA_CONSTANT: {
279 *access_info = PropertyAccessInfo::DataConstant( 286 *access_info = PropertyAccessInfo::DataConstant(
280 MapList{receiver_map}, 287 MapList{receiver_map},
281 handle(descriptors->GetValue(number), isolate()), holder); 288 handle(descriptors->GetValue(number), isolate()), holder);
282 return true; 289 return true;
283 } 290 }
284 case DATA: { 291 case DATA: {
285 int index = descriptors->GetFieldIndex(number); 292 int index = descriptors->GetFieldIndex(number);
286 Representation field_representation = details.representation(); 293 Representation details_representation = details.representation();
287 FieldIndex field_index = FieldIndex::ForPropertyIndex( 294 FieldIndex field_index = FieldIndex::ForPropertyIndex(
288 *map, index, field_representation.IsDouble()); 295 *map, index, details_representation.IsDouble());
289 Type* field_type = Type::Tagged(); 296 Type* field_type = Type::Tagged();
290 if (field_representation.IsSmi()) { 297 MachineRepresentation field_representation =
298 MachineRepresentation::kTagged;
299 if (details_representation.IsSmi()) {
291 field_type = type_cache_.kSmi; 300 field_type = type_cache_.kSmi;
292 } else if (field_representation.IsDouble()) { 301 field_representation = MachineRepresentation::kTaggedSigned;
302 } else if (details_representation.IsDouble()) {
293 field_type = type_cache_.kFloat64; 303 field_type = type_cache_.kFloat64;
294 } else if (field_representation.IsHeapObject()) { 304 field_representation = MachineRepresentation::kFloat64;
305 } else if (details_representation.IsHeapObject()) {
295 // Extract the field type from the property details (make sure its 306 // Extract the field type from the property details (make sure its
296 // representation is TaggedPointer to reflect the heap object case). 307 // representation is TaggedPointer to reflect the heap object case).
297 field_type = Type::Intersect( 308 field_representation = MachineRepresentation::kTaggedPointer;
298 descriptors->GetFieldType(number)->Convert(zone()), 309 field_type = descriptors->GetFieldType(number)->Convert(zone());
299 Type::TaggedPointer(), zone());
300 if (field_type->Is(Type::None())) { 310 if (field_type->Is(Type::None())) {
301 // Store is not safe if the field type was cleared. 311 // Store is not safe if the field type was cleared.
302 if (access_mode == AccessMode::kStore) return false; 312 if (access_mode == AccessMode::kStore) return false;
303 313
304 // The field type was cleared by the GC, so we don't know anything 314 // The field type was cleared by the GC, so we don't know anything
305 // about the contents now. 315 // about the contents now.
306 // TODO(bmeurer): It would be awesome to make this saner in the 316 // TODO(bmeurer): It would be awesome to make this saner in the
307 // runtime/GC interaction. 317 // runtime/GC interaction.
308 field_type = Type::TaggedPointer(); 318 field_type = Type::Any();
309 } else if (!Type::Any()->Is(field_type)) { 319 } else if (!Type::Any()->Is(field_type)) {
310 // Add proper code dependencies in case of stable field map(s). 320 // Add proper code dependencies in case of stable field map(s).
321 field_representation = MachineRepresentation::kTaggedPointer;
311 Handle<Map> field_owner_map(map->FindFieldOwner(number), 322 Handle<Map> field_owner_map(map->FindFieldOwner(number),
312 isolate()); 323 isolate());
313 dependencies()->AssumeFieldType(field_owner_map); 324 dependencies()->AssumeFieldType(field_owner_map);
314 } 325 }
315 DCHECK(field_type->Is(Type::TaggedPointer()));
316 } 326 }
317 *access_info = PropertyAccessInfo::DataField( 327 *access_info = PropertyAccessInfo::DataField(
318 MapList{receiver_map}, field_index, field_type, holder); 328 MapList{receiver_map}, field_index, field_representation,
329 field_type, holder);
319 return true; 330 return true;
320 } 331 }
321 case ACCESSOR_CONSTANT: { 332 case ACCESSOR_CONSTANT: {
322 Handle<Object> accessors(descriptors->GetValue(number), isolate()); 333 Handle<Object> accessors(descriptors->GetValue(number), isolate());
323 if (!accessors->IsAccessorPair()) return false; 334 if (!accessors->IsAccessorPair()) return false;
324 Handle<Object> accessor( 335 Handle<Object> accessor(
325 access_mode == AccessMode::kLoad 336 access_mode == AccessMode::kLoad
326 ? Handle<AccessorPair>::cast(accessors)->getter() 337 ? Handle<AccessorPair>::cast(accessors)->getter()
327 : Handle<AccessorPair>::cast(accessors)->setter(), 338 : Handle<AccessorPair>::cast(accessors)->setter(),
328 isolate()); 339 isolate());
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
415 } 426 }
416 427
417 428
418 bool AccessInfoFactory::LookupSpecialFieldAccessor( 429 bool AccessInfoFactory::LookupSpecialFieldAccessor(
419 Handle<Map> map, Handle<Name> name, PropertyAccessInfo* access_info) { 430 Handle<Map> map, Handle<Name> name, PropertyAccessInfo* access_info) {
420 // Check for special JSObject field accessors. 431 // Check for special JSObject field accessors.
421 int offset; 432 int offset;
422 if (Accessors::IsJSObjectFieldAccessor(map, name, &offset)) { 433 if (Accessors::IsJSObjectFieldAccessor(map, name, &offset)) {
423 FieldIndex field_index = FieldIndex::ForInObjectOffset(offset); 434 FieldIndex field_index = FieldIndex::ForInObjectOffset(offset);
424 Type* field_type = Type::Tagged(); 435 Type* field_type = Type::Tagged();
436 MachineRepresentation field_representation = MachineRepresentation::kTagged;
425 if (map->IsStringMap()) { 437 if (map->IsStringMap()) {
426 DCHECK(Name::Equals(factory()->length_string(), name)); 438 DCHECK(Name::Equals(factory()->length_string(), name));
427 // The String::length property is always a smi in the range 439 // The String::length property is always a smi in the range
428 // [0, String::kMaxLength]. 440 // [0, String::kMaxLength].
429 field_type = type_cache_.kStringLengthType; 441 field_type = type_cache_.kStringLengthType;
442 field_representation = MachineRepresentation::kTaggedSigned;
430 } else if (map->IsJSArrayMap()) { 443 } else if (map->IsJSArrayMap()) {
431 DCHECK(Name::Equals(factory()->length_string(), name)); 444 DCHECK(Name::Equals(factory()->length_string(), name));
432 // The JSArray::length property is a smi in the range 445 // The JSArray::length property is a smi in the range
433 // [0, FixedDoubleArray::kMaxLength] in case of fast double 446 // [0, FixedDoubleArray::kMaxLength] in case of fast double
434 // elements, a smi in the range [0, FixedArray::kMaxLength] 447 // elements, a smi in the range [0, FixedArray::kMaxLength]
435 // in case of other fast elements, and [0, kMaxUInt32] in 448 // in case of other fast elements, and [0, kMaxUInt32] in
436 // case of other arrays. 449 // case of other arrays.
437 if (IsFastDoubleElementsKind(map->elements_kind())) { 450 if (IsFastDoubleElementsKind(map->elements_kind())) {
438 field_type = type_cache_.kFixedDoubleArrayLengthType; 451 field_type = type_cache_.kFixedDoubleArrayLengthType;
452 field_representation = MachineRepresentation::kTaggedSigned;
439 } else if (IsFastElementsKind(map->elements_kind())) { 453 } else if (IsFastElementsKind(map->elements_kind())) {
440 field_type = type_cache_.kFixedArrayLengthType; 454 field_type = type_cache_.kFixedArrayLengthType;
455 field_representation = MachineRepresentation::kTaggedSigned;
441 } else { 456 } else {
442 field_type = type_cache_.kJSArrayLengthType; 457 field_type = type_cache_.kJSArrayLengthType;
443 } 458 }
444 } 459 }
445 *access_info = 460 *access_info = PropertyAccessInfo::DataField(
446 PropertyAccessInfo::DataField(MapList{map}, field_index, field_type); 461 MapList{map}, field_index, field_representation, field_type);
447 return true; 462 return true;
448 } 463 }
449 return false; 464 return false;
450 } 465 }
451 466
452 467
453 bool AccessInfoFactory::LookupTransition(Handle<Map> map, Handle<Name> name, 468 bool AccessInfoFactory::LookupTransition(Handle<Map> map, Handle<Name> name,
454 MaybeHandle<JSObject> holder, 469 MaybeHandle<JSObject> holder,
455 PropertyAccessInfo* access_info) { 470 PropertyAccessInfo* access_info) {
456 // Check if the {map} has a data transition with the given {name}. 471 // Check if the {map} has a data transition with the given {name}.
457 if (map->unused_property_fields() == 0) return false; 472 if (map->unused_property_fields() == 0) return false;
458 Handle<Map> transition_map; 473 Handle<Map> transition_map;
459 if (TransitionArray::SearchTransition(map, kData, name, NONE) 474 if (TransitionArray::SearchTransition(map, kData, name, NONE)
460 .ToHandle(&transition_map)) { 475 .ToHandle(&transition_map)) {
461 int const number = transition_map->LastAdded(); 476 int const number = transition_map->LastAdded();
462 PropertyDetails const details = 477 PropertyDetails const details =
463 transition_map->instance_descriptors()->GetDetails(number); 478 transition_map->instance_descriptors()->GetDetails(number);
464 // Don't bother optimizing stores to read-only properties. 479 // Don't bother optimizing stores to read-only properties.
465 if (details.IsReadOnly()) return false; 480 if (details.IsReadOnly()) return false;
466 // TODO(bmeurer): Handle transition to data constant? 481 // TODO(bmeurer): Handle transition to data constant?
467 if (details.type() != DATA) return false; 482 if (details.type() != DATA) return false;
468 int const index = details.field_index(); 483 int const index = details.field_index();
469 Representation field_representation = details.representation(); 484 Representation details_representation = details.representation();
470 FieldIndex field_index = FieldIndex::ForPropertyIndex( 485 FieldIndex field_index = FieldIndex::ForPropertyIndex(
471 *transition_map, index, field_representation.IsDouble()); 486 *transition_map, index, details_representation.IsDouble());
472 Type* field_type = Type::Tagged(); 487 Type* field_type = Type::Tagged();
473 if (field_representation.IsSmi()) { 488 MachineRepresentation field_representation = MachineRepresentation::kTagged;
489 if (details_representation.IsSmi()) {
474 field_type = type_cache_.kSmi; 490 field_type = type_cache_.kSmi;
475 } else if (field_representation.IsDouble()) { 491 field_representation = MachineRepresentation::kTaggedSigned;
492 } else if (details_representation.IsDouble()) {
476 field_type = type_cache_.kFloat64; 493 field_type = type_cache_.kFloat64;
477 } else if (field_representation.IsHeapObject()) { 494 field_representation = MachineRepresentation::kFloat64;
495 } else if (details_representation.IsHeapObject()) {
478 // Extract the field type from the property details (make sure its 496 // Extract the field type from the property details (make sure its
479 // representation is TaggedPointer to reflect the heap object case). 497 // representation is TaggedPointer to reflect the heap object case).
480 field_type = Type::Intersect( 498 field_representation = MachineRepresentation::kTaggedPointer;
499 field_type =
481 transition_map->instance_descriptors()->GetFieldType(number)->Convert( 500 transition_map->instance_descriptors()->GetFieldType(number)->Convert(
482 zone()), 501 zone());
483 Type::TaggedPointer(), zone());
484 if (field_type->Is(Type::None())) { 502 if (field_type->Is(Type::None())) {
485 // Store is not safe if the field type was cleared. 503 // Store is not safe if the field type was cleared.
486 return false; 504 return false;
487 } else if (!Type::Any()->Is(field_type)) { 505 } else if (!Type::Any()->Is(field_type)) {
488 // Add proper code dependencies in case of stable field map(s). 506 // Add proper code dependencies in case of stable field map(s).
489 Handle<Map> field_owner_map(transition_map->FindFieldOwner(number), 507 Handle<Map> field_owner_map(transition_map->FindFieldOwner(number),
490 isolate()); 508 isolate());
491 dependencies()->AssumeFieldType(field_owner_map); 509 dependencies()->AssumeFieldType(field_owner_map);
492 } 510 }
493 DCHECK(field_type->Is(Type::TaggedPointer()));
494 } 511 }
495 dependencies()->AssumeMapNotDeprecated(transition_map); 512 dependencies()->AssumeMapNotDeprecated(transition_map);
496 *access_info = PropertyAccessInfo::DataField( 513 *access_info = PropertyAccessInfo::DataField(
497 MapList{map}, field_index, field_type, holder, transition_map); 514 MapList{map}, field_index, field_representation, field_type, holder,
515 transition_map);
498 return true; 516 return true;
499 } 517 }
500 return false; 518 return false;
501 } 519 }
502 520
503 521
504 Factory* AccessInfoFactory::factory() const { return isolate()->factory(); } 522 Factory* AccessInfoFactory::factory() const { return isolate()->factory(); }
505 523
506 } // namespace compiler 524 } // namespace compiler
507 } // namespace internal 525 } // namespace internal
508 } // namespace v8 526 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/access-info.h ('k') | src/compiler/js-native-context-specialization.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698