| 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 "src/objects.h" | 5 #include "src/objects.h" |
| 6 | 6 |
| 7 #include <cmath> | 7 #include <cmath> |
| 8 #include <iomanip> | 8 #include <iomanip> |
| 9 #include <sstream> | 9 #include <sstream> |
| 10 | 10 |
| (...skipping 2659 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2670 case kDouble: return "d"; | 2670 case kDouble: return "d"; |
| 2671 case kInteger32: return "i"; | 2671 case kInteger32: return "i"; |
| 2672 case kHeapObject: return "h"; | 2672 case kHeapObject: return "h"; |
| 2673 case kExternal: return "x"; | 2673 case kExternal: return "x"; |
| 2674 default: | 2674 default: |
| 2675 UNREACHABLE(); | 2675 UNREACHABLE(); |
| 2676 return NULL; | 2676 return NULL; |
| 2677 } | 2677 } |
| 2678 } | 2678 } |
| 2679 | 2679 |
| 2680 bool Map::InstancesNeedRewriting(Map* target) { |
| 2681 int target_number_of_fields = target->NumberOfFields(); |
| 2682 int target_inobject = target->GetInObjectProperties(); |
| 2683 int target_unused = target->unused_property_fields(); |
| 2684 int old_number_of_fields; |
| 2685 |
| 2686 return InstancesNeedRewriting(target, target_number_of_fields, |
| 2687 target_inobject, target_unused, |
| 2688 &old_number_of_fields); |
| 2689 } |
| 2680 | 2690 |
| 2681 bool Map::InstancesNeedRewriting(Map* target, int target_number_of_fields, | 2691 bool Map::InstancesNeedRewriting(Map* target, int target_number_of_fields, |
| 2682 int target_inobject, int target_unused, | 2692 int target_inobject, int target_unused, |
| 2683 int* old_number_of_fields) { | 2693 int* old_number_of_fields) { |
| 2684 // If fields were added (or removed), rewrite the instance. | 2694 // If fields were added (or removed), rewrite the instance. |
| 2685 *old_number_of_fields = NumberOfFields(); | 2695 *old_number_of_fields = NumberOfFields(); |
| 2686 DCHECK(target_number_of_fields >= *old_number_of_fields); | 2696 DCHECK(target_number_of_fields >= *old_number_of_fields); |
| 2687 if (target_number_of_fields != *old_number_of_fields) return true; | 2697 if (target_number_of_fields != *old_number_of_fields) return true; |
| 2688 | 2698 |
| 2689 // If smi descriptors were replaced by double descriptors, rewrite. | 2699 // If smi descriptors were replaced by double descriptors, rewrite. |
| (...skipping 440 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3130 | 3140 |
| 3131 int Map::NumberOfFields() { | 3141 int Map::NumberOfFields() { |
| 3132 DescriptorArray* descriptors = instance_descriptors(); | 3142 DescriptorArray* descriptors = instance_descriptors(); |
| 3133 int result = 0; | 3143 int result = 0; |
| 3134 for (int i = 0; i < NumberOfOwnDescriptors(); i++) { | 3144 for (int i = 0; i < NumberOfOwnDescriptors(); i++) { |
| 3135 if (descriptors->GetDetails(i).location() == kField) result++; | 3145 if (descriptors->GetDetails(i).location() == kField) result++; |
| 3136 } | 3146 } |
| 3137 return result; | 3147 return result; |
| 3138 } | 3148 } |
| 3139 | 3149 |
| 3140 | |
| 3141 Handle<Map> Map::CopyGeneralizeAllRepresentations( | 3150 Handle<Map> Map::CopyGeneralizeAllRepresentations( |
| 3142 Handle<Map> map, int modify_index, StoreMode store_mode, PropertyKind kind, | 3151 Handle<Map> map, ElementsKind elements_kind, int modify_index, |
| 3143 PropertyAttributes attributes, const char* reason) { | 3152 StoreMode store_mode, PropertyKind kind, PropertyAttributes attributes, |
| 3153 const char* reason) { |
| 3144 Isolate* isolate = map->GetIsolate(); | 3154 Isolate* isolate = map->GetIsolate(); |
| 3145 Handle<DescriptorArray> old_descriptors(map->instance_descriptors(), isolate); | 3155 Handle<DescriptorArray> old_descriptors(map->instance_descriptors(), isolate); |
| 3146 int number_of_own_descriptors = map->NumberOfOwnDescriptors(); | 3156 int number_of_own_descriptors = map->NumberOfOwnDescriptors(); |
| 3147 Handle<DescriptorArray> descriptors = | 3157 Handle<DescriptorArray> descriptors = |
| 3148 DescriptorArray::CopyUpTo(old_descriptors, number_of_own_descriptors); | 3158 DescriptorArray::CopyUpTo(old_descriptors, number_of_own_descriptors); |
| 3149 | 3159 |
| 3150 for (int i = 0; i < number_of_own_descriptors; i++) { | 3160 for (int i = 0; i < number_of_own_descriptors; i++) { |
| 3151 descriptors->SetRepresentation(i, Representation::Tagged()); | 3161 descriptors->SetRepresentation(i, Representation::Tagged()); |
| 3152 if (descriptors->GetDetails(i).type() == DATA) { | 3162 if (descriptors->GetDetails(i).type() == DATA) { |
| 3153 descriptors->SetValue(i, FieldType::Any()); | 3163 descriptors->SetValue(i, FieldType::Any()); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3189 } | 3199 } |
| 3190 map->PrintGeneralization( | 3200 map->PrintGeneralization( |
| 3191 stdout, reason, modify_index, new_map->NumberOfOwnDescriptors(), | 3201 stdout, reason, modify_index, new_map->NumberOfOwnDescriptors(), |
| 3192 new_map->NumberOfOwnDescriptors(), | 3202 new_map->NumberOfOwnDescriptors(), |
| 3193 details.type() == DATA_CONSTANT && store_mode == FORCE_FIELD, | 3203 details.type() == DATA_CONSTANT && store_mode == FORCE_FIELD, |
| 3194 details.representation(), Representation::Tagged(), field_type, | 3204 details.representation(), Representation::Tagged(), field_type, |
| 3195 MaybeHandle<Object>(), FieldType::Any(isolate), | 3205 MaybeHandle<Object>(), FieldType::Any(isolate), |
| 3196 MaybeHandle<Object>()); | 3206 MaybeHandle<Object>()); |
| 3197 } | 3207 } |
| 3198 } | 3208 } |
| 3209 new_map->set_elements_kind(elements_kind); |
| 3199 return new_map; | 3210 return new_map; |
| 3200 } | 3211 } |
| 3201 | 3212 |
| 3202 | 3213 |
| 3203 void Map::DeprecateTransitionTree() { | 3214 void Map::DeprecateTransitionTree() { |
| 3204 if (is_deprecated()) return; | 3215 if (is_deprecated()) return; |
| 3205 Object* transitions = raw_transitions(); | 3216 Object* transitions = raw_transitions(); |
| 3206 int num_transitions = TransitionArray::NumberOfTransitions(transitions); | 3217 int num_transitions = TransitionArray::NumberOfTransitions(transitions); |
| 3207 for (int i = 0; i < num_transitions; ++i) { | 3218 for (int i = 0; i < num_transitions; ++i) { |
| 3208 TransitionArray::GetTarget(transitions, i)->DeprecateTransitionTree(); | 3219 TransitionArray::GetTarget(transitions, i)->DeprecateTransitionTree(); |
| (...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3441 DCHECK_EQ(details.location(), location); | 3452 DCHECK_EQ(details.location(), location); |
| 3442 #endif | 3453 #endif |
| 3443 if (location == kField) { | 3454 if (location == kField) { |
| 3444 return handle(descriptors->GetFieldType(descriptor), isolate); | 3455 return handle(descriptors->GetFieldType(descriptor), isolate); |
| 3445 } else { | 3456 } else { |
| 3446 return descriptors->GetValue(descriptor) | 3457 return descriptors->GetValue(descriptor) |
| 3447 ->OptimalType(isolate, representation); | 3458 ->OptimalType(isolate, representation); |
| 3448 } | 3459 } |
| 3449 } | 3460 } |
| 3450 | 3461 |
| 3451 | 3462 // Reconfigures elements kind to |new_elements_kind| and/or property at |
| 3452 // Reconfigures property at |modify_index| with |new_kind|, |new_attributes|, | 3463 // |modify_index| with |new_kind|, |new_attributes|, |store_mode| and/or |
| 3453 // |store_mode| and/or |new_representation|/|new_field_type|. | 3464 // |new_representation|/|new_field_type|. |
| 3454 // If |modify_index| is negative then no properties are reconfigured but the | 3465 // If |modify_index| is negative then no properties are reconfigured but the |
| 3455 // map is migrated to the up-to-date non-deprecated state. | 3466 // map is migrated to the up-to-date non-deprecated state. |
| 3456 // | 3467 // |
| 3457 // This method rewrites or completes the transition tree to reflect the new | 3468 // This method rewrites or completes the transition tree to reflect the new |
| 3458 // change. To avoid high degrees over polymorphism, and to stabilize quickly, | 3469 // change. To avoid high degrees over polymorphism, and to stabilize quickly, |
| 3459 // on every rewrite the new type is deduced by merging the current type with | 3470 // on every rewrite the new type is deduced by merging the current type with |
| 3460 // any potential new (partial) version of the type in the transition tree. | 3471 // any potential new (partial) version of the type in the transition tree. |
| 3461 // To do this, on each rewrite: | 3472 // To do this, on each rewrite: |
| 3462 // - Search the root of the transition tree using FindRootMap. | 3473 // - Search the root of the transition tree using FindRootMap. |
| 3474 // - Find/create a |root_map| with requested |new_elements_kind|. |
| 3463 // - Find |target_map|, the newest matching version of this map using the | 3475 // - Find |target_map|, the newest matching version of this map using the |
| 3464 // virtually "enhanced" |old_map|'s descriptor array (i.e. whose entry at | 3476 // virtually "enhanced" |old_map|'s descriptor array (i.e. whose entry at |
| 3465 // |modify_index| is considered to be of |new_kind| and having | 3477 // |modify_index| is considered to be of |new_kind| and having |
| 3466 // |new_attributes|) to walk the transition tree. | 3478 // |new_attributes|) to walk the transition tree. |
| 3467 // - Merge/generalize the "enhanced" descriptor array of the |old_map| and | 3479 // - Merge/generalize the "enhanced" descriptor array of the |old_map| and |
| 3468 // descriptor array of the |target_map|. | 3480 // descriptor array of the |target_map|. |
| 3469 // - Generalize the |modify_index| descriptor using |new_representation| and | 3481 // - Generalize the |modify_index| descriptor using |new_representation| and |
| 3470 // |new_field_type|. | 3482 // |new_field_type|. |
| 3471 // - Walk the tree again starting from the root towards |target_map|. Stop at | 3483 // - Walk the tree again starting from the root towards |target_map|. Stop at |
| 3472 // |split_map|, the first map who's descriptor array does not match the merged | 3484 // |split_map|, the first map who's descriptor array does not match the merged |
| 3473 // descriptor array. | 3485 // descriptor array. |
| 3474 // - If |target_map| == |split_map|, |target_map| is in the expected state. | 3486 // - If |target_map| == |split_map|, |target_map| is in the expected state. |
| 3475 // Return it. | 3487 // Return it. |
| 3476 // - Otherwise, invalidate the outdated transition target from |target_map|, and | 3488 // - Otherwise, invalidate the outdated transition target from |target_map|, and |
| 3477 // replace its transition tree with a new branch for the updated descriptors. | 3489 // replace its transition tree with a new branch for the updated descriptors. |
| 3478 Handle<Map> Map::ReconfigureProperty(Handle<Map> old_map, int modify_index, | 3490 Handle<Map> Map::Reconfigure(Handle<Map> old_map, |
| 3479 PropertyKind new_kind, | 3491 ElementsKind new_elements_kind, int modify_index, |
| 3480 PropertyAttributes new_attributes, | 3492 PropertyKind new_kind, |
| 3481 Representation new_representation, | 3493 PropertyAttributes new_attributes, |
| 3482 Handle<FieldType> new_field_type, | 3494 Representation new_representation, |
| 3483 StoreMode store_mode) { | 3495 Handle<FieldType> new_field_type, |
| 3496 StoreMode store_mode) { |
| 3484 DCHECK_NE(kAccessor, new_kind); // TODO(ishell): not supported yet. | 3497 DCHECK_NE(kAccessor, new_kind); // TODO(ishell): not supported yet. |
| 3485 DCHECK(store_mode != FORCE_FIELD || modify_index >= 0); | 3498 DCHECK(store_mode != FORCE_FIELD || modify_index >= 0); |
| 3486 Isolate* isolate = old_map->GetIsolate(); | 3499 Isolate* isolate = old_map->GetIsolate(); |
| 3487 | 3500 |
| 3488 Handle<DescriptorArray> old_descriptors( | 3501 Handle<DescriptorArray> old_descriptors( |
| 3489 old_map->instance_descriptors(), isolate); | 3502 old_map->instance_descriptors(), isolate); |
| 3490 int old_nof = old_map->NumberOfOwnDescriptors(); | 3503 int old_nof = old_map->NumberOfOwnDescriptors(); |
| 3491 | 3504 |
| 3492 // If it's just a representation generalization case (i.e. property kind and | 3505 // If it's just a representation generalization case (i.e. property kind and |
| 3493 // attributes stays unchanged) it's fine to transition from None to anything | 3506 // attributes stays unchanged) it's fine to transition from None to anything |
| 3494 // but double without any modification to the object, because the default | 3507 // but double without any modification to the object, because the default |
| 3495 // uninitialized value for representation None can be overwritten by both | 3508 // uninitialized value for representation None can be overwritten by both |
| 3496 // smi and tagged values. Doubles, however, would require a box allocation. | 3509 // smi and tagged values. Doubles, however, would require a box allocation. |
| 3497 if (modify_index >= 0 && !new_representation.IsNone() && | 3510 if (modify_index >= 0 && !new_representation.IsNone() && |
| 3498 !new_representation.IsDouble()) { | 3511 !new_representation.IsDouble() && |
| 3512 old_map->elements_kind() == new_elements_kind) { |
| 3499 PropertyDetails old_details = old_descriptors->GetDetails(modify_index); | 3513 PropertyDetails old_details = old_descriptors->GetDetails(modify_index); |
| 3500 Representation old_representation = old_details.representation(); | 3514 Representation old_representation = old_details.representation(); |
| 3501 | 3515 |
| 3502 if (old_representation.IsNone()) { | 3516 if (old_representation.IsNone()) { |
| 3503 DCHECK_EQ(new_kind, old_details.kind()); | 3517 DCHECK_EQ(new_kind, old_details.kind()); |
| 3504 DCHECK_EQ(new_attributes, old_details.attributes()); | 3518 DCHECK_EQ(new_attributes, old_details.attributes()); |
| 3505 DCHECK_EQ(DATA, old_details.type()); | 3519 DCHECK_EQ(DATA, old_details.type()); |
| 3506 if (FLAG_trace_generalization) { | 3520 if (FLAG_trace_generalization) { |
| 3507 old_map->PrintGeneralization( | 3521 old_map->PrintGeneralization( |
| 3508 stdout, "uninitialized field", modify_index, | 3522 stdout, "uninitialized field", modify_index, |
| (...skipping 12 matching lines...) Expand all Loading... |
| 3521 .Equals(new_representation)); | 3535 .Equals(new_representation)); |
| 3522 DCHECK( | 3536 DCHECK( |
| 3523 old_descriptors->GetFieldType(modify_index)->NowIs(new_field_type)); | 3537 old_descriptors->GetFieldType(modify_index)->NowIs(new_field_type)); |
| 3524 return old_map; | 3538 return old_map; |
| 3525 } | 3539 } |
| 3526 } | 3540 } |
| 3527 | 3541 |
| 3528 // Check the state of the root map. | 3542 // Check the state of the root map. |
| 3529 Handle<Map> root_map(old_map->FindRootMap(), isolate); | 3543 Handle<Map> root_map(old_map->FindRootMap(), isolate); |
| 3530 if (!old_map->EquivalentToForTransition(*root_map)) { | 3544 if (!old_map->EquivalentToForTransition(*root_map)) { |
| 3531 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, | 3545 return CopyGeneralizeAllRepresentations( |
| 3532 new_kind, new_attributes, | 3546 old_map, new_elements_kind, modify_index, store_mode, new_kind, |
| 3533 "GenAll_NotEquivalent"); | 3547 new_attributes, "GenAll_NotEquivalent"); |
| 3534 } | 3548 } |
| 3535 | 3549 |
| 3536 ElementsKind from_kind = root_map->elements_kind(); | 3550 ElementsKind from_kind = root_map->elements_kind(); |
| 3537 ElementsKind to_kind = old_map->elements_kind(); | 3551 ElementsKind to_kind = new_elements_kind; |
| 3538 // TODO(ishell): Add a test for SLOW_SLOPPY_ARGUMENTS_ELEMENTS. | 3552 // TODO(ishell): Add a test for SLOW_SLOPPY_ARGUMENTS_ELEMENTS. |
| 3539 if (from_kind != to_kind && to_kind != DICTIONARY_ELEMENTS && | 3553 if (from_kind != to_kind && to_kind != DICTIONARY_ELEMENTS && |
| 3554 to_kind != SLOW_STRING_WRAPPER_ELEMENTS && |
| 3540 to_kind != SLOW_SLOPPY_ARGUMENTS_ELEMENTS && | 3555 to_kind != SLOW_SLOPPY_ARGUMENTS_ELEMENTS && |
| 3541 !(IsTransitionableFastElementsKind(from_kind) && | 3556 !(IsTransitionableFastElementsKind(from_kind) && |
| 3542 IsMoreGeneralElementsKindTransition(from_kind, to_kind))) { | 3557 IsMoreGeneralElementsKindTransition(from_kind, to_kind))) { |
| 3543 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, | 3558 return CopyGeneralizeAllRepresentations( |
| 3544 new_kind, new_attributes, | 3559 old_map, to_kind, modify_index, store_mode, new_kind, new_attributes, |
| 3545 "GenAll_InvalidElementsTransition"); | 3560 "GenAll_InvalidElementsTransition"); |
| 3546 } | 3561 } |
| 3547 int root_nof = root_map->NumberOfOwnDescriptors(); | 3562 int root_nof = root_map->NumberOfOwnDescriptors(); |
| 3548 if (modify_index >= 0 && modify_index < root_nof) { | 3563 if (modify_index >= 0 && modify_index < root_nof) { |
| 3549 PropertyDetails old_details = old_descriptors->GetDetails(modify_index); | 3564 PropertyDetails old_details = old_descriptors->GetDetails(modify_index); |
| 3550 if (old_details.kind() != new_kind || | 3565 if (old_details.kind() != new_kind || |
| 3551 old_details.attributes() != new_attributes) { | 3566 old_details.attributes() != new_attributes) { |
| 3552 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, | 3567 return CopyGeneralizeAllRepresentations( |
| 3553 new_kind, new_attributes, | 3568 old_map, to_kind, modify_index, store_mode, new_kind, new_attributes, |
| 3554 "GenAll_RootModification1"); | 3569 "GenAll_RootModification1"); |
| 3555 } | 3570 } |
| 3556 if ((old_details.type() != DATA && store_mode == FORCE_FIELD) || | 3571 if ((old_details.type() != DATA && store_mode == FORCE_FIELD) || |
| 3557 (old_details.type() == DATA && | 3572 (old_details.type() == DATA && |
| 3558 (!new_field_type->NowIs(old_descriptors->GetFieldType(modify_index)) || | 3573 (!new_field_type->NowIs(old_descriptors->GetFieldType(modify_index)) || |
| 3559 !new_representation.fits_into(old_details.representation())))) { | 3574 !new_representation.fits_into(old_details.representation())))) { |
| 3560 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, | 3575 return CopyGeneralizeAllRepresentations( |
| 3561 new_kind, new_attributes, | 3576 old_map, to_kind, modify_index, store_mode, new_kind, new_attributes, |
| 3562 "GenAll_RootModification2"); | 3577 "GenAll_RootModification2"); |
| 3563 } | 3578 } |
| 3564 } | 3579 } |
| 3565 | 3580 |
| 3566 // From here on, use the map with correct elements kind as root map. | 3581 // From here on, use the map with correct elements kind as root map. |
| 3567 if (from_kind != to_kind) { | 3582 if (from_kind != to_kind) { |
| 3568 root_map = Map::AsElementsKind(root_map, to_kind); | 3583 root_map = Map::AsElementsKind(root_map, to_kind); |
| 3569 } | 3584 } |
| 3570 | 3585 |
| 3571 Handle<Map> target_map = root_map; | 3586 Handle<Map> target_map = root_map; |
| 3572 for (int i = root_nof; i < old_nof; ++i) { | 3587 for (int i = root_nof; i < old_nof; ++i) { |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3606 Handle<DescriptorArray> tmp_descriptors = handle( | 3621 Handle<DescriptorArray> tmp_descriptors = handle( |
| 3607 tmp_map->instance_descriptors(), isolate); | 3622 tmp_map->instance_descriptors(), isolate); |
| 3608 | 3623 |
| 3609 // Check if target map is incompatible. | 3624 // Check if target map is incompatible. |
| 3610 PropertyDetails tmp_details = tmp_descriptors->GetDetails(i); | 3625 PropertyDetails tmp_details = tmp_descriptors->GetDetails(i); |
| 3611 DCHECK_EQ(next_kind, tmp_details.kind()); | 3626 DCHECK_EQ(next_kind, tmp_details.kind()); |
| 3612 DCHECK_EQ(next_attributes, tmp_details.attributes()); | 3627 DCHECK_EQ(next_attributes, tmp_details.attributes()); |
| 3613 if (next_kind == kAccessor && | 3628 if (next_kind == kAccessor && |
| 3614 !EqualImmutableValues(old_descriptors->GetValue(i), | 3629 !EqualImmutableValues(old_descriptors->GetValue(i), |
| 3615 tmp_descriptors->GetValue(i))) { | 3630 tmp_descriptors->GetValue(i))) { |
| 3616 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, | 3631 return CopyGeneralizeAllRepresentations( |
| 3617 new_kind, new_attributes, | 3632 old_map, to_kind, modify_index, store_mode, new_kind, new_attributes, |
| 3618 "GenAll_Incompatible"); | 3633 "GenAll_Incompatible"); |
| 3619 } | 3634 } |
| 3620 if (next_location == kField && tmp_details.location() == kDescriptor) break; | 3635 if (next_location == kField && tmp_details.location() == kDescriptor) break; |
| 3621 | 3636 |
| 3622 Representation tmp_representation = tmp_details.representation(); | 3637 Representation tmp_representation = tmp_details.representation(); |
| 3623 if (!next_representation.fits_into(tmp_representation)) break; | 3638 if (!next_representation.fits_into(tmp_representation)) break; |
| 3624 | 3639 |
| 3625 PropertyLocation old_location = old_details.location(); | 3640 PropertyLocation old_location = old_details.location(); |
| 3626 PropertyLocation tmp_location = tmp_details.location(); | 3641 PropertyLocation tmp_location = tmp_details.location(); |
| 3627 if (tmp_location == kField) { | 3642 if (tmp_location == kField) { |
| 3628 if (next_kind == kData) { | 3643 if (next_kind == kData) { |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3701 | 3716 |
| 3702 // Check if target map is compatible. | 3717 // Check if target map is compatible. |
| 3703 #ifdef DEBUG | 3718 #ifdef DEBUG |
| 3704 PropertyDetails tmp_details = tmp_descriptors->GetDetails(i); | 3719 PropertyDetails tmp_details = tmp_descriptors->GetDetails(i); |
| 3705 DCHECK_EQ(next_kind, tmp_details.kind()); | 3720 DCHECK_EQ(next_kind, tmp_details.kind()); |
| 3706 DCHECK_EQ(next_attributes, tmp_details.attributes()); | 3721 DCHECK_EQ(next_attributes, tmp_details.attributes()); |
| 3707 #endif | 3722 #endif |
| 3708 if (next_kind == kAccessor && | 3723 if (next_kind == kAccessor && |
| 3709 !EqualImmutableValues(old_descriptors->GetValue(i), | 3724 !EqualImmutableValues(old_descriptors->GetValue(i), |
| 3710 tmp_descriptors->GetValue(i))) { | 3725 tmp_descriptors->GetValue(i))) { |
| 3711 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, | 3726 return CopyGeneralizeAllRepresentations( |
| 3712 new_kind, new_attributes, | 3727 old_map, to_kind, modify_index, store_mode, new_kind, new_attributes, |
| 3713 "GenAll_Incompatible"); | 3728 "GenAll_Incompatible"); |
| 3714 } | 3729 } |
| 3715 DCHECK(!tmp_map->is_deprecated()); | 3730 DCHECK(!tmp_map->is_deprecated()); |
| 3716 target_map = tmp_map; | 3731 target_map = tmp_map; |
| 3717 } | 3732 } |
| 3718 target_nof = target_map->NumberOfOwnDescriptors(); | 3733 target_nof = target_map->NumberOfOwnDescriptors(); |
| 3719 target_descriptors = handle(target_map->instance_descriptors(), isolate); | 3734 target_descriptors = handle(target_map->instance_descriptors(), isolate); |
| 3720 | 3735 |
| 3721 // Allocate a new descriptor array large enough to hold the required | 3736 // Allocate a new descriptor array large enough to hold the required |
| 3722 // descriptors, with minimally the exact same size as the old descriptor | 3737 // descriptors, with minimally the exact same size as the old descriptor |
| 3723 // array. | 3738 // array. |
| (...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3934 split_attributes); | 3949 split_attributes); |
| 3935 if (maybe_transition != NULL) { | 3950 if (maybe_transition != NULL) { |
| 3936 maybe_transition->DeprecateTransitionTree(); | 3951 maybe_transition->DeprecateTransitionTree(); |
| 3937 } | 3952 } |
| 3938 | 3953 |
| 3939 // If |maybe_transition| is not NULL then the transition array already | 3954 // If |maybe_transition| is not NULL then the transition array already |
| 3940 // contains entry for given descriptor. This means that the transition | 3955 // contains entry for given descriptor. This means that the transition |
| 3941 // could be inserted regardless of whether transitions array is full or not. | 3956 // could be inserted regardless of whether transitions array is full or not. |
| 3942 if (maybe_transition == NULL && | 3957 if (maybe_transition == NULL && |
| 3943 !TransitionArray::CanHaveMoreTransitions(split_map)) { | 3958 !TransitionArray::CanHaveMoreTransitions(split_map)) { |
| 3944 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, | 3959 return CopyGeneralizeAllRepresentations( |
| 3945 new_kind, new_attributes, | 3960 old_map, to_kind, modify_index, store_mode, new_kind, new_attributes, |
| 3946 "GenAll_CantHaveMoreTransitions"); | 3961 "GenAll_CantHaveMoreTransitions"); |
| 3947 } | 3962 } |
| 3948 | 3963 |
| 3949 old_map->NotifyLeafMapLayoutChange(); | 3964 old_map->NotifyLeafMapLayoutChange(); |
| 3950 | 3965 |
| 3951 if (FLAG_trace_generalization && modify_index >= 0) { | 3966 if (FLAG_trace_generalization && modify_index >= 0) { |
| 3952 PropertyDetails old_details = old_descriptors->GetDetails(modify_index); | 3967 PropertyDetails old_details = old_descriptors->GetDetails(modify_index); |
| 3953 PropertyDetails new_details = new_descriptors->GetDetails(modify_index); | 3968 PropertyDetails new_details = new_descriptors->GetDetails(modify_index); |
| 3954 MaybeHandle<FieldType> old_field_type; | 3969 MaybeHandle<FieldType> old_field_type; |
| 3955 MaybeHandle<FieldType> new_field_type; | 3970 MaybeHandle<FieldType> new_field_type; |
| 3956 MaybeHandle<Object> old_value; | 3971 MaybeHandle<Object> old_value; |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4017 if (!old_map->EquivalentToForTransition(root_map)) return MaybeHandle<Map>(); | 4032 if (!old_map->EquivalentToForTransition(root_map)) return MaybeHandle<Map>(); |
| 4018 | 4033 |
| 4019 ElementsKind from_kind = root_map->elements_kind(); | 4034 ElementsKind from_kind = root_map->elements_kind(); |
| 4020 ElementsKind to_kind = old_map->elements_kind(); | 4035 ElementsKind to_kind = old_map->elements_kind(); |
| 4021 if (from_kind != to_kind) { | 4036 if (from_kind != to_kind) { |
| 4022 // Try to follow existing elements kind transitions. | 4037 // Try to follow existing elements kind transitions. |
| 4023 root_map = root_map->LookupElementsTransitionMap(to_kind); | 4038 root_map = root_map->LookupElementsTransitionMap(to_kind); |
| 4024 if (root_map == NULL) return MaybeHandle<Map>(); | 4039 if (root_map == NULL) return MaybeHandle<Map>(); |
| 4025 // From here on, use the map with correct elements kind as root map. | 4040 // From here on, use the map with correct elements kind as root map. |
| 4026 } | 4041 } |
| 4027 int root_nof = root_map->NumberOfOwnDescriptors(); | 4042 Map* new_map = root_map->TryReplayPropertyTransitions(*old_map); |
| 4043 if (new_map == nullptr) return MaybeHandle<Map>(); |
| 4044 return handle(new_map); |
| 4045 } |
| 4046 |
| 4047 Map* Map::TryReplayPropertyTransitions(Map* old_map) { |
| 4048 DisallowHeapAllocation no_allocation; |
| 4049 DisallowDeoptimization no_deoptimization(GetIsolate()); |
| 4050 |
| 4051 int root_nof = NumberOfOwnDescriptors(); |
| 4028 | 4052 |
| 4029 int old_nof = old_map->NumberOfOwnDescriptors(); | 4053 int old_nof = old_map->NumberOfOwnDescriptors(); |
| 4030 DescriptorArray* old_descriptors = old_map->instance_descriptors(); | 4054 DescriptorArray* old_descriptors = old_map->instance_descriptors(); |
| 4031 | 4055 |
| 4032 Map* new_map = root_map; | 4056 Map* new_map = this; |
| 4033 for (int i = root_nof; i < old_nof; ++i) { | 4057 for (int i = root_nof; i < old_nof; ++i) { |
| 4034 PropertyDetails old_details = old_descriptors->GetDetails(i); | 4058 PropertyDetails old_details = old_descriptors->GetDetails(i); |
| 4035 Map* transition = TransitionArray::SearchTransition( | 4059 Map* transition = TransitionArray::SearchTransition( |
| 4036 new_map, old_details.kind(), old_descriptors->GetKey(i), | 4060 new_map, old_details.kind(), old_descriptors->GetKey(i), |
| 4037 old_details.attributes()); | 4061 old_details.attributes()); |
| 4038 if (transition == NULL) return MaybeHandle<Map>(); | 4062 if (transition == NULL) return nullptr; |
| 4039 new_map = transition; | 4063 new_map = transition; |
| 4040 DescriptorArray* new_descriptors = new_map->instance_descriptors(); | 4064 DescriptorArray* new_descriptors = new_map->instance_descriptors(); |
| 4041 | 4065 |
| 4042 PropertyDetails new_details = new_descriptors->GetDetails(i); | 4066 PropertyDetails new_details = new_descriptors->GetDetails(i); |
| 4043 DCHECK_EQ(old_details.kind(), new_details.kind()); | 4067 DCHECK_EQ(old_details.kind(), new_details.kind()); |
| 4044 DCHECK_EQ(old_details.attributes(), new_details.attributes()); | 4068 DCHECK_EQ(old_details.attributes(), new_details.attributes()); |
| 4045 if (!old_details.representation().fits_into(new_details.representation())) { | 4069 if (!old_details.representation().fits_into(new_details.representation())) { |
| 4046 return MaybeHandle<Map>(); | 4070 return nullptr; |
| 4047 } | 4071 } |
| 4048 switch (new_details.type()) { | 4072 switch (new_details.type()) { |
| 4049 case DATA: { | 4073 case DATA: { |
| 4050 FieldType* new_type = new_descriptors->GetFieldType(i); | 4074 FieldType* new_type = new_descriptors->GetFieldType(i); |
| 4051 // Cleared field types need special treatment. They represent lost | 4075 // Cleared field types need special treatment. They represent lost |
| 4052 // knowledge, so we must first generalize the new_type to "Any". | 4076 // knowledge, so we must first generalize the new_type to "Any". |
| 4053 if (FieldTypeIsCleared(new_details.representation(), new_type)) { | 4077 if (FieldTypeIsCleared(new_details.representation(), new_type)) { |
| 4054 return MaybeHandle<Map>(); | 4078 return nullptr; |
| 4055 } | 4079 } |
| 4056 PropertyType old_property_type = old_details.type(); | 4080 PropertyType old_property_type = old_details.type(); |
| 4057 if (old_property_type == DATA) { | 4081 if (old_property_type == DATA) { |
| 4058 FieldType* old_type = old_descriptors->GetFieldType(i); | 4082 FieldType* old_type = old_descriptors->GetFieldType(i); |
| 4059 if (FieldTypeIsCleared(old_details.representation(), old_type) || | 4083 if (FieldTypeIsCleared(old_details.representation(), old_type) || |
| 4060 !old_type->NowIs(new_type)) { | 4084 !old_type->NowIs(new_type)) { |
| 4061 return MaybeHandle<Map>(); | 4085 return nullptr; |
| 4062 } | 4086 } |
| 4063 } else { | 4087 } else { |
| 4064 DCHECK(old_property_type == DATA_CONSTANT); | 4088 DCHECK(old_property_type == DATA_CONSTANT); |
| 4065 Object* old_value = old_descriptors->GetValue(i); | 4089 Object* old_value = old_descriptors->GetValue(i); |
| 4066 if (!new_type->NowContains(old_value)) { | 4090 if (!new_type->NowContains(old_value)) { |
| 4067 return MaybeHandle<Map>(); | 4091 return nullptr; |
| 4068 } | 4092 } |
| 4069 } | 4093 } |
| 4070 break; | 4094 break; |
| 4071 } | 4095 } |
| 4072 case ACCESSOR: { | 4096 case ACCESSOR: { |
| 4073 #ifdef DEBUG | 4097 #ifdef DEBUG |
| 4074 FieldType* new_type = new_descriptors->GetFieldType(i); | 4098 FieldType* new_type = new_descriptors->GetFieldType(i); |
| 4075 DCHECK(new_type->IsAny()); | 4099 DCHECK(new_type->IsAny()); |
| 4076 #endif | 4100 #endif |
| 4077 break; | 4101 break; |
| 4078 } | 4102 } |
| 4079 | 4103 |
| 4080 case DATA_CONSTANT: | 4104 case DATA_CONSTANT: |
| 4081 case ACCESSOR_CONSTANT: { | 4105 case ACCESSOR_CONSTANT: { |
| 4082 Object* old_value = old_descriptors->GetValue(i); | 4106 Object* old_value = old_descriptors->GetValue(i); |
| 4083 Object* new_value = new_descriptors->GetValue(i); | 4107 Object* new_value = new_descriptors->GetValue(i); |
| 4084 if (old_details.location() == kField || old_value != new_value) { | 4108 if (old_details.location() == kField || old_value != new_value) { |
| 4085 return MaybeHandle<Map>(); | 4109 return nullptr; |
| 4086 } | 4110 } |
| 4087 break; | 4111 break; |
| 4088 } | 4112 } |
| 4089 } | 4113 } |
| 4090 } | 4114 } |
| 4091 if (new_map->NumberOfOwnDescriptors() != old_nof) return MaybeHandle<Map>(); | 4115 if (new_map->NumberOfOwnDescriptors() != old_nof) return nullptr; |
| 4092 return handle(new_map); | 4116 return new_map; |
| 4093 } | 4117 } |
| 4094 | 4118 |
| 4095 | 4119 |
| 4096 // static | 4120 // static |
| 4097 Handle<Map> Map::Update(Handle<Map> map) { | 4121 Handle<Map> Map::Update(Handle<Map> map) { |
| 4098 if (!map->is_deprecated()) return map; | 4122 if (!map->is_deprecated()) return map; |
| 4099 return ReconfigureProperty(map, -1, kData, NONE, Representation::None(), | 4123 return ReconfigureProperty(map, -1, kData, NONE, Representation::None(), |
| 4100 FieldType::None(map->GetIsolate()), | 4124 FieldType::None(map->GetIsolate()), |
| 4101 ALLOW_IN_DESCRIPTOR); | 4125 ALLOW_IN_DESCRIPTOR); |
| 4102 } | 4126 } |
| (...skipping 635 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4738 | 4762 |
| 4739 | 4763 |
| 4740 static bool ContainsMap(MapHandleList* maps, Map* map) { | 4764 static bool ContainsMap(MapHandleList* maps, Map* map) { |
| 4741 DCHECK_NOT_NULL(map); | 4765 DCHECK_NOT_NULL(map); |
| 4742 for (int i = 0; i < maps->length(); ++i) { | 4766 for (int i = 0; i < maps->length(); ++i) { |
| 4743 if (!maps->at(i).is_null() && *maps->at(i) == map) return true; | 4767 if (!maps->at(i).is_null() && *maps->at(i) == map) return true; |
| 4744 } | 4768 } |
| 4745 return false; | 4769 return false; |
| 4746 } | 4770 } |
| 4747 | 4771 |
| 4772 Map* Map::FindElementsKindTransitionedMap(MapHandleList* candidates) { |
| 4773 DisallowHeapAllocation no_allocation; |
| 4774 DisallowDeoptimization no_deoptimization(GetIsolate()); |
| 4748 | 4775 |
| 4749 Handle<Map> Map::FindTransitionedMap(Handle<Map> map, | 4776 ElementsKind kind = elements_kind(); |
| 4750 MapHandleList* candidates) { | |
| 4751 ElementsKind kind = map->elements_kind(); | |
| 4752 bool packed = IsFastPackedElementsKind(kind); | 4777 bool packed = IsFastPackedElementsKind(kind); |
| 4753 | 4778 |
| 4754 Map* transition = nullptr; | 4779 Map* transition = nullptr; |
| 4755 if (IsTransitionableFastElementsKind(kind)) { | 4780 if (IsTransitionableFastElementsKind(kind)) { |
| 4756 for (Map* current = map->ElementsTransitionMap(); | 4781 // Check the state of the root map. |
| 4757 current != nullptr && current->has_fast_elements(); | 4782 Map* root_map = FindRootMap(); |
| 4758 current = current->ElementsTransitionMap()) { | 4783 if (!EquivalentToForTransition(root_map)) return nullptr; |
| 4784 root_map = root_map->LookupElementsTransitionMap(kind); |
| 4785 DCHECK_NOT_NULL(root_map); |
| 4786 // Starting from the next existing elements kind transition try to |
| 4787 // replay the property transitions that does not involve instance rewriting |
| 4788 // (ElementsTransitionAndStoreStub does not support that). |
| 4789 for (root_map = root_map->ElementsTransitionMap(); |
| 4790 root_map != nullptr && root_map->has_fast_elements(); |
| 4791 root_map = root_map->ElementsTransitionMap()) { |
| 4792 Map* current = root_map->TryReplayPropertyTransitions(this); |
| 4793 if (current == nullptr) continue; |
| 4794 if (InstancesNeedRewriting(current)) continue; |
| 4795 |
| 4759 if (ContainsMap(candidates, current) && | 4796 if (ContainsMap(candidates, current) && |
| 4760 (packed || !IsFastPackedElementsKind(current->elements_kind()))) { | 4797 (packed || !IsFastPackedElementsKind(current->elements_kind()))) { |
| 4761 transition = current; | 4798 transition = current; |
| 4762 packed = packed && IsFastPackedElementsKind(current->elements_kind()); | 4799 packed = packed && IsFastPackedElementsKind(current->elements_kind()); |
| 4763 } | 4800 } |
| 4764 } | 4801 } |
| 4765 } | 4802 } |
| 4766 return transition == nullptr ? Handle<Map>() : handle(transition); | 4803 return transition; |
| 4767 } | 4804 } |
| 4768 | 4805 |
| 4769 | 4806 |
| 4770 static Map* FindClosestElementsTransition(Map* map, ElementsKind to_kind) { | 4807 static Map* FindClosestElementsTransition(Map* map, ElementsKind to_kind) { |
| 4808 // Ensure we are requested to search elements kind transition "near the root". |
| 4809 DCHECK_EQ(map->FindRootMap()->NumberOfOwnDescriptors(), |
| 4810 map->NumberOfOwnDescriptors()); |
| 4771 Map* current_map = map; | 4811 Map* current_map = map; |
| 4772 | 4812 |
| 4773 ElementsKind kind = map->elements_kind(); | 4813 ElementsKind kind = map->elements_kind(); |
| 4774 while (kind != to_kind) { | 4814 while (kind != to_kind) { |
| 4775 Map* next_map = current_map->ElementsTransitionMap(); | 4815 Map* next_map = current_map->ElementsTransitionMap(); |
| 4776 if (next_map == nullptr) return current_map; | 4816 if (next_map == nullptr) return current_map; |
| 4777 kind = next_map->elements_kind(); | 4817 kind = next_map->elements_kind(); |
| 4778 current_map = next_map; | 4818 current_map = next_map; |
| 4779 } | 4819 } |
| 4780 | 4820 |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4889 if (IsFastElementsKind(to_kind)) { | 4929 if (IsFastElementsKind(to_kind)) { |
| 4890 allow_store_transition = | 4930 allow_store_transition = |
| 4891 allow_store_transition && IsTransitionableFastElementsKind(from_kind) && | 4931 allow_store_transition && IsTransitionableFastElementsKind(from_kind) && |
| 4892 IsMoreGeneralElementsKindTransition(from_kind, to_kind); | 4932 IsMoreGeneralElementsKindTransition(from_kind, to_kind); |
| 4893 } | 4933 } |
| 4894 | 4934 |
| 4895 if (!allow_store_transition) { | 4935 if (!allow_store_transition) { |
| 4896 return Map::CopyAsElementsKind(map, to_kind, OMIT_TRANSITION); | 4936 return Map::CopyAsElementsKind(map, to_kind, OMIT_TRANSITION); |
| 4897 } | 4937 } |
| 4898 | 4938 |
| 4899 return Map::AsElementsKind(map, to_kind); | 4939 return Map::ReconfigureElementsKind(map, to_kind); |
| 4900 } | 4940 } |
| 4901 | 4941 |
| 4902 | 4942 |
| 4903 // static | 4943 // static |
| 4904 Handle<Map> Map::AsElementsKind(Handle<Map> map, ElementsKind kind) { | 4944 Handle<Map> Map::AsElementsKind(Handle<Map> map, ElementsKind kind) { |
| 4905 Handle<Map> closest_map(FindClosestElementsTransition(*map, kind)); | 4945 Handle<Map> closest_map(FindClosestElementsTransition(*map, kind)); |
| 4906 | 4946 |
| 4907 if (closest_map->elements_kind() == kind) { | 4947 if (closest_map->elements_kind() == kind) { |
| 4908 return closest_map; | 4948 return closest_map; |
| 4909 } | 4949 } |
| (...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5213 if (map_kind != obj_kind) { | 5253 if (map_kind != obj_kind) { |
| 5214 ElementsKind to_kind = GetMoreGeneralElementsKind(map_kind, obj_kind); | 5254 ElementsKind to_kind = GetMoreGeneralElementsKind(map_kind, obj_kind); |
| 5215 if (IsDictionaryElementsKind(obj_kind)) { | 5255 if (IsDictionaryElementsKind(obj_kind)) { |
| 5216 to_kind = obj_kind; | 5256 to_kind = obj_kind; |
| 5217 } | 5257 } |
| 5218 if (IsDictionaryElementsKind(to_kind)) { | 5258 if (IsDictionaryElementsKind(to_kind)) { |
| 5219 NormalizeElements(object); | 5259 NormalizeElements(object); |
| 5220 } else { | 5260 } else { |
| 5221 TransitionElementsKind(object, to_kind); | 5261 TransitionElementsKind(object, to_kind); |
| 5222 } | 5262 } |
| 5223 map = Map::AsElementsKind(map, to_kind); | 5263 map = Map::ReconfigureElementsKind(map, to_kind); |
| 5224 } | 5264 } |
| 5225 JSObject::MigrateToMap(object, map); | 5265 JSObject::MigrateToMap(object, map); |
| 5226 } | 5266 } |
| 5227 | 5267 |
| 5228 | 5268 |
| 5229 void JSObject::MigrateInstance(Handle<JSObject> object) { | 5269 void JSObject::MigrateInstance(Handle<JSObject> object) { |
| 5230 Handle<Map> original_map(object->map()); | 5270 Handle<Map> original_map(object->map()); |
| 5231 Handle<Map> map = Map::Update(original_map); | 5271 Handle<Map> map = Map::Update(original_map); |
| 5232 map->set_migration_target(true); | 5272 map->set_migration_target(true); |
| 5233 MigrateToMap(object, map); | 5273 MigrateToMap(object, map); |
| (...skipping 4321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9555 | 9595 |
| 9556 Handle<Name> name = handle(descriptors->GetKey(new_descriptor)); | 9596 Handle<Name> name = handle(descriptors->GetKey(new_descriptor)); |
| 9557 ConnectTransition(parent, child, name, SIMPLE_PROPERTY_TRANSITION); | 9597 ConnectTransition(parent, child, name, SIMPLE_PROPERTY_TRANSITION); |
| 9558 } | 9598 } |
| 9559 | 9599 |
| 9560 | 9600 |
| 9561 Handle<Map> Map::CopyAsElementsKind(Handle<Map> map, ElementsKind kind, | 9601 Handle<Map> Map::CopyAsElementsKind(Handle<Map> map, ElementsKind kind, |
| 9562 TransitionFlag flag) { | 9602 TransitionFlag flag) { |
| 9563 Map* maybe_elements_transition_map = NULL; | 9603 Map* maybe_elements_transition_map = NULL; |
| 9564 if (flag == INSERT_TRANSITION) { | 9604 if (flag == INSERT_TRANSITION) { |
| 9605 // Ensure we are requested to add elements kind transition "near the root". |
| 9606 DCHECK_EQ(map->FindRootMap()->NumberOfOwnDescriptors(), |
| 9607 map->NumberOfOwnDescriptors()); |
| 9608 |
| 9565 maybe_elements_transition_map = map->ElementsTransitionMap(); | 9609 maybe_elements_transition_map = map->ElementsTransitionMap(); |
| 9566 DCHECK(maybe_elements_transition_map == NULL || | 9610 DCHECK(maybe_elements_transition_map == NULL || |
| 9567 (maybe_elements_transition_map->elements_kind() == | 9611 (maybe_elements_transition_map->elements_kind() == |
| 9568 DICTIONARY_ELEMENTS && | 9612 DICTIONARY_ELEMENTS && |
| 9569 kind == DICTIONARY_ELEMENTS)); | 9613 kind == DICTIONARY_ELEMENTS)); |
| 9570 DCHECK(!IsFastElementsKind(kind) || | 9614 DCHECK(!IsFastElementsKind(kind) || |
| 9571 IsMoreGeneralElementsKindTransition(map->elements_kind(), kind)); | 9615 IsMoreGeneralElementsKindTransition(map->elements_kind(), kind)); |
| 9572 DCHECK(kind != map->elements_kind()); | 9616 DCHECK(kind != map->elements_kind()); |
| 9573 } | 9617 } |
| 9574 | 9618 |
| (...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9878 Handle<Map> Map::ReconfigureExistingProperty(Handle<Map> map, int descriptor, | 9922 Handle<Map> Map::ReconfigureExistingProperty(Handle<Map> map, int descriptor, |
| 9879 PropertyKind kind, | 9923 PropertyKind kind, |
| 9880 PropertyAttributes attributes) { | 9924 PropertyAttributes attributes) { |
| 9881 // Dictionaries have to be reconfigured in-place. | 9925 // Dictionaries have to be reconfigured in-place. |
| 9882 DCHECK(!map->is_dictionary_map()); | 9926 DCHECK(!map->is_dictionary_map()); |
| 9883 | 9927 |
| 9884 if (!map->GetBackPointer()->IsMap()) { | 9928 if (!map->GetBackPointer()->IsMap()) { |
| 9885 // There is no benefit from reconstructing transition tree for maps without | 9929 // There is no benefit from reconstructing transition tree for maps without |
| 9886 // back pointers. | 9930 // back pointers. |
| 9887 return CopyGeneralizeAllRepresentations( | 9931 return CopyGeneralizeAllRepresentations( |
| 9888 map, descriptor, FORCE_FIELD, kind, attributes, | 9932 map, map->elements_kind(), descriptor, FORCE_FIELD, kind, attributes, |
| 9889 "GenAll_AttributesMismatchProtoMap"); | 9933 "GenAll_AttributesMismatchProtoMap"); |
| 9890 } | 9934 } |
| 9891 | 9935 |
| 9892 if (FLAG_trace_generalization) { | 9936 if (FLAG_trace_generalization) { |
| 9893 map->PrintReconfiguration(stdout, descriptor, kind, attributes); | 9937 map->PrintReconfiguration(stdout, descriptor, kind, attributes); |
| 9894 } | 9938 } |
| 9895 | 9939 |
| 9896 Isolate* isolate = map->GetIsolate(); | 9940 Isolate* isolate = map->GetIsolate(); |
| 9897 Handle<Map> new_map = ReconfigureProperty( | 9941 Handle<Map> new_map = ReconfigureProperty( |
| 9898 map, descriptor, kind, attributes, Representation::None(), | 9942 map, descriptor, kind, attributes, Representation::None(), |
| (...skipping 9952 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 19851 if (cell->value() != *new_value) { | 19895 if (cell->value() != *new_value) { |
| 19852 cell->set_value(*new_value); | 19896 cell->set_value(*new_value); |
| 19853 Isolate* isolate = cell->GetIsolate(); | 19897 Isolate* isolate = cell->GetIsolate(); |
| 19854 cell->dependent_code()->DeoptimizeDependentCodeGroup( | 19898 cell->dependent_code()->DeoptimizeDependentCodeGroup( |
| 19855 isolate, DependentCode::kPropertyCellChangedGroup); | 19899 isolate, DependentCode::kPropertyCellChangedGroup); |
| 19856 } | 19900 } |
| 19857 } | 19901 } |
| 19858 | 19902 |
| 19859 } // namespace internal | 19903 } // namespace internal |
| 19860 } // namespace v8 | 19904 } // namespace v8 |
| OLD | NEW |