Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(202)

Unified Diff: src/objects.cc

Issue 437953004: Don't insert transitions between maps for prototypes. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Insert transition in ConnectTransition Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/objects.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/objects.cc
diff --git a/src/objects.cc b/src/objects.cc
index 802a4342884138667e1d0c9aa579515a44e7a02c..6fe947bb92c13378c28019bf6950c6bca9eaa568 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -2074,15 +2074,10 @@ bool Map::InstancesNeedRewriting(Map* target, int target_number_of_fields,
}
-Handle<TransitionArray> Map::SetElementsTransitionMap(
- Handle<Map> map, Handle<Map> transitioned_map) {
- Handle<TransitionArray> transitions = TransitionArray::CopyInsert(
- map,
- map->GetIsolate()->factory()->elements_transition_symbol(),
- transitioned_map,
- FULL_TRANSITION);
- map->set_transitions(*transitions);
- return transitions;
+void Map::ConnectElementsTransition(Handle<Map> parent, Handle<Map> child) {
+ Isolate* isolate = parent->GetIsolate();
+ Handle<Name> name = isolate->factory()->elements_transition_symbol();
+ ConnectTransition(parent, child, name, FULL_TRANSITION);
}
@@ -2090,7 +2085,17 @@ void JSObject::MigrateToMap(Handle<JSObject> object, Handle<Map> new_map) {
if (object->map() == *new_map) return;
if (object->HasFastProperties()) {
if (!new_map->is_dictionary_map()) {
+ Handle<Map> old_map(object->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 {
MigrateFastToSlow(object, new_map, 0);
}
@@ -3459,10 +3464,12 @@ static Handle<Map> AddMissingElementsTransitions(Handle<Map> map,
Handle<Map> current_map = map;
ElementsKind kind = map->elements_kind();
- while (kind != to_kind && !IsTerminalElementsKind(kind)) {
- kind = GetNextTransitionElementsKind(kind);
- current_map = Map::CopyAsElementsKind(
- current_map, kind, INSERT_TRANSITION);
+ if (!map->is_prototype_map()) {
+ while (kind != to_kind && !IsTerminalElementsKind(kind)) {
+ kind = GetNextTransitionElementsKind(kind);
+ current_map =
+ Map::CopyAsElementsKind(current_map, kind, INSERT_TRANSITION);
+ }
}
// In case we are exiting the fast elements kind system, just add the map in
@@ -5708,7 +5715,7 @@ MaybeHandle<Object> JSObject::Freeze(Handle<JSObject> object) {
Handle<Map> new_map = Map::CopyForFreeze(old_map);
JSObject::MigrateToMap(object, new_map);
} else {
- ASSERT(!old_map->is_prototype_map());
+ DCHECK(!old_map->is_prototype_map());
// Slow path: need to normalize properties for safety
NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0);
@@ -7110,8 +7117,6 @@ Handle<Map> Map::ShareDescriptor(Handle<Map> map,
Handle<Map> result = CopyDropDescriptors(map);
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.
if (descriptors->NumberOfSlackDescriptors() == 0) {
@@ -7124,22 +7129,33 @@ Handle<Map> Map::ShareDescriptor(Handle<Map> map,
}
}
- // Commit the state atomically.
- DisallowHeapAllocation no_gc;
-
- descriptors->Append(descriptor);
- result->SetBackPointer(*map);
- result->InitializeDescriptors(*descriptors);
+ {
+ DisallowHeapAllocation no_gc;
+ descriptors->Append(descriptor);
+ result->InitializeDescriptors(*descriptors);
+ }
DCHECK(result->NumberOfOwnDescriptors() == map->NumberOfOwnDescriptors() + 1);
-
- map->set_transitions(*transitions);
- map->set_owns_descriptors(false);
+ ConnectTransition(map, result, name, SIMPLE_TRANSITION);
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<DescriptorArray> descriptors,
TransitionFlag flag,
@@ -7150,19 +7166,18 @@ Handle<Map> Map::CopyReplaceDescriptors(Handle<Map> map,
Handle<Map> result = CopyDropDescriptors(map);
result->InitializeDescriptors(*descriptors);
- if (flag == INSERT_TRANSITION && map->CanHaveMoreTransitions()) {
- Handle<Name> name;
- CHECK(maybe_name.ToHandle(&name));
- Handle<TransitionArray> transitions = TransitionArray::CopyInsert(
- map, name, result, simple_flag);
- map->set_transitions(*transitions);
- result->SetBackPointer(*map);
- } else {
- int length = descriptors->number_of_descriptors();
- for (int i = 0; i < length; i++) {
- descriptors->SetRepresentation(i, Representation::Tagged());
- if (descriptors->GetDetails(i).type() == FIELD) {
- descriptors->SetValue(i, HeapType::Any());
+ if (!map->is_prototype_map()) {
+ if (flag == INSERT_TRANSITION && map->CanHaveMoreTransitions()) {
+ Handle<Name> name;
+ CHECK(maybe_name.ToHandle(&name));
+ ConnectTransition(map, result, name, simple_flag);
+ } else {
+ int length = descriptors->number_of_descriptors();
+ for (int i = 0; i < length; i++) {
+ descriptors->SetRepresentation(i, Representation::Tagged());
+ if (descriptors->GetDetails(i).type() == FIELD) {
+ descriptors->SetValue(i, HeapType::Any());
+ }
}
}
}
@@ -7195,11 +7210,7 @@ Handle<Map> Map::CopyInstallDescriptors(Handle<Map> map,
result->set_owns_descriptors(false);
Igor Sheludko 2014/08/04 14:25:55 This is going to be done again in ConnectTransitio
Handle<Name> name = handle(descriptors->GetKey(new_descriptor));
- Handle<TransitionArray> transitions = TransitionArray::CopyInsert(
- map, name, result, SIMPLE_TRANSITION);
-
- map->set_transitions(*transitions);
- result->SetBackPointer(*map);
+ ConnectTransition(map, result, name, SIMPLE_TRANSITION);
return result;
}
@@ -7228,12 +7239,10 @@ Handle<Map> Map::CopyAsElementsKind(Handle<Map> map, ElementsKind kind,
// transfer ownership to the new map.
Handle<Map> new_map = CopyDropDescriptors(map);
- SetElementsTransitionMap(map, new_map);
+ ConnectElementsTransition(map, new_map);
new_map->set_elements_kind(kind);
new_map->InitializeDescriptors(map->instance_descriptors());
- new_map->SetBackPointer(*map);
- map->set_owns_descriptors(false);
return new_map;
}
@@ -7245,8 +7254,7 @@ Handle<Map> Map::CopyAsElementsKind(Handle<Map> map, ElementsKind kind,
new_map->set_elements_kind(kind);
if (insert_transition) {
- SetElementsTransitionMap(map, new_map);
- new_map->SetBackPointer(*map);
+ ConnectElementsTransition(map, new_map);
}
return new_map;
@@ -7264,22 +7272,18 @@ Handle<Map> Map::CopyForObserved(Handle<Map> map) {
if (map->owns_descriptors()) {
new_map = CopyDropDescriptors(map);
} else {
+ DCHECK(!map->is_prototype_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();
-
if (map->owns_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;
}
@@ -11923,7 +11927,9 @@ Handle<Map> Map::PutPrototypeTransition(Handle<Map> map,
Handle<Map> target_map) {
DCHECK(target_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;
const int step = kProtoTransitionElementsPerEntry;
« no previous file with comments | « src/objects.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698