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
This commit is contained in:
parent
88ca76bce1
commit
b922b0dd8a
@ -2779,31 +2779,64 @@ MaybeHandle<Map> Map::CurrentMapForDeprecated(Handle<Map> map) {
|
||||
|
||||
|
||||
// static
|
||||
MaybeHandle<Map> Map::CurrentMapForDeprecatedInternal(Handle<Map> map) {
|
||||
if (!map->is_deprecated()) return map;
|
||||
|
||||
MaybeHandle<Map> Map::CurrentMapForDeprecatedInternal(Handle<Map> 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<Map>();
|
||||
int verbatim = root_map->NumberOfOwnDescriptors();
|
||||
Map* root_map = old_map->FindRootMap();
|
||||
if (!old_map->EquivalentToForTransition(root_map)) return MaybeHandle<Map>();
|
||||
int root_nof = root_map->NumberOfOwnDescriptors();
|
||||
|
||||
Map* updated = root_map->FindUpdatedMap(
|
||||
verbatim, descriptors, old_descriptors);
|
||||
if (updated == NULL) return MaybeHandle<Map>();
|
||||
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>();
|
||||
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<Map>();
|
||||
new_map = new_map->GetTransition(j);
|
||||
DescriptorArray* new_descriptors = new_map->instance_descriptors();
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
return handle(updated);
|
||||
if (new_map->NumberOfOwnDescriptors() != old_nof) return MaybeHandle<Map>();
|
||||
return handle(new_map);
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user