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

Side by Side Diff: src/objects.cc

Issue 1276353004: Fasterify JSObject::UnregisterPrototypeUser (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: fix compaction<->serialization interaction 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 1877 matching lines...) Expand 10 before | Expand all | Expand 10 after
1888 DCHECK(target_inobject < inobject_properties()); 1888 DCHECK(target_inobject < inobject_properties());
1889 if (target_number_of_fields <= target_inobject) { 1889 if (target_number_of_fields <= target_inobject) {
1890 DCHECK(target_number_of_fields + target_unused == target_inobject); 1890 DCHECK(target_number_of_fields + target_unused == target_inobject);
1891 return false; 1891 return false;
1892 } 1892 }
1893 // Otherwise, properties will need to be moved to the backing store. 1893 // Otherwise, properties will need to be moved to the backing store.
1894 return true; 1894 return true;
1895 } 1895 }
1896 1896
1897 1897
1898 static void UpdatePrototypeUserRegistration(Handle<Map> old_map,
1899 Handle<Map> new_map,
1900 Isolate* isolate) {
1901 if (!FLAG_track_prototype_users) return;
1902 if (!old_map->is_prototype_map()) return;
1903 DCHECK(new_map->is_prototype_map());
1904 bool was_registered = JSObject::UnregisterPrototypeUser(old_map, isolate);
1905 new_map->set_prototype_info(old_map->prototype_info());
1906 old_map->set_prototype_info(Smi::FromInt(0));
1907 if (FLAG_trace_prototype_users) {
1908 PrintF("Moving prototype_info %p from map %p to map %p.\n",
1909 reinterpret_cast<void*>(new_map->prototype_info()),
1910 reinterpret_cast<void*>(*old_map),
1911 reinterpret_cast<void*>(*new_map));
1912 }
1913 if (was_registered) {
1914 if (new_map->prototype_info()->IsPrototypeInfo()) {
1915 // The new map isn't registered with its prototype yet; reflect this fact
1916 // in the PrototypeInfo it just inherited from the old map.
1917 PrototypeInfo::cast(new_map->prototype_info())
1918 ->set_registry_slot(PrototypeInfo::UNREGISTERED);
1919 }
1920 JSObject::LazyRegisterPrototypeUser(new_map, isolate);
1921 }
1922 }
1923
1924
1898 void JSObject::MigrateToMap(Handle<JSObject> object, Handle<Map> new_map, 1925 void JSObject::MigrateToMap(Handle<JSObject> object, Handle<Map> new_map,
1899 int expected_additional_properties) { 1926 int expected_additional_properties) {
1900 if (object->map() == *new_map) return; 1927 if (object->map() == *new_map) return;
1901 // If this object is a prototype (the callee will check), invalidate any 1928 // If this object is a prototype (the callee will check), invalidate any
1902 // prototype chains involving it. 1929 // prototype chains involving it.
1903 InvalidatePrototypeChains(object->map()); 1930 InvalidatePrototypeChains(object->map());
1904 Handle<Map> old_map(object->map()); 1931 Handle<Map> old_map(object->map());
1905 1932
1906 // If the map was registered with its prototype before, ensure that it 1933 // If the map was registered with its prototype before, ensure that it
1907 // registers with its new prototype now. This preserves the invariant that 1934 // registers with its new prototype now. This preserves the invariant that
1908 // when a map on a prototype chain is registered with its prototype, then 1935 // when a map on a prototype chain is registered with its prototype, then
1909 // all prototypes further up the chain are also registered with their 1936 // all prototypes further up the chain are also registered with their
1910 // respective prototypes. 1937 // respective prototypes.
1911 Object* maybe_old_prototype = old_map->prototype(); 1938 UpdatePrototypeUserRegistration(old_map, new_map, new_map->GetIsolate());
1912 if (FLAG_track_prototype_users && old_map->is_prototype_map() &&
1913 maybe_old_prototype->IsJSObject()) {
1914 Handle<JSObject> old_prototype(JSObject::cast(maybe_old_prototype));
1915 bool was_registered =
1916 JSObject::UnregisterPrototypeUser(old_prototype, old_map);
1917 if (was_registered) {
1918 JSObject::LazyRegisterPrototypeUser(new_map, new_map->GetIsolate());
1919 }
1920 }
1921 1939
1922 if (object->HasFastProperties()) { 1940 if (object->HasFastProperties()) {
1923 if (!new_map->is_dictionary_map()) { 1941 if (!new_map->is_dictionary_map()) {
1924 MigrateFastToFast(object, new_map); 1942 MigrateFastToFast(object, new_map);
1925 if (old_map->is_prototype_map()) { 1943 if (old_map->is_prototype_map()) {
1926 // Clear out the old descriptor array to avoid problems to sharing 1944 // Clear out the old descriptor array to avoid problems to sharing
1927 // the descriptor array without using an explicit. 1945 // the descriptor array without using an explicit.
1928 old_map->InitializeDescriptors( 1946 old_map->InitializeDescriptors(
1929 old_map->GetHeap()->empty_descriptor_array(), 1947 old_map->GetHeap()->empty_descriptor_array(),
1930 LayoutDescriptor::FastPointerLayout()); 1948 LayoutDescriptor::FastPointerLayout());
(...skipping 12 matching lines...) Expand all
1943 1961
1944 // Slow-to-slow migration is trivial. 1962 // Slow-to-slow migration is trivial.
1945 object->set_map(*new_map); 1963 object->set_map(*new_map);
1946 } 1964 }
1947 1965
1948 // Careful: Don't allocate here! 1966 // Careful: Don't allocate here!
1949 // For some callers of this method, |object| might be in an inconsistent 1967 // For some callers of this method, |object| might be in an inconsistent
1950 // state now: the new map might have a new elements_kind, but the object's 1968 // state now: the new map might have a new elements_kind, but the object's
1951 // elements pointer hasn't been updated yet. Callers will fix this, but in 1969 // elements pointer hasn't been updated yet. Callers will fix this, but in
1952 // the meantime, (indirectly) calling JSObjectVerify() must be avoided. 1970 // the meantime, (indirectly) calling JSObjectVerify() must be avoided.
1953 DisallowHeapAllocation no_object_verification; 1971 // When adding code here, add a DisallowHeapAllocation too.
1954
1955 if (old_map->is_prototype_map() && FLAG_track_prototype_users) {
1956 DCHECK(new_map->is_prototype_map());
1957 DCHECK(object->map() == *new_map);
1958 new_map->set_prototype_info(old_map->prototype_info());
1959 old_map->set_prototype_info(Smi::FromInt(0));
1960 if (FLAG_trace_prototype_users) {
1961 PrintF("Moving prototype_info %p from map %p to map %p.\n",
1962 reinterpret_cast<void*>(new_map->prototype_info()),
1963 reinterpret_cast<void*>(*old_map),
1964 reinterpret_cast<void*>(*new_map));
1965 }
1966 }
1967 } 1972 }
1968 1973
1969 1974
1970 // To migrate a fast instance to a fast map: 1975 // To migrate a fast instance to a fast map:
1971 // - First check whether the instance needs to be rewritten. If not, simply 1976 // - First check whether the instance needs to be rewritten. If not, simply
1972 // change the map. 1977 // change the map.
1973 // - Otherwise, allocate a fixed array large enough to hold all fields, in 1978 // - Otherwise, allocate a fixed array large enough to hold all fields, in
1974 // addition to unused space. 1979 // addition to unused space.
1975 // - Copy all existing properties in, in the following order: backing store 1980 // - Copy all existing properties in, in the following order: backing store
1976 // properties, unused fields, inobject properties. 1981 // properties, unused fields, inobject properties.
(...skipping 2785 matching lines...) Expand 10 before | Expand all | Expand 10 after
4762 } 4767 }
4763 4768
4764 Handle<Map> old_map(object->map(), isolate); 4769 Handle<Map> old_map(object->map(), isolate);
4765 4770
4766 int inobject_props = old_map->inobject_properties(); 4771 int inobject_props = old_map->inobject_properties();
4767 4772
4768 // Allocate new map. 4773 // Allocate new map.
4769 Handle<Map> new_map = Map::CopyDropDescriptors(old_map); 4774 Handle<Map> new_map = Map::CopyDropDescriptors(old_map);
4770 new_map->set_dictionary_map(false); 4775 new_map->set_dictionary_map(false);
4771 4776
4772 if (old_map->is_prototype_map() && FLAG_track_prototype_users) { 4777 UpdatePrototypeUserRegistration(old_map, new_map, isolate);
4773 DCHECK(new_map->is_prototype_map());
4774
4775 Object* maybe_old_prototype = old_map->prototype();
4776 if (maybe_old_prototype->IsJSObject()) {
4777 Handle<JSObject> old_prototype(JSObject::cast(maybe_old_prototype));
4778 bool was_registered =
4779 JSObject::UnregisterPrototypeUser(old_prototype, old_map);
4780 if (was_registered) {
4781 JSObject::LazyRegisterPrototypeUser(new_map, isolate);
4782 }
4783 }
4784 new_map->set_prototype_info(old_map->prototype_info());
4785 old_map->set_prototype_info(Smi::FromInt(0));
4786 if (FLAG_trace_prototype_users) {
4787 PrintF("Moving prototype_info %p from map %p to map %p.\n",
4788 reinterpret_cast<void*>(new_map->prototype_info()),
4789 reinterpret_cast<void*>(*old_map),
4790 reinterpret_cast<void*>(*new_map));
4791 }
4792 }
4793 4778
4794 #if TRACE_MAPS 4779 #if TRACE_MAPS
4795 if (FLAG_trace_maps) { 4780 if (FLAG_trace_maps) {
4796 PrintF("[TraceMaps: SlowToFast from= %p to= %p reason= %s ]\n", 4781 PrintF("[TraceMaps: SlowToFast from= %p to= %p reason= %s ]\n",
4797 reinterpret_cast<void*>(*old_map), reinterpret_cast<void*>(*new_map), 4782 reinterpret_cast<void*>(*old_map), reinterpret_cast<void*>(*new_map),
4798 reason); 4783 reason);
4799 } 4784 }
4800 #endif 4785 #endif
4801 4786
4802 if (instance_descriptor_length == 0) { 4787 if (instance_descriptor_length == 0) {
(...skipping 3128 matching lines...) Expand 10 before | Expand all | Expand 10 after
7931 : array->GetIsolate()->factory()->NewWeakCell(value); 7916 : array->GetIsolate()->factory()->NewWeakCell(value);
7932 Handle<FixedArray>::cast(array)->set(index + kFirstIndex, *cell); 7917 Handle<FixedArray>::cast(array)->set(index + kFirstIndex, *cell);
7933 if (FLAG_trace_weak_arrays) { 7918 if (FLAG_trace_weak_arrays) {
7934 PrintF("[WeakFixedArray: storing at index %d ]\n", index); 7919 PrintF("[WeakFixedArray: storing at index %d ]\n", index);
7935 } 7920 }
7936 array->set_last_used_index(index); 7921 array->set_last_used_index(index);
7937 } 7922 }
7938 7923
7939 7924
7940 // static 7925 // static
7941 Handle<WeakFixedArray> WeakFixedArray::Add( 7926 Handle<WeakFixedArray> WeakFixedArray::Add(Handle<Object> maybe_array,
7942 Handle<Object> maybe_array, Handle<HeapObject> value, 7927 Handle<HeapObject> value,
7943 SearchForDuplicates search_for_duplicates, bool* was_present) { 7928 int* assigned_index) {
7944 Handle<WeakFixedArray> array = 7929 Handle<WeakFixedArray> array =
7945 (maybe_array.is_null() || !maybe_array->IsWeakFixedArray()) 7930 (maybe_array.is_null() || !maybe_array->IsWeakFixedArray())
7946 ? Allocate(value->GetIsolate(), 1, Handle<WeakFixedArray>::null()) 7931 ? Allocate(value->GetIsolate(), 1, Handle<WeakFixedArray>::null())
7947 : Handle<WeakFixedArray>::cast(maybe_array); 7932 : Handle<WeakFixedArray>::cast(maybe_array);
7948 if (was_present != NULL) *was_present = false;
7949 if (search_for_duplicates == kAddIfNotFound) {
7950 for (int i = 0; i < array->Length(); ++i) {
7951 if (array->Get(i) == *value) {
7952 if (was_present != NULL) *was_present = true;
7953 return array;
7954 }
7955 }
7956 #if 0 // Enable this if you want to check your search_for_duplicates flags.
7957 } else {
7958 for (int i = 0; i < array->Length(); ++i) {
7959 DCHECK_NE(*value, array->Get(i));
7960 }
7961 #endif
7962 }
7963
7964 // Try to store the new entry if there's room. Optimize for consecutive 7933 // Try to store the new entry if there's room. Optimize for consecutive
7965 // accesses. 7934 // accesses.
7966 int first_index = array->last_used_index(); 7935 int first_index = array->last_used_index();
7967 if (array->Length() > 0) { 7936 int length = array->Length();
7937 if (length > 0) {
7968 for (int i = first_index;;) { 7938 for (int i = first_index;;) {
7969 if (array->IsEmptySlot((i))) { 7939 if (array->IsEmptySlot((i))) {
7970 WeakFixedArray::Set(array, i, value); 7940 WeakFixedArray::Set(array, i, value);
7941 if (assigned_index != NULL) *assigned_index = i;
7971 return array; 7942 return array;
7972 } 7943 }
7973 if (FLAG_trace_weak_arrays) { 7944 if (FLAG_trace_weak_arrays) {
7974 PrintF("[WeakFixedArray: searching for free slot]\n"); 7945 PrintF("[WeakFixedArray: searching for free slot]\n");
7975 } 7946 }
7976 i = (i + 1) % array->Length(); 7947 i = (i + 1) % length;
7977 if (i == first_index) break; 7948 if (i == first_index) break;
7978 } 7949 }
7979 } 7950 }
7980 7951
7981 // No usable slot found, grow the array. 7952 // No usable slot found, grow the array.
7982 int new_length = 7953 int new_length = length == 0 ? 1 : length + (length >> 1) + 4;
7983 array->Length() == 0 ? 1 : array->Length() + (array->Length() >> 1) + 4;
7984 Handle<WeakFixedArray> new_array = 7954 Handle<WeakFixedArray> new_array =
7985 Allocate(array->GetIsolate(), new_length, array); 7955 Allocate(array->GetIsolate(), new_length, array);
7986 if (FLAG_trace_weak_arrays) { 7956 if (FLAG_trace_weak_arrays) {
7987 PrintF("[WeakFixedArray: growing to size %d ]\n", new_length); 7957 PrintF("[WeakFixedArray: growing to size %d ]\n", new_length);
7988 } 7958 }
7989 WeakFixedArray::Set(new_array, array->Length(), value); 7959 WeakFixedArray::Set(new_array, length, value);
7960 if (assigned_index != NULL) *assigned_index = length;
7990 return new_array; 7961 return new_array;
7991 } 7962 }
7992 7963
7993 7964
7965 template <class CompactionCallback>
7994 void WeakFixedArray::Compact() { 7966 void WeakFixedArray::Compact() {
7995 FixedArray* array = FixedArray::cast(this); 7967 FixedArray* array = FixedArray::cast(this);
7996 int new_length = kFirstIndex; 7968 int new_length = kFirstIndex;
7997 for (int i = kFirstIndex; i < array->length(); i++) { 7969 for (int i = kFirstIndex; i < array->length(); i++) {
7998 Object* element = array->get(i); 7970 Object* element = array->get(i);
7999 if (element->IsSmi()) continue; 7971 if (element->IsSmi()) continue;
8000 if (WeakCell::cast(element)->cleared()) continue; 7972 if (WeakCell::cast(element)->cleared()) continue;
7973 Object* value = WeakCell::cast(element)->value();
7974 CompactionCallback::Callback(value, i - kFirstIndex,
7975 new_length - kFirstIndex);
8001 array->set(new_length++, element); 7976 array->set(new_length++, element);
8002 } 7977 }
8003 array->Shrink(new_length); 7978 array->Shrink(new_length);
8004 set_last_used_index(0); 7979 set_last_used_index(0);
8005 } 7980 }
8006 7981
8007 7982
7983 void JSObject::PrototypeRegistryCompactionCallback::Callback(Object* value,
7984 int old_index,
7985 int new_index) {
7986 DCHECK(value->IsMap() && Map::cast(value)->is_prototype_map());
7987 Map* map = Map::cast(value);
7988 DCHECK(map->prototype_info()->IsPrototypeInfo());
7989 PrototypeInfo* proto_info = PrototypeInfo::cast(map->prototype_info());
7990 DCHECK_EQ(old_index, proto_info->registry_slot());
7991 proto_info->set_registry_slot(new_index);
7992 }
7993
7994
7995 template void WeakFixedArray::Compact<WeakFixedArray::NullCallback>();
7996 template void
7997 WeakFixedArray::Compact<JSObject::PrototypeRegistryCompactionCallback>();
7998
7999
8008 bool WeakFixedArray::Remove(Handle<HeapObject> value) { 8000 bool WeakFixedArray::Remove(Handle<HeapObject> value) {
8009 if (Length() == 0) return false; 8001 if (Length() == 0) return false;
8010 // Optimize for the most recently added element to be removed again. 8002 // Optimize for the most recently added element to be removed again.
8011 int first_index = last_used_index(); 8003 int first_index = last_used_index();
8012 for (int i = first_index;;) { 8004 for (int i = first_index;;) {
8013 if (Get(i) == *value) { 8005 if (Get(i) == *value) {
8014 Clear(i); 8006 Clear(i);
8015 // Users of WeakFixedArray should make sure that there are no duplicates, 8007 // Users of WeakFixedArray should make sure that there are no duplicates.
8016 // they can use Add(..., kAddIfNotFound) if necessary.
8017 return true; 8008 return true;
8018 } 8009 }
8019 i = (i + 1) % Length(); 8010 i = (i + 1) % Length();
8020 if (i == first_index) return false; 8011 if (i == first_index) return false;
8021 } 8012 }
8022 UNREACHABLE(); 8013 UNREACHABLE();
8023 } 8014 }
8024 8015
8025 8016
8026 // static 8017 // static
(...skipping 1724 matching lines...) Expand 10 before | Expand all | Expand 10 after
9751 9742
9752 9743
9753 // static 9744 // static
9754 void JSObject::LazyRegisterPrototypeUser(Handle<Map> user, Isolate* isolate) { 9745 void JSObject::LazyRegisterPrototypeUser(Handle<Map> user, Isolate* isolate) {
9755 DCHECK(FLAG_track_prototype_users); 9746 DCHECK(FLAG_track_prototype_users);
9756 // Contract: In line with InvalidatePrototypeChains()'s requirements, 9747 // Contract: In line with InvalidatePrototypeChains()'s requirements,
9757 // leaf maps don't need to register as users, only prototypes do. 9748 // leaf maps don't need to register as users, only prototypes do.
9758 DCHECK(user->is_prototype_map()); 9749 DCHECK(user->is_prototype_map());
9759 9750
9760 Handle<Map> current_user = user; 9751 Handle<Map> current_user = user;
9752 Handle<PrototypeInfo> current_user_info =
9753 Map::GetOrCreatePrototypeInfo(user, isolate);
9761 for (PrototypeIterator iter(user); !iter.IsAtEnd(); iter.Advance()) { 9754 for (PrototypeIterator iter(user); !iter.IsAtEnd(); iter.Advance()) {
9755 // Walk up the prototype chain as far as links haven't been registered yet.
9756 if (current_user_info->registry_slot() != PrototypeInfo::UNREGISTERED) {
9757 break;
9758 }
9762 Handle<Object> maybe_proto = PrototypeIterator::GetCurrent(iter); 9759 Handle<Object> maybe_proto = PrototypeIterator::GetCurrent(iter);
9763 if (maybe_proto->IsJSGlobalProxy()) continue; 9760 if (maybe_proto->IsJSGlobalProxy()) continue;
9764 // Proxies on the prototype chain are not supported. 9761 // Proxies on the prototype chain are not supported.
9765 if (maybe_proto->IsJSProxy()) return; 9762 if (maybe_proto->IsJSProxy()) return;
9766 Handle<JSObject> proto = Handle<JSObject>::cast(maybe_proto); 9763 Handle<JSObject> proto = Handle<JSObject>::cast(maybe_proto);
9767 bool just_registered = 9764 Handle<PrototypeInfo> proto_info =
9768 RegisterPrototypeUserIfNotRegistered(proto, current_user, isolate); 9765 Map::GetOrCreatePrototypeInfo(proto, isolate);
9769 // Walk up the prototype chain as far as links haven't been registered yet. 9766 Handle<Object> maybe_registry(proto_info->prototype_users(), isolate);
9770 if (!just_registered) break; 9767 int slot = 0;
9768 Handle<WeakFixedArray> new_array =
9769 WeakFixedArray::Add(maybe_registry, current_user, &slot);
9770 current_user_info->set_registry_slot(slot);
9771 if (!maybe_registry.is_identical_to(new_array)) {
9772 proto_info->set_prototype_users(*new_array);
9773 }
9774 if (FLAG_trace_prototype_users) {
9775 PrintF("Registering %p as a user of prototype %p (map=%p).\n",
9776 reinterpret_cast<void*>(*current_user),
9777 reinterpret_cast<void*>(*proto),
9778 reinterpret_cast<void*>(proto->map()));
9779 }
9780
9771 current_user = handle(proto->map(), isolate); 9781 current_user = handle(proto->map(), isolate);
9782 current_user_info = proto_info;
9772 } 9783 }
9773 } 9784 }
9774 9785
9775 9786
9776 // Returns true if the user was not yet registered.
9777 // static
9778 bool JSObject::RegisterPrototypeUserIfNotRegistered(Handle<JSObject> prototype,
9779 Handle<HeapObject> user,
9780 Isolate* isolate) {
9781 Handle<PrototypeInfo> proto_info =
9782 Map::GetOrCreatePrototypeInfo(prototype, isolate);
9783 Handle<Object> maybe_registry(proto_info->prototype_users(), isolate);
9784 bool was_present = false;
9785 Handle<WeakFixedArray> new_array = WeakFixedArray::Add(
9786 maybe_registry, user, WeakFixedArray::kAddIfNotFound, &was_present);
9787 if (!maybe_registry.is_identical_to(new_array)) {
9788 proto_info->set_prototype_users(*new_array);
9789 }
9790 if (FLAG_trace_prototype_users && !was_present) {
9791 PrintF("Registering %p as a user of prototype %p (map=%p).\n",
9792 reinterpret_cast<void*>(*user), reinterpret_cast<void*>(*prototype),
9793 reinterpret_cast<void*>(prototype->map()));
9794 }
9795 return !was_present;
9796 }
9797
9798
9799 // Can be called regardless of whether |user| was actually registered with 9787 // Can be called regardless of whether |user| was actually registered with
9800 // |prototype|. Returns true when there was a registration. 9788 // |prototype|. Returns true when there was a registration.
9801 // static 9789 // static
9802 bool JSObject::UnregisterPrototypeUser(Handle<JSObject> prototype, 9790 bool JSObject::UnregisterPrototypeUser(Handle<Map> user, Isolate* isolate) {
9803 Handle<HeapObject> user) { 9791 DCHECK(user->is_prototype_map());
9804 Isolate* isolate = prototype->GetIsolate(); 9792 // If it doesn't have a PrototypeInfo, it was never registered.
9793 if (!user->prototype_info()->IsPrototypeInfo()) return false;
9794 // If it doesn't have a prototype, it can't be registered.
9795 if (!user->prototype()->IsJSObject()) return false;
9796 Handle<JSObject> prototype(JSObject::cast(user->prototype()), isolate);
9797 Handle<PrototypeInfo> user_info =
9798 Map::GetOrCreatePrototypeInfo(user, isolate);
9799 int slot = user_info->registry_slot();
9800 if (slot == PrototypeInfo::UNREGISTERED) return false;
9805 if (prototype->IsJSGlobalProxy()) { 9801 if (prototype->IsJSGlobalProxy()) {
9806 PrototypeIterator iter(isolate, prototype); 9802 PrototypeIterator iter(isolate, prototype);
9807 prototype = Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)); 9803 prototype = Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter));
9808 } 9804 }
9809 DCHECK(prototype->map()->is_prototype_map()); 9805 DCHECK(prototype->map()->is_prototype_map());
9810 Object* maybe_proto_info = prototype->map()->prototype_info(); 9806 Object* maybe_proto_info = prototype->map()->prototype_info();
9811 if (!maybe_proto_info->IsPrototypeInfo()) return false; 9807 // User knows its registry slot, prototype info and user registry must exist.
9808 DCHECK(maybe_proto_info->IsPrototypeInfo());
9812 Handle<PrototypeInfo> proto_info(PrototypeInfo::cast(maybe_proto_info), 9809 Handle<PrototypeInfo> proto_info(PrototypeInfo::cast(maybe_proto_info),
9813 isolate); 9810 isolate);
9814 Object* maybe_registry = proto_info->prototype_users(); 9811 Object* maybe_registry = proto_info->prototype_users();
9815 if (!maybe_registry->IsWeakFixedArray()) return false; 9812 DCHECK(maybe_registry->IsWeakFixedArray());
9816 bool result = WeakFixedArray::cast(maybe_registry)->Remove(user); 9813 DCHECK(WeakFixedArray::cast(maybe_registry)->Get(slot) == *user);
9817 if (FLAG_trace_prototype_users && result) { 9814 WeakFixedArray::cast(maybe_registry)->Clear(slot);
9815 if (FLAG_trace_prototype_users) {
9818 PrintF("Unregistering %p as a user of prototype %p.\n", 9816 PrintF("Unregistering %p as a user of prototype %p.\n",
9819 reinterpret_cast<void*>(*user), reinterpret_cast<void*>(*prototype)); 9817 reinterpret_cast<void*>(*user), reinterpret_cast<void*>(*prototype));
9820 } 9818 }
9821 return result; 9819 return true;
9822 } 9820 }
9823 9821
9824 9822
9825 static void InvalidatePrototypeChainsInternal(Map* map) { 9823 static void InvalidatePrototypeChainsInternal(Map* map) {
9826 if (!map->is_prototype_map()) return; 9824 if (!map->is_prototype_map()) return;
9827 if (FLAG_trace_prototype_users) { 9825 if (FLAG_trace_prototype_users) {
9828 PrintF("Invalidating prototype map %p 's cell\n", 9826 PrintF("Invalidating prototype map %p 's cell\n",
9829 reinterpret_cast<void*>(map)); 9827 reinterpret_cast<void*>(map));
9830 } 9828 }
9831 Object* maybe_proto_info = map->prototype_info(); 9829 Object* maybe_proto_info = map->prototype_info();
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
9873 if (maybe_proto_info->IsPrototypeInfo()) { 9871 if (maybe_proto_info->IsPrototypeInfo()) {
9874 return handle(PrototypeInfo::cast(maybe_proto_info), isolate); 9872 return handle(PrototypeInfo::cast(maybe_proto_info), isolate);
9875 } 9873 }
9876 Handle<PrototypeInfo> proto_info = isolate->factory()->NewPrototypeInfo(); 9874 Handle<PrototypeInfo> proto_info = isolate->factory()->NewPrototypeInfo();
9877 prototype->map()->set_prototype_info(*proto_info); 9875 prototype->map()->set_prototype_info(*proto_info);
9878 return proto_info; 9876 return proto_info;
9879 } 9877 }
9880 9878
9881 9879
9882 // static 9880 // static
9881 Handle<PrototypeInfo> Map::GetOrCreatePrototypeInfo(Handle<Map> prototype_map,
9882 Isolate* isolate) {
9883 Object* maybe_proto_info = prototype_map->prototype_info();
9884 if (maybe_proto_info->IsPrototypeInfo()) {
9885 return handle(PrototypeInfo::cast(maybe_proto_info), isolate);
9886 }
9887 Handle<PrototypeInfo> proto_info = isolate->factory()->NewPrototypeInfo();
9888 prototype_map->set_prototype_info(*proto_info);
9889 return proto_info;
9890 }
9891
9892
9893 // static
9883 Handle<Cell> Map::GetOrCreatePrototypeChainValidityCell(Handle<Map> map, 9894 Handle<Cell> Map::GetOrCreatePrototypeChainValidityCell(Handle<Map> map,
9884 Isolate* isolate) { 9895 Isolate* isolate) {
9885 Handle<Object> maybe_prototype(map->prototype(), isolate); 9896 Handle<Object> maybe_prototype(map->prototype(), isolate);
9886 if (!maybe_prototype->IsJSObject()) return Handle<Cell>::null(); 9897 if (!maybe_prototype->IsJSObject()) return Handle<Cell>::null();
9887 Handle<JSObject> prototype = Handle<JSObject>::cast(maybe_prototype); 9898 Handle<JSObject> prototype = Handle<JSObject>::cast(maybe_prototype);
9888 if (prototype->IsJSGlobalProxy()) { 9899 if (prototype->IsJSGlobalProxy()) {
9889 PrototypeIterator iter(isolate, prototype); 9900 PrototypeIterator iter(isolate, prototype);
9890 prototype = Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)); 9901 prototype = Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter));
9891 } 9902 }
9892 // Ensure the prototype is registered with its own prototypes so its cell 9903 // Ensure the prototype is registered with its own prototypes so its cell
(...skipping 470 matching lines...) Expand 10 before | Expand all | Expand 10 after
10363 WeakFixedArray* list = 10374 WeakFixedArray* list =
10364 WeakFixedArray::cast(old_script->shared_function_infos()); 10375 WeakFixedArray::cast(old_script->shared_function_infos());
10365 list->Remove(shared); 10376 list->Remove(shared);
10366 } 10377 }
10367 } 10378 }
10368 // Add shared function info to new script's list. 10379 // Add shared function info to new script's list.
10369 if (script_object->IsScript()) { 10380 if (script_object->IsScript()) {
10370 Handle<Script> script = Handle<Script>::cast(script_object); 10381 Handle<Script> script = Handle<Script>::cast(script_object);
10371 Handle<Object> list(script->shared_function_infos(), shared->GetIsolate()); 10382 Handle<Object> list(script->shared_function_infos(), shared->GetIsolate());
10372 #ifdef DEBUG 10383 #ifdef DEBUG
10373 bool found = false; 10384 if (list->IsWeakFixedArray()) {
10374 list = WeakFixedArray::Add(list, shared, WeakFixedArray::kAddIfNotFound, 10385 Handle<WeakFixedArray> array = Handle<WeakFixedArray>::cast(list);
10375 &found); 10386 for (int i = 0; i < array->Length(); ++i) {
10376 CHECK(!found); 10387 DCHECK(array->Get(i) != *shared);
10377 #else 10388 }
10378 list = WeakFixedArray::Add(list, shared, WeakFixedArray::kAlwaysAdd); 10389 }
10379 #endif // DEBUG 10390 #endif // DEBUG
10391 list = WeakFixedArray::Add(list, shared);
10380 script->set_shared_function_infos(*list); 10392 script->set_shared_function_infos(*list);
10381 } 10393 }
10382 // Finally set new script. 10394 // Finally set new script.
10383 shared->set_script(*script_object); 10395 shared->set_script(*script_object);
10384 } 10396 }
10385 10397
10386 10398
10387 String* SharedFunctionInfo::DebugName() { 10399 String* SharedFunctionInfo::DebugName() {
10388 Object* n = name(); 10400 Object* n = name();
10389 if (!n->IsString() || String::cast(n)->length() == 0) return inferred_name(); 10401 if (!n->IsString() || String::cast(n)->length() == 0) return inferred_name();
(...skipping 5479 matching lines...) Expand 10 before | Expand all | Expand 10 after
15869 if (cell->value() != *new_value) { 15881 if (cell->value() != *new_value) {
15870 cell->set_value(*new_value); 15882 cell->set_value(*new_value);
15871 Isolate* isolate = cell->GetIsolate(); 15883 Isolate* isolate = cell->GetIsolate();
15872 cell->dependent_code()->DeoptimizeDependentCodeGroup( 15884 cell->dependent_code()->DeoptimizeDependentCodeGroup(
15873 isolate, DependentCode::kPropertyCellChangedGroup); 15885 isolate, DependentCode::kPropertyCellChangedGroup);
15874 } 15886 }
15875 } 15887 }
15876 15888
15877 } // namespace internal 15889 } // namespace internal
15878 } // namespace v8 15890 } // 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