Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |