Index: src/objects.cc |
diff --git a/src/objects.cc b/src/objects.cc |
index 0910176e40ffd128f962b69f0fcb5358f3e7473f..38409d1d024d483e4c1fa383a23aecd5008f95bf 100644 |
--- a/src/objects.cc |
+++ b/src/objects.cc |
@@ -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(); |
- 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); |
} |