From b922b0dd8a416b7f7f51955b7c8487b15c1c061a Mon Sep 17 00:00:00 2001 From: "bmeurer@chromium.org" Date: Mon, 28 Apr 2014 06:31:23 +0000 Subject: [PATCH] Fix and improve Map::CurrentMapForDeprecatedInternal(). Inline relevant bits from Map::FindUpdatedMap() and Map::IsMoreGeneralThan() into Map::CurrentMapForDeprecatedInternal() to fix issues introduced with field type tracking, avoid the useless second pass over the transition tree, and finally make it easier to understand what this method actually does. TEST=mjsunit/regress/regress-365172-2 R=svenpanne@chromium.org Review URL: https://codereview.chromium.org/257893004 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@20997 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/objects.cc | 69 +++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 51 insertions(+), 18 deletions(-) diff --git a/src/objects.cc b/src/objects.cc index 0910176..38409d1 100644 --- a/src/objects.cc +++ b/src/objects.cc @@ -2779,31 +2779,64 @@ MaybeHandle Map::CurrentMapForDeprecated(Handle map) { // static -MaybeHandle Map::CurrentMapForDeprecatedInternal(Handle map) { - if (!map->is_deprecated()) return map; - +MaybeHandle Map::CurrentMapForDeprecatedInternal(Handle old_map) { DisallowHeapAllocation no_allocation; - DescriptorArray* old_descriptors = map->instance_descriptors(); - int descriptors = map->NumberOfOwnDescriptors(); - Map* root_map = map->FindRootMap(); + if (!old_map->is_deprecated()) return old_map; // Check the state of the root map. - if (!map->EquivalentToForTransition(root_map)) return MaybeHandle(); - int verbatim = root_map->NumberOfOwnDescriptors(); + Map* root_map = old_map->FindRootMap(); + if (!old_map->EquivalentToForTransition(root_map)) return MaybeHandle(); + int root_nof = root_map->NumberOfOwnDescriptors(); - Map* updated = root_map->FindUpdatedMap( - verbatim, descriptors, old_descriptors); - if (updated == NULL) return MaybeHandle(); + int old_nof = old_map->NumberOfOwnDescriptors(); + DescriptorArray* old_descriptors = old_map->instance_descriptors(); - DescriptorArray* updated_descriptors = updated->instance_descriptors(); - int valid = updated->NumberOfOwnDescriptors(); - if (!updated_descriptors->IsMoreGeneralThan( - verbatim, valid, descriptors, old_descriptors)) { - return MaybeHandle(); - } + Map* new_map = root_map; + for (int i = root_nof; i < old_nof; ++i) { + int j = new_map->SearchTransition(old_descriptors->GetKey(i)); + if (j == TransitionArray::kNotFound) return MaybeHandle(); + new_map = new_map->GetTransition(j); + DescriptorArray* new_descriptors = new_map->instance_descriptors(); - return handle(updated); + PropertyDetails new_details = new_descriptors->GetDetails(i); + PropertyDetails old_details = old_descriptors->GetDetails(i); + if (old_details.attributes() != new_details.attributes() || + !old_details.representation().fits_into(new_details.representation())) { + return MaybeHandle(); + } + PropertyType new_type = new_details.type(); + PropertyType old_type = old_details.type(); + Object* new_value = new_descriptors->GetValue(i); + Object* old_value = old_descriptors->GetValue(i); + switch (new_type) { + case FIELD: + if ((old_type == FIELD && + !HeapType::cast(old_value)->NowIs(HeapType::cast(new_value))) || + (old_type == CONSTANT && + !HeapType::cast(new_value)->NowContains(old_value)) || + (old_type == CALLBACKS && + !HeapType::Any()->Is(HeapType::cast(new_value)))) { + return MaybeHandle(); + } + break; + + case CONSTANT: + case CALLBACKS: + if (old_type != new_type || old_value != new_value) { + return MaybeHandle(); + } + break; + + case NORMAL: + case HANDLER: + case INTERCEPTOR: + case NONEXISTENT: + UNREACHABLE(); + } + } + if (new_map->NumberOfOwnDescriptors() != old_nof) return MaybeHandle(); + return handle(new_map); } -- 2.7.4