| 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 3198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3209 | 3209 |
| 3210 int Map::NumberOfFields() { | 3210 int Map::NumberOfFields() { |
| 3211 DescriptorArray* descriptors = instance_descriptors(); | 3211 DescriptorArray* descriptors = instance_descriptors(); |
| 3212 int result = 0; | 3212 int result = 0; |
| 3213 for (int i = 0; i < NumberOfOwnDescriptors(); i++) { | 3213 for (int i = 0; i < NumberOfOwnDescriptors(); i++) { |
| 3214 if (descriptors->GetDetails(i).location() == kField) result++; | 3214 if (descriptors->GetDetails(i).location() == kField) result++; |
| 3215 } | 3215 } |
| 3216 return result; | 3216 return result; |
| 3217 } | 3217 } |
| 3218 | 3218 |
| 3219 | |
| 3220 Handle<Map> Map::CopyGeneralizeAllRepresentations( | 3219 Handle<Map> Map::CopyGeneralizeAllRepresentations( |
| 3221 Handle<Map> map, int modify_index, StoreMode store_mode, PropertyKind kind, | 3220 Handle<Map> map, ElementsKind elements_kind, int modify_index, |
| 3222 PropertyAttributes attributes, const char* reason) { | 3221 StoreMode store_mode, PropertyKind kind, PropertyAttributes attributes, |
| 3222 const char* reason) { |
| 3223 Isolate* isolate = map->GetIsolate(); | 3223 Isolate* isolate = map->GetIsolate(); |
| 3224 Handle<DescriptorArray> old_descriptors(map->instance_descriptors(), isolate); | 3224 Handle<DescriptorArray> old_descriptors(map->instance_descriptors(), isolate); |
| 3225 int number_of_own_descriptors = map->NumberOfOwnDescriptors(); | 3225 int number_of_own_descriptors = map->NumberOfOwnDescriptors(); |
| 3226 Handle<DescriptorArray> descriptors = | 3226 Handle<DescriptorArray> descriptors = |
| 3227 DescriptorArray::CopyUpTo(old_descriptors, number_of_own_descriptors); | 3227 DescriptorArray::CopyUpTo(old_descriptors, number_of_own_descriptors); |
| 3228 | 3228 |
| 3229 for (int i = 0; i < number_of_own_descriptors; i++) { | 3229 for (int i = 0; i < number_of_own_descriptors; i++) { |
| 3230 descriptors->SetRepresentation(i, Representation::Tagged()); | 3230 descriptors->SetRepresentation(i, Representation::Tagged()); |
| 3231 if (descriptors->GetDetails(i).type() == DATA) { | 3231 if (descriptors->GetDetails(i).type() == DATA) { |
| 3232 descriptors->SetValue(i, FieldType::Any()); | 3232 descriptors->SetValue(i, FieldType::Any()); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3268 } | 3268 } |
| 3269 map->PrintGeneralization( | 3269 map->PrintGeneralization( |
| 3270 stdout, reason, modify_index, new_map->NumberOfOwnDescriptors(), | 3270 stdout, reason, modify_index, new_map->NumberOfOwnDescriptors(), |
| 3271 new_map->NumberOfOwnDescriptors(), | 3271 new_map->NumberOfOwnDescriptors(), |
| 3272 details.type() == DATA_CONSTANT && store_mode == FORCE_FIELD, | 3272 details.type() == DATA_CONSTANT && store_mode == FORCE_FIELD, |
| 3273 details.representation(), Representation::Tagged(), field_type, | 3273 details.representation(), Representation::Tagged(), field_type, |
| 3274 MaybeHandle<Object>(), FieldType::Any(isolate), | 3274 MaybeHandle<Object>(), FieldType::Any(isolate), |
| 3275 MaybeHandle<Object>()); | 3275 MaybeHandle<Object>()); |
| 3276 } | 3276 } |
| 3277 } | 3277 } |
| 3278 new_map->set_elements_kind(elements_kind); |
| 3278 return new_map; | 3279 return new_map; |
| 3279 } | 3280 } |
| 3280 | 3281 |
| 3281 | 3282 |
| 3282 void Map::DeprecateTransitionTree() { | 3283 void Map::DeprecateTransitionTree() { |
| 3283 if (is_deprecated()) return; | 3284 if (is_deprecated()) return; |
| 3284 Object* transitions = raw_transitions(); | 3285 Object* transitions = raw_transitions(); |
| 3285 int num_transitions = TransitionArray::NumberOfTransitions(transitions); | 3286 int num_transitions = TransitionArray::NumberOfTransitions(transitions); |
| 3286 for (int i = 0; i < num_transitions; ++i) { | 3287 for (int i = 0; i < num_transitions; ++i) { |
| 3287 TransitionArray::GetTarget(transitions, i)->DeprecateTransitionTree(); | 3288 TransitionArray::GetTarget(transitions, i)->DeprecateTransitionTree(); |
| (...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3520 DCHECK_EQ(details.location(), location); | 3521 DCHECK_EQ(details.location(), location); |
| 3521 #endif | 3522 #endif |
| 3522 if (location == kField) { | 3523 if (location == kField) { |
| 3523 return handle(descriptors->GetFieldType(descriptor), isolate); | 3524 return handle(descriptors->GetFieldType(descriptor), isolate); |
| 3524 } else { | 3525 } else { |
| 3525 return descriptors->GetValue(descriptor) | 3526 return descriptors->GetValue(descriptor) |
| 3526 ->OptimalType(isolate, representation); | 3527 ->OptimalType(isolate, representation); |
| 3527 } | 3528 } |
| 3528 } | 3529 } |
| 3529 | 3530 |
| 3530 | 3531 // Reconfigures elements kind to |new_elements_kind| and/or property at |
| 3531 // Reconfigures property at |modify_index| with |new_kind|, |new_attributes|, | 3532 // |modify_index| with |new_kind|, |new_attributes|, |store_mode| and/or |
| 3532 // |store_mode| and/or |new_representation|/|new_field_type|. | 3533 // |new_representation|/|new_field_type|. |
| 3533 // If |modify_index| is negative then no properties are reconfigured but the | 3534 // If |modify_index| is negative then no properties are reconfigured but the |
| 3534 // map is migrated to the up-to-date non-deprecated state. | 3535 // map is migrated to the up-to-date non-deprecated state. |
| 3535 // | 3536 // |
| 3536 // This method rewrites or completes the transition tree to reflect the new | 3537 // This method rewrites or completes the transition tree to reflect the new |
| 3537 // change. To avoid high degrees over polymorphism, and to stabilize quickly, | 3538 // change. To avoid high degrees over polymorphism, and to stabilize quickly, |
| 3538 // on every rewrite the new type is deduced by merging the current type with | 3539 // on every rewrite the new type is deduced by merging the current type with |
| 3539 // any potential new (partial) version of the type in the transition tree. | 3540 // any potential new (partial) version of the type in the transition tree. |
| 3540 // To do this, on each rewrite: | 3541 // To do this, on each rewrite: |
| 3541 // - Search the root of the transition tree using FindRootMap. | 3542 // - Search the root of the transition tree using FindRootMap. |
| 3543 // - Find/create a |root_map| with requested |new_elements_kind|. |
| 3542 // - Find |target_map|, the newest matching version of this map using the | 3544 // - Find |target_map|, the newest matching version of this map using the |
| 3543 // virtually "enhanced" |old_map|'s descriptor array (i.e. whose entry at | 3545 // virtually "enhanced" |old_map|'s descriptor array (i.e. whose entry at |
| 3544 // |modify_index| is considered to be of |new_kind| and having | 3546 // |modify_index| is considered to be of |new_kind| and having |
| 3545 // |new_attributes|) to walk the transition tree. | 3547 // |new_attributes|) to walk the transition tree. |
| 3546 // - Merge/generalize the "enhanced" descriptor array of the |old_map| and | 3548 // - Merge/generalize the "enhanced" descriptor array of the |old_map| and |
| 3547 // descriptor array of the |target_map|. | 3549 // descriptor array of the |target_map|. |
| 3548 // - Generalize the |modify_index| descriptor using |new_representation| and | 3550 // - Generalize the |modify_index| descriptor using |new_representation| and |
| 3549 // |new_field_type|. | 3551 // |new_field_type|. |
| 3550 // - Walk the tree again starting from the root towards |target_map|. Stop at | 3552 // - Walk the tree again starting from the root towards |target_map|. Stop at |
| 3551 // |split_map|, the first map who's descriptor array does not match the merged | 3553 // |split_map|, the first map who's descriptor array does not match the merged |
| 3552 // descriptor array. | 3554 // descriptor array. |
| 3553 // - If |target_map| == |split_map|, |target_map| is in the expected state. | 3555 // - If |target_map| == |split_map|, |target_map| is in the expected state. |
| 3554 // Return it. | 3556 // Return it. |
| 3555 // - Otherwise, invalidate the outdated transition target from |target_map|, and | 3557 // - Otherwise, invalidate the outdated transition target from |target_map|, and |
| 3556 // replace its transition tree with a new branch for the updated descriptors. | 3558 // replace its transition tree with a new branch for the updated descriptors. |
| 3557 Handle<Map> Map::ReconfigureProperty(Handle<Map> old_map, int modify_index, | 3559 Handle<Map> Map::Reconfigure(Handle<Map> old_map, |
| 3558 PropertyKind new_kind, | 3560 ElementsKind new_elements_kind, int modify_index, |
| 3559 PropertyAttributes new_attributes, | 3561 PropertyKind new_kind, |
| 3560 Representation new_representation, | 3562 PropertyAttributes new_attributes, |
| 3561 Handle<FieldType> new_field_type, | 3563 Representation new_representation, |
| 3562 StoreMode store_mode) { | 3564 Handle<FieldType> new_field_type, |
| 3565 StoreMode store_mode) { |
| 3563 DCHECK_NE(kAccessor, new_kind); // TODO(ishell): not supported yet. | 3566 DCHECK_NE(kAccessor, new_kind); // TODO(ishell): not supported yet. |
| 3564 DCHECK(store_mode != FORCE_FIELD || modify_index >= 0); | 3567 DCHECK(store_mode != FORCE_FIELD || modify_index >= 0); |
| 3565 Isolate* isolate = old_map->GetIsolate(); | 3568 Isolate* isolate = old_map->GetIsolate(); |
| 3566 | 3569 |
| 3567 Handle<DescriptorArray> old_descriptors( | 3570 Handle<DescriptorArray> old_descriptors( |
| 3568 old_map->instance_descriptors(), isolate); | 3571 old_map->instance_descriptors(), isolate); |
| 3569 int old_nof = old_map->NumberOfOwnDescriptors(); | 3572 int old_nof = old_map->NumberOfOwnDescriptors(); |
| 3570 | 3573 |
| 3571 // If it's just a representation generalization case (i.e. property kind and | 3574 // If it's just a representation generalization case (i.e. property kind and |
| 3572 // attributes stays unchanged) it's fine to transition from None to anything | 3575 // attributes stays unchanged) it's fine to transition from None to anything |
| 3573 // but double without any modification to the object, because the default | 3576 // but double without any modification to the object, because the default |
| 3574 // uninitialized value for representation None can be overwritten by both | 3577 // uninitialized value for representation None can be overwritten by both |
| 3575 // smi and tagged values. Doubles, however, would require a box allocation. | 3578 // smi and tagged values. Doubles, however, would require a box allocation. |
| 3576 if (modify_index >= 0 && !new_representation.IsNone() && | 3579 if (modify_index >= 0 && !new_representation.IsNone() && |
| 3577 !new_representation.IsDouble()) { | 3580 !new_representation.IsDouble() && |
| 3581 old_map->elements_kind() == new_elements_kind) { |
| 3578 PropertyDetails old_details = old_descriptors->GetDetails(modify_index); | 3582 PropertyDetails old_details = old_descriptors->GetDetails(modify_index); |
| 3579 Representation old_representation = old_details.representation(); | 3583 Representation old_representation = old_details.representation(); |
| 3580 | 3584 |
| 3581 if (old_representation.IsNone()) { | 3585 if (old_representation.IsNone()) { |
| 3582 DCHECK_EQ(new_kind, old_details.kind()); | 3586 DCHECK_EQ(new_kind, old_details.kind()); |
| 3583 DCHECK_EQ(new_attributes, old_details.attributes()); | 3587 DCHECK_EQ(new_attributes, old_details.attributes()); |
| 3584 DCHECK_EQ(DATA, old_details.type()); | 3588 DCHECK_EQ(DATA, old_details.type()); |
| 3585 if (FLAG_trace_generalization) { | 3589 if (FLAG_trace_generalization) { |
| 3586 old_map->PrintGeneralization( | 3590 old_map->PrintGeneralization( |
| 3587 stdout, "uninitialized field", modify_index, | 3591 stdout, "uninitialized field", modify_index, |
| (...skipping 12 matching lines...) Expand all Loading... |
| 3600 .Equals(new_representation)); | 3604 .Equals(new_representation)); |
| 3601 DCHECK( | 3605 DCHECK( |
| 3602 old_descriptors->GetFieldType(modify_index)->NowIs(new_field_type)); | 3606 old_descriptors->GetFieldType(modify_index)->NowIs(new_field_type)); |
| 3603 return old_map; | 3607 return old_map; |
| 3604 } | 3608 } |
| 3605 } | 3609 } |
| 3606 | 3610 |
| 3607 // Check the state of the root map. | 3611 // Check the state of the root map. |
| 3608 Handle<Map> root_map(old_map->FindRootMap(), isolate); | 3612 Handle<Map> root_map(old_map->FindRootMap(), isolate); |
| 3609 if (!old_map->EquivalentToForTransition(*root_map)) { | 3613 if (!old_map->EquivalentToForTransition(*root_map)) { |
| 3610 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, | 3614 return CopyGeneralizeAllRepresentations( |
| 3611 new_kind, new_attributes, | 3615 old_map, new_elements_kind, modify_index, store_mode, new_kind, |
| 3612 "GenAll_NotEquivalent"); | 3616 new_attributes, "GenAll_NotEquivalent"); |
| 3613 } | 3617 } |
| 3614 | 3618 |
| 3615 ElementsKind from_kind = root_map->elements_kind(); | 3619 ElementsKind from_kind = root_map->elements_kind(); |
| 3616 ElementsKind to_kind = old_map->elements_kind(); | 3620 ElementsKind to_kind = new_elements_kind; |
| 3617 // TODO(ishell): Add a test for SLOW_SLOPPY_ARGUMENTS_ELEMENTS. | 3621 // TODO(ishell): Add a test for SLOW_SLOPPY_ARGUMENTS_ELEMENTS. |
| 3618 if (from_kind != to_kind && to_kind != DICTIONARY_ELEMENTS && | 3622 if (from_kind != to_kind && to_kind != DICTIONARY_ELEMENTS && |
| 3623 to_kind != SLOW_STRING_WRAPPER_ELEMENTS && |
| 3619 to_kind != SLOW_SLOPPY_ARGUMENTS_ELEMENTS && | 3624 to_kind != SLOW_SLOPPY_ARGUMENTS_ELEMENTS && |
| 3620 !(IsTransitionableFastElementsKind(from_kind) && | 3625 !(IsTransitionableFastElementsKind(from_kind) && |
| 3621 IsMoreGeneralElementsKindTransition(from_kind, to_kind))) { | 3626 IsMoreGeneralElementsKindTransition(from_kind, to_kind))) { |
| 3622 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, | 3627 return CopyGeneralizeAllRepresentations( |
| 3623 new_kind, new_attributes, | 3628 old_map, to_kind, modify_index, store_mode, new_kind, new_attributes, |
| 3624 "GenAll_InvalidElementsTransition"); | 3629 "GenAll_InvalidElementsTransition"); |
| 3625 } | 3630 } |
| 3626 int root_nof = root_map->NumberOfOwnDescriptors(); | 3631 int root_nof = root_map->NumberOfOwnDescriptors(); |
| 3627 if (modify_index >= 0 && modify_index < root_nof) { | 3632 if (modify_index >= 0 && modify_index < root_nof) { |
| 3628 PropertyDetails old_details = old_descriptors->GetDetails(modify_index); | 3633 PropertyDetails old_details = old_descriptors->GetDetails(modify_index); |
| 3629 if (old_details.kind() != new_kind || | 3634 if (old_details.kind() != new_kind || |
| 3630 old_details.attributes() != new_attributes) { | 3635 old_details.attributes() != new_attributes) { |
| 3631 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, | 3636 return CopyGeneralizeAllRepresentations( |
| 3632 new_kind, new_attributes, | 3637 old_map, to_kind, modify_index, store_mode, new_kind, new_attributes, |
| 3633 "GenAll_RootModification1"); | 3638 "GenAll_RootModification1"); |
| 3634 } | 3639 } |
| 3635 if ((old_details.type() != DATA && store_mode == FORCE_FIELD) || | 3640 if ((old_details.type() != DATA && store_mode == FORCE_FIELD) || |
| 3636 (old_details.type() == DATA && | 3641 (old_details.type() == DATA && |
| 3637 (!new_field_type->NowIs(old_descriptors->GetFieldType(modify_index)) || | 3642 (!new_field_type->NowIs(old_descriptors->GetFieldType(modify_index)) || |
| 3638 !new_representation.fits_into(old_details.representation())))) { | 3643 !new_representation.fits_into(old_details.representation())))) { |
| 3639 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, | 3644 return CopyGeneralizeAllRepresentations( |
| 3640 new_kind, new_attributes, | 3645 old_map, to_kind, modify_index, store_mode, new_kind, new_attributes, |
| 3641 "GenAll_RootModification2"); | 3646 "GenAll_RootModification2"); |
| 3642 } | 3647 } |
| 3643 } | 3648 } |
| 3644 | 3649 |
| 3645 // From here on, use the map with correct elements kind as root map. | 3650 // From here on, use the map with correct elements kind as root map. |
| 3646 if (from_kind != to_kind) { | 3651 if (from_kind != to_kind) { |
| 3647 root_map = Map::AsElementsKind(root_map, to_kind); | 3652 root_map = Map::AsElementsKind(root_map, to_kind); |
| 3648 } | 3653 } |
| 3649 | 3654 |
| 3650 Handle<Map> target_map = root_map; | 3655 Handle<Map> target_map = root_map; |
| 3651 for (int i = root_nof; i < old_nof; ++i) { | 3656 for (int i = root_nof; i < old_nof; ++i) { |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3685 Handle<DescriptorArray> tmp_descriptors = handle( | 3690 Handle<DescriptorArray> tmp_descriptors = handle( |
| 3686 tmp_map->instance_descriptors(), isolate); | 3691 tmp_map->instance_descriptors(), isolate); |
| 3687 | 3692 |
| 3688 // Check if target map is incompatible. | 3693 // Check if target map is incompatible. |
| 3689 PropertyDetails tmp_details = tmp_descriptors->GetDetails(i); | 3694 PropertyDetails tmp_details = tmp_descriptors->GetDetails(i); |
| 3690 DCHECK_EQ(next_kind, tmp_details.kind()); | 3695 DCHECK_EQ(next_kind, tmp_details.kind()); |
| 3691 DCHECK_EQ(next_attributes, tmp_details.attributes()); | 3696 DCHECK_EQ(next_attributes, tmp_details.attributes()); |
| 3692 if (next_kind == kAccessor && | 3697 if (next_kind == kAccessor && |
| 3693 !EqualImmutableValues(old_descriptors->GetValue(i), | 3698 !EqualImmutableValues(old_descriptors->GetValue(i), |
| 3694 tmp_descriptors->GetValue(i))) { | 3699 tmp_descriptors->GetValue(i))) { |
| 3695 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, | 3700 return CopyGeneralizeAllRepresentations( |
| 3696 new_kind, new_attributes, | 3701 old_map, to_kind, modify_index, store_mode, new_kind, new_attributes, |
| 3697 "GenAll_Incompatible"); | 3702 "GenAll_Incompatible"); |
| 3698 } | 3703 } |
| 3699 if (next_location == kField && tmp_details.location() == kDescriptor) break; | 3704 if (next_location == kField && tmp_details.location() == kDescriptor) break; |
| 3700 | 3705 |
| 3701 Representation tmp_representation = tmp_details.representation(); | 3706 Representation tmp_representation = tmp_details.representation(); |
| 3702 if (!next_representation.fits_into(tmp_representation)) break; | 3707 if (!next_representation.fits_into(tmp_representation)) break; |
| 3703 | 3708 |
| 3704 PropertyLocation old_location = old_details.location(); | 3709 PropertyLocation old_location = old_details.location(); |
| 3705 PropertyLocation tmp_location = tmp_details.location(); | 3710 PropertyLocation tmp_location = tmp_details.location(); |
| 3706 if (tmp_location == kField) { | 3711 if (tmp_location == kField) { |
| 3707 if (next_kind == kData) { | 3712 if (next_kind == kData) { |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3780 | 3785 |
| 3781 // Check if target map is compatible. | 3786 // Check if target map is compatible. |
| 3782 #ifdef DEBUG | 3787 #ifdef DEBUG |
| 3783 PropertyDetails tmp_details = tmp_descriptors->GetDetails(i); | 3788 PropertyDetails tmp_details = tmp_descriptors->GetDetails(i); |
| 3784 DCHECK_EQ(next_kind, tmp_details.kind()); | 3789 DCHECK_EQ(next_kind, tmp_details.kind()); |
| 3785 DCHECK_EQ(next_attributes, tmp_details.attributes()); | 3790 DCHECK_EQ(next_attributes, tmp_details.attributes()); |
| 3786 #endif | 3791 #endif |
| 3787 if (next_kind == kAccessor && | 3792 if (next_kind == kAccessor && |
| 3788 !EqualImmutableValues(old_descriptors->GetValue(i), | 3793 !EqualImmutableValues(old_descriptors->GetValue(i), |
| 3789 tmp_descriptors->GetValue(i))) { | 3794 tmp_descriptors->GetValue(i))) { |
| 3790 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, | 3795 return CopyGeneralizeAllRepresentations( |
| 3791 new_kind, new_attributes, | 3796 old_map, to_kind, modify_index, store_mode, new_kind, new_attributes, |
| 3792 "GenAll_Incompatible"); | 3797 "GenAll_Incompatible"); |
| 3793 } | 3798 } |
| 3794 DCHECK(!tmp_map->is_deprecated()); | 3799 DCHECK(!tmp_map->is_deprecated()); |
| 3795 target_map = tmp_map; | 3800 target_map = tmp_map; |
| 3796 } | 3801 } |
| 3797 target_nof = target_map->NumberOfOwnDescriptors(); | 3802 target_nof = target_map->NumberOfOwnDescriptors(); |
| 3798 target_descriptors = handle(target_map->instance_descriptors(), isolate); | 3803 target_descriptors = handle(target_map->instance_descriptors(), isolate); |
| 3799 | 3804 |
| 3800 // Allocate a new descriptor array large enough to hold the required | 3805 // Allocate a new descriptor array large enough to hold the required |
| 3801 // descriptors, with minimally the exact same size as the old descriptor | 3806 // descriptors, with minimally the exact same size as the old descriptor |
| 3802 // array. | 3807 // array. |
| (...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4013 split_attributes); | 4018 split_attributes); |
| 4014 if (maybe_transition != NULL) { | 4019 if (maybe_transition != NULL) { |
| 4015 maybe_transition->DeprecateTransitionTree(); | 4020 maybe_transition->DeprecateTransitionTree(); |
| 4016 } | 4021 } |
| 4017 | 4022 |
| 4018 // If |maybe_transition| is not NULL then the transition array already | 4023 // If |maybe_transition| is not NULL then the transition array already |
| 4019 // contains entry for given descriptor. This means that the transition | 4024 // contains entry for given descriptor. This means that the transition |
| 4020 // could be inserted regardless of whether transitions array is full or not. | 4025 // could be inserted regardless of whether transitions array is full or not. |
| 4021 if (maybe_transition == NULL && | 4026 if (maybe_transition == NULL && |
| 4022 !TransitionArray::CanHaveMoreTransitions(split_map)) { | 4027 !TransitionArray::CanHaveMoreTransitions(split_map)) { |
| 4023 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, | 4028 return CopyGeneralizeAllRepresentations( |
| 4024 new_kind, new_attributes, | 4029 old_map, to_kind, modify_index, store_mode, new_kind, new_attributes, |
| 4025 "GenAll_CantHaveMoreTransitions"); | 4030 "GenAll_CantHaveMoreTransitions"); |
| 4026 } | 4031 } |
| 4027 | 4032 |
| 4028 old_map->NotifyLeafMapLayoutChange(); | 4033 old_map->NotifyLeafMapLayoutChange(); |
| 4029 | 4034 |
| 4030 if (FLAG_trace_generalization && modify_index >= 0) { | 4035 if (FLAG_trace_generalization && modify_index >= 0) { |
| 4031 PropertyDetails old_details = old_descriptors->GetDetails(modify_index); | 4036 PropertyDetails old_details = old_descriptors->GetDetails(modify_index); |
| 4032 PropertyDetails new_details = new_descriptors->GetDetails(modify_index); | 4037 PropertyDetails new_details = new_descriptors->GetDetails(modify_index); |
| 4033 MaybeHandle<FieldType> old_field_type; | 4038 MaybeHandle<FieldType> old_field_type; |
| 4034 MaybeHandle<FieldType> new_field_type; | 4039 MaybeHandle<FieldType> new_field_type; |
| 4035 MaybeHandle<Object> old_value; | 4040 MaybeHandle<Object> old_value; |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4096 if (!old_map->EquivalentToForTransition(root_map)) return MaybeHandle<Map>(); | 4101 if (!old_map->EquivalentToForTransition(root_map)) return MaybeHandle<Map>(); |
| 4097 | 4102 |
| 4098 ElementsKind from_kind = root_map->elements_kind(); | 4103 ElementsKind from_kind = root_map->elements_kind(); |
| 4099 ElementsKind to_kind = old_map->elements_kind(); | 4104 ElementsKind to_kind = old_map->elements_kind(); |
| 4100 if (from_kind != to_kind) { | 4105 if (from_kind != to_kind) { |
| 4101 // Try to follow existing elements kind transitions. | 4106 // Try to follow existing elements kind transitions. |
| 4102 root_map = root_map->LookupElementsTransitionMap(to_kind); | 4107 root_map = root_map->LookupElementsTransitionMap(to_kind); |
| 4103 if (root_map == NULL) return MaybeHandle<Map>(); | 4108 if (root_map == NULL) return MaybeHandle<Map>(); |
| 4104 // From here on, use the map with correct elements kind as root map. | 4109 // From here on, use the map with correct elements kind as root map. |
| 4105 } | 4110 } |
| 4106 int root_nof = root_map->NumberOfOwnDescriptors(); | 4111 Map* new_map = root_map->TryReplayPropertyTransitions(*old_map); |
| 4112 if (new_map == nullptr) return MaybeHandle<Map>(); |
| 4113 return handle(new_map); |
| 4114 } |
| 4115 |
| 4116 Map* Map::TryReplayPropertyTransitions(Map* old_map) { |
| 4117 DisallowHeapAllocation no_allocation; |
| 4118 DisallowDeoptimization no_deoptimization(GetIsolate()); |
| 4119 |
| 4120 int root_nof = NumberOfOwnDescriptors(); |
| 4107 | 4121 |
| 4108 int old_nof = old_map->NumberOfOwnDescriptors(); | 4122 int old_nof = old_map->NumberOfOwnDescriptors(); |
| 4109 DescriptorArray* old_descriptors = old_map->instance_descriptors(); | 4123 DescriptorArray* old_descriptors = old_map->instance_descriptors(); |
| 4110 | 4124 |
| 4111 Map* new_map = root_map; | 4125 Map* new_map = this; |
| 4112 for (int i = root_nof; i < old_nof; ++i) { | 4126 for (int i = root_nof; i < old_nof; ++i) { |
| 4113 PropertyDetails old_details = old_descriptors->GetDetails(i); | 4127 PropertyDetails old_details = old_descriptors->GetDetails(i); |
| 4114 Map* transition = TransitionArray::SearchTransition( | 4128 Map* transition = TransitionArray::SearchTransition( |
| 4115 new_map, old_details.kind(), old_descriptors->GetKey(i), | 4129 new_map, old_details.kind(), old_descriptors->GetKey(i), |
| 4116 old_details.attributes()); | 4130 old_details.attributes()); |
| 4117 if (transition == NULL) return MaybeHandle<Map>(); | 4131 if (transition == NULL) return nullptr; |
| 4118 new_map = transition; | 4132 new_map = transition; |
| 4119 DescriptorArray* new_descriptors = new_map->instance_descriptors(); | 4133 DescriptorArray* new_descriptors = new_map->instance_descriptors(); |
| 4120 | 4134 |
| 4121 PropertyDetails new_details = new_descriptors->GetDetails(i); | 4135 PropertyDetails new_details = new_descriptors->GetDetails(i); |
| 4122 DCHECK_EQ(old_details.kind(), new_details.kind()); | 4136 DCHECK_EQ(old_details.kind(), new_details.kind()); |
| 4123 DCHECK_EQ(old_details.attributes(), new_details.attributes()); | 4137 DCHECK_EQ(old_details.attributes(), new_details.attributes()); |
| 4124 if (!old_details.representation().fits_into(new_details.representation())) { | 4138 if (!old_details.representation().fits_into(new_details.representation())) { |
| 4125 return MaybeHandle<Map>(); | 4139 return nullptr; |
| 4126 } | 4140 } |
| 4127 switch (new_details.type()) { | 4141 switch (new_details.type()) { |
| 4128 case DATA: { | 4142 case DATA: { |
| 4129 FieldType* new_type = new_descriptors->GetFieldType(i); | 4143 FieldType* new_type = new_descriptors->GetFieldType(i); |
| 4130 // Cleared field types need special treatment. They represent lost | 4144 // Cleared field types need special treatment. They represent lost |
| 4131 // knowledge, so we must first generalize the new_type to "Any". | 4145 // knowledge, so we must first generalize the new_type to "Any". |
| 4132 if (FieldTypeIsCleared(new_details.representation(), new_type)) { | 4146 if (FieldTypeIsCleared(new_details.representation(), new_type)) { |
| 4133 return MaybeHandle<Map>(); | 4147 return nullptr; |
| 4134 } | 4148 } |
| 4135 PropertyType old_property_type = old_details.type(); | 4149 PropertyType old_property_type = old_details.type(); |
| 4136 if (old_property_type == DATA) { | 4150 if (old_property_type == DATA) { |
| 4137 FieldType* old_type = old_descriptors->GetFieldType(i); | 4151 FieldType* old_type = old_descriptors->GetFieldType(i); |
| 4138 if (FieldTypeIsCleared(old_details.representation(), old_type) || | 4152 if (FieldTypeIsCleared(old_details.representation(), old_type) || |
| 4139 !old_type->NowIs(new_type)) { | 4153 !old_type->NowIs(new_type)) { |
| 4140 return MaybeHandle<Map>(); | 4154 return nullptr; |
| 4141 } | 4155 } |
| 4142 } else { | 4156 } else { |
| 4143 DCHECK(old_property_type == DATA_CONSTANT); | 4157 DCHECK(old_property_type == DATA_CONSTANT); |
| 4144 Object* old_value = old_descriptors->GetValue(i); | 4158 Object* old_value = old_descriptors->GetValue(i); |
| 4145 if (!new_type->NowContains(old_value)) { | 4159 if (!new_type->NowContains(old_value)) { |
| 4146 return MaybeHandle<Map>(); | 4160 return nullptr; |
| 4147 } | 4161 } |
| 4148 } | 4162 } |
| 4149 break; | 4163 break; |
| 4150 } | 4164 } |
| 4151 case ACCESSOR: { | 4165 case ACCESSOR: { |
| 4152 #ifdef DEBUG | 4166 #ifdef DEBUG |
| 4153 FieldType* new_type = new_descriptors->GetFieldType(i); | 4167 FieldType* new_type = new_descriptors->GetFieldType(i); |
| 4154 DCHECK(new_type->IsAny()); | 4168 DCHECK(new_type->IsAny()); |
| 4155 #endif | 4169 #endif |
| 4156 break; | 4170 break; |
| 4157 } | 4171 } |
| 4158 | 4172 |
| 4159 case DATA_CONSTANT: | 4173 case DATA_CONSTANT: |
| 4160 case ACCESSOR_CONSTANT: { | 4174 case ACCESSOR_CONSTANT: { |
| 4161 Object* old_value = old_descriptors->GetValue(i); | 4175 Object* old_value = old_descriptors->GetValue(i); |
| 4162 Object* new_value = new_descriptors->GetValue(i); | 4176 Object* new_value = new_descriptors->GetValue(i); |
| 4163 if (old_details.location() == kField || old_value != new_value) { | 4177 if (old_details.location() == kField || old_value != new_value) { |
| 4164 return MaybeHandle<Map>(); | 4178 return nullptr; |
| 4165 } | 4179 } |
| 4166 break; | 4180 break; |
| 4167 } | 4181 } |
| 4168 } | 4182 } |
| 4169 } | 4183 } |
| 4170 if (new_map->NumberOfOwnDescriptors() != old_nof) return MaybeHandle<Map>(); | 4184 if (new_map->NumberOfOwnDescriptors() != old_nof) return nullptr; |
| 4171 return handle(new_map); | 4185 return new_map; |
| 4172 } | 4186 } |
| 4173 | 4187 |
| 4174 | 4188 |
| 4175 // static | 4189 // static |
| 4176 Handle<Map> Map::Update(Handle<Map> map) { | 4190 Handle<Map> Map::Update(Handle<Map> map) { |
| 4177 if (!map->is_deprecated()) return map; | 4191 if (!map->is_deprecated()) return map; |
| 4178 return ReconfigureProperty(map, -1, kData, NONE, Representation::None(), | 4192 return ReconfigureProperty(map, -1, kData, NONE, Representation::None(), |
| 4179 FieldType::None(map->GetIsolate()), | 4193 FieldType::None(map->GetIsolate()), |
| 4180 ALLOW_IN_DESCRIPTOR); | 4194 ALLOW_IN_DESCRIPTOR); |
| 4181 } | 4195 } |
| (...skipping 572 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4754 | 4768 |
| 4755 | 4769 |
| 4756 static bool ContainsMap(MapHandleList* maps, Map* map) { | 4770 static bool ContainsMap(MapHandleList* maps, Map* map) { |
| 4757 DCHECK_NOT_NULL(map); | 4771 DCHECK_NOT_NULL(map); |
| 4758 for (int i = 0; i < maps->length(); ++i) { | 4772 for (int i = 0; i < maps->length(); ++i) { |
| 4759 if (!maps->at(i).is_null() && *maps->at(i) == map) return true; | 4773 if (!maps->at(i).is_null() && *maps->at(i) == map) return true; |
| 4760 } | 4774 } |
| 4761 return false; | 4775 return false; |
| 4762 } | 4776 } |
| 4763 | 4777 |
| 4778 Map* Map::FindElementsKindTransitionedMap(MapHandleList* candidates) { |
| 4779 DisallowHeapAllocation no_allocation; |
| 4780 DisallowDeoptimization no_deoptimization(GetIsolate()); |
| 4764 | 4781 |
| 4765 Handle<Map> Map::FindTransitionedMap(Handle<Map> map, | 4782 ElementsKind kind = elements_kind(); |
| 4766 MapHandleList* candidates) { | |
| 4767 ElementsKind kind = map->elements_kind(); | |
| 4768 bool packed = IsFastPackedElementsKind(kind); | 4783 bool packed = IsFastPackedElementsKind(kind); |
| 4769 | 4784 |
| 4770 Map* transition = nullptr; | 4785 Map* transition = nullptr; |
| 4771 if (IsTransitionableFastElementsKind(kind)) { | 4786 if (IsTransitionableFastElementsKind(kind)) { |
| 4772 for (Map* current = map->ElementsTransitionMap(); | 4787 // Check the state of the root map. |
| 4773 current != nullptr && current->has_fast_elements(); | 4788 Map* root_map = FindRootMap(); |
| 4774 current = current->ElementsTransitionMap()) { | 4789 if (!EquivalentToForTransition(root_map)) return nullptr; |
| 4790 root_map = root_map->LookupElementsTransitionMap(kind); |
| 4791 DCHECK_NOT_NULL(root_map); |
| 4792 // Starting from the next existing elements kind transition try to |
| 4793 // replay the property transitions. |
| 4794 for (root_map = root_map->ElementsTransitionMap(); |
| 4795 root_map != nullptr && root_map->has_fast_elements(); |
| 4796 root_map = root_map->ElementsTransitionMap()) { |
| 4797 Map* current = root_map->TryReplayPropertyTransitions(this); |
| 4798 if (current == nullptr) continue; |
| 4799 |
| 4775 if (ContainsMap(candidates, current) && | 4800 if (ContainsMap(candidates, current) && |
| 4776 (packed || !IsFastPackedElementsKind(current->elements_kind()))) { | 4801 (packed || !IsFastPackedElementsKind(current->elements_kind()))) { |
| 4777 transition = current; | 4802 transition = current; |
| 4778 packed = packed && IsFastPackedElementsKind(current->elements_kind()); | 4803 packed = packed && IsFastPackedElementsKind(current->elements_kind()); |
| 4779 } | 4804 } |
| 4780 } | 4805 } |
| 4781 } | 4806 } |
| 4782 return transition == nullptr ? Handle<Map>() : handle(transition); | 4807 return transition; |
| 4783 } | 4808 } |
| 4784 | 4809 |
| 4785 | 4810 |
| 4786 static Map* FindClosestElementsTransition(Map* map, ElementsKind to_kind) { | 4811 static Map* FindClosestElementsTransition(Map* map, ElementsKind to_kind) { |
| 4812 // Ensure we are requested to search elements kind transition "near the root". |
| 4813 DCHECK_EQ(map->FindRootMap()->NumberOfOwnDescriptors(), |
| 4814 map->NumberOfOwnDescriptors()); |
| 4787 Map* current_map = map; | 4815 Map* current_map = map; |
| 4788 | 4816 |
| 4789 ElementsKind kind = map->elements_kind(); | 4817 ElementsKind kind = map->elements_kind(); |
| 4790 while (kind != to_kind) { | 4818 while (kind != to_kind) { |
| 4791 Map* next_map = current_map->ElementsTransitionMap(); | 4819 Map* next_map = current_map->ElementsTransitionMap(); |
| 4792 if (next_map == nullptr) return current_map; | 4820 if (next_map == nullptr) return current_map; |
| 4793 kind = next_map->elements_kind(); | 4821 kind = next_map->elements_kind(); |
| 4794 current_map = next_map; | 4822 current_map = next_map; |
| 4795 } | 4823 } |
| 4796 | 4824 |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4905 if (IsFastElementsKind(to_kind)) { | 4933 if (IsFastElementsKind(to_kind)) { |
| 4906 allow_store_transition = | 4934 allow_store_transition = |
| 4907 allow_store_transition && IsTransitionableFastElementsKind(from_kind) && | 4935 allow_store_transition && IsTransitionableFastElementsKind(from_kind) && |
| 4908 IsMoreGeneralElementsKindTransition(from_kind, to_kind); | 4936 IsMoreGeneralElementsKindTransition(from_kind, to_kind); |
| 4909 } | 4937 } |
| 4910 | 4938 |
| 4911 if (!allow_store_transition) { | 4939 if (!allow_store_transition) { |
| 4912 return Map::CopyAsElementsKind(map, to_kind, OMIT_TRANSITION); | 4940 return Map::CopyAsElementsKind(map, to_kind, OMIT_TRANSITION); |
| 4913 } | 4941 } |
| 4914 | 4942 |
| 4915 return Map::AsElementsKind(map, to_kind); | 4943 return Map::ReconfigureElementsKind(map, to_kind); |
| 4916 } | 4944 } |
| 4917 | 4945 |
| 4918 | 4946 |
| 4919 // static | 4947 // static |
| 4920 Handle<Map> Map::AsElementsKind(Handle<Map> map, ElementsKind kind) { | 4948 Handle<Map> Map::AsElementsKind(Handle<Map> map, ElementsKind kind) { |
| 4921 Handle<Map> closest_map(FindClosestElementsTransition(*map, kind)); | 4949 Handle<Map> closest_map(FindClosestElementsTransition(*map, kind)); |
| 4922 | 4950 |
| 4923 if (closest_map->elements_kind() == kind) { | 4951 if (closest_map->elements_kind() == kind) { |
| 4924 return closest_map; | 4952 return closest_map; |
| 4925 } | 4953 } |
| (...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5267 if (map_kind != obj_kind) { | 5295 if (map_kind != obj_kind) { |
| 5268 ElementsKind to_kind = GetMoreGeneralElementsKind(map_kind, obj_kind); | 5296 ElementsKind to_kind = GetMoreGeneralElementsKind(map_kind, obj_kind); |
| 5269 if (IsDictionaryElementsKind(obj_kind)) { | 5297 if (IsDictionaryElementsKind(obj_kind)) { |
| 5270 to_kind = obj_kind; | 5298 to_kind = obj_kind; |
| 5271 } | 5299 } |
| 5272 if (IsDictionaryElementsKind(to_kind)) { | 5300 if (IsDictionaryElementsKind(to_kind)) { |
| 5273 NormalizeElements(object); | 5301 NormalizeElements(object); |
| 5274 } else { | 5302 } else { |
| 5275 TransitionElementsKind(object, to_kind); | 5303 TransitionElementsKind(object, to_kind); |
| 5276 } | 5304 } |
| 5277 map = Map::AsElementsKind(map, to_kind); | 5305 map = Map::ReconfigureElementsKind(map, to_kind); |
| 5278 } | 5306 } |
| 5279 JSObject::MigrateToMap(object, map); | 5307 JSObject::MigrateToMap(object, map); |
| 5280 } | 5308 } |
| 5281 | 5309 |
| 5282 | 5310 |
| 5283 void JSObject::MigrateInstance(Handle<JSObject> object) { | 5311 void JSObject::MigrateInstance(Handle<JSObject> object) { |
| 5284 Handle<Map> original_map(object->map()); | 5312 Handle<Map> original_map(object->map()); |
| 5285 Handle<Map> map = Map::Update(original_map); | 5313 Handle<Map> map = Map::Update(original_map); |
| 5286 map->set_migration_target(true); | 5314 map->set_migration_target(true); |
| 5287 MigrateToMap(object, map); | 5315 MigrateToMap(object, map); |
| (...skipping 3562 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8850 | 8878 |
| 8851 Handle<Name> name = handle(descriptors->GetKey(new_descriptor)); | 8879 Handle<Name> name = handle(descriptors->GetKey(new_descriptor)); |
| 8852 ConnectTransition(parent, child, name, SIMPLE_PROPERTY_TRANSITION); | 8880 ConnectTransition(parent, child, name, SIMPLE_PROPERTY_TRANSITION); |
| 8853 } | 8881 } |
| 8854 | 8882 |
| 8855 | 8883 |
| 8856 Handle<Map> Map::CopyAsElementsKind(Handle<Map> map, ElementsKind kind, | 8884 Handle<Map> Map::CopyAsElementsKind(Handle<Map> map, ElementsKind kind, |
| 8857 TransitionFlag flag) { | 8885 TransitionFlag flag) { |
| 8858 Map* maybe_elements_transition_map = NULL; | 8886 Map* maybe_elements_transition_map = NULL; |
| 8859 if (flag == INSERT_TRANSITION) { | 8887 if (flag == INSERT_TRANSITION) { |
| 8888 // Ensure we are requested to add elements kind transition "near the root". |
| 8889 DCHECK_EQ(map->FindRootMap()->NumberOfOwnDescriptors(), |
| 8890 map->NumberOfOwnDescriptors()); |
| 8891 |
| 8860 maybe_elements_transition_map = map->ElementsTransitionMap(); | 8892 maybe_elements_transition_map = map->ElementsTransitionMap(); |
| 8861 DCHECK(maybe_elements_transition_map == NULL || | 8893 DCHECK(maybe_elements_transition_map == NULL || |
| 8862 (maybe_elements_transition_map->elements_kind() == | 8894 (maybe_elements_transition_map->elements_kind() == |
| 8863 DICTIONARY_ELEMENTS && | 8895 DICTIONARY_ELEMENTS && |
| 8864 kind == DICTIONARY_ELEMENTS)); | 8896 kind == DICTIONARY_ELEMENTS)); |
| 8865 DCHECK(!IsFastElementsKind(kind) || | 8897 DCHECK(!IsFastElementsKind(kind) || |
| 8866 IsMoreGeneralElementsKindTransition(map->elements_kind(), kind)); | 8898 IsMoreGeneralElementsKindTransition(map->elements_kind(), kind)); |
| 8867 DCHECK(kind != map->elements_kind()); | 8899 DCHECK(kind != map->elements_kind()); |
| 8868 } | 8900 } |
| 8869 | 8901 |
| (...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9154 Handle<Map> Map::ReconfigureExistingProperty(Handle<Map> map, int descriptor, | 9186 Handle<Map> Map::ReconfigureExistingProperty(Handle<Map> map, int descriptor, |
| 9155 PropertyKind kind, | 9187 PropertyKind kind, |
| 9156 PropertyAttributes attributes) { | 9188 PropertyAttributes attributes) { |
| 9157 // Dictionaries have to be reconfigured in-place. | 9189 // Dictionaries have to be reconfigured in-place. |
| 9158 DCHECK(!map->is_dictionary_map()); | 9190 DCHECK(!map->is_dictionary_map()); |
| 9159 | 9191 |
| 9160 if (!map->GetBackPointer()->IsMap()) { | 9192 if (!map->GetBackPointer()->IsMap()) { |
| 9161 // There is no benefit from reconstructing transition tree for maps without | 9193 // There is no benefit from reconstructing transition tree for maps without |
| 9162 // back pointers. | 9194 // back pointers. |
| 9163 return CopyGeneralizeAllRepresentations( | 9195 return CopyGeneralizeAllRepresentations( |
| 9164 map, descriptor, FORCE_FIELD, kind, attributes, | 9196 map, map->elements_kind(), descriptor, FORCE_FIELD, kind, attributes, |
| 9165 "GenAll_AttributesMismatchProtoMap"); | 9197 "GenAll_AttributesMismatchProtoMap"); |
| 9166 } | 9198 } |
| 9167 | 9199 |
| 9168 if (FLAG_trace_generalization) { | 9200 if (FLAG_trace_generalization) { |
| 9169 map->PrintReconfiguration(stdout, descriptor, kind, attributes); | 9201 map->PrintReconfiguration(stdout, descriptor, kind, attributes); |
| 9170 } | 9202 } |
| 9171 | 9203 |
| 9172 Isolate* isolate = map->GetIsolate(); | 9204 Isolate* isolate = map->GetIsolate(); |
| 9173 Handle<Map> new_map = ReconfigureProperty( | 9205 Handle<Map> new_map = ReconfigureProperty( |
| 9174 map, descriptor, kind, attributes, Representation::None(), | 9206 map, descriptor, kind, attributes, Representation::None(), |
| (...skipping 9290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 18465 if (cell->value() != *new_value) { | 18497 if (cell->value() != *new_value) { |
| 18466 cell->set_value(*new_value); | 18498 cell->set_value(*new_value); |
| 18467 Isolate* isolate = cell->GetIsolate(); | 18499 Isolate* isolate = cell->GetIsolate(); |
| 18468 cell->dependent_code()->DeoptimizeDependentCodeGroup( | 18500 cell->dependent_code()->DeoptimizeDependentCodeGroup( |
| 18469 isolate, DependentCode::kPropertyCellChangedGroup); | 18501 isolate, DependentCode::kPropertyCellChangedGroup); |
| 18470 } | 18502 } |
| 18471 } | 18503 } |
| 18472 | 18504 |
| 18473 } // namespace internal | 18505 } // namespace internal |
| 18474 } // namespace v8 | 18506 } // namespace v8 |
| OLD | NEW |