| 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 2663 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2674 case kDouble: return "d"; | 2674 case kDouble: return "d"; |
| 2675 case kInteger32: return "i"; | 2675 case kInteger32: return "i"; |
| 2676 case kHeapObject: return "h"; | 2676 case kHeapObject: return "h"; |
| 2677 case kExternal: return "x"; | 2677 case kExternal: return "x"; |
| 2678 default: | 2678 default: |
| 2679 UNREACHABLE(); | 2679 UNREACHABLE(); |
| 2680 return NULL; | 2680 return NULL; |
| 2681 } | 2681 } |
| 2682 } | 2682 } |
| 2683 | 2683 |
| 2684 bool Map::InstancesNeedRewriting(Map* target) { |
| 2685 int target_number_of_fields = target->NumberOfFields(); |
| 2686 int target_inobject = target->GetInObjectProperties(); |
| 2687 int target_unused = target->unused_property_fields(); |
| 2688 int old_number_of_fields; |
| 2689 |
| 2690 return InstancesNeedRewriting(target, target_number_of_fields, |
| 2691 target_inobject, target_unused, |
| 2692 &old_number_of_fields); |
| 2693 } |
| 2684 | 2694 |
| 2685 bool Map::InstancesNeedRewriting(Map* target, int target_number_of_fields, | 2695 bool Map::InstancesNeedRewriting(Map* target, int target_number_of_fields, |
| 2686 int target_inobject, int target_unused, | 2696 int target_inobject, int target_unused, |
| 2687 int* old_number_of_fields) { | 2697 int* old_number_of_fields) { |
| 2688 // If fields were added (or removed), rewrite the instance. | 2698 // If fields were added (or removed), rewrite the instance. |
| 2689 *old_number_of_fields = NumberOfFields(); | 2699 *old_number_of_fields = NumberOfFields(); |
| 2690 DCHECK(target_number_of_fields >= *old_number_of_fields); | 2700 DCHECK(target_number_of_fields >= *old_number_of_fields); |
| 2691 if (target_number_of_fields != *old_number_of_fields) return true; | 2701 if (target_number_of_fields != *old_number_of_fields) return true; |
| 2692 | 2702 |
| 2693 // If smi descriptors were replaced by double descriptors, rewrite. | 2703 // If smi descriptors were replaced by double descriptors, rewrite. |
| (...skipping 440 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3134 | 3144 |
| 3135 int Map::NumberOfFields() { | 3145 int Map::NumberOfFields() { |
| 3136 DescriptorArray* descriptors = instance_descriptors(); | 3146 DescriptorArray* descriptors = instance_descriptors(); |
| 3137 int result = 0; | 3147 int result = 0; |
| 3138 for (int i = 0; i < NumberOfOwnDescriptors(); i++) { | 3148 for (int i = 0; i < NumberOfOwnDescriptors(); i++) { |
| 3139 if (descriptors->GetDetails(i).location() == kField) result++; | 3149 if (descriptors->GetDetails(i).location() == kField) result++; |
| 3140 } | 3150 } |
| 3141 return result; | 3151 return result; |
| 3142 } | 3152 } |
| 3143 | 3153 |
| 3144 | |
| 3145 Handle<Map> Map::CopyGeneralizeAllRepresentations( | 3154 Handle<Map> Map::CopyGeneralizeAllRepresentations( |
| 3146 Handle<Map> map, int modify_index, StoreMode store_mode, PropertyKind kind, | 3155 Handle<Map> map, ElementsKind elements_kind, int modify_index, |
| 3147 PropertyAttributes attributes, const char* reason) { | 3156 StoreMode store_mode, PropertyKind kind, PropertyAttributes attributes, |
| 3157 const char* reason) { |
| 3148 Isolate* isolate = map->GetIsolate(); | 3158 Isolate* isolate = map->GetIsolate(); |
| 3149 Handle<DescriptorArray> old_descriptors(map->instance_descriptors(), isolate); | 3159 Handle<DescriptorArray> old_descriptors(map->instance_descriptors(), isolate); |
| 3150 int number_of_own_descriptors = map->NumberOfOwnDescriptors(); | 3160 int number_of_own_descriptors = map->NumberOfOwnDescriptors(); |
| 3151 Handle<DescriptorArray> descriptors = | 3161 Handle<DescriptorArray> descriptors = |
| 3152 DescriptorArray::CopyUpTo(old_descriptors, number_of_own_descriptors); | 3162 DescriptorArray::CopyUpTo(old_descriptors, number_of_own_descriptors); |
| 3153 | 3163 |
| 3154 for (int i = 0; i < number_of_own_descriptors; i++) { | 3164 for (int i = 0; i < number_of_own_descriptors; i++) { |
| 3155 descriptors->SetRepresentation(i, Representation::Tagged()); | 3165 descriptors->SetRepresentation(i, Representation::Tagged()); |
| 3156 if (descriptors->GetDetails(i).type() == DATA) { | 3166 if (descriptors->GetDetails(i).type() == DATA) { |
| 3157 descriptors->SetValue(i, FieldType::Any()); | 3167 descriptors->SetValue(i, FieldType::Any()); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3193 } | 3203 } |
| 3194 map->PrintGeneralization( | 3204 map->PrintGeneralization( |
| 3195 stdout, reason, modify_index, new_map->NumberOfOwnDescriptors(), | 3205 stdout, reason, modify_index, new_map->NumberOfOwnDescriptors(), |
| 3196 new_map->NumberOfOwnDescriptors(), | 3206 new_map->NumberOfOwnDescriptors(), |
| 3197 details.type() == DATA_CONSTANT && store_mode == FORCE_FIELD, | 3207 details.type() == DATA_CONSTANT && store_mode == FORCE_FIELD, |
| 3198 details.representation(), Representation::Tagged(), field_type, | 3208 details.representation(), Representation::Tagged(), field_type, |
| 3199 MaybeHandle<Object>(), FieldType::Any(isolate), | 3209 MaybeHandle<Object>(), FieldType::Any(isolate), |
| 3200 MaybeHandle<Object>()); | 3210 MaybeHandle<Object>()); |
| 3201 } | 3211 } |
| 3202 } | 3212 } |
| 3213 new_map->set_elements_kind(elements_kind); |
| 3203 return new_map; | 3214 return new_map; |
| 3204 } | 3215 } |
| 3205 | 3216 |
| 3206 | 3217 |
| 3207 void Map::DeprecateTransitionTree() { | 3218 void Map::DeprecateTransitionTree() { |
| 3208 if (is_deprecated()) return; | 3219 if (is_deprecated()) return; |
| 3209 Object* transitions = raw_transitions(); | 3220 Object* transitions = raw_transitions(); |
| 3210 int num_transitions = TransitionArray::NumberOfTransitions(transitions); | 3221 int num_transitions = TransitionArray::NumberOfTransitions(transitions); |
| 3211 for (int i = 0; i < num_transitions; ++i) { | 3222 for (int i = 0; i < num_transitions; ++i) { |
| 3212 TransitionArray::GetTarget(transitions, i)->DeprecateTransitionTree(); | 3223 TransitionArray::GetTarget(transitions, i)->DeprecateTransitionTree(); |
| (...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3430 DCHECK_EQ(details.location(), location); | 3441 DCHECK_EQ(details.location(), location); |
| 3431 #endif | 3442 #endif |
| 3432 if (location == kField) { | 3443 if (location == kField) { |
| 3433 return handle(descriptors->GetFieldType(descriptor), isolate); | 3444 return handle(descriptors->GetFieldType(descriptor), isolate); |
| 3434 } else { | 3445 } else { |
| 3435 return descriptors->GetValue(descriptor) | 3446 return descriptors->GetValue(descriptor) |
| 3436 ->OptimalType(isolate, representation); | 3447 ->OptimalType(isolate, representation); |
| 3437 } | 3448 } |
| 3438 } | 3449 } |
| 3439 | 3450 |
| 3440 | 3451 // Reconfigures elements kind to |new_elements_kind| and/or property at |
| 3441 // Reconfigures property at |modify_index| with |new_kind|, |new_attributes|, | 3452 // |modify_index| with |new_kind|, |new_attributes|, |store_mode| and/or |
| 3442 // |store_mode| and/or |new_representation|/|new_field_type|. | 3453 // |new_representation|/|new_field_type|. |
| 3443 // If |modify_index| is negative then no properties are reconfigured but the | 3454 // If |modify_index| is negative then no properties are reconfigured but the |
| 3444 // map is migrated to the up-to-date non-deprecated state. | 3455 // map is migrated to the up-to-date non-deprecated state. |
| 3445 // | 3456 // |
| 3446 // This method rewrites or completes the transition tree to reflect the new | 3457 // This method rewrites or completes the transition tree to reflect the new |
| 3447 // change. To avoid high degrees over polymorphism, and to stabilize quickly, | 3458 // change. To avoid high degrees over polymorphism, and to stabilize quickly, |
| 3448 // on every rewrite the new type is deduced by merging the current type with | 3459 // on every rewrite the new type is deduced by merging the current type with |
| 3449 // any potential new (partial) version of the type in the transition tree. | 3460 // any potential new (partial) version of the type in the transition tree. |
| 3450 // To do this, on each rewrite: | 3461 // To do this, on each rewrite: |
| 3451 // - Search the root of the transition tree using FindRootMap. | 3462 // - Search the root of the transition tree using FindRootMap. |
| 3463 // - Find/create a |root_map| with requested |new_elements_kind|. |
| 3452 // - Find |target_map|, the newest matching version of this map using the | 3464 // - Find |target_map|, the newest matching version of this map using the |
| 3453 // virtually "enhanced" |old_map|'s descriptor array (i.e. whose entry at | 3465 // virtually "enhanced" |old_map|'s descriptor array (i.e. whose entry at |
| 3454 // |modify_index| is considered to be of |new_kind| and having | 3466 // |modify_index| is considered to be of |new_kind| and having |
| 3455 // |new_attributes|) to walk the transition tree. | 3467 // |new_attributes|) to walk the transition tree. |
| 3456 // - Merge/generalize the "enhanced" descriptor array of the |old_map| and | 3468 // - Merge/generalize the "enhanced" descriptor array of the |old_map| and |
| 3457 // descriptor array of the |target_map|. | 3469 // descriptor array of the |target_map|. |
| 3458 // - Generalize the |modify_index| descriptor using |new_representation| and | 3470 // - Generalize the |modify_index| descriptor using |new_representation| and |
| 3459 // |new_field_type|. | 3471 // |new_field_type|. |
| 3460 // - Walk the tree again starting from the root towards |target_map|. Stop at | 3472 // - Walk the tree again starting from the root towards |target_map|. Stop at |
| 3461 // |split_map|, the first map who's descriptor array does not match the merged | 3473 // |split_map|, the first map who's descriptor array does not match the merged |
| 3462 // descriptor array. | 3474 // descriptor array. |
| 3463 // - If |target_map| == |split_map|, |target_map| is in the expected state. | 3475 // - If |target_map| == |split_map|, |target_map| is in the expected state. |
| 3464 // Return it. | 3476 // Return it. |
| 3465 // - Otherwise, invalidate the outdated transition target from |target_map|, and | 3477 // - Otherwise, invalidate the outdated transition target from |target_map|, and |
| 3466 // replace its transition tree with a new branch for the updated descriptors. | 3478 // replace its transition tree with a new branch for the updated descriptors. |
| 3467 Handle<Map> Map::ReconfigureProperty(Handle<Map> old_map, int modify_index, | 3479 Handle<Map> Map::Reconfigure(Handle<Map> old_map, |
| 3468 PropertyKind new_kind, | 3480 ElementsKind new_elements_kind, int modify_index, |
| 3469 PropertyAttributes new_attributes, | 3481 PropertyKind new_kind, |
| 3470 Representation new_representation, | 3482 PropertyAttributes new_attributes, |
| 3471 Handle<FieldType> new_field_type, | 3483 Representation new_representation, |
| 3472 StoreMode store_mode) { | 3484 Handle<FieldType> new_field_type, |
| 3485 StoreMode store_mode) { |
| 3473 DCHECK_NE(kAccessor, new_kind); // TODO(ishell): not supported yet. | 3486 DCHECK_NE(kAccessor, new_kind); // TODO(ishell): not supported yet. |
| 3474 DCHECK(store_mode != FORCE_FIELD || modify_index >= 0); | 3487 DCHECK(store_mode != FORCE_FIELD || modify_index >= 0); |
| 3475 Isolate* isolate = old_map->GetIsolate(); | 3488 Isolate* isolate = old_map->GetIsolate(); |
| 3476 | 3489 |
| 3477 Handle<DescriptorArray> old_descriptors( | 3490 Handle<DescriptorArray> old_descriptors( |
| 3478 old_map->instance_descriptors(), isolate); | 3491 old_map->instance_descriptors(), isolate); |
| 3479 int old_nof = old_map->NumberOfOwnDescriptors(); | 3492 int old_nof = old_map->NumberOfOwnDescriptors(); |
| 3480 | 3493 |
| 3481 // If it's just a representation generalization case (i.e. property kind and | 3494 // If it's just a representation generalization case (i.e. property kind and |
| 3482 // attributes stays unchanged) it's fine to transition from None to anything | 3495 // attributes stays unchanged) it's fine to transition from None to anything |
| 3483 // but double without any modification to the object, because the default | 3496 // but double without any modification to the object, because the default |
| 3484 // uninitialized value for representation None can be overwritten by both | 3497 // uninitialized value for representation None can be overwritten by both |
| 3485 // smi and tagged values. Doubles, however, would require a box allocation. | 3498 // smi and tagged values. Doubles, however, would require a box allocation. |
| 3486 if (modify_index >= 0 && !new_representation.IsNone() && | 3499 if (modify_index >= 0 && !new_representation.IsNone() && |
| 3487 !new_representation.IsDouble()) { | 3500 !new_representation.IsDouble() && |
| 3501 old_map->elements_kind() == new_elements_kind) { |
| 3488 PropertyDetails old_details = old_descriptors->GetDetails(modify_index); | 3502 PropertyDetails old_details = old_descriptors->GetDetails(modify_index); |
| 3489 Representation old_representation = old_details.representation(); | 3503 Representation old_representation = old_details.representation(); |
| 3490 | 3504 |
| 3491 if (old_representation.IsNone()) { | 3505 if (old_representation.IsNone()) { |
| 3492 DCHECK_EQ(new_kind, old_details.kind()); | 3506 DCHECK_EQ(new_kind, old_details.kind()); |
| 3493 DCHECK_EQ(new_attributes, old_details.attributes()); | 3507 DCHECK_EQ(new_attributes, old_details.attributes()); |
| 3494 DCHECK_EQ(DATA, old_details.type()); | 3508 DCHECK_EQ(DATA, old_details.type()); |
| 3495 if (FLAG_trace_generalization) { | 3509 if (FLAG_trace_generalization) { |
| 3496 old_map->PrintGeneralization( | 3510 old_map->PrintGeneralization( |
| 3497 stdout, "uninitialized field", modify_index, | 3511 stdout, "uninitialized field", modify_index, |
| (...skipping 12 matching lines...) Expand all Loading... |
| 3510 .Equals(new_representation)); | 3524 .Equals(new_representation)); |
| 3511 DCHECK( | 3525 DCHECK( |
| 3512 old_descriptors->GetFieldType(modify_index)->NowIs(new_field_type)); | 3526 old_descriptors->GetFieldType(modify_index)->NowIs(new_field_type)); |
| 3513 return old_map; | 3527 return old_map; |
| 3514 } | 3528 } |
| 3515 } | 3529 } |
| 3516 | 3530 |
| 3517 // Check the state of the root map. | 3531 // Check the state of the root map. |
| 3518 Handle<Map> root_map(old_map->FindRootMap(), isolate); | 3532 Handle<Map> root_map(old_map->FindRootMap(), isolate); |
| 3519 if (!old_map->EquivalentToForTransition(*root_map)) { | 3533 if (!old_map->EquivalentToForTransition(*root_map)) { |
| 3520 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, | 3534 return CopyGeneralizeAllRepresentations( |
| 3521 new_kind, new_attributes, | 3535 old_map, new_elements_kind, modify_index, store_mode, new_kind, |
| 3522 "GenAll_NotEquivalent"); | 3536 new_attributes, "GenAll_NotEquivalent"); |
| 3523 } | 3537 } |
| 3524 | 3538 |
| 3525 ElementsKind from_kind = root_map->elements_kind(); | 3539 ElementsKind from_kind = root_map->elements_kind(); |
| 3526 ElementsKind to_kind = old_map->elements_kind(); | 3540 ElementsKind to_kind = new_elements_kind; |
| 3527 // TODO(ishell): Add a test for SLOW_SLOPPY_ARGUMENTS_ELEMENTS. | 3541 // TODO(ishell): Add a test for SLOW_SLOPPY_ARGUMENTS_ELEMENTS. |
| 3528 if (from_kind != to_kind && to_kind != DICTIONARY_ELEMENTS && | 3542 if (from_kind != to_kind && to_kind != DICTIONARY_ELEMENTS && |
| 3543 to_kind != SLOW_STRING_WRAPPER_ELEMENTS && |
| 3529 to_kind != SLOW_SLOPPY_ARGUMENTS_ELEMENTS && | 3544 to_kind != SLOW_SLOPPY_ARGUMENTS_ELEMENTS && |
| 3530 !(IsTransitionableFastElementsKind(from_kind) && | 3545 !(IsTransitionableFastElementsKind(from_kind) && |
| 3531 IsMoreGeneralElementsKindTransition(from_kind, to_kind))) { | 3546 IsMoreGeneralElementsKindTransition(from_kind, to_kind))) { |
| 3532 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, | 3547 return CopyGeneralizeAllRepresentations( |
| 3533 new_kind, new_attributes, | 3548 old_map, to_kind, modify_index, store_mode, new_kind, new_attributes, |
| 3534 "GenAll_InvalidElementsTransition"); | 3549 "GenAll_InvalidElementsTransition"); |
| 3535 } | 3550 } |
| 3536 int root_nof = root_map->NumberOfOwnDescriptors(); | 3551 int root_nof = root_map->NumberOfOwnDescriptors(); |
| 3537 if (modify_index >= 0 && modify_index < root_nof) { | 3552 if (modify_index >= 0 && modify_index < root_nof) { |
| 3538 PropertyDetails old_details = old_descriptors->GetDetails(modify_index); | 3553 PropertyDetails old_details = old_descriptors->GetDetails(modify_index); |
| 3539 if (old_details.kind() != new_kind || | 3554 if (old_details.kind() != new_kind || |
| 3540 old_details.attributes() != new_attributes) { | 3555 old_details.attributes() != new_attributes) { |
| 3541 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, | 3556 return CopyGeneralizeAllRepresentations( |
| 3542 new_kind, new_attributes, | 3557 old_map, to_kind, modify_index, store_mode, new_kind, new_attributes, |
| 3543 "GenAll_RootModification1"); | 3558 "GenAll_RootModification1"); |
| 3544 } | 3559 } |
| 3545 if ((old_details.type() != DATA && store_mode == FORCE_FIELD) || | 3560 if ((old_details.type() != DATA && store_mode == FORCE_FIELD) || |
| 3546 (old_details.type() == DATA && | 3561 (old_details.type() == DATA && |
| 3547 (!new_field_type->NowIs(old_descriptors->GetFieldType(modify_index)) || | 3562 (!new_field_type->NowIs(old_descriptors->GetFieldType(modify_index)) || |
| 3548 !new_representation.fits_into(old_details.representation())))) { | 3563 !new_representation.fits_into(old_details.representation())))) { |
| 3549 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, | 3564 return CopyGeneralizeAllRepresentations( |
| 3550 new_kind, new_attributes, | 3565 old_map, to_kind, modify_index, store_mode, new_kind, new_attributes, |
| 3551 "GenAll_RootModification2"); | 3566 "GenAll_RootModification2"); |
| 3552 } | 3567 } |
| 3553 } | 3568 } |
| 3554 | 3569 |
| 3555 // From here on, use the map with correct elements kind as root map. | 3570 // From here on, use the map with correct elements kind as root map. |
| 3556 if (from_kind != to_kind) { | 3571 if (from_kind != to_kind) { |
| 3557 root_map = Map::AsElementsKind(root_map, to_kind); | 3572 root_map = Map::AsElementsKind(root_map, to_kind); |
| 3558 } | 3573 } |
| 3559 | 3574 |
| 3560 Handle<Map> target_map = root_map; | 3575 Handle<Map> target_map = root_map; |
| 3561 for (int i = root_nof; i < old_nof; ++i) { | 3576 for (int i = root_nof; i < old_nof; ++i) { |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3595 Handle<DescriptorArray> tmp_descriptors = handle( | 3610 Handle<DescriptorArray> tmp_descriptors = handle( |
| 3596 tmp_map->instance_descriptors(), isolate); | 3611 tmp_map->instance_descriptors(), isolate); |
| 3597 | 3612 |
| 3598 // Check if target map is incompatible. | 3613 // Check if target map is incompatible. |
| 3599 PropertyDetails tmp_details = tmp_descriptors->GetDetails(i); | 3614 PropertyDetails tmp_details = tmp_descriptors->GetDetails(i); |
| 3600 DCHECK_EQ(next_kind, tmp_details.kind()); | 3615 DCHECK_EQ(next_kind, tmp_details.kind()); |
| 3601 DCHECK_EQ(next_attributes, tmp_details.attributes()); | 3616 DCHECK_EQ(next_attributes, tmp_details.attributes()); |
| 3602 if (next_kind == kAccessor && | 3617 if (next_kind == kAccessor && |
| 3603 !EqualImmutableValues(old_descriptors->GetValue(i), | 3618 !EqualImmutableValues(old_descriptors->GetValue(i), |
| 3604 tmp_descriptors->GetValue(i))) { | 3619 tmp_descriptors->GetValue(i))) { |
| 3605 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, | 3620 return CopyGeneralizeAllRepresentations( |
| 3606 new_kind, new_attributes, | 3621 old_map, to_kind, modify_index, store_mode, new_kind, new_attributes, |
| 3607 "GenAll_Incompatible"); | 3622 "GenAll_Incompatible"); |
| 3608 } | 3623 } |
| 3609 if (next_location == kField && tmp_details.location() == kDescriptor) break; | 3624 if (next_location == kField && tmp_details.location() == kDescriptor) break; |
| 3610 | 3625 |
| 3611 Representation tmp_representation = tmp_details.representation(); | 3626 Representation tmp_representation = tmp_details.representation(); |
| 3612 if (!next_representation.fits_into(tmp_representation)) break; | 3627 if (!next_representation.fits_into(tmp_representation)) break; |
| 3613 | 3628 |
| 3614 PropertyLocation old_location = old_details.location(); | 3629 PropertyLocation old_location = old_details.location(); |
| 3615 PropertyLocation tmp_location = tmp_details.location(); | 3630 PropertyLocation tmp_location = tmp_details.location(); |
| 3616 if (tmp_location == kField) { | 3631 if (tmp_location == kField) { |
| 3617 if (next_kind == kData) { | 3632 if (next_kind == kData) { |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3690 | 3705 |
| 3691 // Check if target map is compatible. | 3706 // Check if target map is compatible. |
| 3692 #ifdef DEBUG | 3707 #ifdef DEBUG |
| 3693 PropertyDetails tmp_details = tmp_descriptors->GetDetails(i); | 3708 PropertyDetails tmp_details = tmp_descriptors->GetDetails(i); |
| 3694 DCHECK_EQ(next_kind, tmp_details.kind()); | 3709 DCHECK_EQ(next_kind, tmp_details.kind()); |
| 3695 DCHECK_EQ(next_attributes, tmp_details.attributes()); | 3710 DCHECK_EQ(next_attributes, tmp_details.attributes()); |
| 3696 #endif | 3711 #endif |
| 3697 if (next_kind == kAccessor && | 3712 if (next_kind == kAccessor && |
| 3698 !EqualImmutableValues(old_descriptors->GetValue(i), | 3713 !EqualImmutableValues(old_descriptors->GetValue(i), |
| 3699 tmp_descriptors->GetValue(i))) { | 3714 tmp_descriptors->GetValue(i))) { |
| 3700 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, | 3715 return CopyGeneralizeAllRepresentations( |
| 3701 new_kind, new_attributes, | 3716 old_map, to_kind, modify_index, store_mode, new_kind, new_attributes, |
| 3702 "GenAll_Incompatible"); | 3717 "GenAll_Incompatible"); |
| 3703 } | 3718 } |
| 3704 DCHECK(!tmp_map->is_deprecated()); | 3719 DCHECK(!tmp_map->is_deprecated()); |
| 3705 target_map = tmp_map; | 3720 target_map = tmp_map; |
| 3706 } | 3721 } |
| 3707 target_nof = target_map->NumberOfOwnDescriptors(); | 3722 target_nof = target_map->NumberOfOwnDescriptors(); |
| 3708 target_descriptors = handle(target_map->instance_descriptors(), isolate); | 3723 target_descriptors = handle(target_map->instance_descriptors(), isolate); |
| 3709 | 3724 |
| 3710 // Allocate a new descriptor array large enough to hold the required | 3725 // Allocate a new descriptor array large enough to hold the required |
| 3711 // descriptors, with minimally the exact same size as the old descriptor | 3726 // descriptors, with minimally the exact same size as the old descriptor |
| 3712 // array. | 3727 // array. |
| (...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3923 split_attributes); | 3938 split_attributes); |
| 3924 if (maybe_transition != NULL) { | 3939 if (maybe_transition != NULL) { |
| 3925 maybe_transition->DeprecateTransitionTree(); | 3940 maybe_transition->DeprecateTransitionTree(); |
| 3926 } | 3941 } |
| 3927 | 3942 |
| 3928 // If |maybe_transition| is not NULL then the transition array already | 3943 // If |maybe_transition| is not NULL then the transition array already |
| 3929 // contains entry for given descriptor. This means that the transition | 3944 // contains entry for given descriptor. This means that the transition |
| 3930 // could be inserted regardless of whether transitions array is full or not. | 3945 // could be inserted regardless of whether transitions array is full or not. |
| 3931 if (maybe_transition == NULL && | 3946 if (maybe_transition == NULL && |
| 3932 !TransitionArray::CanHaveMoreTransitions(split_map)) { | 3947 !TransitionArray::CanHaveMoreTransitions(split_map)) { |
| 3933 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, | 3948 return CopyGeneralizeAllRepresentations( |
| 3934 new_kind, new_attributes, | 3949 old_map, to_kind, modify_index, store_mode, new_kind, new_attributes, |
| 3935 "GenAll_CantHaveMoreTransitions"); | 3950 "GenAll_CantHaveMoreTransitions"); |
| 3936 } | 3951 } |
| 3937 | 3952 |
| 3938 old_map->NotifyLeafMapLayoutChange(); | 3953 old_map->NotifyLeafMapLayoutChange(); |
| 3939 | 3954 |
| 3940 if (FLAG_trace_generalization && modify_index >= 0) { | 3955 if (FLAG_trace_generalization && modify_index >= 0) { |
| 3941 PropertyDetails old_details = old_descriptors->GetDetails(modify_index); | 3956 PropertyDetails old_details = old_descriptors->GetDetails(modify_index); |
| 3942 PropertyDetails new_details = new_descriptors->GetDetails(modify_index); | 3957 PropertyDetails new_details = new_descriptors->GetDetails(modify_index); |
| 3943 MaybeHandle<FieldType> old_field_type; | 3958 MaybeHandle<FieldType> old_field_type; |
| 3944 MaybeHandle<FieldType> new_field_type; | 3959 MaybeHandle<FieldType> new_field_type; |
| 3945 MaybeHandle<Object> old_value; | 3960 MaybeHandle<Object> old_value; |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4006 if (!old_map->EquivalentToForTransition(root_map)) return MaybeHandle<Map>(); | 4021 if (!old_map->EquivalentToForTransition(root_map)) return MaybeHandle<Map>(); |
| 4007 | 4022 |
| 4008 ElementsKind from_kind = root_map->elements_kind(); | 4023 ElementsKind from_kind = root_map->elements_kind(); |
| 4009 ElementsKind to_kind = old_map->elements_kind(); | 4024 ElementsKind to_kind = old_map->elements_kind(); |
| 4010 if (from_kind != to_kind) { | 4025 if (from_kind != to_kind) { |
| 4011 // Try to follow existing elements kind transitions. | 4026 // Try to follow existing elements kind transitions. |
| 4012 root_map = root_map->LookupElementsTransitionMap(to_kind); | 4027 root_map = root_map->LookupElementsTransitionMap(to_kind); |
| 4013 if (root_map == NULL) return MaybeHandle<Map>(); | 4028 if (root_map == NULL) return MaybeHandle<Map>(); |
| 4014 // From here on, use the map with correct elements kind as root map. | 4029 // From here on, use the map with correct elements kind as root map. |
| 4015 } | 4030 } |
| 4016 int root_nof = root_map->NumberOfOwnDescriptors(); | 4031 Map* new_map = root_map->TryReplayPropertyTransitions(*old_map); |
| 4032 if (new_map == nullptr) return MaybeHandle<Map>(); |
| 4033 return handle(new_map); |
| 4034 } |
| 4035 |
| 4036 Map* Map::TryReplayPropertyTransitions(Map* old_map) { |
| 4037 DisallowHeapAllocation no_allocation; |
| 4038 DisallowDeoptimization no_deoptimization(GetIsolate()); |
| 4039 |
| 4040 int root_nof = NumberOfOwnDescriptors(); |
| 4017 | 4041 |
| 4018 int old_nof = old_map->NumberOfOwnDescriptors(); | 4042 int old_nof = old_map->NumberOfOwnDescriptors(); |
| 4019 DescriptorArray* old_descriptors = old_map->instance_descriptors(); | 4043 DescriptorArray* old_descriptors = old_map->instance_descriptors(); |
| 4020 | 4044 |
| 4021 Map* new_map = root_map; | 4045 Map* new_map = this; |
| 4022 for (int i = root_nof; i < old_nof; ++i) { | 4046 for (int i = root_nof; i < old_nof; ++i) { |
| 4023 PropertyDetails old_details = old_descriptors->GetDetails(i); | 4047 PropertyDetails old_details = old_descriptors->GetDetails(i); |
| 4024 Map* transition = TransitionArray::SearchTransition( | 4048 Map* transition = TransitionArray::SearchTransition( |
| 4025 new_map, old_details.kind(), old_descriptors->GetKey(i), | 4049 new_map, old_details.kind(), old_descriptors->GetKey(i), |
| 4026 old_details.attributes()); | 4050 old_details.attributes()); |
| 4027 if (transition == NULL) return MaybeHandle<Map>(); | 4051 if (transition == NULL) return nullptr; |
| 4028 new_map = transition; | 4052 new_map = transition; |
| 4029 DescriptorArray* new_descriptors = new_map->instance_descriptors(); | 4053 DescriptorArray* new_descriptors = new_map->instance_descriptors(); |
| 4030 | 4054 |
| 4031 PropertyDetails new_details = new_descriptors->GetDetails(i); | 4055 PropertyDetails new_details = new_descriptors->GetDetails(i); |
| 4032 DCHECK_EQ(old_details.kind(), new_details.kind()); | 4056 DCHECK_EQ(old_details.kind(), new_details.kind()); |
| 4033 DCHECK_EQ(old_details.attributes(), new_details.attributes()); | 4057 DCHECK_EQ(old_details.attributes(), new_details.attributes()); |
| 4034 if (!old_details.representation().fits_into(new_details.representation())) { | 4058 if (!old_details.representation().fits_into(new_details.representation())) { |
| 4035 return MaybeHandle<Map>(); | 4059 return nullptr; |
| 4036 } | 4060 } |
| 4037 switch (new_details.type()) { | 4061 switch (new_details.type()) { |
| 4038 case DATA: { | 4062 case DATA: { |
| 4039 FieldType* new_type = new_descriptors->GetFieldType(i); | 4063 FieldType* new_type = new_descriptors->GetFieldType(i); |
| 4040 // Cleared field types need special treatment. They represent lost | 4064 // Cleared field types need special treatment. They represent lost |
| 4041 // knowledge, so we must first generalize the new_type to "Any". | 4065 // knowledge, so we must first generalize the new_type to "Any". |
| 4042 if (FieldTypeIsCleared(new_details.representation(), new_type)) { | 4066 if (FieldTypeIsCleared(new_details.representation(), new_type)) { |
| 4043 return MaybeHandle<Map>(); | 4067 return nullptr; |
| 4044 } | 4068 } |
| 4045 PropertyType old_property_type = old_details.type(); | 4069 PropertyType old_property_type = old_details.type(); |
| 4046 if (old_property_type == DATA) { | 4070 if (old_property_type == DATA) { |
| 4047 FieldType* old_type = old_descriptors->GetFieldType(i); | 4071 FieldType* old_type = old_descriptors->GetFieldType(i); |
| 4048 if (FieldTypeIsCleared(old_details.representation(), old_type) || | 4072 if (FieldTypeIsCleared(old_details.representation(), old_type) || |
| 4049 !old_type->NowIs(new_type)) { | 4073 !old_type->NowIs(new_type)) { |
| 4050 return MaybeHandle<Map>(); | 4074 return nullptr; |
| 4051 } | 4075 } |
| 4052 } else { | 4076 } else { |
| 4053 DCHECK(old_property_type == DATA_CONSTANT); | 4077 DCHECK(old_property_type == DATA_CONSTANT); |
| 4054 Object* old_value = old_descriptors->GetValue(i); | 4078 Object* old_value = old_descriptors->GetValue(i); |
| 4055 if (!new_type->NowContains(old_value)) { | 4079 if (!new_type->NowContains(old_value)) { |
| 4056 return MaybeHandle<Map>(); | 4080 return nullptr; |
| 4057 } | 4081 } |
| 4058 } | 4082 } |
| 4059 break; | 4083 break; |
| 4060 } | 4084 } |
| 4061 case ACCESSOR: { | 4085 case ACCESSOR: { |
| 4062 #ifdef DEBUG | 4086 #ifdef DEBUG |
| 4063 FieldType* new_type = new_descriptors->GetFieldType(i); | 4087 FieldType* new_type = new_descriptors->GetFieldType(i); |
| 4064 DCHECK(new_type->IsAny()); | 4088 DCHECK(new_type->IsAny()); |
| 4065 #endif | 4089 #endif |
| 4066 break; | 4090 break; |
| 4067 } | 4091 } |
| 4068 | 4092 |
| 4069 case DATA_CONSTANT: | 4093 case DATA_CONSTANT: |
| 4070 case ACCESSOR_CONSTANT: { | 4094 case ACCESSOR_CONSTANT: { |
| 4071 Object* old_value = old_descriptors->GetValue(i); | 4095 Object* old_value = old_descriptors->GetValue(i); |
| 4072 Object* new_value = new_descriptors->GetValue(i); | 4096 Object* new_value = new_descriptors->GetValue(i); |
| 4073 if (old_details.location() == kField || old_value != new_value) { | 4097 if (old_details.location() == kField || old_value != new_value) { |
| 4074 return MaybeHandle<Map>(); | 4098 return nullptr; |
| 4075 } | 4099 } |
| 4076 break; | 4100 break; |
| 4077 } | 4101 } |
| 4078 } | 4102 } |
| 4079 } | 4103 } |
| 4080 if (new_map->NumberOfOwnDescriptors() != old_nof) return MaybeHandle<Map>(); | 4104 if (new_map->NumberOfOwnDescriptors() != old_nof) return nullptr; |
| 4081 return handle(new_map); | 4105 return new_map; |
| 4082 } | 4106 } |
| 4083 | 4107 |
| 4084 | 4108 |
| 4085 // static | 4109 // static |
| 4086 Handle<Map> Map::Update(Handle<Map> map) { | 4110 Handle<Map> Map::Update(Handle<Map> map) { |
| 4087 if (!map->is_deprecated()) return map; | 4111 if (!map->is_deprecated()) return map; |
| 4088 return ReconfigureProperty(map, -1, kData, NONE, Representation::None(), | 4112 return ReconfigureProperty(map, -1, kData, NONE, Representation::None(), |
| 4089 FieldType::None(map->GetIsolate()), | 4113 FieldType::None(map->GetIsolate()), |
| 4090 ALLOW_IN_DESCRIPTOR); | 4114 ALLOW_IN_DESCRIPTOR); |
| 4091 } | 4115 } |
| (...skipping 637 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4729 | 4753 |
| 4730 | 4754 |
| 4731 static bool ContainsMap(MapHandleList* maps, Map* map) { | 4755 static bool ContainsMap(MapHandleList* maps, Map* map) { |
| 4732 DCHECK_NOT_NULL(map); | 4756 DCHECK_NOT_NULL(map); |
| 4733 for (int i = 0; i < maps->length(); ++i) { | 4757 for (int i = 0; i < maps->length(); ++i) { |
| 4734 if (!maps->at(i).is_null() && *maps->at(i) == map) return true; | 4758 if (!maps->at(i).is_null() && *maps->at(i) == map) return true; |
| 4735 } | 4759 } |
| 4736 return false; | 4760 return false; |
| 4737 } | 4761 } |
| 4738 | 4762 |
| 4763 Map* Map::FindElementsKindTransitionedMap(MapHandleList* candidates) { |
| 4764 DisallowHeapAllocation no_allocation; |
| 4765 DisallowDeoptimization no_deoptimization(GetIsolate()); |
| 4739 | 4766 |
| 4740 Handle<Map> Map::FindTransitionedMap(Handle<Map> map, | 4767 ElementsKind kind = elements_kind(); |
| 4741 MapHandleList* candidates) { | |
| 4742 ElementsKind kind = map->elements_kind(); | |
| 4743 bool packed = IsFastPackedElementsKind(kind); | 4768 bool packed = IsFastPackedElementsKind(kind); |
| 4744 | 4769 |
| 4745 Map* transition = nullptr; | 4770 Map* transition = nullptr; |
| 4746 if (IsTransitionableFastElementsKind(kind)) { | 4771 if (IsTransitionableFastElementsKind(kind)) { |
| 4747 for (Map* current = map->ElementsTransitionMap(); | 4772 // Check the state of the root map. |
| 4748 current != nullptr && current->has_fast_elements(); | 4773 Map* root_map = FindRootMap(); |
| 4749 current = current->ElementsTransitionMap()) { | 4774 if (!EquivalentToForTransition(root_map)) return nullptr; |
| 4775 root_map = root_map->LookupElementsTransitionMap(kind); |
| 4776 DCHECK_NOT_NULL(root_map); |
| 4777 // Starting from the next existing elements kind transition try to |
| 4778 // replay the property transitions that does not involve instance rewriting |
| 4779 // (ElementsTransitionAndStoreStub does not support that). |
| 4780 for (root_map = root_map->ElementsTransitionMap(); |
| 4781 root_map != nullptr && root_map->has_fast_elements(); |
| 4782 root_map = root_map->ElementsTransitionMap()) { |
| 4783 Map* current = root_map->TryReplayPropertyTransitions(this); |
| 4784 if (current == nullptr) continue; |
| 4785 if (InstancesNeedRewriting(current)) continue; |
| 4786 |
| 4750 if (ContainsMap(candidates, current) && | 4787 if (ContainsMap(candidates, current) && |
| 4751 (packed || !IsFastPackedElementsKind(current->elements_kind()))) { | 4788 (packed || !IsFastPackedElementsKind(current->elements_kind()))) { |
| 4752 transition = current; | 4789 transition = current; |
| 4753 packed = packed && IsFastPackedElementsKind(current->elements_kind()); | 4790 packed = packed && IsFastPackedElementsKind(current->elements_kind()); |
| 4754 } | 4791 } |
| 4755 } | 4792 } |
| 4756 } | 4793 } |
| 4757 return transition == nullptr ? Handle<Map>() : handle(transition); | 4794 return transition; |
| 4758 } | 4795 } |
| 4759 | 4796 |
| 4760 | 4797 |
| 4761 static Map* FindClosestElementsTransition(Map* map, ElementsKind to_kind) { | 4798 static Map* FindClosestElementsTransition(Map* map, ElementsKind to_kind) { |
| 4799 // Ensure we are requested to search elements kind transition "near the root". |
| 4800 DCHECK_EQ(map->FindRootMap()->NumberOfOwnDescriptors(), |
| 4801 map->NumberOfOwnDescriptors()); |
| 4762 Map* current_map = map; | 4802 Map* current_map = map; |
| 4763 | 4803 |
| 4764 ElementsKind kind = map->elements_kind(); | 4804 ElementsKind kind = map->elements_kind(); |
| 4765 while (kind != to_kind) { | 4805 while (kind != to_kind) { |
| 4766 Map* next_map = current_map->ElementsTransitionMap(); | 4806 Map* next_map = current_map->ElementsTransitionMap(); |
| 4767 if (next_map == nullptr) return current_map; | 4807 if (next_map == nullptr) return current_map; |
| 4768 kind = next_map->elements_kind(); | 4808 kind = next_map->elements_kind(); |
| 4769 current_map = next_map; | 4809 current_map = next_map; |
| 4770 } | 4810 } |
| 4771 | 4811 |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4882 if (IsFastElementsKind(to_kind)) { | 4922 if (IsFastElementsKind(to_kind)) { |
| 4883 allow_store_transition = | 4923 allow_store_transition = |
| 4884 allow_store_transition && IsTransitionableFastElementsKind(from_kind) && | 4924 allow_store_transition && IsTransitionableFastElementsKind(from_kind) && |
| 4885 IsMoreGeneralElementsKindTransition(from_kind, to_kind); | 4925 IsMoreGeneralElementsKindTransition(from_kind, to_kind); |
| 4886 } | 4926 } |
| 4887 | 4927 |
| 4888 if (!allow_store_transition) { | 4928 if (!allow_store_transition) { |
| 4889 return Map::CopyAsElementsKind(map, to_kind, OMIT_TRANSITION); | 4929 return Map::CopyAsElementsKind(map, to_kind, OMIT_TRANSITION); |
| 4890 } | 4930 } |
| 4891 | 4931 |
| 4892 return Map::AsElementsKind(map, to_kind); | 4932 return Map::ReconfigureElementsKind(map, to_kind); |
| 4893 } | 4933 } |
| 4894 | 4934 |
| 4895 | 4935 |
| 4896 // static | 4936 // static |
| 4897 Handle<Map> Map::AsElementsKind(Handle<Map> map, ElementsKind kind) { | 4937 Handle<Map> Map::AsElementsKind(Handle<Map> map, ElementsKind kind) { |
| 4898 Handle<Map> closest_map(FindClosestElementsTransition(*map, kind)); | 4938 Handle<Map> closest_map(FindClosestElementsTransition(*map, kind)); |
| 4899 | 4939 |
| 4900 if (closest_map->elements_kind() == kind) { | 4940 if (closest_map->elements_kind() == kind) { |
| 4901 return closest_map; | 4941 return closest_map; |
| 4902 } | 4942 } |
| (...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5208 if (map_kind != obj_kind) { | 5248 if (map_kind != obj_kind) { |
| 5209 ElementsKind to_kind = GetMoreGeneralElementsKind(map_kind, obj_kind); | 5249 ElementsKind to_kind = GetMoreGeneralElementsKind(map_kind, obj_kind); |
| 5210 if (IsDictionaryElementsKind(obj_kind)) { | 5250 if (IsDictionaryElementsKind(obj_kind)) { |
| 5211 to_kind = obj_kind; | 5251 to_kind = obj_kind; |
| 5212 } | 5252 } |
| 5213 if (IsDictionaryElementsKind(to_kind)) { | 5253 if (IsDictionaryElementsKind(to_kind)) { |
| 5214 NormalizeElements(object); | 5254 NormalizeElements(object); |
| 5215 } else { | 5255 } else { |
| 5216 TransitionElementsKind(object, to_kind); | 5256 TransitionElementsKind(object, to_kind); |
| 5217 } | 5257 } |
| 5218 map = Map::AsElementsKind(map, to_kind); | 5258 map = Map::ReconfigureElementsKind(map, to_kind); |
| 5219 } | 5259 } |
| 5220 JSObject::MigrateToMap(object, map); | 5260 JSObject::MigrateToMap(object, map); |
| 5221 } | 5261 } |
| 5222 | 5262 |
| 5223 | 5263 |
| 5224 void JSObject::MigrateInstance(Handle<JSObject> object) { | 5264 void JSObject::MigrateInstance(Handle<JSObject> object) { |
| 5225 Handle<Map> original_map(object->map()); | 5265 Handle<Map> original_map(object->map()); |
| 5226 Handle<Map> map = Map::Update(original_map); | 5266 Handle<Map> map = Map::Update(original_map); |
| 5227 map->set_migration_target(true); | 5267 map->set_migration_target(true); |
| 5228 MigrateToMap(object, map); | 5268 MigrateToMap(object, map); |
| (...skipping 4327 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9556 | 9596 |
| 9557 Handle<Name> name = handle(descriptors->GetKey(new_descriptor)); | 9597 Handle<Name> name = handle(descriptors->GetKey(new_descriptor)); |
| 9558 ConnectTransition(parent, child, name, SIMPLE_PROPERTY_TRANSITION); | 9598 ConnectTransition(parent, child, name, SIMPLE_PROPERTY_TRANSITION); |
| 9559 } | 9599 } |
| 9560 | 9600 |
| 9561 | 9601 |
| 9562 Handle<Map> Map::CopyAsElementsKind(Handle<Map> map, ElementsKind kind, | 9602 Handle<Map> Map::CopyAsElementsKind(Handle<Map> map, ElementsKind kind, |
| 9563 TransitionFlag flag) { | 9603 TransitionFlag flag) { |
| 9564 Map* maybe_elements_transition_map = NULL; | 9604 Map* maybe_elements_transition_map = NULL; |
| 9565 if (flag == INSERT_TRANSITION) { | 9605 if (flag == INSERT_TRANSITION) { |
| 9606 // Ensure we are requested to add elements kind transition "near the root". |
| 9607 DCHECK_EQ(map->FindRootMap()->NumberOfOwnDescriptors(), |
| 9608 map->NumberOfOwnDescriptors()); |
| 9609 |
| 9566 maybe_elements_transition_map = map->ElementsTransitionMap(); | 9610 maybe_elements_transition_map = map->ElementsTransitionMap(); |
| 9567 DCHECK(maybe_elements_transition_map == NULL || | 9611 DCHECK(maybe_elements_transition_map == NULL || |
| 9568 (maybe_elements_transition_map->elements_kind() == | 9612 (maybe_elements_transition_map->elements_kind() == |
| 9569 DICTIONARY_ELEMENTS && | 9613 DICTIONARY_ELEMENTS && |
| 9570 kind == DICTIONARY_ELEMENTS)); | 9614 kind == DICTIONARY_ELEMENTS)); |
| 9571 DCHECK(!IsFastElementsKind(kind) || | 9615 DCHECK(!IsFastElementsKind(kind) || |
| 9572 IsMoreGeneralElementsKindTransition(map->elements_kind(), kind)); | 9616 IsMoreGeneralElementsKindTransition(map->elements_kind(), kind)); |
| 9573 DCHECK(kind != map->elements_kind()); | 9617 DCHECK(kind != map->elements_kind()); |
| 9574 } | 9618 } |
| 9575 | 9619 |
| (...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9883 Handle<Map> Map::ReconfigureExistingProperty(Handle<Map> map, int descriptor, | 9927 Handle<Map> Map::ReconfigureExistingProperty(Handle<Map> map, int descriptor, |
| 9884 PropertyKind kind, | 9928 PropertyKind kind, |
| 9885 PropertyAttributes attributes) { | 9929 PropertyAttributes attributes) { |
| 9886 // Dictionaries have to be reconfigured in-place. | 9930 // Dictionaries have to be reconfigured in-place. |
| 9887 DCHECK(!map->is_dictionary_map()); | 9931 DCHECK(!map->is_dictionary_map()); |
| 9888 | 9932 |
| 9889 if (!map->GetBackPointer()->IsMap()) { | 9933 if (!map->GetBackPointer()->IsMap()) { |
| 9890 // There is no benefit from reconstructing transition tree for maps without | 9934 // There is no benefit from reconstructing transition tree for maps without |
| 9891 // back pointers. | 9935 // back pointers. |
| 9892 return CopyGeneralizeAllRepresentations( | 9936 return CopyGeneralizeAllRepresentations( |
| 9893 map, descriptor, FORCE_FIELD, kind, attributes, | 9937 map, map->elements_kind(), descriptor, FORCE_FIELD, kind, attributes, |
| 9894 "GenAll_AttributesMismatchProtoMap"); | 9938 "GenAll_AttributesMismatchProtoMap"); |
| 9895 } | 9939 } |
| 9896 | 9940 |
| 9897 if (FLAG_trace_generalization) { | 9941 if (FLAG_trace_generalization) { |
| 9898 map->PrintReconfiguration(stdout, descriptor, kind, attributes); | 9942 map->PrintReconfiguration(stdout, descriptor, kind, attributes); |
| 9899 } | 9943 } |
| 9900 | 9944 |
| 9901 Isolate* isolate = map->GetIsolate(); | 9945 Isolate* isolate = map->GetIsolate(); |
| 9902 Handle<Map> new_map = ReconfigureProperty( | 9946 Handle<Map> new_map = ReconfigureProperty( |
| 9903 map, descriptor, kind, attributes, Representation::None(), | 9947 map, descriptor, kind, attributes, Representation::None(), |
| (...skipping 9997 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 19901 if (cell->value() != *new_value) { | 19945 if (cell->value() != *new_value) { |
| 19902 cell->set_value(*new_value); | 19946 cell->set_value(*new_value); |
| 19903 Isolate* isolate = cell->GetIsolate(); | 19947 Isolate* isolate = cell->GetIsolate(); |
| 19904 cell->dependent_code()->DeoptimizeDependentCodeGroup( | 19948 cell->dependent_code()->DeoptimizeDependentCodeGroup( |
| 19905 isolate, DependentCode::kPropertyCellChangedGroup); | 19949 isolate, DependentCode::kPropertyCellChangedGroup); |
| 19906 } | 19950 } |
| 19907 } | 19951 } |
| 19908 | 19952 |
| 19909 } // namespace internal | 19953 } // namespace internal |
| 19910 } // namespace v8 | 19954 } // namespace v8 |
| OLD | NEW |