Commit fafa02ea authored by verwaest@chromium.org's avatar verwaest@chromium.org

Don't insert transitions between maps for prototypes.

BUG=
R=ishell@chromium.org

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

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@22828 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 1404664e
...@@ -2074,15 +2074,10 @@ bool Map::InstancesNeedRewriting(Map* target, int target_number_of_fields, ...@@ -2074,15 +2074,10 @@ bool Map::InstancesNeedRewriting(Map* target, int target_number_of_fields,
} }
Handle<TransitionArray> Map::SetElementsTransitionMap( void Map::ConnectElementsTransition(Handle<Map> parent, Handle<Map> child) {
Handle<Map> map, Handle<Map> transitioned_map) { Isolate* isolate = parent->GetIsolate();
Handle<TransitionArray> transitions = TransitionArray::CopyInsert( Handle<Name> name = isolate->factory()->elements_transition_symbol();
map, ConnectTransition(parent, child, name, FULL_TRANSITION);
map->GetIsolate()->factory()->elements_transition_symbol(),
transitioned_map,
FULL_TRANSITION);
map->set_transitions(*transitions);
return transitions;
} }
...@@ -2090,7 +2085,17 @@ void JSObject::MigrateToMap(Handle<JSObject> object, Handle<Map> new_map) { ...@@ -2090,7 +2085,17 @@ void JSObject::MigrateToMap(Handle<JSObject> object, Handle<Map> new_map) {
if (object->map() == *new_map) return; if (object->map() == *new_map) return;
if (object->HasFastProperties()) { if (object->HasFastProperties()) {
if (!new_map->is_dictionary_map()) { if (!new_map->is_dictionary_map()) {
Handle<Map> old_map(object->map());
MigrateFastToFast(object, new_map); MigrateFastToFast(object, new_map);
if (old_map->is_prototype_map()) {
// Clear out the old descriptor array to avoid problems to sharing
// the descriptor array without using an explicit.
old_map->InitializeDescriptors(
old_map->GetHeap()->empty_descriptor_array());
// Ensure that no transition was inserted for prototype migrations.
DCHECK(!old_map->HasTransitionArray());
DCHECK(new_map->GetBackPointer()->IsUndefined());
}
} else { } else {
MigrateFastToSlow(object, new_map, 0); MigrateFastToSlow(object, new_map, 0);
} }
...@@ -3459,10 +3464,12 @@ static Handle<Map> AddMissingElementsTransitions(Handle<Map> map, ...@@ -3459,10 +3464,12 @@ static Handle<Map> AddMissingElementsTransitions(Handle<Map> map,
Handle<Map> current_map = map; Handle<Map> current_map = map;
ElementsKind kind = map->elements_kind(); ElementsKind kind = map->elements_kind();
while (kind != to_kind && !IsTerminalElementsKind(kind)) { if (!map->is_prototype_map()) {
kind = GetNextTransitionElementsKind(kind); while (kind != to_kind && !IsTerminalElementsKind(kind)) {
current_map = Map::CopyAsElementsKind( kind = GetNextTransitionElementsKind(kind);
current_map, kind, INSERT_TRANSITION); current_map =
Map::CopyAsElementsKind(current_map, kind, INSERT_TRANSITION);
}
} }
// In case we are exiting the fast elements kind system, just add the map in // In case we are exiting the fast elements kind system, just add the map in
...@@ -7110,8 +7117,6 @@ Handle<Map> Map::ShareDescriptor(Handle<Map> map, ...@@ -7110,8 +7117,6 @@ Handle<Map> Map::ShareDescriptor(Handle<Map> map,
Handle<Map> result = CopyDropDescriptors(map); Handle<Map> result = CopyDropDescriptors(map);
Handle<Name> name = descriptor->GetKey(); Handle<Name> name = descriptor->GetKey();
Handle<TransitionArray> transitions =
TransitionArray::CopyInsert(map, name, result, SIMPLE_TRANSITION);
// Ensure there's space for the new descriptor in the shared descriptor array. // Ensure there's space for the new descriptor in the shared descriptor array.
if (descriptors->NumberOfSlackDescriptors() == 0) { if (descriptors->NumberOfSlackDescriptors() == 0) {
...@@ -7124,22 +7129,33 @@ Handle<Map> Map::ShareDescriptor(Handle<Map> map, ...@@ -7124,22 +7129,33 @@ Handle<Map> Map::ShareDescriptor(Handle<Map> map,
} }
} }
// Commit the state atomically. {
DisallowHeapAllocation no_gc; DisallowHeapAllocation no_gc;
descriptors->Append(descriptor);
descriptors->Append(descriptor); result->InitializeDescriptors(*descriptors);
result->SetBackPointer(*map); }
result->InitializeDescriptors(*descriptors);
DCHECK(result->NumberOfOwnDescriptors() == map->NumberOfOwnDescriptors() + 1); DCHECK(result->NumberOfOwnDescriptors() == map->NumberOfOwnDescriptors() + 1);
ConnectTransition(map, result, name, SIMPLE_TRANSITION);
map->set_transitions(*transitions);
map->set_owns_descriptors(false);
return result; return result;
} }
void Map::ConnectTransition(Handle<Map> parent, Handle<Map> child,
Handle<Name> name, SimpleTransitionFlag flag) {
parent->set_owns_descriptors(false);
if (parent->is_prototype_map()) {
DCHECK(child->is_prototype_map());
} else {
Handle<TransitionArray> transitions =
TransitionArray::CopyInsert(parent, name, child, flag);
parent->set_transitions(*transitions);
child->SetBackPointer(*parent);
}
}
Handle<Map> Map::CopyReplaceDescriptors(Handle<Map> map, Handle<Map> Map::CopyReplaceDescriptors(Handle<Map> map,
Handle<DescriptorArray> descriptors, Handle<DescriptorArray> descriptors,
TransitionFlag flag, TransitionFlag flag,
...@@ -7150,19 +7166,18 @@ Handle<Map> Map::CopyReplaceDescriptors(Handle<Map> map, ...@@ -7150,19 +7166,18 @@ Handle<Map> Map::CopyReplaceDescriptors(Handle<Map> map,
Handle<Map> result = CopyDropDescriptors(map); Handle<Map> result = CopyDropDescriptors(map);
result->InitializeDescriptors(*descriptors); result->InitializeDescriptors(*descriptors);
if (flag == INSERT_TRANSITION && map->CanHaveMoreTransitions()) { if (!map->is_prototype_map()) {
Handle<Name> name; if (flag == INSERT_TRANSITION && map->CanHaveMoreTransitions()) {
CHECK(maybe_name.ToHandle(&name)); Handle<Name> name;
Handle<TransitionArray> transitions = TransitionArray::CopyInsert( CHECK(maybe_name.ToHandle(&name));
map, name, result, simple_flag); ConnectTransition(map, result, name, simple_flag);
map->set_transitions(*transitions); } else {
result->SetBackPointer(*map); int length = descriptors->number_of_descriptors();
} else { for (int i = 0; i < length; i++) {
int length = descriptors->number_of_descriptors(); descriptors->SetRepresentation(i, Representation::Tagged());
for (int i = 0; i < length; i++) { if (descriptors->GetDetails(i).type() == FIELD) {
descriptors->SetRepresentation(i, Representation::Tagged()); descriptors->SetValue(i, HeapType::Any());
if (descriptors->GetDetails(i).type() == FIELD) { }
descriptors->SetValue(i, HeapType::Any());
} }
} }
} }
...@@ -7192,14 +7207,9 @@ Handle<Map> Map::CopyInstallDescriptors(Handle<Map> map, ...@@ -7192,14 +7207,9 @@ Handle<Map> Map::CopyInstallDescriptors(Handle<Map> map,
} }
result->set_unused_property_fields(unused_property_fields); result->set_unused_property_fields(unused_property_fields);
result->set_owns_descriptors(false);
Handle<Name> name = handle(descriptors->GetKey(new_descriptor)); Handle<Name> name = handle(descriptors->GetKey(new_descriptor));
Handle<TransitionArray> transitions = TransitionArray::CopyInsert( ConnectTransition(map, result, name, SIMPLE_TRANSITION);
map, name, result, SIMPLE_TRANSITION);
map->set_transitions(*transitions);
result->SetBackPointer(*map);
return result; return result;
} }
...@@ -7228,12 +7238,10 @@ Handle<Map> Map::CopyAsElementsKind(Handle<Map> map, ElementsKind kind, ...@@ -7228,12 +7238,10 @@ Handle<Map> Map::CopyAsElementsKind(Handle<Map> map, ElementsKind kind,
// transfer ownership to the new map. // transfer ownership to the new map.
Handle<Map> new_map = CopyDropDescriptors(map); Handle<Map> new_map = CopyDropDescriptors(map);
SetElementsTransitionMap(map, new_map); ConnectElementsTransition(map, new_map);
new_map->set_elements_kind(kind); new_map->set_elements_kind(kind);
new_map->InitializeDescriptors(map->instance_descriptors()); new_map->InitializeDescriptors(map->instance_descriptors());
new_map->SetBackPointer(*map);
map->set_owns_descriptors(false);
return new_map; return new_map;
} }
...@@ -7245,8 +7253,7 @@ Handle<Map> Map::CopyAsElementsKind(Handle<Map> map, ElementsKind kind, ...@@ -7245,8 +7253,7 @@ Handle<Map> Map::CopyAsElementsKind(Handle<Map> map, ElementsKind kind,
new_map->set_elements_kind(kind); new_map->set_elements_kind(kind);
if (insert_transition) { if (insert_transition) {
SetElementsTransitionMap(map, new_map); ConnectElementsTransition(map, new_map);
new_map->SetBackPointer(*map);
} }
return new_map; return new_map;
...@@ -7264,22 +7271,18 @@ Handle<Map> Map::CopyForObserved(Handle<Map> map) { ...@@ -7264,22 +7271,18 @@ Handle<Map> Map::CopyForObserved(Handle<Map> map) {
if (map->owns_descriptors()) { if (map->owns_descriptors()) {
new_map = CopyDropDescriptors(map); new_map = CopyDropDescriptors(map);
} else { } else {
DCHECK(!map->is_prototype_map());
new_map = Copy(map); new_map = Copy(map);
} }
Handle<TransitionArray> transitions = TransitionArray::CopyInsert(
map, isolate->factory()->observed_symbol(), new_map, FULL_TRANSITION);
map->set_transitions(*transitions);
new_map->set_is_observed(); new_map->set_is_observed();
if (map->owns_descriptors()) { if (map->owns_descriptors()) {
new_map->InitializeDescriptors(map->instance_descriptors()); new_map->InitializeDescriptors(map->instance_descriptors());
map->set_owns_descriptors(false);
} }
new_map->SetBackPointer(*map); Handle<Name> name = isolate->factory()->observed_symbol();
ConnectTransition(map, new_map, name, FULL_TRANSITION);
return new_map; return new_map;
} }
...@@ -11923,7 +11926,9 @@ Handle<Map> Map::PutPrototypeTransition(Handle<Map> map, ...@@ -11923,7 +11926,9 @@ Handle<Map> Map::PutPrototypeTransition(Handle<Map> map,
Handle<Map> target_map) { Handle<Map> target_map) {
DCHECK(target_map->IsMap()); DCHECK(target_map->IsMap());
DCHECK(HeapObject::cast(*prototype)->map()->IsMap()); DCHECK(HeapObject::cast(*prototype)->map()->IsMap());
// Don't cache prototype transition if this map is shared. // Don't cache prototype transition if this map is either shared, or a map of
// a prototype.
if (map->is_prototype_map()) return map;
if (map->is_shared() || !FLAG_cache_prototype_transitions) return map; if (map->is_shared() || !FLAG_cache_prototype_transitions) return map;
const int step = kProtoTransitionElementsPerEntry; const int step = kProtoTransitionElementsPerEntry;
......
...@@ -6767,8 +6767,9 @@ class Map: public HeapObject { ...@@ -6767,8 +6767,9 @@ class Map: public HeapObject {
bool EquivalentToForNormalization(Map* other, PropertyNormalizationMode mode); bool EquivalentToForNormalization(Map* other, PropertyNormalizationMode mode);
private: private:
static Handle<TransitionArray> SetElementsTransitionMap( static void ConnectElementsTransition(Handle<Map> parent, Handle<Map> child);
Handle<Map> map, Handle<Map> transitioned_map); static void ConnectTransition(Handle<Map> parent, Handle<Map> child,
Handle<Name> name, SimpleTransitionFlag flag);
bool EquivalentToForTransition(Map* other); bool EquivalentToForTransition(Map* other);
static Handle<Map> RawCopy(Handle<Map> map, int instance_size); static Handle<Map> RawCopy(Handle<Map> map, int instance_size);
......
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