Commit 30d2fb6b authored by verwaest's avatar verwaest Committed by Commit bot

[runtime] Always normalize prototype maps that aren't marked as 'should be fast' yet

This makes the test in the bug ~10x faster. It could inadvertently make other things slower, so revert eagerly if included in a range where performance tanks.

BUG=chromium:666852

Review-Url: https://codereview.chromium.org/2525573002
Cr-Commit-Position: refs/heads/master@{#41178}
parent a0e91600
...@@ -12547,19 +12547,10 @@ void Map::CompleteInobjectSlackTracking() { ...@@ -12547,19 +12547,10 @@ void Map::CompleteInobjectSlackTracking() {
static bool PrototypeBenefitsFromNormalization(Handle<JSObject> object) { static bool PrototypeBenefitsFromNormalization(Handle<JSObject> object) {
DisallowHeapAllocation no_gc; DisallowHeapAllocation no_gc;
if (!object->HasFastProperties()) return false; if (!object->HasFastProperties()) return false;
Map* map = object->map(); if (object->IsJSGlobalProxy()) return false;
if (map->is_prototype_map()) return false; if (object->GetIsolate()->bootstrapper()->IsActive()) return false;
DescriptorArray* descriptors = map->instance_descriptors(); return !object->map()->is_prototype_map() ||
for (int i = 0; i < map->NumberOfOwnDescriptors(); i++) { !object->map()->should_be_fast_prototype_map();
PropertyDetails details = descriptors->GetDetails(i);
if (details.location() == kDescriptor) continue;
if (details.representation().IsHeapObject() ||
details.representation().IsTagged()) {
FieldIndex index = FieldIndex::ForDescriptor(map, i);
if (object->RawFastPropertyAt(index)->IsJSFunction()) return true;
}
}
return false;
} }
// static // static
...@@ -12574,8 +12565,10 @@ void JSObject::MakePrototypesFast(Handle<Object> receiver, ...@@ -12574,8 +12565,10 @@ void JSObject::MakePrototypesFast(Handle<Object> receiver,
if (!current->IsJSObject()) return; if (!current->IsJSObject()) return;
Handle<JSObject> current_obj = Handle<JSObject>::cast(current); Handle<JSObject> current_obj = Handle<JSObject>::cast(current);
Map* current_map = current_obj->map(); Map* current_map = current_obj->map();
if (current_map->is_prototype_map() && if (current_map->is_prototype_map()) {
!current_map->should_be_fast_prototype_map()) { // If the map is already marked as should be fast, we're done. Its
// prototypes will have been marked already as well.
if (current_map->should_be_fast_prototype_map()) return;
Handle<Map> map(current_map); Handle<Map> map(current_map);
Map::SetShouldBeFastPrototypeMap(map, true, isolate); Map::SetShouldBeFastPrototypeMap(map, true, isolate);
JSObject::OptimizeAsPrototype(current_obj, FAST_PROTOTYPE); JSObject::OptimizeAsPrototype(current_obj, FAST_PROTOTYPE);
......
...@@ -101,11 +101,12 @@ for (var i = 0; i < 4; i++) { ...@@ -101,11 +101,12 @@ for (var i = 0; i < 4; i++) {
var x = {a: 1, b: 2, c: 3}; var x = {a: 1, b: 2, c: 3};
var o = { __proto__: x }; var o = { __proto__: x };
assertTrue(%HasFastProperties(x)); assertFalse(%HasFastProperties(x));
for (key in x) { for (key in x) {
assertTrue(key == 'a'); assertTrue(key == 'a');
break; break;
} }
assertTrue(%HasFastProperties(x));
delete x.b; delete x.b;
for (key in x) { for (key in x) {
assertTrue(key == 'a'); assertTrue(key == 'a');
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment