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

Unified Diff: src/objects.cc

Issue 2036493006: Keep prototype maps in dictionary mode until ICs see them (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: make ignition tests happy Created 4 years, 6 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-inl.h » ('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 a1f34cb95d7e86f02ce7d95da679b85a2ede8e11..4164df55d8db6723e2177182dfaa0ce26800960e 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -1026,7 +1026,7 @@ Object* FunctionTemplateInfo::GetCompatibleReceiver(Isolate* isolate,
FunctionTemplateInfo* signature = FunctionTemplateInfo::cast(recv_type);
// Check the receiver.
for (PrototypeIterator iter(isolate, JSObject::cast(receiver),
- PrototypeIterator::START_AT_RECEIVER,
+ kStartAtReceiver,
PrototypeIterator::END_AT_NON_HIDDEN);
!iter.IsAtEnd(); iter.Advance()) {
if (signature->IsTemplateFor(iter.GetCurrent())) return iter.GetCurrent();
@@ -1484,7 +1484,7 @@ void JSObject::SetNormalizedProperty(Handle<JSObject> object,
Maybe<bool> JSReceiver::HasInPrototypeChain(Isolate* isolate,
Handle<JSReceiver> object,
Handle<Object> proto) {
- PrototypeIterator iter(isolate, object, PrototypeIterator::START_AT_RECEIVER);
+ PrototypeIterator iter(isolate, object, kStartAtReceiver);
while (true) {
if (!iter.AdvanceFollowingProxies()) return Nothing<bool>();
if (iter.IsAtEnd()) return Just(false);
@@ -11862,6 +11862,26 @@ static bool PrototypeBenefitsFromNormalization(Handle<JSObject> object) {
return false;
}
+// static
+void JSObject::MakePrototypesFast(Handle<Object> receiver,
+ WhereToStart where_to_start,
+ Isolate* isolate) {
+ if (!receiver->IsJSReceiver()) return;
+ for (PrototypeIterator iter(isolate, Handle<JSReceiver>::cast(receiver),
+ where_to_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,
@@ -11873,10 +11893,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);
@@ -11904,6 +11926,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);
}
@@ -12045,6 +12068,15 @@ Handle<PrototypeInfo> Map::GetOrCreatePrototypeInfo(Handle<Map> prototype_map,
return proto_info;
}
+// static
+void Map::SetShouldBeFastPrototypeMap(Handle<Map> map, bool value,
+ Isolate* isolate) {
+ if (value == false && !map->prototype_info()->IsPrototypeInfo()) {
+ // "False" is the implicit default value, so there's nothing to do.
+ return;
+ }
+ GetOrCreatePrototypeInfo(map, isolate)->set_should_be_fast_map(value);
+}
// static
Handle<Cell> Map::GetOrCreatePrototypeChainValidityCell(Handle<Map> map,
@@ -13041,9 +13073,8 @@ void JSFunction::CalculateInstanceSizeForDerivedClass(
int* instance_size, int* in_object_properties) {
Isolate* isolate = GetIsolate();
int expected_nof_properties = 0;
- for (PrototypeIterator iter(isolate, this,
- PrototypeIterator::START_AT_RECEIVER);
- !iter.IsAtEnd(); iter.Advance()) {
+ for (PrototypeIterator iter(isolate, this, kStartAtReceiver); !iter.IsAtEnd();
+ iter.Advance()) {
JSReceiver* current = iter.GetCurrent<JSReceiver>();
if (!current->IsJSFunction()) break;
JSFunction* func = JSFunction::cast(current);
@@ -14867,8 +14898,7 @@ Maybe<bool> JSObject::SetPrototype(Handle<JSObject> object,
if (from_javascript) {
// Find the first object in the chain whose prototype object is not
// hidden.
- PrototypeIterator iter(isolate, real_receiver,
- PrototypeIterator::START_AT_PROTOTYPE,
+ PrototypeIterator iter(isolate, real_receiver, kStartAtPrototype,
PrototypeIterator::END_AT_NON_HIDDEN);
while (!iter.IsAtEnd()) {
// Casting to JSObject is fine because hidden prototypes are never
@@ -14901,7 +14931,7 @@ Maybe<bool> JSObject::SetPrototype(Handle<JSObject> object,
// new prototype chain.
if (value->IsJSReceiver()) {
for (PrototypeIterator iter(isolate, JSReceiver::cast(*value),
- PrototypeIterator::START_AT_RECEIVER);
+ kStartAtReceiver);
!iter.IsAtEnd(); iter.Advance()) {
if (iter.GetCurrent<JSReceiver>() == *object) {
// Cycle detected.
« no previous file with comments | « src/objects.h ('k') | src/objects-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698