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

Side by Side Diff: src/map-updater.cc

Issue 2598543003: [runtime][ic] Constant field tracking support. (Closed)
Patch Set: Addressing comments Created 3 years, 10 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/map-updater.h ('k') | src/objects.h » ('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 2017 the V8 project authors. All rights reserved. 1 // Copyright 2017 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/map-updater.h" 5 #include "src/map-updater.h"
6 6
7 #include "src/field-type.h" 7 #include "src/field-type.h"
8 #include "src/handles.h" 8 #include "src/handles.h"
9 #include "src/isolate.h" 9 #include "src/isolate.h"
10 #include "src/objects-inl.h" 10 #include "src/objects-inl.h"
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
78 if (location == kField) { 78 if (location == kField) {
79 return handle(descriptors->GetFieldType(descriptor), isolate_); 79 return handle(descriptors->GetFieldType(descriptor), isolate_);
80 } else { 80 } else {
81 return descriptors->GetValue(descriptor) 81 return descriptors->GetValue(descriptor)
82 ->OptimalType(isolate_, representation); 82 ->OptimalType(isolate_, representation);
83 } 83 }
84 } 84 }
85 85
86 Handle<Map> MapUpdater::ReconfigureToDataField(int descriptor, 86 Handle<Map> MapUpdater::ReconfigureToDataField(int descriptor,
87 PropertyAttributes attributes, 87 PropertyAttributes attributes,
88 PropertyConstness constness,
88 Representation representation, 89 Representation representation,
89 Handle<FieldType> field_type) { 90 Handle<FieldType> field_type) {
90 DCHECK_EQ(kInitialized, state_); 91 DCHECK_EQ(kInitialized, state_);
91 DCHECK_LE(0, descriptor); 92 DCHECK_LE(0, descriptor);
92 DCHECK(!old_map_->is_dictionary_map()); 93 DCHECK(!old_map_->is_dictionary_map());
93 modified_descriptor_ = descriptor; 94 modified_descriptor_ = descriptor;
94 new_kind_ = kData; 95 new_kind_ = kData;
95 new_attributes_ = attributes; 96 new_attributes_ = attributes;
96 new_location_ = kField; 97 new_location_ = kField;
97 98
98 PropertyDetails old_details = 99 PropertyDetails old_details =
99 old_descriptors_->GetDetails(modified_descriptor_); 100 old_descriptors_->GetDetails(modified_descriptor_);
100 101
101 // If property kind is not reconfigured merge the result with 102 // If property kind is not reconfigured merge the result with
102 // representation/field type from the old descriptor. 103 // representation/field type from the old descriptor.
103 if (old_details.kind() == new_kind_) { 104 if (old_details.kind() == new_kind_) {
104 new_constness_ = kMutable; 105 new_constness_ = GeneralizeConstness(constness, old_details.constness());
105 106
106 Representation old_representation = old_details.representation(); 107 Representation old_representation = old_details.representation();
107 new_representation_ = representation.generalize(old_representation); 108 new_representation_ = representation.generalize(old_representation);
108 109
109 Handle<FieldType> old_field_type = 110 Handle<FieldType> old_field_type =
110 GetOrComputeFieldType(old_descriptors_, modified_descriptor_, 111 GetOrComputeFieldType(old_descriptors_, modified_descriptor_,
111 old_details.location(), new_representation_); 112 old_details.location(), new_representation_);
112 113
113 new_field_type_ = 114 new_field_type_ =
114 Map::GeneralizeFieldType(old_representation, old_field_type, 115 Map::GeneralizeFieldType(old_representation, old_field_type,
(...skipping 30 matching lines...) Expand all
145 DCHECK_EQ(kInitialized, state_); 146 DCHECK_EQ(kInitialized, state_);
146 DCHECK(old_map_->is_deprecated()); 147 DCHECK(old_map_->is_deprecated());
147 148
148 if (FindRootMap() == kEnd) return result_map_; 149 if (FindRootMap() == kEnd) return result_map_;
149 if (FindTargetMap() == kEnd) return result_map_; 150 if (FindTargetMap() == kEnd) return result_map_;
150 ConstructNewMap(); 151 ConstructNewMap();
151 DCHECK_EQ(kEnd, state_); 152 DCHECK_EQ(kEnd, state_);
152 return result_map_; 153 return result_map_;
153 } 154 }
154 155
156 void MapUpdater::GeneralizeField(Handle<Map> map, int modify_index,
157 PropertyConstness new_constness,
158 Representation new_representation,
159 Handle<FieldType> new_field_type) {
160 Map::GeneralizeField(map, modify_index, new_constness, new_representation,
161 new_field_type);
162
163 DCHECK_EQ(*old_descriptors_, old_map_->instance_descriptors());
164 }
165
155 MapUpdater::State MapUpdater::CopyGeneralizeAllFields(const char* reason) { 166 MapUpdater::State MapUpdater::CopyGeneralizeAllFields(const char* reason) {
156 result_map_ = Map::CopyGeneralizeAllFields(old_map_, new_elements_kind_, 167 result_map_ = Map::CopyGeneralizeAllFields(old_map_, new_elements_kind_,
157 modified_descriptor_, new_kind_, 168 modified_descriptor_, new_kind_,
158 new_attributes_, reason); 169 new_attributes_, reason);
159 state_ = kEnd; 170 state_ = kEnd;
160 return state_; // Done. 171 return state_; // Done.
161 } 172 }
162 173
163 MapUpdater::State MapUpdater::TryRecofigureToDataFieldInplace() { 174 MapUpdater::State MapUpdater::TryRecofigureToDataFieldInplace() {
164 // If it's just a representation generalization case (i.e. property kind and 175 // If it's just a representation generalization case (i.e. property kind and
(...skipping 18 matching lines...) Expand all
183 if (FLAG_trace_generalization) { 194 if (FLAG_trace_generalization) {
184 old_map_->PrintGeneralization( 195 old_map_->PrintGeneralization(
185 stdout, "uninitialized field", modified_descriptor_, old_nof_, old_nof_, 196 stdout, "uninitialized field", modified_descriptor_, old_nof_, old_nof_,
186 false, old_representation, new_representation_, 197 false, old_representation, new_representation_,
187 handle(old_descriptors_->GetFieldType(modified_descriptor_), isolate_), 198 handle(old_descriptors_->GetFieldType(modified_descriptor_), isolate_),
188 MaybeHandle<Object>(), new_field_type_, MaybeHandle<Object>()); 199 MaybeHandle<Object>(), new_field_type_, MaybeHandle<Object>());
189 } 200 }
190 Handle<Map> field_owner(old_map_->FindFieldOwner(modified_descriptor_), 201 Handle<Map> field_owner(old_map_->FindFieldOwner(modified_descriptor_),
191 isolate_); 202 isolate_);
192 203
193 Map::GeneralizeField(field_owner, modified_descriptor_, new_representation_, 204 GeneralizeField(field_owner, modified_descriptor_, new_constness_,
194 new_field_type_); 205 new_representation_, new_field_type_);
195 // Check that the descriptor array was updated. 206 // Check that the descriptor array was updated.
196 DCHECK(old_descriptors_->GetDetails(modified_descriptor_) 207 DCHECK(old_descriptors_->GetDetails(modified_descriptor_)
197 .representation() 208 .representation()
198 .Equals(new_representation_)); 209 .Equals(new_representation_));
199 DCHECK(old_descriptors_->GetFieldType(modified_descriptor_) 210 DCHECK(old_descriptors_->GetFieldType(modified_descriptor_)
200 ->NowIs(new_field_type_)); 211 ->NowIs(new_field_type_));
201 212
202 result_map_ = old_map_; 213 result_map_ = old_map_;
203 state_ = kEnd; 214 state_ = kEnd;
204 return state_; // Done. 215 return state_; // Done.
(...skipping 22 matching lines...) Expand all
227 if (modified_descriptor_ >= 0 && modified_descriptor_ < root_nof) { 238 if (modified_descriptor_ >= 0 && modified_descriptor_ < root_nof) {
228 PropertyDetails old_details = 239 PropertyDetails old_details =
229 old_descriptors_->GetDetails(modified_descriptor_); 240 old_descriptors_->GetDetails(modified_descriptor_);
230 if (old_details.kind() != new_kind_ || 241 if (old_details.kind() != new_kind_ ||
231 old_details.attributes() != new_attributes_) { 242 old_details.attributes() != new_attributes_) {
232 return CopyGeneralizeAllFields("GenAll_RootModification1"); 243 return CopyGeneralizeAllFields("GenAll_RootModification1");
233 } 244 }
234 if (old_details.location() != kField) { 245 if (old_details.location() != kField) {
235 return CopyGeneralizeAllFields("GenAll_RootModification2"); 246 return CopyGeneralizeAllFields("GenAll_RootModification2");
236 } 247 }
237 DCHECK_EQ(kMutable, old_details.constness()); 248 if (new_constness_ != old_details.constness()) {
238 if (!new_representation_.fits_into(old_details.representation())) {
239 return CopyGeneralizeAllFields("GenAll_RootModification3"); 249 return CopyGeneralizeAllFields("GenAll_RootModification3");
240 } 250 }
251 if (!new_representation_.fits_into(old_details.representation())) {
252 return CopyGeneralizeAllFields("GenAll_RootModification4");
253 }
254
241 DCHECK_EQ(kData, old_details.kind()); 255 DCHECK_EQ(kData, old_details.kind());
242 DCHECK_EQ(kData, new_kind_); 256 DCHECK_EQ(kData, new_kind_);
243 DCHECK_EQ(kField, new_location_); 257 DCHECK_EQ(kField, new_location_);
244 FieldType* old_field_type = 258 FieldType* old_field_type =
245 old_descriptors_->GetFieldType(modified_descriptor_); 259 old_descriptors_->GetFieldType(modified_descriptor_);
246 if (!new_field_type_->NowIs(old_field_type)) { 260 if (!new_field_type_->NowIs(old_field_type)) {
247 return CopyGeneralizeAllFields("GenAll_RootModification4"); 261 return CopyGeneralizeAllFields("GenAll_RootModification5");
248 } 262 }
249 } 263 }
250 264
251 // From here on, use the map with correct elements kind as root map. 265 // From here on, use the map with correct elements kind as root map.
252 if (from_kind != to_kind) { 266 if (from_kind != to_kind) {
253 root_map_ = Map::AsElementsKind(root_map_, to_kind); 267 root_map_ = Map::AsElementsKind(root_map_, to_kind);
254 } 268 }
255 state_ = kAtRootMap; 269 state_ = kAtRootMap;
256 return state_; // Not done yet. 270 return state_; // Not done yet.
257 } 271 }
(...skipping 15 matching lines...) Expand all
273 287
274 // Check if target map is incompatible. 288 // Check if target map is incompatible.
275 PropertyDetails tmp_details = tmp_descriptors->GetDetails(i); 289 PropertyDetails tmp_details = tmp_descriptors->GetDetails(i);
276 DCHECK_EQ(old_details.kind(), tmp_details.kind()); 290 DCHECK_EQ(old_details.kind(), tmp_details.kind());
277 DCHECK_EQ(old_details.attributes(), tmp_details.attributes()); 291 DCHECK_EQ(old_details.attributes(), tmp_details.attributes());
278 if (old_details.kind() == kAccessor && 292 if (old_details.kind() == kAccessor &&
279 !EqualImmutableValues(GetValue(i), tmp_descriptors->GetValue(i))) { 293 !EqualImmutableValues(GetValue(i), tmp_descriptors->GetValue(i))) {
280 // TODO(ishell): mutable accessors are not implemented yet. 294 // TODO(ishell): mutable accessors are not implemented yet.
281 return CopyGeneralizeAllFields("GenAll_Incompatible"); 295 return CopyGeneralizeAllFields("GenAll_Incompatible");
282 } 296 }
283 // Check if old constness fits into tmp constness. 297 PropertyConstness tmp_constness = tmp_details.constness();
284 if (!IsGeneralizableTo(old_details.constness(), tmp_details.constness())) { 298 if (!IsGeneralizableTo(old_details.constness(), tmp_constness)) {
285 break; 299 break;
286 } 300 }
287 // Check if old location fits into tmp location.
288 if (!IsGeneralizableTo(old_details.location(), tmp_details.location())) { 301 if (!IsGeneralizableTo(old_details.location(), tmp_details.location())) {
289 break; 302 break;
290 } 303 }
291
292 // Check if old representation fits into tmp representation.
293 Representation tmp_representation = tmp_details.representation(); 304 Representation tmp_representation = tmp_details.representation();
294 if (!old_details.representation().fits_into(tmp_representation)) { 305 if (!old_details.representation().fits_into(tmp_representation)) {
295 break; 306 break;
296 } 307 }
297 308
298 if (tmp_details.location() == kField) { 309 if (tmp_details.location() == kField) {
299 Handle<FieldType> old_field_type = 310 Handle<FieldType> old_field_type =
300 GetOrComputeFieldType(i, old_details.location(), tmp_representation); 311 GetOrComputeFieldType(i, old_details.location(), tmp_representation);
301 Map::GeneralizeField(tmp_map, i, tmp_representation, old_field_type); 312 GeneralizeField(tmp_map, i, tmp_constness, tmp_representation,
313 old_field_type);
302 } else { 314 } else {
303 // kDescriptor: Check that the value matches. 315 // kDescriptor: Check that the value matches.
304 if (!EqualImmutableValues(GetValue(i), tmp_descriptors->GetValue(i))) { 316 if (!EqualImmutableValues(GetValue(i), tmp_descriptors->GetValue(i))) {
305 break; 317 break;
306 } 318 }
307 } 319 }
308 DCHECK(!tmp_map->is_deprecated()); 320 DCHECK(!tmp_map->is_deprecated());
309 target_map_ = tmp_map; 321 target_map_ = tmp_map;
310 } 322 }
311 323
312 // Directly change the map if the target map is more general. 324 // Directly change the map if the target map is more general.
313 int target_nof = target_map_->NumberOfOwnDescriptors(); 325 int target_nof = target_map_->NumberOfOwnDescriptors();
314 if (target_nof == old_nof_) { 326 if (target_nof == old_nof_) {
315 #ifdef DEBUG 327 #ifdef DEBUG
316 if (modified_descriptor_ >= 0) { 328 if (modified_descriptor_ >= 0) {
317 DescriptorArray* target_descriptors = target_map_->instance_descriptors(); 329 DescriptorArray* target_descriptors = target_map_->instance_descriptors();
318 PropertyDetails details = 330 PropertyDetails details =
319 target_descriptors->GetDetails(modified_descriptor_); 331 target_descriptors->GetDetails(modified_descriptor_);
320 DCHECK_EQ(new_kind_, details.kind()); 332 DCHECK_EQ(new_kind_, details.kind());
321 DCHECK_EQ(new_attributes_, details.attributes()); 333 DCHECK_EQ(new_attributes_, details.attributes());
334 DCHECK(IsGeneralizableTo(new_constness_, details.constness()));
322 DCHECK_EQ(new_location_, details.location()); 335 DCHECK_EQ(new_location_, details.location());
323 DCHECK(new_representation_.fits_into(details.representation())); 336 DCHECK(new_representation_.fits_into(details.representation()));
324 if (new_location_ == kField) { 337 if (new_location_ == kField) {
325 DCHECK_EQ(kField, details.location()); 338 DCHECK_EQ(kField, details.location());
326 DCHECK(new_field_type_->NowIs( 339 DCHECK(new_field_type_->NowIs(
327 target_descriptors->GetFieldType(modified_descriptor_))); 340 target_descriptors->GetFieldType(modified_descriptor_)));
328 } else { 341 } else {
329 DCHECK(details.location() == kField || 342 DCHECK(details.location() == kField ||
330 EqualImmutableValues(*new_value_, target_descriptors->GetValue( 343 EqualImmutableValues(*new_value_, target_descriptors->GetValue(
331 modified_descriptor_))); 344 modified_descriptor_)));
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
420 // Note: failed values equality check does not invalidate per-object 433 // Note: failed values equality check does not invalidate per-object
421 // property constness. 434 // property constness.
422 PropertyLocation next_location = 435 PropertyLocation next_location =
423 old_details.location() == kField || 436 old_details.location() == kField ||
424 target_details.location() == kField || 437 target_details.location() == kField ||
425 !EqualImmutableValues(target_descriptors->GetValue(i), 438 !EqualImmutableValues(target_descriptors->GetValue(i),
426 GetValue(i)) 439 GetValue(i))
427 ? kField 440 ? kField
428 : kDescriptor; 441 : kDescriptor;
429 442
430 // TODO(ishell): remove once constant field tracking is done. 443 if (!FLAG_track_constant_fields && next_location == kField) {
431 if (next_location == kField) next_constness = kMutable; 444 next_constness = kMutable;
445 }
432 // Ensure that mutable values are stored in fields. 446 // Ensure that mutable values are stored in fields.
433 DCHECK_IMPLIES(next_constness == kMutable, next_location == kField); 447 DCHECK_IMPLIES(next_constness == kMutable, next_location == kField);
434 448
435 Representation next_representation = 449 Representation next_representation =
436 old_details.representation().generalize( 450 old_details.representation().generalize(
437 target_details.representation()); 451 target_details.representation());
438 452
439 if (next_location == kField) { 453 if (next_location == kField) {
440 Handle<FieldType> old_field_type = 454 Handle<FieldType> old_field_type =
441 GetOrComputeFieldType(i, old_details.location(), next_representation); 455 GetOrComputeFieldType(i, old_details.location(), next_representation);
(...skipping 18 matching lines...) Expand all
460 } 474 }
461 current_offset += d.GetDetails().field_width_in_words(); 475 current_offset += d.GetDetails().field_width_in_words();
462 new_descriptors->Set(i, &d); 476 new_descriptors->Set(i, &d);
463 } else { 477 } else {
464 DCHECK_EQ(kDescriptor, next_location); 478 DCHECK_EQ(kDescriptor, next_location);
465 DCHECK_EQ(kConst, next_constness); 479 DCHECK_EQ(kConst, next_constness);
466 480
467 Handle<Object> value(GetValue(i), isolate_); 481 Handle<Object> value(GetValue(i), isolate_);
468 Descriptor d; 482 Descriptor d;
469 if (next_kind == kData) { 483 if (next_kind == kData) {
484 DCHECK(!FLAG_track_constant_fields);
470 d = Descriptor::DataConstant(key, value, next_attributes); 485 d = Descriptor::DataConstant(key, value, next_attributes);
471 } else { 486 } else {
472 DCHECK_EQ(kAccessor, next_kind); 487 DCHECK_EQ(kAccessor, next_kind);
473 d = Descriptor::AccessorConstant(key, value, next_attributes); 488 d = Descriptor::AccessorConstant(key, value, next_attributes);
474 } 489 }
475 new_descriptors->Set(i, &d); 490 new_descriptors->Set(i, &d);
476 } 491 }
477 } 492 }
478 493
479 // Take "updated" old_descriptor entries. 494 // Take "updated" old_descriptor entries.
480 // |target_nof| -> |old_nof| 495 // |target_nof| -> |old_nof|
481 for (int i = target_nof; i < old_nof_; ++i) { 496 for (int i = target_nof; i < old_nof_; ++i) {
482 PropertyDetails old_details = GetDetails(i); 497 PropertyDetails old_details = GetDetails(i);
483 Handle<Name> key(GetKey(i), isolate_); 498 Handle<Name> key(GetKey(i), isolate_);
484 499
485 PropertyKind next_kind = old_details.kind(); 500 PropertyKind next_kind = old_details.kind();
486 PropertyAttributes next_attributes = old_details.attributes(); 501 PropertyAttributes next_attributes = old_details.attributes();
487 PropertyConstness next_constness = old_details.constness(); 502 PropertyConstness next_constness = old_details.constness();
488 PropertyLocation next_location = old_details.location(); 503 PropertyLocation next_location = old_details.location();
489 Representation next_representation = old_details.representation(); 504 Representation next_representation = old_details.representation();
490 505
491 Descriptor d; 506 Descriptor d;
492 if (next_location == kField) { 507 if (next_location == kField) {
493 DCHECK_EQ(kMutable, next_constness);
494 Handle<FieldType> old_field_type = 508 Handle<FieldType> old_field_type =
495 GetOrComputeFieldType(i, old_details.location(), next_representation); 509 GetOrComputeFieldType(i, old_details.location(), next_representation);
496 510
497 Handle<Object> wrapped_type(Map::WrapFieldType(old_field_type)); 511 Handle<Object> wrapped_type(Map::WrapFieldType(old_field_type));
498 Descriptor d; 512 Descriptor d;
499 if (next_kind == kData) { 513 if (next_kind == kData) {
514 DCHECK_IMPLIES(!FLAG_track_constant_fields, next_constness == kMutable);
500 d = Descriptor::DataField(key, current_offset, next_attributes, 515 d = Descriptor::DataField(key, current_offset, next_attributes,
501 next_constness, next_representation, 516 next_constness, next_representation,
502 wrapped_type); 517 wrapped_type);
503 } else { 518 } else {
504 // TODO(ishell): mutable accessors are not implemented yet. 519 // TODO(ishell): mutable accessors are not implemented yet.
505 UNIMPLEMENTED(); 520 UNIMPLEMENTED();
506 } 521 }
507 current_offset += d.GetDetails().field_width_in_words(); 522 current_offset += d.GetDetails().field_width_in_words();
508 new_descriptors->Set(i, &d); 523 new_descriptors->Set(i, &d);
509 } else { 524 } else {
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
630 // the new descriptors to maintain descriptors sharing invariant. 645 // the new descriptors to maintain descriptors sharing invariant.
631 split_map->ReplaceDescriptors(*new_descriptors, *new_layout_descriptor); 646 split_map->ReplaceDescriptors(*new_descriptors, *new_layout_descriptor);
632 647
633 result_map_ = new_map; 648 result_map_ = new_map;
634 state_ = kEnd; 649 state_ = kEnd;
635 return state_; // Done. 650 return state_; // Done.
636 } 651 }
637 652
638 } // namespace internal 653 } // namespace internal
639 } // namespace v8 654 } // namespace v8
OLDNEW
« no previous file with comments | « src/map-updater.h ('k') | src/objects.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698