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

Side by Side Diff: src/objects.cc

Issue 1281613004: Version 4.4.63.31 (cherry-pick) (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@4.4
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 1893 matching lines...) Expand 10 before | Expand all | Expand 10 after
1904 } 1904 }
1905 1905
1906 1906
1907 void Map::ConnectElementsTransition(Handle<Map> parent, Handle<Map> child) { 1907 void Map::ConnectElementsTransition(Handle<Map> parent, Handle<Map> child) {
1908 Isolate* isolate = parent->GetIsolate(); 1908 Isolate* isolate = parent->GetIsolate();
1909 Handle<Name> name = isolate->factory()->elements_transition_symbol(); 1909 Handle<Name> name = isolate->factory()->elements_transition_symbol();
1910 ConnectTransition(parent, child, name, SPECIAL_TRANSITION); 1910 ConnectTransition(parent, child, name, SPECIAL_TRANSITION);
1911 } 1911 }
1912 1912
1913 1913
1914 static void UpdatePrototypeUserRegistration(Handle<Map> old_map,
1915 Handle<Map> new_map,
1916 Isolate* isolate) {
1917 if (!FLAG_track_prototype_users) return;
1918 if (!old_map->is_prototype_map()) return;
1919 DCHECK(new_map->is_prototype_map());
1920 bool was_registered = JSObject::UnregisterPrototypeUser(old_map, isolate);
1921 new_map->set_prototype_info(old_map->prototype_info());
1922 old_map->set_prototype_info(Smi::FromInt(0));
1923 if (FLAG_trace_prototype_users) {
1924 PrintF("Moving prototype_info %p from map %p to map %p.\n",
1925 reinterpret_cast<void*>(new_map->prototype_info()),
1926 reinterpret_cast<void*>(*old_map),
1927 reinterpret_cast<void*>(*new_map));
1928 }
1929 if (was_registered) {
1930 if (new_map->prototype_info()->IsPrototypeInfo()) {
1931 // The new map isn't registered with its prototype yet; reflect this fact
1932 // in the PrototypeInfo it just inherited from the old map.
1933 PrototypeInfo::cast(new_map->prototype_info())
1934 ->set_registry_slot(PrototypeInfo::UNREGISTERED);
1935 }
1936 JSObject::LazyRegisterPrototypeUser(new_map, isolate);
1937 }
1938 }
1939
1940
1914 void JSObject::MigrateToMap(Handle<JSObject> object, Handle<Map> new_map, 1941 void JSObject::MigrateToMap(Handle<JSObject> object, Handle<Map> new_map,
1915 int expected_additional_properties) { 1942 int expected_additional_properties) {
1916 if (object->map() == *new_map) return; 1943 if (object->map() == *new_map) return;
1917 // If this object is a prototype (the callee will check), invalidate any 1944 // If this object is a prototype (the callee will check), invalidate any
1918 // prototype chains involving it. 1945 // prototype chains involving it.
1919 InvalidatePrototypeChains(object->map()); 1946 InvalidatePrototypeChains(object->map());
1920 Handle<Map> old_map(object->map()); 1947 Handle<Map> old_map(object->map());
1921 1948
1922 // If the map was registered with its prototype before, ensure that it 1949 // If the map was registered with its prototype before, ensure that it
1923 // registers with its new prototype now. This preserves the invariant that 1950 // registers with its new prototype now. This preserves the invariant that
1924 // when a map on a prototype chain is registered with its prototype, then 1951 // when a map on a prototype chain is registered with its prototype, then
1925 // all prototypes further up the chain are also registered with their 1952 // all prototypes further up the chain are also registered with their
1926 // respective prototypes. 1953 // respective prototypes.
1927 Object* maybe_old_prototype = old_map->prototype(); 1954 UpdatePrototypeUserRegistration(old_map, new_map, new_map->GetIsolate());
1928 if (FLAG_track_prototype_users && old_map->is_prototype_map() &&
1929 maybe_old_prototype->IsJSObject()) {
1930 Handle<JSObject> old_prototype(JSObject::cast(maybe_old_prototype));
1931 bool was_registered =
1932 JSObject::UnregisterPrototypeUser(old_prototype, old_map);
1933 if (was_registered) {
1934 JSObject::LazyRegisterPrototypeUser(new_map, new_map->GetIsolate());
1935 }
1936 }
1937 1955
1938 if (object->HasFastProperties()) { 1956 if (object->HasFastProperties()) {
1939 if (!new_map->is_dictionary_map()) { 1957 if (!new_map->is_dictionary_map()) {
1940 MigrateFastToFast(object, new_map); 1958 MigrateFastToFast(object, new_map);
1941 if (old_map->is_prototype_map()) { 1959 if (old_map->is_prototype_map()) {
1942 // Clear out the old descriptor array to avoid problems to sharing 1960 // Clear out the old descriptor array to avoid problems to sharing
1943 // the descriptor array without using an explicit. 1961 // the descriptor array without using an explicit.
1944 old_map->InitializeDescriptors( 1962 old_map->InitializeDescriptors(
1945 old_map->GetHeap()->empty_descriptor_array(), 1963 old_map->GetHeap()->empty_descriptor_array(),
1946 LayoutDescriptor::FastPointerLayout()); 1964 LayoutDescriptor::FastPointerLayout());
(...skipping 12 matching lines...) Expand all
1959 1977
1960 // Slow-to-slow migration is trivial. 1978 // Slow-to-slow migration is trivial.
1961 object->set_map(*new_map); 1979 object->set_map(*new_map);
1962 } 1980 }
1963 1981
1964 // Careful: Don't allocate here! 1982 // Careful: Don't allocate here!
1965 // For some callers of this method, |object| might be in an inconsistent 1983 // For some callers of this method, |object| might be in an inconsistent
1966 // state now: the new map might have a new elements_kind, but the object's 1984 // state now: the new map might have a new elements_kind, but the object's
1967 // elements pointer hasn't been updated yet. Callers will fix this, but in 1985 // elements pointer hasn't been updated yet. Callers will fix this, but in
1968 // the meantime, (indirectly) calling JSObjectVerify() must be avoided. 1986 // the meantime, (indirectly) calling JSObjectVerify() must be avoided.
1969 DisallowHeapAllocation no_object_verification; 1987 // When adding code here, add a DisallowHeapAllocation too.
1970
1971 if (old_map->is_prototype_map() && FLAG_track_prototype_users) {
1972 DCHECK(new_map->is_prototype_map());
1973 DCHECK(object->map() == *new_map);
1974 new_map->set_prototype_info(old_map->prototype_info());
1975 old_map->set_prototype_info(Smi::FromInt(0));
1976 if (FLAG_trace_prototype_users) {
1977 PrintF("Moving prototype_info %p from map %p to map %p.\n",
1978 reinterpret_cast<void*>(new_map->prototype_info()),
1979 reinterpret_cast<void*>(*old_map),
1980 reinterpret_cast<void*>(*new_map));
1981 }
1982 }
1983 } 1988 }
1984 1989
1985 1990
1986 // To migrate a fast instance to a fast map: 1991 // To migrate a fast instance to a fast map:
1987 // - First check whether the instance needs to be rewritten. If not, simply 1992 // - First check whether the instance needs to be rewritten. If not, simply
1988 // change the map. 1993 // change the map.
1989 // - Otherwise, allocate a fixed array large enough to hold all fields, in 1994 // - Otherwise, allocate a fixed array large enough to hold all fields, in
1990 // addition to unused space. 1995 // addition to unused space.
1991 // - Copy all existing properties in, in the following order: backing store 1996 // - Copy all existing properties in, in the following order: backing store
1992 // properties, unused fields, inobject properties. 1997 // properties, unused fields, inobject properties.
(...skipping 2773 matching lines...) Expand 10 before | Expand all | Expand 10 after
4766 } 4771 }
4767 4772
4768 Handle<Map> old_map(object->map(), isolate); 4773 Handle<Map> old_map(object->map(), isolate);
4769 4774
4770 int inobject_props = old_map->inobject_properties(); 4775 int inobject_props = old_map->inobject_properties();
4771 4776
4772 // Allocate new map. 4777 // Allocate new map.
4773 Handle<Map> new_map = Map::CopyDropDescriptors(old_map); 4778 Handle<Map> new_map = Map::CopyDropDescriptors(old_map);
4774 new_map->set_dictionary_map(false); 4779 new_map->set_dictionary_map(false);
4775 4780
4776 if (old_map->is_prototype_map() && FLAG_track_prototype_users) { 4781 UpdatePrototypeUserRegistration(old_map, new_map, isolate);
4777 DCHECK(new_map->is_prototype_map());
4778
4779 Object* maybe_old_prototype = old_map->prototype();
4780 if (maybe_old_prototype->IsJSObject()) {
4781 Handle<JSObject> old_prototype(JSObject::cast(maybe_old_prototype));
4782 bool was_registered =
4783 JSObject::UnregisterPrototypeUser(old_prototype, old_map);
4784 if (was_registered) {
4785 JSObject::LazyRegisterPrototypeUser(new_map, isolate);
4786 }
4787 }
4788 new_map->set_prototype_info(old_map->prototype_info());
4789 old_map->set_prototype_info(Smi::FromInt(0));
4790 if (FLAG_trace_prototype_users) {
4791 PrintF("Moving prototype_info %p from map %p to map %p.\n",
4792 reinterpret_cast<void*>(new_map->prototype_info()),
4793 reinterpret_cast<void*>(*old_map),
4794 reinterpret_cast<void*>(*new_map));
4795 }
4796 }
4797 4782
4798 #if TRACE_MAPS 4783 #if TRACE_MAPS
4799 if (FLAG_trace_maps) { 4784 if (FLAG_trace_maps) {
4800 PrintF("[TraceMaps: SlowToFast from= %p to= %p reason= %s ]\n", 4785 PrintF("[TraceMaps: SlowToFast from= %p to= %p reason= %s ]\n",
4801 reinterpret_cast<void*>(*old_map), reinterpret_cast<void*>(*new_map), 4786 reinterpret_cast<void*>(*old_map), reinterpret_cast<void*>(*new_map),
4802 reason); 4787 reason);
4803 } 4788 }
4804 #endif 4789 #endif
4805 4790
4806 if (instance_descriptor_length == 0) { 4791 if (instance_descriptor_length == 0) {
(...skipping 3496 matching lines...) Expand 10 before | Expand all | Expand 10 after
8303 : array->GetIsolate()->factory()->NewWeakCell(value); 8288 : array->GetIsolate()->factory()->NewWeakCell(value);
8304 Handle<FixedArray>::cast(array)->set(index + kFirstIndex, *cell); 8289 Handle<FixedArray>::cast(array)->set(index + kFirstIndex, *cell);
8305 if (FLAG_trace_weak_arrays) { 8290 if (FLAG_trace_weak_arrays) {
8306 PrintF("[WeakFixedArray: storing at index %d ]\n", index); 8291 PrintF("[WeakFixedArray: storing at index %d ]\n", index);
8307 } 8292 }
8308 array->set_last_used_index(index); 8293 array->set_last_used_index(index);
8309 } 8294 }
8310 8295
8311 8296
8312 // static 8297 // static
8313 Handle<WeakFixedArray> WeakFixedArray::Add( 8298 Handle<WeakFixedArray> WeakFixedArray::Add(Handle<Object> maybe_array,
8314 Handle<Object> maybe_array, Handle<HeapObject> value, 8299 Handle<HeapObject> value,
8315 SearchForDuplicates search_for_duplicates, bool* was_present) { 8300 int* assigned_index) {
8316 Handle<WeakFixedArray> array = 8301 Handle<WeakFixedArray> array =
8317 (maybe_array.is_null() || !maybe_array->IsWeakFixedArray()) 8302 (maybe_array.is_null() || !maybe_array->IsWeakFixedArray())
8318 ? Allocate(value->GetIsolate(), 1, Handle<WeakFixedArray>::null()) 8303 ? Allocate(value->GetIsolate(), 1, Handle<WeakFixedArray>::null())
8319 : Handle<WeakFixedArray>::cast(maybe_array); 8304 : Handle<WeakFixedArray>::cast(maybe_array);
8320 if (was_present != NULL) *was_present = false;
8321 if (search_for_duplicates == kAddIfNotFound) {
8322 for (int i = 0; i < array->Length(); ++i) {
8323 if (array->Get(i) == *value) {
8324 if (was_present != NULL) *was_present = true;
8325 return array;
8326 }
8327 }
8328 #if 0 // Enable this if you want to check your search_for_duplicates flags.
8329 } else {
8330 for (int i = 0; i < array->Length(); ++i) {
8331 DCHECK_NE(*value, array->Get(i));
8332 }
8333 #endif
8334 }
8335
8336 // Try to store the new entry if there's room. Optimize for consecutive 8305 // Try to store the new entry if there's room. Optimize for consecutive
8337 // accesses. 8306 // accesses.
8338 int first_index = array->last_used_index(); 8307 int first_index = array->last_used_index();
8339 if (array->Length() > 0) { 8308 int length = array->Length();
8309 if (length > 0) {
8340 for (int i = first_index;;) { 8310 for (int i = first_index;;) {
8341 if (array->IsEmptySlot((i))) { 8311 if (array->IsEmptySlot((i))) {
8342 WeakFixedArray::Set(array, i, value); 8312 WeakFixedArray::Set(array, i, value);
8313 if (assigned_index != NULL) *assigned_index = i;
8343 return array; 8314 return array;
8344 } 8315 }
8345 if (FLAG_trace_weak_arrays) { 8316 if (FLAG_trace_weak_arrays) {
8346 PrintF("[WeakFixedArray: searching for free slot]\n"); 8317 PrintF("[WeakFixedArray: searching for free slot]\n");
8347 } 8318 }
8348 i = (i + 1) % array->Length(); 8319 i = (i + 1) % length;
8349 if (i == first_index) break; 8320 if (i == first_index) break;
8350 } 8321 }
8351 } 8322 }
8352 8323
8353 // No usable slot found, grow the array. 8324 // No usable slot found, grow the array.
8354 int new_length = 8325 int new_length = length == 0 ? 1 : length + (length >> 1) + 4;
8355 array->Length() == 0 ? 1 : array->Length() + (array->Length() >> 1) + 4;
8356 Handle<WeakFixedArray> new_array = 8326 Handle<WeakFixedArray> new_array =
8357 Allocate(array->GetIsolate(), new_length, array); 8327 Allocate(array->GetIsolate(), new_length, array);
8358 if (FLAG_trace_weak_arrays) { 8328 if (FLAG_trace_weak_arrays) {
8359 PrintF("[WeakFixedArray: growing to size %d ]\n", new_length); 8329 PrintF("[WeakFixedArray: growing to size %d ]\n", new_length);
8360 } 8330 }
8361 WeakFixedArray::Set(new_array, array->Length(), value); 8331 WeakFixedArray::Set(new_array, length, value);
8332 if (assigned_index != NULL) *assigned_index = length;
8362 return new_array; 8333 return new_array;
8363 } 8334 }
8364 8335
8365 8336
8337 template <class CompactionCallback>
8366 void WeakFixedArray::Compact() { 8338 void WeakFixedArray::Compact() {
8367 FixedArray* array = FixedArray::cast(this); 8339 FixedArray* array = FixedArray::cast(this);
8368 int new_length = kFirstIndex; 8340 int new_length = kFirstIndex;
8369 for (int i = kFirstIndex; i < array->length(); i++) { 8341 for (int i = kFirstIndex; i < array->length(); i++) {
8370 Object* element = array->get(i); 8342 Object* element = array->get(i);
8371 if (element->IsSmi()) continue; 8343 if (element->IsSmi()) continue;
8372 if (WeakCell::cast(element)->cleared()) continue; 8344 if (WeakCell::cast(element)->cleared()) continue;
8345 Object* value = WeakCell::cast(element)->value();
8346 CompactionCallback::Callback(value, i - kFirstIndex,
8347 new_length - kFirstIndex);
8373 array->set(new_length++, element); 8348 array->set(new_length++, element);
8374 } 8349 }
8375 array->Shrink(new_length); 8350 array->Shrink(new_length);
8376 set_last_used_index(0); 8351 set_last_used_index(0);
8377 } 8352 }
8378 8353
8379 8354
8355 void JSObject::PrototypeRegistryCompactionCallback::Callback(Object* value,
8356 int old_index,
8357 int new_index) {
8358 DCHECK(value->IsMap() && Map::cast(value)->is_prototype_map());
8359 Map* map = Map::cast(value);
8360 DCHECK(map->prototype_info()->IsPrototypeInfo());
8361 PrototypeInfo* proto_info = PrototypeInfo::cast(map->prototype_info());
8362 DCHECK_EQ(old_index, proto_info->registry_slot());
8363 proto_info->set_registry_slot(new_index);
8364 }
8365
8366
8367 template void WeakFixedArray::Compact<WeakFixedArray::NullCallback>();
8368 template void
8369 WeakFixedArray::Compact<JSObject::PrototypeRegistryCompactionCallback>();
8370
8371
8380 bool WeakFixedArray::Remove(Handle<HeapObject> value) { 8372 bool WeakFixedArray::Remove(Handle<HeapObject> value) {
8381 if (Length() == 0) return false; 8373 if (Length() == 0) return false;
8382 // Optimize for the most recently added element to be removed again. 8374 // Optimize for the most recently added element to be removed again.
8383 int first_index = last_used_index(); 8375 int first_index = last_used_index();
8384 for (int i = first_index;;) { 8376 for (int i = first_index;;) {
8385 if (Get(i) == *value) { 8377 if (Get(i) == *value) {
8386 Clear(i); 8378 Clear(i);
8387 // Users of WeakFixedArray should make sure that there are no duplicates, 8379 // Users of WeakFixedArray should make sure that there are no duplicates.
8388 // they can use Add(..., kAddIfNotFound) if necessary.
8389 return true; 8380 return true;
8390 } 8381 }
8391 i = (i + 1) % Length(); 8382 i = (i + 1) % Length();
8392 if (i == first_index) return false; 8383 if (i == first_index) return false;
8393 } 8384 }
8394 UNREACHABLE(); 8385 UNREACHABLE();
8395 } 8386 }
8396 8387
8397 8388
8398 // static 8389 // static
(...skipping 1730 matching lines...) Expand 10 before | Expand all | Expand 10 after
10129 10120
10130 10121
10131 // static 10122 // static
10132 void JSObject::LazyRegisterPrototypeUser(Handle<Map> user, Isolate* isolate) { 10123 void JSObject::LazyRegisterPrototypeUser(Handle<Map> user, Isolate* isolate) {
10133 DCHECK(FLAG_track_prototype_users); 10124 DCHECK(FLAG_track_prototype_users);
10134 // Contract: In line with InvalidatePrototypeChains()'s requirements, 10125 // Contract: In line with InvalidatePrototypeChains()'s requirements,
10135 // leaf maps don't need to register as users, only prototypes do. 10126 // leaf maps don't need to register as users, only prototypes do.
10136 DCHECK(user->is_prototype_map()); 10127 DCHECK(user->is_prototype_map());
10137 10128
10138 Handle<Map> current_user = user; 10129 Handle<Map> current_user = user;
10130 Handle<PrototypeInfo> current_user_info =
10131 Map::GetOrCreatePrototypeInfo(user, isolate);
10139 for (PrototypeIterator iter(user); !iter.IsAtEnd(); iter.Advance()) { 10132 for (PrototypeIterator iter(user); !iter.IsAtEnd(); iter.Advance()) {
10133 // Walk up the prototype chain as far as links haven't been registered yet.
10134 if (current_user_info->registry_slot() != PrototypeInfo::UNREGISTERED) {
10135 break;
10136 }
10140 Handle<Object> maybe_proto = PrototypeIterator::GetCurrent(iter); 10137 Handle<Object> maybe_proto = PrototypeIterator::GetCurrent(iter);
10141 if (maybe_proto->IsJSGlobalProxy()) continue; 10138 if (maybe_proto->IsJSGlobalProxy()) continue;
10142 // Proxies on the prototype chain are not supported. 10139 // Proxies on the prototype chain are not supported.
10143 if (maybe_proto->IsJSProxy()) return; 10140 if (maybe_proto->IsJSProxy()) return;
10144 Handle<JSObject> proto = Handle<JSObject>::cast(maybe_proto); 10141 Handle<JSObject> proto = Handle<JSObject>::cast(maybe_proto);
10145 bool just_registered = 10142 Handle<PrototypeInfo> proto_info =
10146 RegisterPrototypeUserIfNotRegistered(proto, current_user, isolate); 10143 Map::GetOrCreatePrototypeInfo(proto, isolate);
10147 // Walk up the prototype chain as far as links haven't been registered yet. 10144 Handle<Object> maybe_registry(proto_info->prototype_users(), isolate);
10148 if (!just_registered) break; 10145 int slot = 0;
10146 Handle<WeakFixedArray> new_array =
10147 WeakFixedArray::Add(maybe_registry, current_user, &slot);
10148 current_user_info->set_registry_slot(slot);
10149 if (!maybe_registry.is_identical_to(new_array)) {
10150 proto_info->set_prototype_users(*new_array);
10151 }
10152 if (FLAG_trace_prototype_users) {
10153 PrintF("Registering %p as a user of prototype %p (map=%p).\n",
10154 reinterpret_cast<void*>(*current_user),
10155 reinterpret_cast<void*>(*proto),
10156 reinterpret_cast<void*>(proto->map()));
10157 }
10158
10149 current_user = handle(proto->map(), isolate); 10159 current_user = handle(proto->map(), isolate);
10160 current_user_info = proto_info;
10150 } 10161 }
10151 } 10162 }
10152 10163
10153 10164
10154 // Returns true if the user was not yet registered.
10155 // static
10156 bool JSObject::RegisterPrototypeUserIfNotRegistered(Handle<JSObject> prototype,
10157 Handle<HeapObject> user,
10158 Isolate* isolate) {
10159 Handle<PrototypeInfo> proto_info =
10160 Map::GetOrCreatePrototypeInfo(prototype, isolate);
10161 Handle<Object> maybe_registry(proto_info->prototype_users(), isolate);
10162 bool was_present = false;
10163 Handle<WeakFixedArray> new_array = WeakFixedArray::Add(
10164 maybe_registry, user, WeakFixedArray::kAddIfNotFound, &was_present);
10165 if (!maybe_registry.is_identical_to(new_array)) {
10166 proto_info->set_prototype_users(*new_array);
10167 }
10168 if (FLAG_trace_prototype_users && !was_present) {
10169 PrintF("Registering %p as a user of prototype %p (map=%p).\n",
10170 reinterpret_cast<void*>(*user), reinterpret_cast<void*>(*prototype),
10171 reinterpret_cast<void*>(prototype->map()));
10172 }
10173 return !was_present;
10174 }
10175
10176
10177 // Can be called regardless of whether |user| was actually registered with 10165 // Can be called regardless of whether |user| was actually registered with
10178 // |prototype|. Returns true when there was a registration. 10166 // |prototype|. Returns true when there was a registration.
10179 // static 10167 // static
10180 bool JSObject::UnregisterPrototypeUser(Handle<JSObject> prototype, 10168 bool JSObject::UnregisterPrototypeUser(Handle<Map> user, Isolate* isolate) {
10181 Handle<HeapObject> user) { 10169 DCHECK(user->is_prototype_map());
10182 Isolate* isolate = prototype->GetIsolate(); 10170 // If it doesn't have a PrototypeInfo, it was never registered.
10171 if (!user->prototype_info()->IsPrototypeInfo()) return false;
10172 // If it doesn't have a prototype, it can't be registered.
10173 if (!user->prototype()->IsJSObject()) return false;
10174 Handle<JSObject> prototype(JSObject::cast(user->prototype()), isolate);
10175 Handle<PrototypeInfo> user_info =
10176 Map::GetOrCreatePrototypeInfo(user, isolate);
10177 int slot = user_info->registry_slot();
10178 if (slot == PrototypeInfo::UNREGISTERED) return false;
10183 if (prototype->IsJSGlobalProxy()) { 10179 if (prototype->IsJSGlobalProxy()) {
10184 PrototypeIterator iter(isolate, prototype); 10180 PrototypeIterator iter(isolate, prototype);
10185 prototype = Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)); 10181 prototype = Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter));
10186 } 10182 }
10187 DCHECK(prototype->map()->is_prototype_map()); 10183 DCHECK(prototype->map()->is_prototype_map());
10188 Object* maybe_proto_info = prototype->map()->prototype_info(); 10184 Object* maybe_proto_info = prototype->map()->prototype_info();
10189 if (!maybe_proto_info->IsPrototypeInfo()) return false; 10185 // User knows its registry slot, prototype info and user registry must exist.
10186 DCHECK(maybe_proto_info->IsPrototypeInfo());
10190 Handle<PrototypeInfo> proto_info(PrototypeInfo::cast(maybe_proto_info), 10187 Handle<PrototypeInfo> proto_info(PrototypeInfo::cast(maybe_proto_info),
10191 isolate); 10188 isolate);
10192 Object* maybe_registry = proto_info->prototype_users(); 10189 Object* maybe_registry = proto_info->prototype_users();
10193 if (!maybe_registry->IsWeakFixedArray()) return false; 10190 DCHECK(maybe_registry->IsWeakFixedArray());
10194 bool result = WeakFixedArray::cast(maybe_registry)->Remove(user); 10191 DCHECK(WeakFixedArray::cast(maybe_registry)->Get(slot) == *user);
10195 if (FLAG_trace_prototype_users && result) { 10192 WeakFixedArray::cast(maybe_registry)->Clear(slot);
10193 if (FLAG_trace_prototype_users) {
10196 PrintF("Unregistering %p as a user of prototype %p.\n", 10194 PrintF("Unregistering %p as a user of prototype %p.\n",
10197 reinterpret_cast<void*>(*user), reinterpret_cast<void*>(*prototype)); 10195 reinterpret_cast<void*>(*user), reinterpret_cast<void*>(*prototype));
10198 } 10196 }
10199 return result; 10197 return true;
10200 } 10198 }
10201 10199
10202 10200
10203 static void InvalidatePrototypeChainsInternal(Map* map) { 10201 static void InvalidatePrototypeChainsInternal(Map* map) {
10204 if (!map->is_prototype_map()) return; 10202 if (!map->is_prototype_map()) return;
10205 if (FLAG_trace_prototype_users) { 10203 if (FLAG_trace_prototype_users) {
10206 PrintF("Invalidating prototype map %p 's cell\n", 10204 PrintF("Invalidating prototype map %p 's cell\n",
10207 reinterpret_cast<void*>(map)); 10205 reinterpret_cast<void*>(map));
10208 } 10206 }
10209 Object* maybe_proto_info = map->prototype_info(); 10207 Object* maybe_proto_info = map->prototype_info();
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
10251 if (maybe_proto_info->IsPrototypeInfo()) { 10249 if (maybe_proto_info->IsPrototypeInfo()) {
10252 return handle(PrototypeInfo::cast(maybe_proto_info), isolate); 10250 return handle(PrototypeInfo::cast(maybe_proto_info), isolate);
10253 } 10251 }
10254 Handle<PrototypeInfo> proto_info = isolate->factory()->NewPrototypeInfo(); 10252 Handle<PrototypeInfo> proto_info = isolate->factory()->NewPrototypeInfo();
10255 prototype->map()->set_prototype_info(*proto_info); 10253 prototype->map()->set_prototype_info(*proto_info);
10256 return proto_info; 10254 return proto_info;
10257 } 10255 }
10258 10256
10259 10257
10260 // static 10258 // static
10259 Handle<PrototypeInfo> Map::GetOrCreatePrototypeInfo(Handle<Map> prototype_map,
10260 Isolate* isolate) {
10261 Object* maybe_proto_info = prototype_map->prototype_info();
10262 if (maybe_proto_info->IsPrototypeInfo()) {
10263 return handle(PrototypeInfo::cast(maybe_proto_info), isolate);
10264 }
10265 Handle<PrototypeInfo> proto_info = isolate->factory()->NewPrototypeInfo();
10266 prototype_map->set_prototype_info(*proto_info);
10267 return proto_info;
10268 }
10269
10270
10271 // static
10261 Handle<Cell> Map::GetOrCreatePrototypeChainValidityCell(Handle<Map> map, 10272 Handle<Cell> Map::GetOrCreatePrototypeChainValidityCell(Handle<Map> map,
10262 Isolate* isolate) { 10273 Isolate* isolate) {
10263 Handle<Object> maybe_prototype(map->prototype(), isolate); 10274 Handle<Object> maybe_prototype(map->prototype(), isolate);
10264 if (!maybe_prototype->IsJSObject()) return Handle<Cell>::null(); 10275 if (!maybe_prototype->IsJSObject()) return Handle<Cell>::null();
10265 Handle<JSObject> prototype = Handle<JSObject>::cast(maybe_prototype); 10276 Handle<JSObject> prototype = Handle<JSObject>::cast(maybe_prototype);
10266 if (prototype->IsJSGlobalProxy()) { 10277 if (prototype->IsJSGlobalProxy()) {
10267 PrototypeIterator iter(isolate, prototype); 10278 PrototypeIterator iter(isolate, prototype);
10268 prototype = Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)); 10279 prototype = Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter));
10269 } 10280 }
10270 // Ensure the prototype is registered with its own prototypes so its cell 10281 // Ensure the prototype is registered with its own prototypes so its cell
(...skipping 7008 matching lines...) Expand 10 before | Expand all | Expand 10 after
17279 void PropertyCell::SetValueWithInvalidation(Handle<PropertyCell> cell, 17290 void PropertyCell::SetValueWithInvalidation(Handle<PropertyCell> cell,
17280 Handle<Object> new_value) { 17291 Handle<Object> new_value) {
17281 if (cell->value() != *new_value) { 17292 if (cell->value() != *new_value) {
17282 cell->set_value(*new_value); 17293 cell->set_value(*new_value);
17283 Isolate* isolate = cell->GetIsolate(); 17294 Isolate* isolate = cell->GetIsolate();
17284 cell->dependent_code()->DeoptimizeDependentCodeGroup( 17295 cell->dependent_code()->DeoptimizeDependentCodeGroup(
17285 isolate, DependentCode::kPropertyCellChangedGroup); 17296 isolate, DependentCode::kPropertyCellChangedGroup);
17286 } 17297 }
17287 } 17298 }
17288 } } // namespace v8::internal 17299 } } // namespace v8::internal
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