 Chromium Code Reviews
 Chromium Code Reviews Issue 1330153003:
  Adding template parameter to PrototypeIterator GetCurrent for casting  (Closed) 
  Base URL: https://chromium.googlesource.com/v8/v8.git@master
    
  
    Issue 1330153003:
  Adding template parameter to PrototypeIterator GetCurrent for casting  (Closed) 
  Base URL: https://chromium.googlesource.com/v8/v8.git@master| OLD | NEW | 
|---|---|
| 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 "src/objects.h" | 5 #include "src/objects.h" | 
| 6 | 6 | 
| 7 #include <iomanip> | 7 #include <iomanip> | 
| 8 #include <sstream> | 8 #include <sstream> | 
| 9 | 9 | 
| 10 #include "src/accessors.h" | 10 #include "src/accessors.h" | 
| (...skipping 5057 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5068 | 5068 | 
| 5069 | 5069 | 
| 5070 Object* JSObject::GetHiddenProperty(Handle<Name> key) { | 5070 Object* JSObject::GetHiddenProperty(Handle<Name> key) { | 
| 5071 DisallowHeapAllocation no_gc; | 5071 DisallowHeapAllocation no_gc; | 
| 5072 DCHECK(key->IsUniqueName()); | 5072 DCHECK(key->IsUniqueName()); | 
| 5073 if (IsJSGlobalProxy()) { | 5073 if (IsJSGlobalProxy()) { | 
| 5074 // For a proxy, use the prototype as target object. | 5074 // For a proxy, use the prototype as target object. | 
| 5075 PrototypeIterator iter(GetIsolate(), this); | 5075 PrototypeIterator iter(GetIsolate(), this); | 
| 5076 // If the proxy is detached, return undefined. | 5076 // If the proxy is detached, return undefined. | 
| 5077 if (iter.IsAtEnd()) return GetHeap()->the_hole_value(); | 5077 if (iter.IsAtEnd()) return GetHeap()->the_hole_value(); | 
| 5078 DCHECK(iter.GetCurrent()->IsJSGlobalObject()); | 5078 DCHECK(iter.GetCurrent()->IsJSGlobalObject()); | 
| 
Jakob Kummerow
2015/09/09 14:29:55
Forgot to update this (and a bunch more DCHECKs be
 
Camillo Bruni
2015/09/09 17:24:07
I added a default to the template param, so it wil
 | |
| 5079 return JSObject::cast(iter.GetCurrent())->GetHiddenProperty(key); | 5079 return iter.GetCurrent<JSObject>()->GetHiddenProperty(key); | 
| 5080 } | 5080 } | 
| 5081 DCHECK(!IsJSGlobalProxy()); | 5081 DCHECK(!IsJSGlobalProxy()); | 
| 5082 Object* inline_value = GetHiddenPropertiesHashTable(); | 5082 Object* inline_value = GetHiddenPropertiesHashTable(); | 
| 5083 | 5083 | 
| 5084 if (inline_value->IsUndefined()) return GetHeap()->the_hole_value(); | 5084 if (inline_value->IsUndefined()) return GetHeap()->the_hole_value(); | 
| 5085 | 5085 | 
| 5086 ObjectHashTable* hashtable = ObjectHashTable::cast(inline_value); | 5086 ObjectHashTable* hashtable = ObjectHashTable::cast(inline_value); | 
| 5087 Object* entry = hashtable->Lookup(key); | 5087 Object* entry = hashtable->Lookup(key); | 
| 5088 return entry; | 5088 return entry; | 
| 5089 } | 5089 } | 
| 5090 | 5090 | 
| 5091 | 5091 | 
| 5092 Handle<Object> JSObject::SetHiddenProperty(Handle<JSObject> object, | 5092 Handle<Object> JSObject::SetHiddenProperty(Handle<JSObject> object, | 
| 5093 Handle<Name> key, | 5093 Handle<Name> key, | 
| 5094 Handle<Object> value) { | 5094 Handle<Object> value) { | 
| 5095 Isolate* isolate = object->GetIsolate(); | 5095 Isolate* isolate = object->GetIsolate(); | 
| 5096 | 5096 | 
| 5097 DCHECK(key->IsUniqueName()); | 5097 DCHECK(key->IsUniqueName()); | 
| 5098 if (object->IsJSGlobalProxy()) { | 5098 if (object->IsJSGlobalProxy()) { | 
| 5099 // For a proxy, use the prototype as target object. | 5099 // For a proxy, use the prototype as target object. | 
| 5100 PrototypeIterator iter(isolate, object); | 5100 PrototypeIterator iter(isolate, object); | 
| 5101 // If the proxy is detached, return undefined. | 5101 // If the proxy is detached, return undefined. | 
| 5102 if (iter.IsAtEnd()) return isolate->factory()->undefined_value(); | 5102 if (iter.IsAtEnd()) return isolate->factory()->undefined_value(); | 
| 5103 DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); | 5103 DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); | 
| 5104 return SetHiddenProperty( | 5104 return SetHiddenProperty(PrototypeIterator::GetCurrent<JSObject>(iter), key, | 
| 5105 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), key, | 5105 value); | 
| 5106 value); | |
| 5107 } | 5106 } | 
| 5108 DCHECK(!object->IsJSGlobalProxy()); | 5107 DCHECK(!object->IsJSGlobalProxy()); | 
| 5109 | 5108 | 
| 5110 Handle<Object> inline_value(object->GetHiddenPropertiesHashTable(), isolate); | 5109 Handle<Object> inline_value(object->GetHiddenPropertiesHashTable(), isolate); | 
| 5111 | 5110 | 
| 5112 Handle<ObjectHashTable> hashtable = | 5111 Handle<ObjectHashTable> hashtable = | 
| 5113 GetOrCreateHiddenPropertiesHashtable(object); | 5112 GetOrCreateHiddenPropertiesHashtable(object); | 
| 5114 | 5113 | 
| 5115 // If it was found, check if the key is already in the dictionary. | 5114 // If it was found, check if the key is already in the dictionary. | 
| 5116 Handle<ObjectHashTable> new_table = ObjectHashTable::Put(hashtable, key, | 5115 Handle<ObjectHashTable> new_table = ObjectHashTable::Put(hashtable, key, | 
| (...skipping 10 matching lines...) Expand all Loading... | |
| 5127 | 5126 | 
| 5128 | 5127 | 
| 5129 void JSObject::DeleteHiddenProperty(Handle<JSObject> object, Handle<Name> key) { | 5128 void JSObject::DeleteHiddenProperty(Handle<JSObject> object, Handle<Name> key) { | 
| 5130 Isolate* isolate = object->GetIsolate(); | 5129 Isolate* isolate = object->GetIsolate(); | 
| 5131 DCHECK(key->IsUniqueName()); | 5130 DCHECK(key->IsUniqueName()); | 
| 5132 | 5131 | 
| 5133 if (object->IsJSGlobalProxy()) { | 5132 if (object->IsJSGlobalProxy()) { | 
| 5134 PrototypeIterator iter(isolate, object); | 5133 PrototypeIterator iter(isolate, object); | 
| 5135 if (iter.IsAtEnd()) return; | 5134 if (iter.IsAtEnd()) return; | 
| 5136 DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); | 5135 DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); | 
| 5137 return DeleteHiddenProperty( | 5136 return DeleteHiddenProperty(PrototypeIterator::GetCurrent<JSObject>(iter), | 
| 5138 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), key); | 5137 key); | 
| 5139 } | 5138 } | 
| 5140 | 5139 | 
| 5141 Object* inline_value = object->GetHiddenPropertiesHashTable(); | 5140 Object* inline_value = object->GetHiddenPropertiesHashTable(); | 
| 5142 | 5141 | 
| 5143 if (inline_value->IsUndefined()) return; | 5142 if (inline_value->IsUndefined()) return; | 
| 5144 | 5143 | 
| 5145 Handle<ObjectHashTable> hashtable(ObjectHashTable::cast(inline_value)); | 5144 Handle<ObjectHashTable> hashtable(ObjectHashTable::cast(inline_value)); | 
| 5146 bool was_present = false; | 5145 bool was_present = false; | 
| 5147 ObjectHashTable::Remove(hashtable, key, &was_present); | 5146 ObjectHashTable::Remove(hashtable, key, &was_present); | 
| 5148 } | 5147 } | 
| (...skipping 392 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5541 if (object->IsAccessCheckNeeded() && !isolate->MayAccess(object)) { | 5540 if (object->IsAccessCheckNeeded() && !isolate->MayAccess(object)) { | 
| 5542 isolate->ReportFailedAccessCheck(object); | 5541 isolate->ReportFailedAccessCheck(object); | 
| 5543 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); | 5542 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); | 
| 5544 return isolate->factory()->false_value(); | 5543 return isolate->factory()->false_value(); | 
| 5545 } | 5544 } | 
| 5546 | 5545 | 
| 5547 if (object->IsJSGlobalProxy()) { | 5546 if (object->IsJSGlobalProxy()) { | 
| 5548 PrototypeIterator iter(isolate, object); | 5547 PrototypeIterator iter(isolate, object); | 
| 5549 if (iter.IsAtEnd()) return object; | 5548 if (iter.IsAtEnd()) return object; | 
| 5550 DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); | 5549 DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); | 
| 5551 return PreventExtensions( | 5550 return PreventExtensions(PrototypeIterator::GetCurrent<JSObject>(iter)); | 
| 5552 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter))); | |
| 5553 } | 5551 } | 
| 5554 | 5552 | 
| 5555 // It's not possible to seal objects with external array elements | 5553 // It's not possible to seal objects with external array elements | 
| 5556 if (object->HasFixedTypedArrayElements()) { | 5554 if (object->HasFixedTypedArrayElements()) { | 
| 5557 THROW_NEW_ERROR( | 5555 THROW_NEW_ERROR( | 
| 5558 isolate, NewTypeError(MessageTemplate::kCannotPreventExtExternalArray), | 5556 isolate, NewTypeError(MessageTemplate::kCannotPreventExtExternalArray), | 
| 5559 Object); | 5557 Object); | 
| 5560 } | 5558 } | 
| 5561 | 5559 | 
| 5562 // If there are fast elements we normalize. | 5560 // If there are fast elements we normalize. | 
| (...skipping 21 matching lines...) Expand all Loading... | |
| 5584 } | 5582 } | 
| 5585 return object; | 5583 return object; | 
| 5586 } | 5584 } | 
| 5587 | 5585 | 
| 5588 | 5586 | 
| 5589 bool JSObject::IsExtensible() { | 5587 bool JSObject::IsExtensible() { | 
| 5590 if (IsJSGlobalProxy()) { | 5588 if (IsJSGlobalProxy()) { | 
| 5591 PrototypeIterator iter(GetIsolate(), this); | 5589 PrototypeIterator iter(GetIsolate(), this); | 
| 5592 if (iter.IsAtEnd()) return false; | 5590 if (iter.IsAtEnd()) return false; | 
| 5593 DCHECK(iter.GetCurrent()->IsJSGlobalObject()); | 5591 DCHECK(iter.GetCurrent()->IsJSGlobalObject()); | 
| 5594 return JSObject::cast(iter.GetCurrent())->map()->is_extensible(); | 5592 return iter.GetCurrent<JSObject>()->map()->is_extensible(); | 
| 5595 } | 5593 } | 
| 5596 return map()->is_extensible(); | 5594 return map()->is_extensible(); | 
| 5597 } | 5595 } | 
| 5598 | 5596 | 
| 5599 | 5597 | 
| 5600 template <typename Dictionary> | 5598 template <typename Dictionary> | 
| 5601 static void ApplyAttributesToDictionary(Dictionary* dictionary, | 5599 static void ApplyAttributesToDictionary(Dictionary* dictionary, | 
| 5602 const PropertyAttributes attributes) { | 5600 const PropertyAttributes attributes) { | 
| 5603 int capacity = dictionary->Capacity(); | 5601 int capacity = dictionary->Capacity(); | 
| 5604 for (int i = 0; i < capacity; i++) { | 5602 for (int i = 0; i < capacity; i++) { | 
| (...skipping 30 matching lines...) Expand all Loading... | |
| 5635 isolate->ReportFailedAccessCheck(object); | 5633 isolate->ReportFailedAccessCheck(object); | 
| 5636 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); | 5634 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); | 
| 5637 return isolate->factory()->false_value(); | 5635 return isolate->factory()->false_value(); | 
| 5638 } | 5636 } | 
| 5639 | 5637 | 
| 5640 if (object->IsJSGlobalProxy()) { | 5638 if (object->IsJSGlobalProxy()) { | 
| 5641 PrototypeIterator iter(isolate, object); | 5639 PrototypeIterator iter(isolate, object); | 
| 5642 if (iter.IsAtEnd()) return object; | 5640 if (iter.IsAtEnd()) return object; | 
| 5643 DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); | 5641 DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); | 
| 5644 return PreventExtensionsWithTransition<attrs>( | 5642 return PreventExtensionsWithTransition<attrs>( | 
| 5645 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter))); | 5643 PrototypeIterator::GetCurrent<JSObject>(iter)); | 
| 5646 } | 5644 } | 
| 5647 | 5645 | 
| 5648 // It's not possible to seal or freeze objects with external array elements | 5646 // It's not possible to seal or freeze objects with external array elements | 
| 5649 if (object->HasFixedTypedArrayElements()) { | 5647 if (object->HasFixedTypedArrayElements()) { | 
| 5650 THROW_NEW_ERROR( | 5648 THROW_NEW_ERROR( | 
| 5651 isolate, NewTypeError(MessageTemplate::kCannotPreventExtExternalArray), | 5649 isolate, NewTypeError(MessageTemplate::kCannotPreventExtExternalArray), | 
| 5652 Object); | 5650 Object); | 
| 5653 } | 5651 } | 
| 5654 | 5652 | 
| 5655 Handle<SeededNumberDictionary> new_element_dictionary; | 5653 Handle<SeededNumberDictionary> new_element_dictionary; | 
| (...skipping 434 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6090 // Tests for the fast common case for property enumeration: | 6088 // Tests for the fast common case for property enumeration: | 
| 6091 // - This object and all prototypes has an enum cache (which means that | 6089 // - This object and all prototypes has an enum cache (which means that | 
| 6092 // it is no proxy, has no interceptors and needs no access checks). | 6090 // it is no proxy, has no interceptors and needs no access checks). | 
| 6093 // - This object has no elements. | 6091 // - This object has no elements. | 
| 6094 // - No prototype has enumerable properties/elements. | 6092 // - No prototype has enumerable properties/elements. | 
| 6095 bool JSReceiver::IsSimpleEnum() { | 6093 bool JSReceiver::IsSimpleEnum() { | 
| 6096 for (PrototypeIterator iter(GetIsolate(), this, | 6094 for (PrototypeIterator iter(GetIsolate(), this, | 
| 6097 PrototypeIterator::START_AT_RECEIVER); | 6095 PrototypeIterator::START_AT_RECEIVER); | 
| 6098 !iter.IsAtEnd(); iter.Advance()) { | 6096 !iter.IsAtEnd(); iter.Advance()) { | 
| 6099 if (!iter.GetCurrent()->IsJSObject()) return false; | 6097 if (!iter.GetCurrent()->IsJSObject()) return false; | 
| 6100 JSObject* curr = JSObject::cast(iter.GetCurrent()); | 6098 JSObject* current = iter.GetCurrent<JSObject>(); | 
| 6101 int enum_length = curr->map()->EnumLength(); | 6099 int enum_length = current->map()->EnumLength(); | 
| 6102 if (enum_length == kInvalidEnumCacheSentinel) return false; | 6100 if (enum_length == kInvalidEnumCacheSentinel) return false; | 
| 6103 if (curr->IsAccessCheckNeeded()) return false; | 6101 if (current->IsAccessCheckNeeded()) return false; | 
| 6104 DCHECK(!curr->HasNamedInterceptor()); | 6102 DCHECK(!current->HasNamedInterceptor()); | 
| 6105 DCHECK(!curr->HasIndexedInterceptor()); | 6103 DCHECK(!current->HasIndexedInterceptor()); | 
| 6106 if (curr->NumberOfEnumElements() > 0) return false; | 6104 if (current->NumberOfEnumElements() > 0) return false; | 
| 6107 if (curr != this && enum_length != 0) return false; | 6105 if (current != this && enum_length != 0) return false; | 
| 6108 } | 6106 } | 
| 6109 return true; | 6107 return true; | 
| 6110 } | 6108 } | 
| 6111 | 6109 | 
| 6112 | 6110 | 
| 6113 static bool FilterKey(Object* key, PropertyAttributes filter) { | 6111 static bool FilterKey(Object* key, PropertyAttributes filter) { | 
| 6114 if ((filter & SYMBOLIC) && key->IsSymbol()) { | 6112 if ((filter & SYMBOLIC) && key->IsSymbol()) { | 
| 6115 return true; | 6113 return true; | 
| 6116 } | 6114 } | 
| 6117 | 6115 | 
| (...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6298 JSFunction::cast(isolate->sloppy_arguments_map()->GetConstructor())); | 6296 JSFunction::cast(isolate->sloppy_arguments_map()->GetConstructor())); | 
| 6299 | 6297 | 
| 6300 PrototypeIterator::WhereToEnd end = type == OWN_ONLY | 6298 PrototypeIterator::WhereToEnd end = type == OWN_ONLY | 
| 6301 ? PrototypeIterator::END_AT_NON_HIDDEN | 6299 ? PrototypeIterator::END_AT_NON_HIDDEN | 
| 6302 : PrototypeIterator::END_AT_NULL; | 6300 : PrototypeIterator::END_AT_NULL; | 
| 6303 // Only collect keys if access is permitted. | 6301 // Only collect keys if access is permitted. | 
| 6304 for (PrototypeIterator iter(isolate, object, | 6302 for (PrototypeIterator iter(isolate, object, | 
| 6305 PrototypeIterator::START_AT_RECEIVER); | 6303 PrototypeIterator::START_AT_RECEIVER); | 
| 6306 !iter.IsAtEnd(end); iter.Advance()) { | 6304 !iter.IsAtEnd(end); iter.Advance()) { | 
| 6307 if (PrototypeIterator::GetCurrent(iter)->IsJSProxy()) { | 6305 if (PrototypeIterator::GetCurrent(iter)->IsJSProxy()) { | 
| 6308 Handle<JSProxy> proxy(JSProxy::cast(*PrototypeIterator::GetCurrent(iter)), | 6306 Handle<JSProxy> proxy = PrototypeIterator::GetCurrent<JSProxy>(iter); | 
| 6309 isolate); | |
| 6310 Handle<Object> args[] = { proxy }; | 6307 Handle<Object> args[] = { proxy }; | 
| 6311 Handle<Object> names; | 6308 Handle<Object> names; | 
| 6312 ASSIGN_RETURN_ON_EXCEPTION( | 6309 ASSIGN_RETURN_ON_EXCEPTION( | 
| 6313 isolate, names, | 6310 isolate, names, | 
| 6314 Execution::Call(isolate, | 6311 Execution::Call(isolate, | 
| 6315 isolate->proxy_enumerate(), | 6312 isolate->proxy_enumerate(), | 
| 6316 object, | 6313 object, | 
| 6317 arraysize(args), | 6314 arraysize(args), | 
| 6318 args), | 6315 args), | 
| 6319 FixedArray); | 6316 FixedArray); | 
| 6320 ASSIGN_RETURN_ON_EXCEPTION( | 6317 ASSIGN_RETURN_ON_EXCEPTION( | 
| 6321 isolate, content, | 6318 isolate, content, | 
| 6322 FixedArray::AddKeysFromArrayLike( | 6319 FixedArray::AddKeysFromArrayLike( | 
| 6323 content, Handle<JSObject>::cast(names)), | 6320 content, Handle<JSObject>::cast(names)), | 
| 6324 FixedArray); | 6321 FixedArray); | 
| 6325 break; | 6322 break; | 
| 6326 } | 6323 } | 
| 6327 | 6324 | 
| 6328 Handle<JSObject> current = | 6325 Handle<JSObject> current = PrototypeIterator::GetCurrent<JSObject>(iter); | 
| 6329 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)); | |
| 6330 | 6326 | 
| 6331 // Check access rights if required. | 6327 // Check access rights if required. | 
| 6332 if (current->IsAccessCheckNeeded() && !isolate->MayAccess(current)) { | 6328 if (current->IsAccessCheckNeeded() && !isolate->MayAccess(current)) { | 
| 6333 if (iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN)) { | 6329 if (iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN)) { | 
| 6334 isolate->ReportFailedAccessCheck(current); | 6330 isolate->ReportFailedAccessCheck(current); | 
| 6335 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, FixedArray); | 6331 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, FixedArray); | 
| 6336 } | 6332 } | 
| 6337 break; | 6333 break; | 
| 6338 } | 6334 } | 
| 6339 | 6335 | 
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6402 bool Map::DictionaryElementsInPrototypeChainOnly() { | 6398 bool Map::DictionaryElementsInPrototypeChainOnly() { | 
| 6403 if (IsDictionaryElementsKind(elements_kind())) { | 6399 if (IsDictionaryElementsKind(elements_kind())) { | 
| 6404 return false; | 6400 return false; | 
| 6405 } | 6401 } | 
| 6406 | 6402 | 
| 6407 for (PrototypeIterator iter(this); !iter.IsAtEnd(); iter.Advance()) { | 6403 for (PrototypeIterator iter(this); !iter.IsAtEnd(); iter.Advance()) { | 
| 6408 // Be conservative, don't walk into proxies. | 6404 // Be conservative, don't walk into proxies. | 
| 6409 if (iter.GetCurrent()->IsJSProxy()) return true; | 6405 if (iter.GetCurrent()->IsJSProxy()) return true; | 
| 6410 // String wrappers have non-configurable, non-writable elements. | 6406 // String wrappers have non-configurable, non-writable elements. | 
| 6411 if (iter.GetCurrent()->IsStringWrapper()) return true; | 6407 if (iter.GetCurrent()->IsStringWrapper()) return true; | 
| 6412 JSObject* current = JSObject::cast(iter.GetCurrent()); | 6408 JSObject* current = iter.GetCurrent<JSObject>(); | 
| 6413 | 6409 | 
| 6414 if (current->HasDictionaryElements() && | 6410 if (current->HasDictionaryElements() && | 
| 6415 current->element_dictionary()->requires_slow_elements()) { | 6411 current->element_dictionary()->requires_slow_elements()) { | 
| 6416 return true; | 6412 return true; | 
| 6417 } | 6413 } | 
| 6418 | 6414 | 
| 6419 if (current->HasSlowArgumentsElements()) { | 6415 if (current->HasSlowArgumentsElements()) { | 
| 6420 FixedArray* parameter_map = FixedArray::cast(current->elements()); | 6416 FixedArray* parameter_map = FixedArray::cast(current->elements()); | 
| 6421 Object* arguments = parameter_map->get(1); | 6417 Object* arguments = parameter_map->get(1); | 
| 6422 if (SeededNumberDictionary::cast(arguments)->requires_slow_elements()) { | 6418 if (SeededNumberDictionary::cast(arguments)->requires_slow_elements()) { | 
| (...skipping 3538 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 9961 if (!user->prototype_info()->IsPrototypeInfo()) return false; | 9957 if (!user->prototype_info()->IsPrototypeInfo()) return false; | 
| 9962 // If it doesn't have a prototype, it can't be registered. | 9958 // If it doesn't have a prototype, it can't be registered. | 
| 9963 if (!user->prototype()->IsJSObject()) return false; | 9959 if (!user->prototype()->IsJSObject()) return false; | 
| 9964 Handle<JSObject> prototype(JSObject::cast(user->prototype()), isolate); | 9960 Handle<JSObject> prototype(JSObject::cast(user->prototype()), isolate); | 
| 9965 Handle<PrototypeInfo> user_info = | 9961 Handle<PrototypeInfo> user_info = | 
| 9966 Map::GetOrCreatePrototypeInfo(user, isolate); | 9962 Map::GetOrCreatePrototypeInfo(user, isolate); | 
| 9967 int slot = user_info->registry_slot(); | 9963 int slot = user_info->registry_slot(); | 
| 9968 if (slot == PrototypeInfo::UNREGISTERED) return false; | 9964 if (slot == PrototypeInfo::UNREGISTERED) return false; | 
| 9969 if (prototype->IsJSGlobalProxy()) { | 9965 if (prototype->IsJSGlobalProxy()) { | 
| 9970 PrototypeIterator iter(isolate, prototype); | 9966 PrototypeIterator iter(isolate, prototype); | 
| 9971 prototype = Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)); | 9967 prototype = PrototypeIterator::GetCurrent<JSObject>(iter); | 
| 9972 } | 9968 } | 
| 9973 DCHECK(prototype->map()->is_prototype_map()); | 9969 DCHECK(prototype->map()->is_prototype_map()); | 
| 9974 Object* maybe_proto_info = prototype->map()->prototype_info(); | 9970 Object* maybe_proto_info = prototype->map()->prototype_info(); | 
| 9975 // User knows its registry slot, prototype info and user registry must exist. | 9971 // User knows its registry slot, prototype info and user registry must exist. | 
| 9976 DCHECK(maybe_proto_info->IsPrototypeInfo()); | 9972 DCHECK(maybe_proto_info->IsPrototypeInfo()); | 
| 9977 Handle<PrototypeInfo> proto_info(PrototypeInfo::cast(maybe_proto_info), | 9973 Handle<PrototypeInfo> proto_info(PrototypeInfo::cast(maybe_proto_info), | 
| 9978 isolate); | 9974 isolate); | 
| 9979 Object* maybe_registry = proto_info->prototype_users(); | 9975 Object* maybe_registry = proto_info->prototype_users(); | 
| 9980 DCHECK(maybe_registry->IsWeakFixedArray()); | 9976 DCHECK(maybe_registry->IsWeakFixedArray()); | 
| 9981 DCHECK(WeakFixedArray::cast(maybe_registry)->Get(slot) == *user); | 9977 DCHECK(WeakFixedArray::cast(maybe_registry)->Get(slot) == *user); | 
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 10013 } | 10009 } | 
| 10014 } | 10010 } | 
| 10015 | 10011 | 
| 10016 | 10012 | 
| 10017 // static | 10013 // static | 
| 10018 void JSObject::InvalidatePrototypeChains(Map* map) { | 10014 void JSObject::InvalidatePrototypeChains(Map* map) { | 
| 10019 if (!FLAG_eliminate_prototype_chain_checks) return; | 10015 if (!FLAG_eliminate_prototype_chain_checks) return; | 
| 10020 DisallowHeapAllocation no_gc; | 10016 DisallowHeapAllocation no_gc; | 
| 10021 if (map->IsJSGlobalProxyMap()) { | 10017 if (map->IsJSGlobalProxyMap()) { | 
| 10022 PrototypeIterator iter(map); | 10018 PrototypeIterator iter(map); | 
| 10023 map = JSObject::cast(iter.GetCurrent())->map(); | 10019 map = iter.GetCurrent<JSObject>()->map(); | 
| 10024 } | 10020 } | 
| 10025 InvalidatePrototypeChainsInternal(map); | 10021 InvalidatePrototypeChainsInternal(map); | 
| 10026 } | 10022 } | 
| 10027 | 10023 | 
| 10028 | 10024 | 
| 10029 // static | 10025 // static | 
| 10030 Handle<PrototypeInfo> Map::GetOrCreatePrototypeInfo(Handle<JSObject> prototype, | 10026 Handle<PrototypeInfo> Map::GetOrCreatePrototypeInfo(Handle<JSObject> prototype, | 
| 10031 Isolate* isolate) { | 10027 Isolate* isolate) { | 
| 10032 Object* maybe_proto_info = prototype->map()->prototype_info(); | 10028 Object* maybe_proto_info = prototype->map()->prototype_info(); | 
| 10033 if (maybe_proto_info->IsPrototypeInfo()) { | 10029 if (maybe_proto_info->IsPrototypeInfo()) { | 
| (...skipping 19 matching lines...) Expand all Loading... | |
| 10053 | 10049 | 
| 10054 | 10050 | 
| 10055 // static | 10051 // static | 
| 10056 Handle<Cell> Map::GetOrCreatePrototypeChainValidityCell(Handle<Map> map, | 10052 Handle<Cell> Map::GetOrCreatePrototypeChainValidityCell(Handle<Map> map, | 
| 10057 Isolate* isolate) { | 10053 Isolate* isolate) { | 
| 10058 Handle<Object> maybe_prototype(map->prototype(), isolate); | 10054 Handle<Object> maybe_prototype(map->prototype(), isolate); | 
| 10059 if (!maybe_prototype->IsJSObject()) return Handle<Cell>::null(); | 10055 if (!maybe_prototype->IsJSObject()) return Handle<Cell>::null(); | 
| 10060 Handle<JSObject> prototype = Handle<JSObject>::cast(maybe_prototype); | 10056 Handle<JSObject> prototype = Handle<JSObject>::cast(maybe_prototype); | 
| 10061 if (prototype->IsJSGlobalProxy()) { | 10057 if (prototype->IsJSGlobalProxy()) { | 
| 10062 PrototypeIterator iter(isolate, prototype); | 10058 PrototypeIterator iter(isolate, prototype); | 
| 10063 prototype = Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)); | 10059 prototype = PrototypeIterator::GetCurrent<JSObject>(iter); | 
| 10064 } | 10060 } | 
| 10065 // Ensure the prototype is registered with its own prototypes so its cell | 10061 // Ensure the prototype is registered with its own prototypes so its cell | 
| 10066 // will be invalidated when necessary. | 10062 // will be invalidated when necessary. | 
| 10067 JSObject::LazyRegisterPrototypeUser(handle(prototype->map(), isolate), | 10063 JSObject::LazyRegisterPrototypeUser(handle(prototype->map(), isolate), | 
| 10068 isolate); | 10064 isolate); | 
| 10069 Handle<PrototypeInfo> proto_info = | 10065 Handle<PrototypeInfo> proto_info = | 
| 10070 GetOrCreatePrototypeInfo(prototype, isolate); | 10066 GetOrCreatePrototypeInfo(prototype, isolate); | 
| 10071 Object* maybe_cell = proto_info->validity_cell(); | 10067 Object* maybe_cell = proto_info->validity_cell(); | 
| 10072 // Return existing cell if it's still valid. | 10068 // Return existing cell if it's still valid. | 
| 10073 if (maybe_cell->IsCell()) { | 10069 if (maybe_cell->IsCell()) { | 
| (...skipping 2310 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 12384 Object); | 12380 Object); | 
| 12385 } | 12381 } | 
| 12386 | 12382 | 
| 12387 // Before we can set the prototype we need to be sure | 12383 // Before we can set the prototype we need to be sure | 
| 12388 // prototype cycles are prevented. | 12384 // prototype cycles are prevented. | 
| 12389 // It is sufficient to validate that the receiver is not in the new prototype | 12385 // It is sufficient to validate that the receiver is not in the new prototype | 
| 12390 // chain. | 12386 // chain. | 
| 12391 for (PrototypeIterator iter(isolate, *value, | 12387 for (PrototypeIterator iter(isolate, *value, | 
| 12392 PrototypeIterator::START_AT_RECEIVER); | 12388 PrototypeIterator::START_AT_RECEIVER); | 
| 12393 !iter.IsAtEnd(); iter.Advance()) { | 12389 !iter.IsAtEnd(); iter.Advance()) { | 
| 12394 if (JSReceiver::cast(iter.GetCurrent()) == *object) { | 12390 if (iter.GetCurrent<JSReceiver>() == *object) { | 
| 12395 // Cycle detected. | 12391 // Cycle detected. | 
| 12396 THROW_NEW_ERROR(isolate, NewTypeError(MessageTemplate::kCyclicProto), | 12392 THROW_NEW_ERROR(isolate, NewTypeError(MessageTemplate::kCyclicProto), | 
| 12397 Object); | 12393 Object); | 
| 12398 } | 12394 } | 
| 12399 } | 12395 } | 
| 12400 | 12396 | 
| 12401 bool dictionary_elements_in_chain = | 12397 bool dictionary_elements_in_chain = | 
| 12402 object->map()->DictionaryElementsInPrototypeChainOnly(); | 12398 object->map()->DictionaryElementsInPrototypeChainOnly(); | 
| 12403 Handle<JSObject> real_receiver = object; | 12399 Handle<JSObject> real_receiver = object; | 
| 12404 | 12400 | 
| 12405 if (from_javascript) { | 12401 if (from_javascript) { | 
| 12406 // Find the first object in the chain whose prototype object is not | 12402 // Find the first object in the chain whose prototype object is not | 
| 12407 // hidden and set the new prototype on that object. | 12403 // hidden and set the new prototype on that object. | 
| 12408 PrototypeIterator iter(isolate, real_receiver); | 12404 PrototypeIterator iter(isolate, real_receiver); | 
| 12409 while (!iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN)) { | 12405 while (!iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN)) { | 
| 12410 real_receiver = | 12406 real_receiver = PrototypeIterator::GetCurrent<JSObject>(iter); | 
| 12411 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)); | |
| 12412 iter.Advance(); | 12407 iter.Advance(); | 
| 12413 if (!real_receiver->map()->is_extensible()) { | 12408 if (!real_receiver->map()->is_extensible()) { | 
| 12414 THROW_NEW_ERROR( | 12409 THROW_NEW_ERROR( | 
| 12415 isolate, NewTypeError(MessageTemplate::kNonExtensibleProto, object), | 12410 isolate, NewTypeError(MessageTemplate::kNonExtensibleProto, object), | 
| 12416 Object); | 12411 Object); | 
| 12417 } | 12412 } | 
| 12418 } | 12413 } | 
| 12419 } | 12414 } | 
| 12420 | 12415 | 
| 12421 // Set the new prototype of the object. | 12416 // Set the new prototype of the object. | 
| (...skipping 3742 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 16164 if (cell->value() != *new_value) { | 16159 if (cell->value() != *new_value) { | 
| 16165 cell->set_value(*new_value); | 16160 cell->set_value(*new_value); | 
| 16166 Isolate* isolate = cell->GetIsolate(); | 16161 Isolate* isolate = cell->GetIsolate(); | 
| 16167 cell->dependent_code()->DeoptimizeDependentCodeGroup( | 16162 cell->dependent_code()->DeoptimizeDependentCodeGroup( | 
| 16168 isolate, DependentCode::kPropertyCellChangedGroup); | 16163 isolate, DependentCode::kPropertyCellChangedGroup); | 
| 16169 } | 16164 } | 
| 16170 } | 16165 } | 
| 16171 | 16166 | 
| 16172 } // namespace internal | 16167 } // namespace internal | 
| 16173 } // namespace v8 | 16168 } // namespace v8 | 
| OLD | NEW |