Index: src/objects.cc |
diff --git a/src/objects.cc b/src/objects.cc |
index b389b2b5a046ffddbb9680974d06fe09b34673f1..d0d4a244a00895b55134fd545e4ddf456c8f4874 100644 |
--- a/src/objects.cc |
+++ b/src/objects.cc |
@@ -11849,6 +11849,28 @@ static bool PrototypeBenefitsFromNormalization(Handle<JSObject> object) { |
return false; |
} |
+// static |
+void JSObject::MakePrototypesFast(Handle<Object> receiver, |
+ bool include_receiver, Isolate* isolate) { |
+ if (!receiver->IsJSReceiver()) return; |
+ PrototypeIterator::WhereToStart start = |
+ include_receiver ? PrototypeIterator::START_AT_RECEIVER |
+ : PrototypeIterator::START_AT_PROTOTYPE; |
+ for (PrototypeIterator iter(isolate, Handle<JSReceiver>::cast(receiver), |
+ start); |
+ !iter.IsAtEnd(); iter.Advance()) { |
+ Handle<Object> current = PrototypeIterator::GetCurrent(iter); |
+ if (!current->IsJSObject()) return; |
+ Handle<JSObject> current_obj = Handle<JSObject>::cast(current); |
+ Map* current_map = current_obj->map(); |
+ if (current_map->is_prototype_map() && |
+ !current_map->should_be_fast_prototype_map()) { |
+ Handle<Map> map(current_map); |
+ Map::SetShouldBeFastPrototypeMap(map, true, isolate); |
+ JSObject::OptimizeAsPrototype(current_obj, FAST_PROTOTYPE); |
+ } |
+ } |
+} |
// static |
void JSObject::OptimizeAsPrototype(Handle<JSObject> object, |
@@ -11860,10 +11882,12 @@ void JSObject::OptimizeAsPrototype(Handle<JSObject> object, |
"NormalizeAsPrototype"); |
} |
Handle<Map> previous_map(object->map()); |
- if (!object->HasFastProperties()) { |
- JSObject::MigrateSlowToFast(object, 0, "OptimizeAsPrototype"); |
- } |
- if (!object->map()->is_prototype_map()) { |
+ if (object->map()->is_prototype_map()) { |
+ if (object->map()->should_be_fast_prototype_map() && |
+ !object->HasFastProperties()) { |
+ JSObject::MigrateSlowToFast(object, 0, "OptimizeAsPrototype"); |
+ } |
+ } else { |
if (object->map() == *previous_map) { |
Handle<Map> new_map = Map::Copy(handle(object->map()), "CopyAsPrototype"); |
JSObject::MigrateToMap(object, new_map); |
@@ -11891,6 +11915,7 @@ void JSObject::OptimizeAsPrototype(Handle<JSObject> object, |
// static |
void JSObject::ReoptimizeIfPrototype(Handle<JSObject> object) { |
if (!object->map()->is_prototype_map()) return; |
+ if (!object->map()->should_be_fast_prototype_map()) return; |
OptimizeAsPrototype(object, FAST_PROTOTYPE); |
} |
@@ -12032,6 +12057,11 @@ Handle<PrototypeInfo> Map::GetOrCreatePrototypeInfo(Handle<Map> prototype_map, |
return proto_info; |
} |
+// static |
+void Map::SetShouldBeFastPrototypeMap(Handle<Map> map, bool value, |
+ Isolate* isolate) { |
+ GetOrCreatePrototypeInfo(map, isolate)->set_should_be_fast_map(value); |
Toon Verwaest
2016/06/07 14:48:06
If the bool is false, should we really allocate a
Jakob Kummerow
2016/06/08 12:18:59
Good point (although it never happens currently).
|
+} |
// static |
Handle<Cell> Map::GetOrCreatePrototypeChainValidityCell(Handle<Map> map, |