Index: src/objects.cc |
diff --git a/src/objects.cc b/src/objects.cc |
index 906f7feef6bb30f5bf9f3787e568f1b7f9405a30..fd3e8b73e80d3c51eb6872047aad375c2667b16a 100644 |
--- a/src/objects.cc |
+++ b/src/objects.cc |
@@ -7699,28 +7699,72 @@ MaybeObject* JSObject::OptimizeAsPrototype() { |
} |
+MUST_USE_RESULT static MaybeObject* CacheInitialJSArrayMaps( |
+ Context* native_context, Map* initial_map) { |
+ // Replace all of the cached initial array maps in the native context with |
+ // the appropriate transitioned elements kind maps. |
+ Heap* heap = native_context->GetHeap(); |
+ MaybeObject* maybe_maps = |
+ heap->AllocateFixedArrayWithHoles(kElementsKindCount); |
+ FixedArray* maps; |
+ if (!maybe_maps->To(&maps)) return maybe_maps; |
+ |
+ Map* current_map = initial_map; |
+ ElementsKind kind = current_map->elements_kind(); |
+ ASSERT(kind == GetInitialFastElementsKind()); |
+ maps->set(kind, current_map); |
+ for (int i = GetSequenceIndexFromFastElementsKind(kind) + 1; |
+ i < kFastElementsKindCount; ++i) { |
+ Map* new_map; |
+ ElementsKind next_kind = GetFastElementsKindFromSequenceIndex(i); |
+ MaybeObject* maybe_new_map = |
+ current_map->CopyAsElementsKind(next_kind, INSERT_TRANSITION); |
+ if (!maybe_new_map->To(&new_map)) return maybe_new_map; |
+ maps->set(next_kind, new_map); |
+ current_map = new_map; |
+ } |
+ native_context->set_js_array_maps(maps); |
+ return initial_map; |
+} |
+ |
+ |
MaybeObject* JSFunction::SetInstancePrototype(Object* value) { |
ASSERT(value->IsJSReceiver()); |
Heap* heap = GetHeap(); |
- // First some logic for the map of the prototype to make sure it is in fast |
- // mode. |
+ // First some logic for the map of the prototype to make sure it is in |
danno
2012/11/07 17:26:47
nit: unnecessary whitespace change
Michael Starzinger
2012/11/08 11:23:33
Done. My mental "break at 72 chars" algorithm kick
|
+ // fast mode. |
if (value->IsJSObject()) { |
MaybeObject* ok = JSObject::cast(value)->OptimizeAsPrototype(); |
if (ok->IsFailure()) return ok; |
} |
- // Now some logic for the maps of the objects that are created by using this |
- // function as a constructor. |
+ // Now some logic for the maps of the objects that are created by |
danno
2012/11/07 17:26:47
nit: unnecessary whitespace change
Michael Starzinger
2012/11/08 11:23:33
Done. Likewise.
|
+ // using this function as a constructor. |
if (has_initial_map()) { |
- // If the function has allocated the initial map |
- // replace it with a copy containing the new prototype. |
+ // If the function has allocated the initial map replace it with a |
+ // copy containing the new prototype. Also complete any inobject |
danno
2012/11/07 17:26:47
nit: "in object"
Michael Starzinger
2012/11/08 11:23:33
Done. Used "in-object" as discussed offline.
|
+ // slack tracking that is in progress at this point because it is |
+ // still tracking the old copy. |
+ if (shared()->IsInobjectSlackTrackingInProgress()) { |
+ shared()->CompleteInobjectSlackTracking(); |
+ } |
Map* new_map; |
- MaybeObject* maybe_new_map = initial_map()->Copy(); |
- if (!maybe_new_map->To(&new_map)) return maybe_new_map; |
+ MaybeObject* maybe_object = initial_map()->Copy(); |
+ if (!maybe_object->To(&new_map)) return maybe_object; |
new_map->set_prototype(value); |
- MaybeObject* maybe_object = set_initial_map_and_cache_transitions(new_map); |
- if (maybe_object->IsFailure()) return maybe_object; |
+ |
+ // If the function is used as the global Array function, cache the |
+ // initial map (and transitioned versions) in the native context. |
+ Context* native_context = context()->native_context(); |
+ Object* array_function = native_context->get(Context::ARRAY_FUNCTION_INDEX); |
+ if (array_function->IsJSFunction() && |
+ this == JSFunction::cast(array_function)) { |
+ MaybeObject* ok = CacheInitialJSArrayMaps(native_context, new_map); |
+ if (ok->IsFailure()) return ok; |
+ } |
+ |
+ set_initial_map(new_map); |
} else { |
// Put the value in the initial map field until an initial map is |
// needed. At that point, a new initial map is created and the |