Commit b922b0dd authored by bmeurer@chromium.org's avatar bmeurer@chromium.org

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
parent 88ca76bc
...@@ -2779,31 +2779,64 @@ MaybeHandle<Map> Map::CurrentMapForDeprecated(Handle<Map> map) { ...@@ -2779,31 +2779,64 @@ MaybeHandle<Map> Map::CurrentMapForDeprecated(Handle<Map> map) {
// static // static
MaybeHandle<Map> Map::CurrentMapForDeprecatedInternal(Handle<Map> map) { MaybeHandle<Map> Map::CurrentMapForDeprecatedInternal(Handle<Map> old_map) {
if (!map->is_deprecated()) return map;
DisallowHeapAllocation no_allocation; DisallowHeapAllocation no_allocation;
DescriptorArray* old_descriptors = map->instance_descriptors();
int descriptors = map->NumberOfOwnDescriptors(); if (!old_map->is_deprecated()) return old_map;
Map* root_map = map->FindRootMap();
// Check the state of the root map. // Check the state of the root map.
if (!map->EquivalentToForTransition(root_map)) return MaybeHandle<Map>(); Map* root_map = old_map->FindRootMap();
int verbatim = root_map->NumberOfOwnDescriptors(); if (!old_map->EquivalentToForTransition(root_map)) return MaybeHandle<Map>();
int root_nof = root_map->NumberOfOwnDescriptors();
Map* updated = root_map->FindUpdatedMap( int old_nof = old_map->NumberOfOwnDescriptors();
verbatim, descriptors, old_descriptors); DescriptorArray* old_descriptors = old_map->instance_descriptors();
if (updated == NULL) return MaybeHandle<Map>();
DescriptorArray* updated_descriptors = updated->instance_descriptors(); Map* new_map = root_map;
int valid = updated->NumberOfOwnDescriptors(); for (int i = root_nof; i < old_nof; ++i) {
if (!updated_descriptors->IsMoreGeneralThan( int j = new_map->SearchTransition(old_descriptors->GetKey(i));
verbatim, valid, descriptors, old_descriptors)) { if (j == TransitionArray::kNotFound) return MaybeHandle<Map>();
return MaybeHandle<Map>(); 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<Map>();
}
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<Map>();
}
break;
case CONSTANT:
case CALLBACKS:
if (old_type != new_type || old_value != new_value) {
return MaybeHandle<Map>();
}
break;
case NORMAL:
case HANDLER:
case INTERCEPTOR:
case NONEXISTENT:
UNREACHABLE();
}
}
if (new_map->NumberOfOwnDescriptors() != old_nof) return MaybeHandle<Map>();
return handle(new_map);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment