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

Unified Diff: src/objects.cc

Issue 8017003: Cache multiple ElementsKind map transition per map. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 9 years, 3 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') | src/objects-printer.cc » ('j') | 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 2cdc689059898362b188889eaf37c5ab959eb1bd..862023fa2e5e8a8b62152196189963b1951afd1c 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -2022,6 +2022,70 @@ void Map::LookupInDescriptors(JSObject* holder,
}
+static Map* GetElementsTransitionMapFromDescriptor(Object* descriptor_contents,
+ ElementsKind elements_kind) {
+ if (descriptor_contents->IsMap()) {
+ Map* map = Map::cast(descriptor_contents);
+ if (map->elements_kind() == elements_kind) {
+ return map;
+ }
+ return NULL;
+ }
+
+ FixedArray* map_array = FixedArray::cast(descriptor_contents);
+ for (int i = 0; i < map_array->length(); ++i) {
+ Map* current_map = Map::cast(map_array->get(i));
+ if (current_map->elements_kind() == elements_kind) {
+ return current_map;
+ }
+ }
+
+ return NULL;
+}
+
+
+static MaybeObject* AddElementsTransitionMapToDescriptor(
+ Object* descriptor_contents,
+ Map* new_map) {
+ // Nothing was in the descriptor for an ELEMENTS_TRANSITION,
+ // simply add the map.
+ if (descriptor_contents == NULL) {
+ return new_map;
+ }
+
+ // There was already a map in the descriptor, create a 2-element FixedArray
+ // to contain the existing map plus the new one.
+ FixedArray* new_array;
+ Heap* heap = new_map->GetHeap();
+ if (descriptor_contents->IsMap()) {
+ MaybeObject* maybe_new_array = heap->AllocateFixedArray(2);
+ if (!maybe_new_array->To<FixedArray>(&new_array)) {
+ return maybe_new_array;
+ }
+ new_array->set(0, descriptor_contents);
+ new_array->set(1, new_map);
+ return new_array;
+ }
+
+ // The descriptor already contained a list of maps for different ElementKinds
+ // of ELEMENTS_TRANSITION, create a FixedArray to hold the existing maps plus
+ // the new one and fill it it.
+ FixedArray* array = FixedArray::cast(descriptor_contents);
+ MaybeObject* maybe_new_array =
+ heap->AllocateFixedArray(array->length() + 1);
+ if (!maybe_new_array->To<FixedArray>(&new_array)) {
+ return maybe_new_array;
+ }
+ int i = 0;
+ while (i < array->length()) {
+ new_array->set(i, FixedArray::cast(descriptor_contents)->get(i));
Jakob Kummerow 2011/09/23 12:12:28 Simplification: s/FixedArray::cast(descriptor_cont
danno 2011/09/23 13:33:45 Done.
+ ++i;
+ }
+ new_array->set(i, new_map);
+ return new_array;
+}
+
+
MaybeObject* JSObject::GetElementsTransitionMap(ElementsKind elements_kind) {
Heap* current_heap = GetHeap();
Map* current_map = map();
@@ -2044,6 +2108,7 @@ MaybeObject* JSObject::GetElementsTransitionMap(ElementsKind elements_kind) {
safe_to_add_transition = false;
}
+ Object* descriptor_contents = NULL;
if (safe_to_add_transition) {
// It's only safe to manipulate the descriptor array if it would be
// safe to add a transition.
@@ -2063,12 +2128,14 @@ MaybeObject* JSObject::GetElementsTransitionMap(ElementsKind elements_kind) {
// return it.
if (index != DescriptorArray::kNotFound) {
PropertyDetails details(PropertyDetails(descriptors->GetDetails(index)));
- if (details.type() == ELEMENTS_TRANSITION &&
- details.elements_kind() == elements_kind) {
- return descriptors->GetValue(index);
- } else {
- safe_to_add_transition = false;
+ if (details.type() == ELEMENTS_TRANSITION) {
+ descriptor_contents = descriptors->GetValue(index);
+ Map* maybe_transition_map =
+ GetElementsTransitionMapFromDescriptor(descriptor_contents,
+ elements_kind);
+ if (maybe_transition_map) return maybe_transition_map;
}
+ safe_to_add_transition = false;
}
}
@@ -2085,15 +2152,20 @@ MaybeObject* JSObject::GetElementsTransitionMap(ElementsKind elements_kind) {
// Only remember the map transition if the object's map is NOT equal to the
// global object_function's map and there is not an already existing
// non-matching element transition.
- bool allow_map_transition =
- safe_to_add_transition &&
- (GetIsolate()->context()->global_context()->object_function()->map() !=
- map());
+ bool allow_map_transition = safe_to_add_transition;
+ //&&
+ // (GetIsolate()->context()->global_context()->object_function()->map() !=
+ // map());
if (allow_map_transition) {
- // Allocate new instance descriptors for the old map with map transition.
+ MaybeObject* maybe_new_contents =
+ AddElementsTransitionMapToDescriptor(descriptor_contents, new_map);
+ Object* new_contents;
+ if (!maybe_new_contents->To<Object>(&new_contents)) {
Jakob Kummerow 2011/09/23 12:12:28 Simplification: s/To<Object>/ToObject/
danno 2011/09/23 13:33:45 Done.
+ return maybe_new_contents;
+ }
+
ElementsTransitionDescriptor desc(elements_transition_sentinel_name,
- Map::cast(new_map),
- elements_kind);
+ new_contents);
Object* new_descriptors;
MaybeObject* maybe_new_descriptors = descriptors->CopyInsert(
&desc,
« no previous file with comments | « src/objects.h ('k') | src/objects-printer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698