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

Side by Side Diff: src/objects.cc

Issue 1282143003: Version 4.5.103.22 (cherry-pick) (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@4.5
Patch Set: Created 5 years, 4 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 unified diff | Download patch
« no previous file with comments | « src/objects.h ('k') | src/objects-inl.h » ('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 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 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 <iomanip> 5 #include <iomanip>
6 #include <sstream> 6 #include <sstream>
7 7
8 #include "src/v8.h" 8 #include "src/v8.h"
9 9
10 #include "src/accessors.h" 10 #include "src/accessors.h"
(...skipping 1742 matching lines...) Expand 10 before | Expand all | Expand 10 after
1753 DCHECK(target_inobject < inobject_properties()); 1753 DCHECK(target_inobject < inobject_properties());
1754 if (target_number_of_fields <= target_inobject) { 1754 if (target_number_of_fields <= target_inobject) {
1755 DCHECK(target_number_of_fields + target_unused == target_inobject); 1755 DCHECK(target_number_of_fields + target_unused == target_inobject);
1756 return false; 1756 return false;
1757 } 1757 }
1758 // Otherwise, properties will need to be moved to the backing store. 1758 // Otherwise, properties will need to be moved to the backing store.
1759 return true; 1759 return true;
1760 } 1760 }
1761 1761
1762 1762
1763 static void UpdatePrototypeUserRegistration(Handle<Map> old_map,
1764 Handle<Map> new_map,
1765 Isolate* isolate) {
1766 if (!FLAG_track_prototype_users) return;
1767 if (!old_map->is_prototype_map()) return;
1768 DCHECK(new_map->is_prototype_map());
1769 bool was_registered = JSObject::UnregisterPrototypeUser(old_map, isolate);
1770 new_map->set_prototype_info(old_map->prototype_info());
1771 old_map->set_prototype_info(Smi::FromInt(0));
1772 if (FLAG_trace_prototype_users) {
1773 PrintF("Moving prototype_info %p from map %p to map %p.\n",
1774 reinterpret_cast<void*>(new_map->prototype_info()),
1775 reinterpret_cast<void*>(*old_map),
1776 reinterpret_cast<void*>(*new_map));
1777 }
1778 if (was_registered) {
1779 if (new_map->prototype_info()->IsPrototypeInfo()) {
1780 // The new map isn't registered with its prototype yet; reflect this fact
1781 // in the PrototypeInfo it just inherited from the old map.
1782 PrototypeInfo::cast(new_map->prototype_info())
1783 ->set_registry_slot(PrototypeInfo::UNREGISTERED);
1784 }
1785 JSObject::LazyRegisterPrototypeUser(new_map, isolate);
1786 }
1787 }
1788
1789
1763 void JSObject::MigrateToMap(Handle<JSObject> object, Handle<Map> new_map, 1790 void JSObject::MigrateToMap(Handle<JSObject> object, Handle<Map> new_map,
1764 int expected_additional_properties) { 1791 int expected_additional_properties) {
1765 if (object->map() == *new_map) return; 1792 if (object->map() == *new_map) return;
1766 // If this object is a prototype (the callee will check), invalidate any 1793 // If this object is a prototype (the callee will check), invalidate any
1767 // prototype chains involving it. 1794 // prototype chains involving it.
1768 InvalidatePrototypeChains(object->map()); 1795 InvalidatePrototypeChains(object->map());
1769 Handle<Map> old_map(object->map()); 1796 Handle<Map> old_map(object->map());
1770 1797
1771 // If the map was registered with its prototype before, ensure that it 1798 // If the map was registered with its prototype before, ensure that it
1772 // registers with its new prototype now. This preserves the invariant that 1799 // registers with its new prototype now. This preserves the invariant that
1773 // when a map on a prototype chain is registered with its prototype, then 1800 // when a map on a prototype chain is registered with its prototype, then
1774 // all prototypes further up the chain are also registered with their 1801 // all prototypes further up the chain are also registered with their
1775 // respective prototypes. 1802 // respective prototypes.
1776 Object* maybe_old_prototype = old_map->prototype(); 1803 UpdatePrototypeUserRegistration(old_map, new_map, new_map->GetIsolate());
1777 if (FLAG_track_prototype_users && old_map->is_prototype_map() &&
1778 maybe_old_prototype->IsJSObject()) {
1779 Handle<JSObject> old_prototype(JSObject::cast(maybe_old_prototype));
1780 bool was_registered =
1781 JSObject::UnregisterPrototypeUser(old_prototype, old_map);
1782 if (was_registered) {
1783 JSObject::LazyRegisterPrototypeUser(new_map, new_map->GetIsolate());
1784 }
1785 }
1786 1804
1787 if (object->HasFastProperties()) { 1805 if (object->HasFastProperties()) {
1788 if (!new_map->is_dictionary_map()) { 1806 if (!new_map->is_dictionary_map()) {
1789 MigrateFastToFast(object, new_map); 1807 MigrateFastToFast(object, new_map);
1790 if (old_map->is_prototype_map()) { 1808 if (old_map->is_prototype_map()) {
1791 // Clear out the old descriptor array to avoid problems to sharing 1809 // Clear out the old descriptor array to avoid problems to sharing
1792 // the descriptor array without using an explicit. 1810 // the descriptor array without using an explicit.
1793 old_map->InitializeDescriptors( 1811 old_map->InitializeDescriptors(
1794 old_map->GetHeap()->empty_descriptor_array(), 1812 old_map->GetHeap()->empty_descriptor_array(),
1795 LayoutDescriptor::FastPointerLayout()); 1813 LayoutDescriptor::FastPointerLayout());
(...skipping 12 matching lines...) Expand all
1808 1826
1809 // Slow-to-slow migration is trivial. 1827 // Slow-to-slow migration is trivial.
1810 object->set_map(*new_map); 1828 object->set_map(*new_map);
1811 } 1829 }
1812 1830
1813 // Careful: Don't allocate here! 1831 // Careful: Don't allocate here!
1814 // For some callers of this method, |object| might be in an inconsistent 1832 // For some callers of this method, |object| might be in an inconsistent
1815 // state now: the new map might have a new elements_kind, but the object's 1833 // state now: the new map might have a new elements_kind, but the object's
1816 // elements pointer hasn't been updated yet. Callers will fix this, but in 1834 // elements pointer hasn't been updated yet. Callers will fix this, but in
1817 // the meantime, (indirectly) calling JSObjectVerify() must be avoided. 1835 // the meantime, (indirectly) calling JSObjectVerify() must be avoided.
1818 DisallowHeapAllocation no_object_verification; 1836 // When adding code here, add a DisallowHeapAllocation too.
1819
1820 if (old_map->is_prototype_map() && FLAG_track_prototype_users) {
1821 DCHECK(new_map->is_prototype_map());
1822 DCHECK(object->map() == *new_map);
1823 new_map->set_prototype_info(old_map->prototype_info());
1824 old_map->set_prototype_info(Smi::FromInt(0));
1825 if (FLAG_trace_prototype_users) {
1826 PrintF("Moving prototype_info %p from map %p to map %p.\n",
1827 reinterpret_cast<void*>(new_map->prototype_info()),
1828 reinterpret_cast<void*>(*old_map),
1829 reinterpret_cast<void*>(*new_map));
1830 }
1831 }
1832 } 1837 }
1833 1838
1834 1839
1835 // To migrate a fast instance to a fast map: 1840 // To migrate a fast instance to a fast map:
1836 // - First check whether the instance needs to be rewritten. If not, simply 1841 // - First check whether the instance needs to be rewritten. If not, simply
1837 // change the map. 1842 // change the map.
1838 // - Otherwise, allocate a fixed array large enough to hold all fields, in 1843 // - Otherwise, allocate a fixed array large enough to hold all fields, in
1839 // addition to unused space. 1844 // addition to unused space.
1840 // - Copy all existing properties in, in the following order: backing store 1845 // - Copy all existing properties in, in the following order: backing store
1841 // properties, unused fields, inobject properties. 1846 // properties, unused fields, inobject properties.
(...skipping 2805 matching lines...) Expand 10 before | Expand all | Expand 10 after
4647 } 4652 }
4648 4653
4649 Handle<Map> old_map(object->map(), isolate); 4654 Handle<Map> old_map(object->map(), isolate);
4650 4655
4651 int inobject_props = old_map->inobject_properties(); 4656 int inobject_props = old_map->inobject_properties();
4652 4657
4653 // Allocate new map. 4658 // Allocate new map.
4654 Handle<Map> new_map = Map::CopyDropDescriptors(old_map); 4659 Handle<Map> new_map = Map::CopyDropDescriptors(old_map);
4655 new_map->set_dictionary_map(false); 4660 new_map->set_dictionary_map(false);
4656 4661
4657 if (old_map->is_prototype_map() && FLAG_track_prototype_users) { 4662 UpdatePrototypeUserRegistration(old_map, new_map, isolate);
4658 DCHECK(new_map->is_prototype_map());
4659
4660 Object* maybe_old_prototype = old_map->prototype();
4661 if (maybe_old_prototype->IsJSObject()) {
4662 Handle<JSObject> old_prototype(JSObject::cast(maybe_old_prototype));
4663 bool was_registered =
4664 JSObject::UnregisterPrototypeUser(old_prototype, old_map);
4665 if (was_registered) {
4666 JSObject::LazyRegisterPrototypeUser(new_map, isolate);
4667 }
4668 }
4669 new_map->set_prototype_info(old_map->prototype_info());
4670 old_map->set_prototype_info(Smi::FromInt(0));
4671 if (FLAG_trace_prototype_users) {
4672 PrintF("Moving prototype_info %p from map %p to map %p.\n",
4673 reinterpret_cast<void*>(new_map->prototype_info()),
4674 reinterpret_cast<void*>(*old_map),
4675 reinterpret_cast<void*>(*new_map));
4676 }
4677 }
4678 4663
4679 #if TRACE_MAPS 4664 #if TRACE_MAPS
4680 if (FLAG_trace_maps) { 4665 if (FLAG_trace_maps) {
4681 PrintF("[TraceMaps: SlowToFast from= %p to= %p reason= %s ]\n", 4666 PrintF("[TraceMaps: SlowToFast from= %p to= %p reason= %s ]\n",
4682 reinterpret_cast<void*>(*old_map), reinterpret_cast<void*>(*new_map), 4667 reinterpret_cast<void*>(*old_map), reinterpret_cast<void*>(*new_map),
4683 reason); 4668 reason);
4684 } 4669 }
4685 #endif 4670 #endif
4686 4671
4687 if (instance_descriptor_length == 0) { 4672 if (instance_descriptor_length == 0) {
(...skipping 3373 matching lines...) Expand 10 before | Expand all | Expand 10 after
8061 : array->GetIsolate()->factory()->NewWeakCell(value); 8046 : array->GetIsolate()->factory()->NewWeakCell(value);
8062 Handle<FixedArray>::cast(array)->set(index + kFirstIndex, *cell); 8047 Handle<FixedArray>::cast(array)->set(index + kFirstIndex, *cell);
8063 if (FLAG_trace_weak_arrays) { 8048 if (FLAG_trace_weak_arrays) {
8064 PrintF("[WeakFixedArray: storing at index %d ]\n", index); 8049 PrintF("[WeakFixedArray: storing at index %d ]\n", index);
8065 } 8050 }
8066 array->set_last_used_index(index); 8051 array->set_last_used_index(index);
8067 } 8052 }
8068 8053
8069 8054
8070 // static 8055 // static
8071 Handle<WeakFixedArray> WeakFixedArray::Add( 8056 Handle<WeakFixedArray> WeakFixedArray::Add(Handle<Object> maybe_array,
8072 Handle<Object> maybe_array, Handle<HeapObject> value, 8057 Handle<HeapObject> value,
8073 SearchForDuplicates search_for_duplicates, bool* was_present) { 8058 int* assigned_index) {
8074 Handle<WeakFixedArray> array = 8059 Handle<WeakFixedArray> array =
8075 (maybe_array.is_null() || !maybe_array->IsWeakFixedArray()) 8060 (maybe_array.is_null() || !maybe_array->IsWeakFixedArray())
8076 ? Allocate(value->GetIsolate(), 1, Handle<WeakFixedArray>::null()) 8061 ? Allocate(value->GetIsolate(), 1, Handle<WeakFixedArray>::null())
8077 : Handle<WeakFixedArray>::cast(maybe_array); 8062 : Handle<WeakFixedArray>::cast(maybe_array);
8078 if (was_present != NULL) *was_present = false;
8079 if (search_for_duplicates == kAddIfNotFound) {
8080 for (int i = 0; i < array->Length(); ++i) {
8081 if (array->Get(i) == *value) {
8082 if (was_present != NULL) *was_present = true;
8083 return array;
8084 }
8085 }
8086 #if 0 // Enable this if you want to check your search_for_duplicates flags.
8087 } else {
8088 for (int i = 0; i < array->Length(); ++i) {
8089 DCHECK_NE(*value, array->Get(i));
8090 }
8091 #endif
8092 }
8093
8094 // Try to store the new entry if there's room. Optimize for consecutive 8063 // Try to store the new entry if there's room. Optimize for consecutive
8095 // accesses. 8064 // accesses.
8096 int first_index = array->last_used_index(); 8065 int first_index = array->last_used_index();
8097 if (array->Length() > 0) { 8066 int length = array->Length();
8067 if (length > 0) {
8098 for (int i = first_index;;) { 8068 for (int i = first_index;;) {
8099 if (array->IsEmptySlot((i))) { 8069 if (array->IsEmptySlot((i))) {
8100 WeakFixedArray::Set(array, i, value); 8070 WeakFixedArray::Set(array, i, value);
8071 if (assigned_index != NULL) *assigned_index = i;
8101 return array; 8072 return array;
8102 } 8073 }
8103 if (FLAG_trace_weak_arrays) { 8074 if (FLAG_trace_weak_arrays) {
8104 PrintF("[WeakFixedArray: searching for free slot]\n"); 8075 PrintF("[WeakFixedArray: searching for free slot]\n");
8105 } 8076 }
8106 i = (i + 1) % array->Length(); 8077 i = (i + 1) % length;
8107 if (i == first_index) break; 8078 if (i == first_index) break;
8108 } 8079 }
8109 } 8080 }
8110 8081
8111 // No usable slot found, grow the array. 8082 // No usable slot found, grow the array.
8112 int new_length = 8083 int new_length = length == 0 ? 1 : length + (length >> 1) + 4;
8113 array->Length() == 0 ? 1 : array->Length() + (array->Length() >> 1) + 4;
8114 Handle<WeakFixedArray> new_array = 8084 Handle<WeakFixedArray> new_array =
8115 Allocate(array->GetIsolate(), new_length, array); 8085 Allocate(array->GetIsolate(), new_length, array);
8116 if (FLAG_trace_weak_arrays) { 8086 if (FLAG_trace_weak_arrays) {
8117 PrintF("[WeakFixedArray: growing to size %d ]\n", new_length); 8087 PrintF("[WeakFixedArray: growing to size %d ]\n", new_length);
8118 } 8088 }
8119 WeakFixedArray::Set(new_array, array->Length(), value); 8089 WeakFixedArray::Set(new_array, length, value);
8090 if (assigned_index != NULL) *assigned_index = length;
8120 return new_array; 8091 return new_array;
8121 } 8092 }
8122 8093
8123 8094
8095 template <class CompactionCallback>
8124 void WeakFixedArray::Compact() { 8096 void WeakFixedArray::Compact() {
8125 FixedArray* array = FixedArray::cast(this); 8097 FixedArray* array = FixedArray::cast(this);
8126 int new_length = kFirstIndex; 8098 int new_length = kFirstIndex;
8127 for (int i = kFirstIndex; i < array->length(); i++) { 8099 for (int i = kFirstIndex; i < array->length(); i++) {
8128 Object* element = array->get(i); 8100 Object* element = array->get(i);
8129 if (element->IsSmi()) continue; 8101 if (element->IsSmi()) continue;
8130 if (WeakCell::cast(element)->cleared()) continue; 8102 if (WeakCell::cast(element)->cleared()) continue;
8103 Object* value = WeakCell::cast(element)->value();
8104 CompactionCallback::Callback(value, i - kFirstIndex,
8105 new_length - kFirstIndex);
8131 array->set(new_length++, element); 8106 array->set(new_length++, element);
8132 } 8107 }
8133 array->Shrink(new_length); 8108 array->Shrink(new_length);
8134 set_last_used_index(0); 8109 set_last_used_index(0);
8135 } 8110 }
8136 8111
8137 8112
8113 void JSObject::PrototypeRegistryCompactionCallback::Callback(Object* value,
8114 int old_index,
8115 int new_index) {
8116 DCHECK(value->IsMap() && Map::cast(value)->is_prototype_map());
8117 Map* map = Map::cast(value);
8118 DCHECK(map->prototype_info()->IsPrototypeInfo());
8119 PrototypeInfo* proto_info = PrototypeInfo::cast(map->prototype_info());
8120 DCHECK_EQ(old_index, proto_info->registry_slot());
8121 proto_info->set_registry_slot(new_index);
8122 }
8123
8124
8125 template void WeakFixedArray::Compact<WeakFixedArray::NullCallback>();
8126 template void
8127 WeakFixedArray::Compact<JSObject::PrototypeRegistryCompactionCallback>();
8128
8129
8138 bool WeakFixedArray::Remove(Handle<HeapObject> value) { 8130 bool WeakFixedArray::Remove(Handle<HeapObject> value) {
8139 if (Length() == 0) return false; 8131 if (Length() == 0) return false;
8140 // Optimize for the most recently added element to be removed again. 8132 // Optimize for the most recently added element to be removed again.
8141 int first_index = last_used_index(); 8133 int first_index = last_used_index();
8142 for (int i = first_index;;) { 8134 for (int i = first_index;;) {
8143 if (Get(i) == *value) { 8135 if (Get(i) == *value) {
8144 Clear(i); 8136 Clear(i);
8145 // Users of WeakFixedArray should make sure that there are no duplicates, 8137 // Users of WeakFixedArray should make sure that there are no duplicates.
8146 // they can use Add(..., kAddIfNotFound) if necessary.
8147 return true; 8138 return true;
8148 } 8139 }
8149 i = (i + 1) % Length(); 8140 i = (i + 1) % Length();
8150 if (i == first_index) return false; 8141 if (i == first_index) return false;
8151 } 8142 }
8152 UNREACHABLE(); 8143 UNREACHABLE();
8153 } 8144 }
8154 8145
8155 8146
8156 // static 8147 // static
(...skipping 1697 matching lines...) Expand 10 before | Expand all | Expand 10 after
9854 9845
9855 9846
9856 // static 9847 // static
9857 void JSObject::LazyRegisterPrototypeUser(Handle<Map> user, Isolate* isolate) { 9848 void JSObject::LazyRegisterPrototypeUser(Handle<Map> user, Isolate* isolate) {
9858 DCHECK(FLAG_track_prototype_users); 9849 DCHECK(FLAG_track_prototype_users);
9859 // Contract: In line with InvalidatePrototypeChains()'s requirements, 9850 // Contract: In line with InvalidatePrototypeChains()'s requirements,
9860 // leaf maps don't need to register as users, only prototypes do. 9851 // leaf maps don't need to register as users, only prototypes do.
9861 DCHECK(user->is_prototype_map()); 9852 DCHECK(user->is_prototype_map());
9862 9853
9863 Handle<Map> current_user = user; 9854 Handle<Map> current_user = user;
9855 Handle<PrototypeInfo> current_user_info =
9856 Map::GetOrCreatePrototypeInfo(user, isolate);
9864 for (PrototypeIterator iter(user); !iter.IsAtEnd(); iter.Advance()) { 9857 for (PrototypeIterator iter(user); !iter.IsAtEnd(); iter.Advance()) {
9858 // Walk up the prototype chain as far as links haven't been registered yet.
9859 if (current_user_info->registry_slot() != PrototypeInfo::UNREGISTERED) {
9860 break;
9861 }
9865 Handle<Object> maybe_proto = PrototypeIterator::GetCurrent(iter); 9862 Handle<Object> maybe_proto = PrototypeIterator::GetCurrent(iter);
9866 if (maybe_proto->IsJSGlobalProxy()) continue; 9863 if (maybe_proto->IsJSGlobalProxy()) continue;
9867 // Proxies on the prototype chain are not supported. 9864 // Proxies on the prototype chain are not supported.
9868 if (maybe_proto->IsJSProxy()) return; 9865 if (maybe_proto->IsJSProxy()) return;
9869 Handle<JSObject> proto = Handle<JSObject>::cast(maybe_proto); 9866 Handle<JSObject> proto = Handle<JSObject>::cast(maybe_proto);
9870 bool just_registered = 9867 Handle<PrototypeInfo> proto_info =
9871 RegisterPrototypeUserIfNotRegistered(proto, current_user, isolate); 9868 Map::GetOrCreatePrototypeInfo(proto, isolate);
9872 // Walk up the prototype chain as far as links haven't been registered yet. 9869 Handle<Object> maybe_registry(proto_info->prototype_users(), isolate);
9873 if (!just_registered) break; 9870 int slot = 0;
9871 Handle<WeakFixedArray> new_array =
9872 WeakFixedArray::Add(maybe_registry, current_user, &slot);
9873 current_user_info->set_registry_slot(slot);
9874 if (!maybe_registry.is_identical_to(new_array)) {
9875 proto_info->set_prototype_users(*new_array);
9876 }
9877 if (FLAG_trace_prototype_users) {
9878 PrintF("Registering %p as a user of prototype %p (map=%p).\n",
9879 reinterpret_cast<void*>(*current_user),
9880 reinterpret_cast<void*>(*proto),
9881 reinterpret_cast<void*>(proto->map()));
9882 }
9883
9874 current_user = handle(proto->map(), isolate); 9884 current_user = handle(proto->map(), isolate);
9885 current_user_info = proto_info;
9875 } 9886 }
9876 } 9887 }
9877 9888
9878 9889
9879 // Returns true if the user was not yet registered.
9880 // static
9881 bool JSObject::RegisterPrototypeUserIfNotRegistered(Handle<JSObject> prototype,
9882 Handle<HeapObject> user,
9883 Isolate* isolate) {
9884 Handle<PrototypeInfo> proto_info =
9885 Map::GetOrCreatePrototypeInfo(prototype, isolate);
9886 Handle<Object> maybe_registry(proto_info->prototype_users(), isolate);
9887 bool was_present = false;
9888 Handle<WeakFixedArray> new_array = WeakFixedArray::Add(
9889 maybe_registry, user, WeakFixedArray::kAddIfNotFound, &was_present);
9890 if (!maybe_registry.is_identical_to(new_array)) {
9891 proto_info->set_prototype_users(*new_array);
9892 }
9893 if (FLAG_trace_prototype_users && !was_present) {
9894 PrintF("Registering %p as a user of prototype %p (map=%p).\n",
9895 reinterpret_cast<void*>(*user), reinterpret_cast<void*>(*prototype),
9896 reinterpret_cast<void*>(prototype->map()));
9897 }
9898 return !was_present;
9899 }
9900
9901
9902 // Can be called regardless of whether |user| was actually registered with 9890 // Can be called regardless of whether |user| was actually registered with
9903 // |prototype|. Returns true when there was a registration. 9891 // |prototype|. Returns true when there was a registration.
9904 // static 9892 // static
9905 bool JSObject::UnregisterPrototypeUser(Handle<JSObject> prototype, 9893 bool JSObject::UnregisterPrototypeUser(Handle<Map> user, Isolate* isolate) {
9906 Handle<HeapObject> user) { 9894 DCHECK(user->is_prototype_map());
9907 Isolate* isolate = prototype->GetIsolate(); 9895 // If it doesn't have a PrototypeInfo, it was never registered.
9896 if (!user->prototype_info()->IsPrototypeInfo()) return false;
9897 // If it doesn't have a prototype, it can't be registered.
9898 if (!user->prototype()->IsJSObject()) return false;
9899 Handle<JSObject> prototype(JSObject::cast(user->prototype()), isolate);
9900 Handle<PrototypeInfo> user_info =
9901 Map::GetOrCreatePrototypeInfo(user, isolate);
9902 int slot = user_info->registry_slot();
9903 if (slot == PrototypeInfo::UNREGISTERED) return false;
9908 if (prototype->IsJSGlobalProxy()) { 9904 if (prototype->IsJSGlobalProxy()) {
9909 PrototypeIterator iter(isolate, prototype); 9905 PrototypeIterator iter(isolate, prototype);
9910 prototype = Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)); 9906 prototype = Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter));
9911 } 9907 }
9912 DCHECK(prototype->map()->is_prototype_map()); 9908 DCHECK(prototype->map()->is_prototype_map());
9913 Object* maybe_proto_info = prototype->map()->prototype_info(); 9909 Object* maybe_proto_info = prototype->map()->prototype_info();
9914 if (!maybe_proto_info->IsPrototypeInfo()) return false; 9910 // User knows its registry slot, prototype info and user registry must exist.
9911 DCHECK(maybe_proto_info->IsPrototypeInfo());
9915 Handle<PrototypeInfo> proto_info(PrototypeInfo::cast(maybe_proto_info), 9912 Handle<PrototypeInfo> proto_info(PrototypeInfo::cast(maybe_proto_info),
9916 isolate); 9913 isolate);
9917 Object* maybe_registry = proto_info->prototype_users(); 9914 Object* maybe_registry = proto_info->prototype_users();
9918 if (!maybe_registry->IsWeakFixedArray()) return false; 9915 DCHECK(maybe_registry->IsWeakFixedArray());
9919 bool result = WeakFixedArray::cast(maybe_registry)->Remove(user); 9916 DCHECK(WeakFixedArray::cast(maybe_registry)->Get(slot) == *user);
9920 if (FLAG_trace_prototype_users && result) { 9917 WeakFixedArray::cast(maybe_registry)->Clear(slot);
9918 if (FLAG_trace_prototype_users) {
9921 PrintF("Unregistering %p as a user of prototype %p.\n", 9919 PrintF("Unregistering %p as a user of prototype %p.\n",
9922 reinterpret_cast<void*>(*user), reinterpret_cast<void*>(*prototype)); 9920 reinterpret_cast<void*>(*user), reinterpret_cast<void*>(*prototype));
9923 } 9921 }
9924 return result; 9922 return true;
9925 } 9923 }
9926 9924
9927 9925
9928 static void InvalidatePrototypeChainsInternal(Map* map) { 9926 static void InvalidatePrototypeChainsInternal(Map* map) {
9929 if (!map->is_prototype_map()) return; 9927 if (!map->is_prototype_map()) return;
9930 if (FLAG_trace_prototype_users) { 9928 if (FLAG_trace_prototype_users) {
9931 PrintF("Invalidating prototype map %p 's cell\n", 9929 PrintF("Invalidating prototype map %p 's cell\n",
9932 reinterpret_cast<void*>(map)); 9930 reinterpret_cast<void*>(map));
9933 } 9931 }
9934 Object* maybe_proto_info = map->prototype_info(); 9932 Object* maybe_proto_info = map->prototype_info();
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
9976 if (maybe_proto_info->IsPrototypeInfo()) { 9974 if (maybe_proto_info->IsPrototypeInfo()) {
9977 return handle(PrototypeInfo::cast(maybe_proto_info), isolate); 9975 return handle(PrototypeInfo::cast(maybe_proto_info), isolate);
9978 } 9976 }
9979 Handle<PrototypeInfo> proto_info = isolate->factory()->NewPrototypeInfo(); 9977 Handle<PrototypeInfo> proto_info = isolate->factory()->NewPrototypeInfo();
9980 prototype->map()->set_prototype_info(*proto_info); 9978 prototype->map()->set_prototype_info(*proto_info);
9981 return proto_info; 9979 return proto_info;
9982 } 9980 }
9983 9981
9984 9982
9985 // static 9983 // static
9984 Handle<PrototypeInfo> Map::GetOrCreatePrototypeInfo(Handle<Map> prototype_map,
9985 Isolate* isolate) {
9986 Object* maybe_proto_info = prototype_map->prototype_info();
9987 if (maybe_proto_info->IsPrototypeInfo()) {
9988 return handle(PrototypeInfo::cast(maybe_proto_info), isolate);
9989 }
9990 Handle<PrototypeInfo> proto_info = isolate->factory()->NewPrototypeInfo();
9991 prototype_map->set_prototype_info(*proto_info);
9992 return proto_info;
9993 }
9994
9995
9996 // static
9986 Handle<Cell> Map::GetOrCreatePrototypeChainValidityCell(Handle<Map> map, 9997 Handle<Cell> Map::GetOrCreatePrototypeChainValidityCell(Handle<Map> map,
9987 Isolate* isolate) { 9998 Isolate* isolate) {
9988 Handle<Object> maybe_prototype(map->prototype(), isolate); 9999 Handle<Object> maybe_prototype(map->prototype(), isolate);
9989 if (!maybe_prototype->IsJSObject()) return Handle<Cell>::null(); 10000 if (!maybe_prototype->IsJSObject()) return Handle<Cell>::null();
9990 Handle<JSObject> prototype = Handle<JSObject>::cast(maybe_prototype); 10001 Handle<JSObject> prototype = Handle<JSObject>::cast(maybe_prototype);
9991 if (prototype->IsJSGlobalProxy()) { 10002 if (prototype->IsJSGlobalProxy()) {
9992 PrototypeIterator iter(isolate, prototype); 10003 PrototypeIterator iter(isolate, prototype);
9993 prototype = Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)); 10004 prototype = Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter));
9994 } 10005 }
9995 // Ensure the prototype is registered with its own prototypes so its cell 10006 // Ensure the prototype is registered with its own prototypes so its cell
(...skipping 470 matching lines...) Expand 10 before | Expand all | Expand 10 after
10466 WeakFixedArray* list = 10477 WeakFixedArray* list =
10467 WeakFixedArray::cast(old_script->shared_function_infos()); 10478 WeakFixedArray::cast(old_script->shared_function_infos());
10468 list->Remove(shared); 10479 list->Remove(shared);
10469 } 10480 }
10470 } 10481 }
10471 // Add shared function info to new script's list. 10482 // Add shared function info to new script's list.
10472 if (script_object->IsScript()) { 10483 if (script_object->IsScript()) {
10473 Handle<Script> script = Handle<Script>::cast(script_object); 10484 Handle<Script> script = Handle<Script>::cast(script_object);
10474 Handle<Object> list(script->shared_function_infos(), shared->GetIsolate()); 10485 Handle<Object> list(script->shared_function_infos(), shared->GetIsolate());
10475 #ifdef DEBUG 10486 #ifdef DEBUG
10476 bool found = false; 10487 if (list->IsWeakFixedArray()) {
10477 list = WeakFixedArray::Add(list, shared, WeakFixedArray::kAddIfNotFound, 10488 Handle<WeakFixedArray> array = Handle<WeakFixedArray>::cast(list);
10478 &found); 10489 for (int i = 0; i < array->Length(); ++i) {
10479 CHECK(!found); 10490 DCHECK(array->Get(i) != *shared);
10480 #else 10491 }
10481 list = WeakFixedArray::Add(list, shared, WeakFixedArray::kAlwaysAdd); 10492 }
10482 #endif // DEBUG 10493 #endif // DEBUG
10494 list = WeakFixedArray::Add(list, shared);
10483 script->set_shared_function_infos(*list); 10495 script->set_shared_function_infos(*list);
10484 } 10496 }
10485 // Finally set new script. 10497 // Finally set new script.
10486 shared->set_script(*script_object); 10498 shared->set_script(*script_object);
10487 } 10499 }
10488 10500
10489 10501
10490 String* SharedFunctionInfo::DebugName() { 10502 String* SharedFunctionInfo::DebugName() {
10491 Object* n = name(); 10503 Object* n = name();
10492 if (!n->IsString() || String::cast(n)->length() == 0) return inferred_name(); 10504 if (!n->IsString() || String::cast(n)->length() == 0) return inferred_name();
(...skipping 5658 matching lines...) Expand 10 before | Expand all | Expand 10 after
16151 Handle<Object> new_value) { 16163 Handle<Object> new_value) {
16152 if (cell->value() != *new_value) { 16164 if (cell->value() != *new_value) {
16153 cell->set_value(*new_value); 16165 cell->set_value(*new_value);
16154 Isolate* isolate = cell->GetIsolate(); 16166 Isolate* isolate = cell->GetIsolate();
16155 cell->dependent_code()->DeoptimizeDependentCodeGroup( 16167 cell->dependent_code()->DeoptimizeDependentCodeGroup(
16156 isolate, DependentCode::kPropertyCellChangedGroup); 16168 isolate, DependentCode::kPropertyCellChangedGroup);
16157 } 16169 }
16158 } 16170 }
16159 } // namespace internal 16171 } // namespace internal
16160 } // namespace v8 16172 } // namespace v8
OLDNEW
« 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