Implement most common usecase for elements kind generalization

BUG=

Review URL: https://codereview.chromium.org/931083002

Cr-Commit-Position: refs/heads/master@{#26681}
This commit is contained in:
verwaest 2015-02-17 02:06:52 -08:00 committed by Commit bot
parent e60ec273cc
commit 8e53e31eeb

View File

@ -2243,7 +2243,7 @@ Map* Map::FindLastMatchMap(int verbatim,
DisallowHeapAllocation no_allocation;
// This can only be called on roots of transition trees.
DCHECK(GetBackPointer()->IsUndefined());
DCHECK_EQ(verbatim, NumberOfOwnDescriptors());
Map* current = this;
@ -2482,6 +2482,16 @@ Handle<Map> Map::ReconfigureProperty(Handle<Map> old_map, int modify_index,
new_kind, new_attributes,
"GenAll_NotEquivalent");
}
ElementsKind from_kind = root_map->elements_kind();
ElementsKind to_kind = old_map->elements_kind();
if (from_kind != to_kind &&
!(IsTransitionableFastElementsKind(from_kind) &&
IsMoreGeneralElementsKindTransition(from_kind, to_kind))) {
return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode,
new_kind, new_attributes,
"GenAll_InvalidElementsTransition");
}
int root_nof = root_map->NumberOfOwnDescriptors();
if (modify_index >= 0 && modify_index < root_nof) {
PropertyDetails old_details = old_descriptors->GetDetails(modify_index);
@ -2501,6 +2511,11 @@ Handle<Map> Map::ReconfigureProperty(Handle<Map> old_map, int modify_index,
}
}
// From here on, use the map with correct elements kind as root map.
if (from_kind != to_kind) {
root_map = Map::AsElementsKind(root_map, to_kind);
}
Handle<Map> target_map = root_map;
for (int i = root_nof; i < old_nof; ++i) {
PropertyDetails old_details = old_descriptors->GetDetails(i);
@ -9656,13 +9671,13 @@ int Map::Hash() {
static bool CheckEquivalent(Map* first, Map* second) {
return
first->constructor() == second->constructor() &&
first->prototype() == second->prototype() &&
first->instance_type() == second->instance_type() &&
first->bit_field() == second->bit_field() &&
first->bit_field2() == second->bit_field2() &&
first->has_instance_call_handler() == second->has_instance_call_handler();
return first->constructor() == second->constructor() &&
first->prototype() == second->prototype() &&
first->instance_type() == second->instance_type() &&
first->bit_field() == second->bit_field() &&
first->is_extensible() == second->is_extensible() &&
first->has_instance_call_handler() ==
second->has_instance_call_handler();
}
@ -9675,7 +9690,8 @@ bool Map::EquivalentToForNormalization(Map* other,
PropertyNormalizationMode mode) {
int properties = mode == CLEAR_INOBJECT_PROPERTIES
? 0 : other->inobject_properties();
return CheckEquivalent(this, other) && inobject_properties() == properties;
return CheckEquivalent(this, other) && bit_field2() == other->bit_field2() &&
inobject_properties() == properties;
}