OLD | NEW |
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 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
142 DCHECK_EQ(kInitialized, state_); | 142 DCHECK_EQ(kInitialized, state_); |
143 DCHECK(old_map_->is_deprecated()); | 143 DCHECK(old_map_->is_deprecated()); |
144 | 144 |
145 if (FindRootMap() == kEnd) return result_map_; | 145 if (FindRootMap() == kEnd) return result_map_; |
146 if (FindTargetMap() == kEnd) return result_map_; | 146 if (FindTargetMap() == kEnd) return result_map_; |
147 ConstructNewMap(); | 147 ConstructNewMap(); |
148 DCHECK_EQ(kEnd, state_); | 148 DCHECK_EQ(kEnd, state_); |
149 return result_map_; | 149 return result_map_; |
150 } | 150 } |
151 | 151 |
152 MapUpdater::State MapUpdater::CopyGeneralizeAllRepresentations( | 152 MapUpdater::State MapUpdater::CopyGeneralizeAllFields(const char* reason) { |
153 const char* reason) { | |
154 StoreMode store_mode = | 153 StoreMode store_mode = |
155 modified_descriptor_ >= 0 ? FORCE_FIELD : ALLOW_IN_DESCRIPTOR; | 154 modified_descriptor_ >= 0 ? FORCE_FIELD : ALLOW_IN_DESCRIPTOR; |
156 result_map_ = Map::CopyGeneralizeAllRepresentations( | 155 result_map_ = Map::CopyGeneralizeAllFields( |
157 old_map_, new_elements_kind_, modified_descriptor_, store_mode, new_kind_, | 156 old_map_, new_elements_kind_, modified_descriptor_, store_mode, new_kind_, |
158 new_attributes_, reason); | 157 new_attributes_, reason); |
159 state_ = kEnd; | 158 state_ = kEnd; |
160 return state_; // Done. | 159 return state_; // Done. |
161 } | 160 } |
162 | 161 |
163 MapUpdater::State MapUpdater::TryRecofigureToDataFieldInplace() { | 162 MapUpdater::State MapUpdater::TryRecofigureToDataFieldInplace() { |
164 // If it's just a representation generalization case (i.e. property kind and | 163 // If it's just a representation generalization case (i.e. property kind and |
165 // attributes stays unchanged) it's fine to transition from None to anything | 164 // attributes stays unchanged) it's fine to transition from None to anything |
166 // but double without any modification to the object, because the default | 165 // but double without any modification to the object, because the default |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
203 state_ = kEnd; | 202 state_ = kEnd; |
204 return state_; // Done. | 203 return state_; // Done. |
205 } | 204 } |
206 | 205 |
207 MapUpdater::State MapUpdater::FindRootMap() { | 206 MapUpdater::State MapUpdater::FindRootMap() { |
208 DCHECK_EQ(kInitialized, state_); | 207 DCHECK_EQ(kInitialized, state_); |
209 // Check the state of the root map. | 208 // Check the state of the root map. |
210 root_map_ = handle(old_map_->FindRootMap(), isolate_); | 209 root_map_ = handle(old_map_->FindRootMap(), isolate_); |
211 int root_nof = root_map_->NumberOfOwnDescriptors(); | 210 int root_nof = root_map_->NumberOfOwnDescriptors(); |
212 if (!old_map_->EquivalentToForTransition(*root_map_)) { | 211 if (!old_map_->EquivalentToForTransition(*root_map_)) { |
213 return CopyGeneralizeAllRepresentations("GenAll_NotEquivalent"); | 212 return CopyGeneralizeAllFields("GenAll_NotEquivalent"); |
214 } | 213 } |
215 | 214 |
216 ElementsKind from_kind = root_map_->elements_kind(); | 215 ElementsKind from_kind = root_map_->elements_kind(); |
217 ElementsKind to_kind = new_elements_kind_; | 216 ElementsKind to_kind = new_elements_kind_; |
218 // TODO(ishell): Add a test for SLOW_SLOPPY_ARGUMENTS_ELEMENTS. | 217 // TODO(ishell): Add a test for SLOW_SLOPPY_ARGUMENTS_ELEMENTS. |
219 if (from_kind != to_kind && to_kind != DICTIONARY_ELEMENTS && | 218 if (from_kind != to_kind && to_kind != DICTIONARY_ELEMENTS && |
220 to_kind != SLOW_STRING_WRAPPER_ELEMENTS && | 219 to_kind != SLOW_STRING_WRAPPER_ELEMENTS && |
221 to_kind != SLOW_SLOPPY_ARGUMENTS_ELEMENTS && | 220 to_kind != SLOW_SLOPPY_ARGUMENTS_ELEMENTS && |
222 !(IsTransitionableFastElementsKind(from_kind) && | 221 !(IsTransitionableFastElementsKind(from_kind) && |
223 IsMoreGeneralElementsKindTransition(from_kind, to_kind))) { | 222 IsMoreGeneralElementsKindTransition(from_kind, to_kind))) { |
224 return CopyGeneralizeAllRepresentations("GenAll_InvalidElementsTransition"); | 223 return CopyGeneralizeAllFields("GenAll_InvalidElementsTransition"); |
225 } | 224 } |
226 | 225 |
227 if (modified_descriptor_ >= 0 && modified_descriptor_ < root_nof) { | 226 if (modified_descriptor_ >= 0 && modified_descriptor_ < root_nof) { |
228 PropertyDetails old_details = | 227 PropertyDetails old_details = |
229 old_descriptors_->GetDetails(modified_descriptor_); | 228 old_descriptors_->GetDetails(modified_descriptor_); |
230 if (old_details.kind() != new_kind_ || | 229 if (old_details.kind() != new_kind_ || |
231 old_details.attributes() != new_attributes_) { | 230 old_details.attributes() != new_attributes_) { |
232 return CopyGeneralizeAllRepresentations("GenAll_RootModification1"); | 231 return CopyGeneralizeAllFields("GenAll_RootModification1"); |
233 } | 232 } |
234 if (!new_representation_.fits_into(old_details.representation())) { | 233 if (!new_representation_.fits_into(old_details.representation())) { |
235 return CopyGeneralizeAllRepresentations("GenAll_RootModification2"); | 234 return CopyGeneralizeAllFields("GenAll_RootModification2"); |
236 } | 235 } |
237 if (old_details.location() != kField) { | 236 if (old_details.location() != kField) { |
238 return CopyGeneralizeAllRepresentations("GenAll_RootModification3"); | 237 return CopyGeneralizeAllFields("GenAll_RootModification3"); |
239 } | 238 } |
240 DCHECK_EQ(kData, old_details.kind()); | 239 DCHECK_EQ(kData, old_details.kind()); |
241 DCHECK_EQ(kData, new_kind_); | 240 DCHECK_EQ(kData, new_kind_); |
242 DCHECK_EQ(kField, new_location_); | 241 DCHECK_EQ(kField, new_location_); |
243 FieldType* old_field_type = | 242 FieldType* old_field_type = |
244 old_descriptors_->GetFieldType(modified_descriptor_); | 243 old_descriptors_->GetFieldType(modified_descriptor_); |
245 if (!new_field_type_->NowIs(old_field_type)) { | 244 if (!new_field_type_->NowIs(old_field_type)) { |
246 return CopyGeneralizeAllRepresentations("GenAll_RootModification4"); | 245 return CopyGeneralizeAllFields("GenAll_RootModification4"); |
247 } | 246 } |
248 } | 247 } |
249 | 248 |
250 // From here on, use the map with correct elements kind as root map. | 249 // From here on, use the map with correct elements kind as root map. |
251 if (from_kind != to_kind) { | 250 if (from_kind != to_kind) { |
252 root_map_ = Map::AsElementsKind(root_map_, to_kind); | 251 root_map_ = Map::AsElementsKind(root_map_, to_kind); |
253 } | 252 } |
254 state_ = kAtRootMap; | 253 state_ = kAtRootMap; |
255 return state_; // Not done yet. | 254 return state_; // Not done yet. |
256 } | 255 } |
(...skipping 13 matching lines...) Expand all Loading... |
270 Handle<DescriptorArray> tmp_descriptors(tmp_map->instance_descriptors(), | 269 Handle<DescriptorArray> tmp_descriptors(tmp_map->instance_descriptors(), |
271 isolate_); | 270 isolate_); |
272 | 271 |
273 // Check if target map is incompatible. | 272 // Check if target map is incompatible. |
274 PropertyDetails tmp_details = tmp_descriptors->GetDetails(i); | 273 PropertyDetails tmp_details = tmp_descriptors->GetDetails(i); |
275 DCHECK_EQ(old_details.kind(), tmp_details.kind()); | 274 DCHECK_EQ(old_details.kind(), tmp_details.kind()); |
276 DCHECK_EQ(old_details.attributes(), tmp_details.attributes()); | 275 DCHECK_EQ(old_details.attributes(), tmp_details.attributes()); |
277 if (old_details.kind() == kAccessor && | 276 if (old_details.kind() == kAccessor && |
278 !EqualImmutableValues(GetValue(i), tmp_descriptors->GetValue(i))) { | 277 !EqualImmutableValues(GetValue(i), tmp_descriptors->GetValue(i))) { |
279 // TODO(ishell): mutable accessors are not implemented yet. | 278 // TODO(ishell): mutable accessors are not implemented yet. |
280 return CopyGeneralizeAllRepresentations("GenAll_Incompatible"); | 279 return CopyGeneralizeAllFields("GenAll_Incompatible"); |
281 } | 280 } |
282 // Check if old location fits into tmp location. | 281 // Check if old location fits into tmp location. |
283 if (!LocationFitsInto(old_details.location(), tmp_details.location())) { | 282 if (!LocationFitsInto(old_details.location(), tmp_details.location())) { |
284 break; | 283 break; |
285 } | 284 } |
286 | 285 |
287 // Check if old representation fits into tmp representation. | 286 // Check if old representation fits into tmp representation. |
288 Representation tmp_representation = tmp_details.representation(); | 287 Representation tmp_representation = tmp_details.representation(); |
289 if (!old_details.representation().fits_into(tmp_representation)) { | 288 if (!old_details.representation().fits_into(tmp_representation)) { |
290 break; | 289 break; |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
346 isolate_); | 345 isolate_); |
347 | 346 |
348 #ifdef DEBUG | 347 #ifdef DEBUG |
349 // Check that target map is compatible. | 348 // Check that target map is compatible. |
350 PropertyDetails tmp_details = tmp_descriptors->GetDetails(i); | 349 PropertyDetails tmp_details = tmp_descriptors->GetDetails(i); |
351 DCHECK_EQ(old_details.kind(), tmp_details.kind()); | 350 DCHECK_EQ(old_details.kind(), tmp_details.kind()); |
352 DCHECK_EQ(old_details.attributes(), tmp_details.attributes()); | 351 DCHECK_EQ(old_details.attributes(), tmp_details.attributes()); |
353 #endif | 352 #endif |
354 if (old_details.kind() == kAccessor && | 353 if (old_details.kind() == kAccessor && |
355 !EqualImmutableValues(GetValue(i), tmp_descriptors->GetValue(i))) { | 354 !EqualImmutableValues(GetValue(i), tmp_descriptors->GetValue(i))) { |
356 return CopyGeneralizeAllRepresentations("GenAll_Incompatible"); | 355 return CopyGeneralizeAllFields("GenAll_Incompatible"); |
357 } | 356 } |
358 DCHECK(!tmp_map->is_deprecated()); | 357 DCHECK(!tmp_map->is_deprecated()); |
359 target_map_ = tmp_map; | 358 target_map_ = tmp_map; |
360 } | 359 } |
361 | 360 |
362 state_ = kAtTargetMap; | 361 state_ = kAtTargetMap; |
363 return state_; // Not done yet. | 362 return state_; // Not done yet. |
364 } | 363 } |
365 | 364 |
366 Handle<DescriptorArray> MapUpdater::BuildDescriptorArray() { | 365 Handle<DescriptorArray> MapUpdater::BuildDescriptorArray() { |
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
555 split_details.attributes()); | 554 split_details.attributes()); |
556 if (maybe_transition != NULL) { | 555 if (maybe_transition != NULL) { |
557 maybe_transition->DeprecateTransitionTree(); | 556 maybe_transition->DeprecateTransitionTree(); |
558 } | 557 } |
559 | 558 |
560 // If |maybe_transition| is not NULL then the transition array already | 559 // If |maybe_transition| is not NULL then the transition array already |
561 // contains entry for given descriptor. This means that the transition | 560 // contains entry for given descriptor. This means that the transition |
562 // could be inserted regardless of whether transitions array is full or not. | 561 // could be inserted regardless of whether transitions array is full or not. |
563 if (maybe_transition == NULL && | 562 if (maybe_transition == NULL && |
564 !TransitionArray::CanHaveMoreTransitions(split_map)) { | 563 !TransitionArray::CanHaveMoreTransitions(split_map)) { |
565 return CopyGeneralizeAllRepresentations("GenAll_CantHaveMoreTransitions"); | 564 return CopyGeneralizeAllFields("GenAll_CantHaveMoreTransitions"); |
566 } | 565 } |
567 | 566 |
568 old_map_->NotifyLeafMapLayoutChange(); | 567 old_map_->NotifyLeafMapLayoutChange(); |
569 | 568 |
570 if (FLAG_trace_generalization && modified_descriptor_ >= 0) { | 569 if (FLAG_trace_generalization && modified_descriptor_ >= 0) { |
571 PropertyDetails old_details = | 570 PropertyDetails old_details = |
572 old_descriptors_->GetDetails(modified_descriptor_); | 571 old_descriptors_->GetDetails(modified_descriptor_); |
573 PropertyDetails new_details = | 572 PropertyDetails new_details = |
574 new_descriptors->GetDetails(modified_descriptor_); | 573 new_descriptors->GetDetails(modified_descriptor_); |
575 MaybeHandle<FieldType> old_field_type; | 574 MaybeHandle<FieldType> old_field_type; |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
609 // the new descriptors to maintain descriptors sharing invariant. | 608 // the new descriptors to maintain descriptors sharing invariant. |
610 split_map->ReplaceDescriptors(*new_descriptors, *new_layout_descriptor); | 609 split_map->ReplaceDescriptors(*new_descriptors, *new_layout_descriptor); |
611 | 610 |
612 result_map_ = new_map; | 611 result_map_ = new_map; |
613 state_ = kEnd; | 612 state_ = kEnd; |
614 return state_; // Done. | 613 return state_; // Done. |
615 } | 614 } |
616 | 615 |
617 } // namespace internal | 616 } // namespace internal |
618 } // namespace v8 | 617 } // namespace v8 |
OLD | NEW |