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

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

Issue 2198473002: [turbofan] Add support for accessor inlining. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@TurboFan_CheckMaps
Patch Set: Fixes Created 4 years, 4 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/code-generator.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/field-index-inl.h" 10 #include "src/field-index-inl.h"
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
68 // static 68 // static
69 PropertyAccessInfo PropertyAccessInfo::NotFound(MapList const& receiver_maps, 69 PropertyAccessInfo PropertyAccessInfo::NotFound(MapList 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 MapList const& receiver_maps, Handle<Object> constant,
77 MaybeHandle<JSObject> holder) { 77 MaybeHandle<JSObject> holder) {
78 return PropertyAccessInfo(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 MapList const& receiver_maps, FieldIndex field_index, Type* field_type, 83 MapList const& receiver_maps, FieldIndex field_index, Type* field_type,
84 MaybeHandle<JSObject> holder, MaybeHandle<Map> transition_map) { 84 MaybeHandle<JSObject> holder, MaybeHandle<Map> transition_map) {
85 return PropertyAccessInfo(holder, transition_map, field_index, field_type, 85 return PropertyAccessInfo(holder, transition_map, field_index, field_type,
86 receiver_maps); 86 receiver_maps);
87 } 87 }
88 88
89 // static
90 PropertyAccessInfo PropertyAccessInfo::AccessorConstant(
91 MapList const& receiver_maps, Handle<Object> constant,
92 MaybeHandle<JSObject> holder) {
93 return PropertyAccessInfo(kAccessorConstant, holder, constant, receiver_maps);
94 }
95
89 PropertyAccessInfo::PropertyAccessInfo() 96 PropertyAccessInfo::PropertyAccessInfo()
90 : kind_(kInvalid), field_type_(Type::Any()) {} 97 : kind_(kInvalid), field_type_(Type::Any()) {}
91 98
92 PropertyAccessInfo::PropertyAccessInfo(MaybeHandle<JSObject> holder, 99 PropertyAccessInfo::PropertyAccessInfo(MaybeHandle<JSObject> holder,
93 MapList const& receiver_maps) 100 MapList const& receiver_maps)
94 : kind_(kNotFound), 101 : kind_(kNotFound),
95 receiver_maps_(receiver_maps), 102 receiver_maps_(receiver_maps),
96 holder_(holder), 103 holder_(holder),
97 field_type_(Type::Any()) {} 104 field_type_(Type::Any()) {}
98 105
99 PropertyAccessInfo::PropertyAccessInfo(MaybeHandle<JSObject> holder, 106 PropertyAccessInfo::PropertyAccessInfo(Kind kind, MaybeHandle<JSObject> holder,
100 Handle<Object> constant, 107 Handle<Object> constant,
101 MapList const& receiver_maps) 108 MapList const& receiver_maps)
102 : kind_(kDataConstant), 109 : kind_(kind),
103 receiver_maps_(receiver_maps), 110 receiver_maps_(receiver_maps),
104 constant_(constant), 111 constant_(constant),
105 holder_(holder), 112 holder_(holder),
106 field_type_(Type::Any()) {} 113 field_type_(Type::Any()) {}
107 114
108 PropertyAccessInfo::PropertyAccessInfo(MaybeHandle<JSObject> holder, 115 PropertyAccessInfo::PropertyAccessInfo(MaybeHandle<JSObject> holder,
109 MaybeHandle<Map> transition_map, 116 MaybeHandle<Map> transition_map,
110 FieldIndex field_index, Type* field_type, 117 FieldIndex field_index, Type* field_type,
111 MapList const& receiver_maps) 118 MapList const& receiver_maps)
112 : kind_(kDataField), 119 : kind_(kDataField),
(...skipping 21 matching lines...) Expand all
134 this->field_type_->Is(that->field_type_) && 141 this->field_type_->Is(that->field_type_) &&
135 that->field_type_->Is(this->field_type_)) { 142 that->field_type_->Is(this->field_type_)) {
136 this->receiver_maps_.insert(this->receiver_maps_.end(), 143 this->receiver_maps_.insert(this->receiver_maps_.end(),
137 that->receiver_maps_.begin(), 144 that->receiver_maps_.begin(),
138 that->receiver_maps_.end()); 145 that->receiver_maps_.end());
139 return true; 146 return true;
140 } 147 }
141 return false; 148 return false;
142 } 149 }
143 150
144 case kDataConstant: { 151 case kDataConstant:
152 case kAccessorConstant: {
145 // Check if we actually access the same constant. 153 // Check if we actually access the same constant.
146 if (this->constant_.address() == that->constant_.address()) { 154 if (this->constant_.address() == that->constant_.address()) {
147 this->receiver_maps_.insert(this->receiver_maps_.end(), 155 this->receiver_maps_.insert(this->receiver_maps_.end(),
148 that->receiver_maps_.begin(), 156 that->receiver_maps_.begin(),
149 that->receiver_maps_.end()); 157 that->receiver_maps_.end());
150 return true; 158 return true;
151 } 159 }
152 return false; 160 return false;
153 } 161 }
154 } 162 }
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
281 return false; 289 return false;
282 } 290 }
283 // Check for store to data property on a prototype. 291 // Check for store to data property on a prototype.
284 if (details.kind() == kData && !holder.is_null()) { 292 if (details.kind() == kData && !holder.is_null()) {
285 // Store to property not found on the receiver but on a prototype, we 293 // Store to property not found on the receiver but on a prototype, we
286 // need to transition to a new data property. 294 // need to transition to a new data property.
287 // Implemented according to ES6 section 9.1.9 [[Set]] (P, V, Receiver) 295 // Implemented according to ES6 section 9.1.9 [[Set]] (P, V, Receiver)
288 return LookupTransition(receiver_map, name, holder, access_info); 296 return LookupTransition(receiver_map, name, holder, access_info);
289 } 297 }
290 } 298 }
291 if (details.type() == DATA_CONSTANT) { 299 switch (details.type()) {
292 *access_info = PropertyAccessInfo::DataConstant( 300 case DATA_CONSTANT: {
293 MapList{receiver_map}, 301 *access_info = PropertyAccessInfo::DataConstant(
294 handle(descriptors->GetValue(number), isolate()), holder); 302 MapList{receiver_map},
295 return true; 303 handle(descriptors->GetValue(number), isolate()), holder);
296 } else if (details.type() == DATA) { 304 return true;
297 int index = descriptors->GetFieldIndex(number); 305 }
298 Representation field_representation = details.representation(); 306 case DATA: {
299 FieldIndex field_index = FieldIndex::ForPropertyIndex( 307 int index = descriptors->GetFieldIndex(number);
300 *map, index, field_representation.IsDouble()); 308 Representation field_representation = details.representation();
301 Type* field_type = Type::Tagged(); 309 FieldIndex field_index = FieldIndex::ForPropertyIndex(
302 if (field_representation.IsSmi()) { 310 *map, index, field_representation.IsDouble());
303 field_type = type_cache_.kSmi; 311 Type* field_type = Type::Tagged();
304 } else if (field_representation.IsDouble()) { 312 if (field_representation.IsSmi()) {
305 field_type = type_cache_.kFloat64; 313 field_type = type_cache_.kSmi;
306 } else if (field_representation.IsHeapObject()) { 314 } else if (field_representation.IsDouble()) {
307 // Extract the field type from the property details (make sure its 315 field_type = type_cache_.kFloat64;
308 // representation is TaggedPointer to reflect the heap object case). 316 } else if (field_representation.IsHeapObject()) {
309 field_type = Type::Intersect( 317 // Extract the field type from the property details (make sure its
310 descriptors->GetFieldType(number)->Convert(zone()), 318 // representation is TaggedPointer to reflect the heap object case).
311 Type::TaggedPointer(), zone()); 319 field_type = Type::Intersect(
312 if (field_type->Is(Type::None())) { 320 descriptors->GetFieldType(number)->Convert(zone()),
313 // Store is not safe if the field type was cleared. 321 Type::TaggedPointer(), zone());
314 if (access_mode == AccessMode::kStore) return false; 322 if (field_type->Is(Type::None())) {
323 // Store is not safe if the field type was cleared.
324 if (access_mode == AccessMode::kStore) return false;
315 325
316 // The field type was cleared by the GC, so we don't know anything 326 // The field type was cleared by the GC, so we don't know anything
317 // about the contents now. 327 // about the contents now.
318 // TODO(bmeurer): It would be awesome to make this saner in the 328 // TODO(bmeurer): It would be awesome to make this saner in the
319 // runtime/GC interaction. 329 // runtime/GC interaction.
320 field_type = Type::TaggedPointer(); 330 field_type = Type::TaggedPointer();
321 } else if (!Type::Any()->Is(field_type)) { 331 } else if (!Type::Any()->Is(field_type)) {
322 // Add proper code dependencies in case of stable field map(s). 332 // Add proper code dependencies in case of stable field map(s).
323 Handle<Map> field_owner_map(map->FindFieldOwner(number), isolate()); 333 Handle<Map> field_owner_map(map->FindFieldOwner(number),
324 dependencies()->AssumeFieldType(field_owner_map); 334 isolate());
335 dependencies()->AssumeFieldType(field_owner_map);
336 }
337 DCHECK(field_type->Is(Type::TaggedPointer()));
325 } 338 }
326 DCHECK(field_type->Is(Type::TaggedPointer())); 339 *access_info = PropertyAccessInfo::DataField(
340 MapList{receiver_map}, field_index, field_type, holder);
341 return true;
327 } 342 }
328 *access_info = PropertyAccessInfo::DataField( 343 case ACCESSOR_CONSTANT: {
329 MapList{receiver_map}, field_index, field_type, holder); 344 Handle<Object> accessors(descriptors->GetValue(number), isolate());
330 return true; 345 if (!accessors->IsAccessorPair()) return false;
331 } else { 346 Handle<Object> accessor(
332 // TODO(bmeurer): Add support for accessors. 347 access_mode == AccessMode::kLoad
333 return false; 348 ? Handle<AccessorPair>::cast(accessors)->getter()
349 : Handle<AccessorPair>::cast(accessors)->setter(),
350 isolate());
351 if (!accessor->IsJSFunction()) {
352 // TODO(turbofan): Add support for API accessors.
353 return false;
354 }
355 *access_info = PropertyAccessInfo::AccessorConstant(
356 MapList{receiver_map}, accessor, holder);
357 return true;
358 }
359 case ACCESSOR: {
360 // TODO(turbofan): Add support for general accessors?
361 return false;
362 }
334 } 363 }
364 UNREACHABLE();
365 return false;
335 } 366 }
336 367
337 // Don't search on the prototype chain for special indices in case of 368 // Don't search on the prototype chain for special indices in case of
338 // integer indexed exotic objects (see ES6 section 9.4.5). 369 // integer indexed exotic objects (see ES6 section 9.4.5).
339 if (map->IsJSTypedArrayMap() && name->IsString() && 370 if (map->IsJSTypedArrayMap() && name->IsString() &&
340 IsSpecialIndex(isolate()->unicode_cache(), String::cast(*name))) { 371 IsSpecialIndex(isolate()->unicode_cache(), String::cast(*name))) {
341 return false; 372 return false;
342 } 373 }
343 374
344 // Don't lookup private symbols on the prototype chain. 375 // Don't lookup private symbols on the prototype chain.
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
490 } 521 }
491 return false; 522 return false;
492 } 523 }
493 524
494 525
495 Factory* AccessInfoFactory::factory() const { return isolate()->factory(); } 526 Factory* AccessInfoFactory::factory() const { return isolate()->factory(); }
496 527
497 } // namespace compiler 528 } // namespace compiler
498 } // namespace internal 529 } // namespace internal
499 } // namespace v8 530 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/access-info.h ('k') | src/compiler/code-generator.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698