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 |