Reviewers: danno,

Message:
Promoting elements transition is the first step to extracting all transitions
from the descriptor array.

Extracting all the transitions will allow us to link map -> transitions ->
descriptor array. In such a setup, the descriptor array becomes immutable; and
we can start looking at ways to share (parts of) the descriptor array rather
than always copying it. This change will eat up the space freed up by getting
rid of the ContentArray.

Currently non-fast-elements-kinds are never cached. We should look into
attaching dictionary at the end of the elements-kinds array.

Description:
Promoting elements transitions to their own field.
This is a first step towards separating all transitions from the property
descriptions. If we link the property descriptions from the transition object,
this will in allow the descriptor array (property descriptions) to become
immutable.


Please review this at https://chromiumcodereview.appspot.com/10444055/

SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge

Affected files:
  M src/objects-inl.h
  M src/objects.h
  M src/objects.cc


Index: src/objects-inl.h
diff --git a/src/objects-inl.h b/src/objects-inl.h
index c2d0966afc914c6219b3ce9c9de79d595186c734..84971213eb72fcd2715928f28bd27ad9ff82d09a 100644
--- a/src/objects-inl.h
+++ b/src/objects-inl.h
@@ -4090,12 +4090,12 @@ MaybeObject* JSFunction::set_initial_map_and_cache_transitions(
     maps->set(kind, current_map);
     for (int i = GetSequenceIndexFromFastElementsKind(kind) + 1;
          i < kFastElementsKindCount; ++i) {
- ElementsKind transitioned_kind = GetFastElementsKindFromSequenceIndex(i);
       Map* new_map;
+      ElementsKind next_kind = GetFastElementsKindFromSequenceIndex(i);
       MaybeObject* maybe_new_map =
-          current_map->AddMissingElementsTransitions(transitioned_kind);
+          current_map->CreateNextElementsTransition(next_kind);
       if (!maybe_new_map->To(&new_map)) return maybe_new_map;
-      maps->set(transitioned_kind, new_map);
+      maps->set(next_kind, new_map);
       current_map = new_map;
     }
     global_context->set_js_array_maps(maps);
Index: src/objects.cc
diff --git a/src/objects.cc b/src/objects.cc
index 2302f1077cde7c529897edf2ab3ca0147a63e36c..9c01f886ec4519a1410030764d282bce4a6170e9 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -2248,25 +2248,35 @@ Map* Map::LookupElementsTransitionMap(ElementsKind to_kind) {
 }


-MaybeObject* Map::AddMissingElementsTransitions(ElementsKind to_kind) {
-  int index = GetSequenceIndexFromFastElementsKind(elements_kind()) + 1;
-  int to_index = GetSequenceIndexFromFastElementsKind(to_kind);
-  ASSERT(index <= to_index);
-
-  Map* current_map = this;
-
-  for (; index <= to_index; ++index) {
-    ElementsKind next_kind = GetFastElementsKindFromSequenceIndex(index);
+MaybeObject* Map::CreateNextElementsTransition(ElementsKind next_kind) {
+    ASSERT(elements_transition() == NULL);
+    ASSERT(GetSequenceIndexFromFastElementsKind(elements_kind()) ==
+           (GetSequenceIndexFromFastElementsKind(next_kind) - 1));

     Map* next_map;
-    MaybeObject* maybe_next_map =
-        current_map->CopyDropTransitions(true);
+    MaybeObject* maybe_next_map = this->CopyDropTransitions(true);
     if (!maybe_next_map->To(&next_map)) return maybe_next_map;

     next_map->set_elements_kind(next_kind);
-    next_map->SetBackPointer(current_map);
-    current_map->set_elements_transition(next_map);
-    current_map = next_map;
+    next_map->SetBackPointer(this);
+    this->set_elements_transition(next_map);
+    return next_map;
+}
+
+
+static MaybeObject* AddMissingElementsTransitions(Map* map,
+                                                  ElementsKind to_kind) {
+ int index = GetSequenceIndexFromFastElementsKind(map->elements_kind()) + 1;
+  int to_index = GetSequenceIndexFromFastElementsKind(to_kind);
+  ASSERT(index <= to_index);
+
+  Map* current_map = map;
+
+  for (; index <= to_index; ++index) {
+      ElementsKind next_kind = GetFastElementsKindFromSequenceIndex(index);
+      MaybeObject* maybe_next_map =
+          current_map->CreateNextElementsTransition(next_kind);
+      if (!maybe_next_map->To(&current_map)) return maybe_next_map;
   }

   ASSERT(current_map->elements_kind() == to_kind);
@@ -2334,7 +2344,7 @@ MaybeObject* JSObject::GetElementsTransitionMapSlow(ElementsKind to_kind) {
     return closest_map;
   }

-  return closest_map->AddMissingElementsTransitions(to_kind);
+  return AddMissingElementsTransitions(closest_map, to_kind);
 }


Index: src/objects.h
diff --git a/src/objects.h b/src/objects.h
index 175f22812b797bfe88dfecd33138883375b1a8e2..5945825991abeb5aaefbfb1c31a18d87b01e24c4 100644
--- a/src/objects.h
+++ b/src/objects.h
@@ -4849,7 +4849,7 @@ class Map: public HeapObject {
   Map* LookupElementsTransitionMap(ElementsKind elements_kind);

// Adds a new transitions for changing the elements kind to | elements_kind|.
-  MUST_USE_RESULT MaybeObject* AddMissingElementsTransitions(
+  MUST_USE_RESULT MaybeObject* CreateNextElementsTransition(
       ElementsKind elements_kind);

   // Returns the transitioned map for this map with the most generic


--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to