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

Side by Side Diff: src/objects.cc

Issue 2502393002: [ic] Invalidate prototype validity cell when a slow prototype becomes fast. (Closed)
Patch Set: Added JSObject::NotifyMapChange() Created 4 years, 1 month 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 unified diff | Download patch
« no previous file with comments | « src/objects.h ('k') | test/mjsunit/regress/regress-crbug-665886.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/objects.h" 5 #include "src/objects.h"
6 6
7 #include <cmath> 7 #include <cmath>
8 #include <iomanip> 8 #include <iomanip>
9 #include <memory> 9 #include <memory>
10 #include <sstream> 10 #include <sstream>
(...skipping 3189 matching lines...) Expand 10 before | Expand all | Expand 10 after
3200 } 3200 }
3201 // Otherwise, properties will need to be moved to the backing store. 3201 // Otherwise, properties will need to be moved to the backing store.
3202 return true; 3202 return true;
3203 } 3203 }
3204 3204
3205 3205
3206 // static 3206 // static
3207 void JSObject::UpdatePrototypeUserRegistration(Handle<Map> old_map, 3207 void JSObject::UpdatePrototypeUserRegistration(Handle<Map> old_map,
3208 Handle<Map> new_map, 3208 Handle<Map> new_map,
3209 Isolate* isolate) { 3209 Isolate* isolate) {
3210 if (!old_map->is_prototype_map()) return; 3210 DCHECK(old_map->is_prototype_map());
3211 DCHECK(new_map->is_prototype_map()); 3211 DCHECK(new_map->is_prototype_map());
3212 bool was_registered = JSObject::UnregisterPrototypeUser(old_map, isolate); 3212 bool was_registered = JSObject::UnregisterPrototypeUser(old_map, isolate);
3213 new_map->set_prototype_info(old_map->prototype_info()); 3213 new_map->set_prototype_info(old_map->prototype_info());
3214 old_map->set_prototype_info(Smi::kZero); 3214 old_map->set_prototype_info(Smi::kZero);
3215 if (FLAG_trace_prototype_users) { 3215 if (FLAG_trace_prototype_users) {
3216 PrintF("Moving prototype_info %p from map %p to map %p.\n", 3216 PrintF("Moving prototype_info %p from map %p to map %p.\n",
3217 reinterpret_cast<void*>(new_map->prototype_info()), 3217 reinterpret_cast<void*>(new_map->prototype_info()),
3218 reinterpret_cast<void*>(*old_map), 3218 reinterpret_cast<void*>(*old_map),
3219 reinterpret_cast<void*>(*new_map)); 3219 reinterpret_cast<void*>(*new_map));
3220 } 3220 }
(...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after
3560 if (FLAG_trace_normalization) { 3560 if (FLAG_trace_normalization) {
3561 OFStream os(stdout); 3561 OFStream os(stdout);
3562 os << "Object properties have been normalized:\n"; 3562 os << "Object properties have been normalized:\n";
3563 object->Print(os); 3563 object->Print(os);
3564 } 3564 }
3565 #endif 3565 #endif
3566 } 3566 }
3567 3567
3568 } // namespace 3568 } // namespace
3569 3569
3570 // static
3571 void JSObject::NotifyMapChange(Handle<Map> old_map, Handle<Map> new_map,
3572 Isolate* isolate) {
3573 if (!old_map->is_prototype_map()) return;
3574
3575 // If this object is a prototype (the callee will check), invalidate any
Jakob Kummerow 2016/11/16 17:15:35 nit: outdated comment. I'd just drop it, the metho
Igor Sheludko 2016/11/16 17:20:03 Done.
3576 // prototype chains involving it.
3577 InvalidatePrototypeChains(*old_map);
3578
3579 // If the map was registered with its prototype before, ensure that it
3580 // registers with its new prototype now. This preserves the invariant that
3581 // when a map on a prototype chain is registered with its prototype, then
3582 // all prototypes further up the chain are also registered with their
3583 // respective prototypes.
3584 UpdatePrototypeUserRegistration(old_map, new_map, new_map->GetIsolate());
Jakob Kummerow 2016/11/16 17:15:35 nit: s/new_map->GetIsolate()/isolate/
Igor Sheludko 2016/11/16 17:20:03 Done.
3585 }
3586
3570 void JSObject::MigrateToMap(Handle<JSObject> object, Handle<Map> new_map, 3587 void JSObject::MigrateToMap(Handle<JSObject> object, Handle<Map> new_map,
3571 int expected_additional_properties) { 3588 int expected_additional_properties) {
3572 if (object->map() == *new_map) return; 3589 if (object->map() == *new_map) return;
3573 Handle<Map> old_map(object->map()); 3590 Handle<Map> old_map(object->map());
3574 if (old_map->is_prototype_map()) { 3591 NotifyMapChange(old_map, new_map, new_map->GetIsolate());
3575 // If this object is a prototype (the callee will check), invalidate any
3576 // prototype chains involving it.
3577 InvalidatePrototypeChains(object->map());
3578
3579 // If the map was registered with its prototype before, ensure that it
3580 // registers with its new prototype now. This preserves the invariant that
3581 // when a map on a prototype chain is registered with its prototype, then
3582 // all prototypes further up the chain are also registered with their
3583 // respective prototypes.
3584 UpdatePrototypeUserRegistration(old_map, new_map, new_map->GetIsolate());
3585 }
3586 3592
3587 if (old_map->is_dictionary_map()) { 3593 if (old_map->is_dictionary_map()) {
3588 // For slow-to-fast migrations JSObject::MigrateSlowToFast() 3594 // For slow-to-fast migrations JSObject::MigrateSlowToFast()
3589 // must be used instead. 3595 // must be used instead.
3590 CHECK(new_map->is_dictionary_map()); 3596 CHECK(new_map->is_dictionary_map());
3591 3597
3592 // Slow-to-slow migration is trivial. 3598 // Slow-to-slow migration is trivial.
3593 object->set_map(*new_map); 3599 object->set_map(*new_map);
3594 } else if (!new_map->is_dictionary_map()) { 3600 } else if (!new_map->is_dictionary_map()) {
3595 MigrateFastToFast(object, new_map); 3601 MigrateFastToFast(object, new_map);
(...skipping 2409 matching lines...) Expand 10 before | Expand all | Expand 10 after
6005 } 6011 }
6006 6012
6007 Handle<Map> old_map(object->map(), isolate); 6013 Handle<Map> old_map(object->map(), isolate);
6008 6014
6009 int inobject_props = old_map->GetInObjectProperties(); 6015 int inobject_props = old_map->GetInObjectProperties();
6010 6016
6011 // Allocate new map. 6017 // Allocate new map.
6012 Handle<Map> new_map = Map::CopyDropDescriptors(old_map); 6018 Handle<Map> new_map = Map::CopyDropDescriptors(old_map);
6013 new_map->set_dictionary_map(false); 6019 new_map->set_dictionary_map(false);
6014 6020
6015 UpdatePrototypeUserRegistration(old_map, new_map, isolate); 6021 NotifyMapChange(old_map, new_map, isolate);
6016 6022
6017 #if TRACE_MAPS 6023 #if TRACE_MAPS
6018 if (FLAG_trace_maps) { 6024 if (FLAG_trace_maps) {
6019 PrintF("[TraceMaps: SlowToFast from= %p to= %p reason= %s ]\n", 6025 PrintF("[TraceMaps: SlowToFast from= %p to= %p reason= %s ]\n",
6020 reinterpret_cast<void*>(*old_map), reinterpret_cast<void*>(*new_map), 6026 reinterpret_cast<void*>(*old_map), reinterpret_cast<void*>(*new_map),
6021 reason); 6027 reason);
6022 } 6028 }
6023 #endif 6029 #endif
6024 6030
6025 if (instance_descriptor_length == 0) { 6031 if (instance_descriptor_length == 0) {
(...skipping 6671 matching lines...) Expand 10 before | Expand all | Expand 10 after
12697 WeakFixedArray::cast(maybe_registry)->Clear(slot); 12703 WeakFixedArray::cast(maybe_registry)->Clear(slot);
12698 if (FLAG_trace_prototype_users) { 12704 if (FLAG_trace_prototype_users) {
12699 PrintF("Unregistering %p as a user of prototype %p.\n", 12705 PrintF("Unregistering %p as a user of prototype %p.\n",
12700 reinterpret_cast<void*>(*user), reinterpret_cast<void*>(*prototype)); 12706 reinterpret_cast<void*>(*user), reinterpret_cast<void*>(*prototype));
12701 } 12707 }
12702 return true; 12708 return true;
12703 } 12709 }
12704 12710
12705 12711
12706 static void InvalidatePrototypeChainsInternal(Map* map) { 12712 static void InvalidatePrototypeChainsInternal(Map* map) {
12707 if (!map->is_prototype_map()) return; 12713 DCHECK(map->is_prototype_map());
12708 if (FLAG_trace_prototype_users) { 12714 if (FLAG_trace_prototype_users) {
12709 PrintF("Invalidating prototype map %p 's cell\n", 12715 PrintF("Invalidating prototype map %p 's cell\n",
12710 reinterpret_cast<void*>(map)); 12716 reinterpret_cast<void*>(map));
12711 } 12717 }
12712 Object* maybe_proto_info = map->prototype_info(); 12718 Object* maybe_proto_info = map->prototype_info();
12713 if (!maybe_proto_info->IsPrototypeInfo()) return; 12719 if (!maybe_proto_info->IsPrototypeInfo()) return;
12714 PrototypeInfo* proto_info = PrototypeInfo::cast(maybe_proto_info); 12720 PrototypeInfo* proto_info = PrototypeInfo::cast(maybe_proto_info);
12715 Object* maybe_cell = proto_info->validity_cell(); 12721 Object* maybe_cell = proto_info->validity_cell();
12716 if (maybe_cell->IsCell()) { 12722 if (maybe_cell->IsCell()) {
12717 // Just set the value; the cell will be replaced lazily. 12723 // Just set the value; the cell will be replaced lazily.
(...skipping 7701 matching lines...) Expand 10 before | Expand all | Expand 10 after
20419 // depend on this. 20425 // depend on this.
20420 return DICTIONARY_ELEMENTS; 20426 return DICTIONARY_ELEMENTS;
20421 } 20427 }
20422 DCHECK_LE(kind, LAST_ELEMENTS_KIND); 20428 DCHECK_LE(kind, LAST_ELEMENTS_KIND);
20423 return kind; 20429 return kind;
20424 } 20430 }
20425 } 20431 }
20426 20432
20427 } // namespace internal 20433 } // namespace internal
20428 } // namespace v8 20434 } // namespace v8
OLDNEW
« no previous file with comments | « src/objects.h ('k') | test/mjsunit/regress/regress-crbug-665886.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698