| 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 <sstream> | 5 #include <sstream> |
| 6 | 6 |
| 7 #include "src/v8.h" | 7 #include "src/v8.h" |
| 8 | 8 |
| 9 #include "src/accessors.h" | 9 #include "src/accessors.h" |
| 10 #include "src/allocation-site-scopes.h" | 10 #include "src/allocation-site-scopes.h" |
| (...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 212 bool FunctionTemplateInfo::IsTemplateFor(Object* object) { | 212 bool FunctionTemplateInfo::IsTemplateFor(Object* object) { |
| 213 if (!object->IsHeapObject()) return false; | 213 if (!object->IsHeapObject()) return false; |
| 214 return IsTemplateFor(HeapObject::cast(object)->map()); | 214 return IsTemplateFor(HeapObject::cast(object)->map()); |
| 215 } | 215 } |
| 216 | 216 |
| 217 | 217 |
| 218 bool FunctionTemplateInfo::IsTemplateFor(Map* map) { | 218 bool FunctionTemplateInfo::IsTemplateFor(Map* map) { |
| 219 // There is a constraint on the object; check. | 219 // There is a constraint on the object; check. |
| 220 if (!map->IsJSObjectMap()) return false; | 220 if (!map->IsJSObjectMap()) return false; |
| 221 // Fetch the constructor function of the object. | 221 // Fetch the constructor function of the object. |
| 222 Object* cons_obj = map->constructor(); | 222 Object* cons_obj = map->GetConstructor(); |
| 223 if (!cons_obj->IsJSFunction()) return false; | 223 if (!cons_obj->IsJSFunction()) return false; |
| 224 JSFunction* fun = JSFunction::cast(cons_obj); | 224 JSFunction* fun = JSFunction::cast(cons_obj); |
| 225 // Iterate through the chain of inheriting function templates to | 225 // Iterate through the chain of inheriting function templates to |
| 226 // see if the required one occurs. | 226 // see if the required one occurs. |
| 227 for (Object* type = fun->shared()->function_data(); | 227 for (Object* type = fun->shared()->function_data(); |
| 228 type->IsFunctionTemplateInfo(); | 228 type->IsFunctionTemplateInfo(); |
| 229 type = FunctionTemplateInfo::cast(type)->parent_template()) { | 229 type = FunctionTemplateInfo::cast(type)->parent_template()) { |
| 230 if (type == this) return true; | 230 if (type == this) return true; |
| 231 } | 231 } |
| 232 // Didn't find the required type in the inheritance chain. | 232 // Didn't find the required type in the inheritance chain. |
| (...skipping 968 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1201 } | 1201 } |
| 1202 case JS_MODULE_TYPE: { | 1202 case JS_MODULE_TYPE: { |
| 1203 accumulator->Add("<JS Module>"); | 1203 accumulator->Add("<JS Module>"); |
| 1204 break; | 1204 break; |
| 1205 } | 1205 } |
| 1206 // All other JSObjects are rather similar to each other (JSObject, | 1206 // All other JSObjects are rather similar to each other (JSObject, |
| 1207 // JSGlobalProxy, JSGlobalObject, JSUndetectableObject, JSValue). | 1207 // JSGlobalProxy, JSGlobalObject, JSUndetectableObject, JSValue). |
| 1208 default: { | 1208 default: { |
| 1209 Map* map_of_this = map(); | 1209 Map* map_of_this = map(); |
| 1210 Heap* heap = GetHeap(); | 1210 Heap* heap = GetHeap(); |
| 1211 Object* constructor = map_of_this->constructor(); | 1211 Object* constructor = map_of_this->GetConstructor(); |
| 1212 bool printed = false; | 1212 bool printed = false; |
| 1213 if (constructor->IsHeapObject() && | 1213 if (constructor->IsHeapObject() && |
| 1214 !heap->Contains(HeapObject::cast(constructor))) { | 1214 !heap->Contains(HeapObject::cast(constructor))) { |
| 1215 accumulator->Add("!!!INVALID CONSTRUCTOR!!!"); | 1215 accumulator->Add("!!!INVALID CONSTRUCTOR!!!"); |
| 1216 } else { | 1216 } else { |
| 1217 bool global_object = IsJSGlobalProxy(); | 1217 bool global_object = IsJSGlobalProxy(); |
| 1218 if (constructor->IsJSFunction()) { | 1218 if (constructor->IsJSFunction()) { |
| 1219 if (!heap->Contains(JSFunction::cast(constructor)->shared())) { | 1219 if (!heap->Contains(JSFunction::cast(constructor)->shared())) { |
| 1220 accumulator->Add("!!!INVALID SHARED ON CONSTRUCTOR!!!"); | 1220 accumulator->Add("!!!INVALID SHARED ON CONSTRUCTOR!!!"); |
| 1221 } else { | 1221 } else { |
| (...skipping 442 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1664 | 1664 |
| 1665 void HeapNumber::HeapNumberPrint(std::ostream& os) { // NOLINT | 1665 void HeapNumber::HeapNumberPrint(std::ostream& os) { // NOLINT |
| 1666 os << value(); | 1666 os << value(); |
| 1667 } | 1667 } |
| 1668 | 1668 |
| 1669 | 1669 |
| 1670 String* JSReceiver::class_name() { | 1670 String* JSReceiver::class_name() { |
| 1671 if (IsJSFunction() || IsJSFunctionProxy()) { | 1671 if (IsJSFunction() || IsJSFunctionProxy()) { |
| 1672 return GetHeap()->Function_string(); | 1672 return GetHeap()->Function_string(); |
| 1673 } | 1673 } |
| 1674 if (map()->constructor()->IsJSFunction()) { | 1674 Object* maybe_constructor = map()->GetConstructor(); |
| 1675 JSFunction* constructor = JSFunction::cast(map()->constructor()); | 1675 if (maybe_constructor->IsJSFunction()) { |
| 1676 JSFunction* constructor = JSFunction::cast(maybe_constructor); |
| 1676 return String::cast(constructor->shared()->instance_class_name()); | 1677 return String::cast(constructor->shared()->instance_class_name()); |
| 1677 } | 1678 } |
| 1678 // If the constructor is not present, return "Object". | 1679 // If the constructor is not present, return "Object". |
| 1679 return GetHeap()->Object_string(); | 1680 return GetHeap()->Object_string(); |
| 1680 } | 1681 } |
| 1681 | 1682 |
| 1682 | 1683 |
| 1683 String* Map::constructor_name() { | 1684 String* Map::constructor_name() { |
| 1684 if (constructor()->IsJSFunction()) { | 1685 Object* maybe_constructor = GetConstructor(); |
| 1685 JSFunction* constructor = JSFunction::cast(this->constructor()); | 1686 if (maybe_constructor->IsJSFunction()) { |
| 1687 JSFunction* constructor = JSFunction::cast(maybe_constructor); |
| 1686 String* name = String::cast(constructor->shared()->name()); | 1688 String* name = String::cast(constructor->shared()->name()); |
| 1687 if (name->length() > 0) return name; | 1689 if (name->length() > 0) return name; |
| 1688 String* inferred_name = constructor->shared()->inferred_name(); | 1690 String* inferred_name = constructor->shared()->inferred_name(); |
| 1689 if (inferred_name->length() > 0) return inferred_name; | 1691 if (inferred_name->length() > 0) return inferred_name; |
| 1690 Object* proto = prototype(); | 1692 Object* proto = prototype(); |
| 1691 if (proto->IsJSObject()) return JSObject::cast(proto)->constructor_name(); | 1693 if (proto->IsJSObject()) return JSObject::cast(proto)->constructor_name(); |
| 1692 } | 1694 } |
| 1693 // TODO(rossberg): what about proxies? | 1695 // TODO(rossberg): what about proxies? |
| 1694 // If the constructor is not present, return "Object". | 1696 // If the constructor is not present, return "Object". |
| 1695 return GetHeap()->Object_string(); | 1697 return GetHeap()->Object_string(); |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1777 value = isolate->factory()->NewPropertyCell(value); | 1779 value = isolate->factory()->NewPropertyCell(value); |
| 1778 } | 1780 } |
| 1779 PropertyDetails details(attributes, DATA, 0); | 1781 PropertyDetails details(attributes, DATA, 0); |
| 1780 Handle<NameDictionary> result = | 1782 Handle<NameDictionary> result = |
| 1781 NameDictionary::Add(dict, name, value, details); | 1783 NameDictionary::Add(dict, name, value, details); |
| 1782 if (*dict != *result) object->set_properties(*result); | 1784 if (*dict != *result) object->set_properties(*result); |
| 1783 } | 1785 } |
| 1784 | 1786 |
| 1785 | 1787 |
| 1786 Context* JSObject::GetCreationContext() { | 1788 Context* JSObject::GetCreationContext() { |
| 1787 Object* constructor = this->map()->constructor(); | 1789 Object* constructor = this->map()->GetConstructor(); |
| 1788 JSFunction* function; | 1790 JSFunction* function; |
| 1789 if (!constructor->IsJSFunction()) { | 1791 if (!constructor->IsJSFunction()) { |
| 1790 // Functions have null as a constructor, | 1792 // Functions have null as a constructor, |
| 1791 // but any JSFunction knows its context immediately. | 1793 // but any JSFunction knows its context immediately. |
| 1792 function = JSFunction::cast(this); | 1794 function = JSFunction::cast(this); |
| 1793 } else { | 1795 } else { |
| 1794 function = JSFunction::cast(constructor); | 1796 function = JSFunction::cast(constructor); |
| 1795 } | 1797 } |
| 1796 | 1798 |
| 1797 return function->context()->native_context(); | 1799 return function->context()->native_context(); |
| (...skipping 3640 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5438 } | 5440 } |
| 5439 | 5441 |
| 5440 | 5442 |
| 5441 // Check whether this object references another object. | 5443 // Check whether this object references another object. |
| 5442 bool JSObject::ReferencesObject(Object* obj) { | 5444 bool JSObject::ReferencesObject(Object* obj) { |
| 5443 Map* map_of_this = map(); | 5445 Map* map_of_this = map(); |
| 5444 Heap* heap = GetHeap(); | 5446 Heap* heap = GetHeap(); |
| 5445 DisallowHeapAllocation no_allocation; | 5447 DisallowHeapAllocation no_allocation; |
| 5446 | 5448 |
| 5447 // Is the object the constructor for this object? | 5449 // Is the object the constructor for this object? |
| 5448 if (map_of_this->constructor() == obj) { | 5450 if (map_of_this->GetConstructor() == obj) { |
| 5449 return true; | 5451 return true; |
| 5450 } | 5452 } |
| 5451 | 5453 |
| 5452 // Is the object the prototype for this object? | 5454 // Is the object the prototype for this object? |
| 5453 if (map_of_this->prototype() == obj) { | 5455 if (map_of_this->prototype() == obj) { |
| 5454 return true; | 5456 return true; |
| 5455 } | 5457 } |
| 5456 | 5458 |
| 5457 // Check if the object is among the named properties. | 5459 // Check if the object is among the named properties. |
| 5458 Object* key = SlowReverseLookup(obj); | 5460 Object* key = SlowReverseLookup(obj); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5502 break; | 5504 break; |
| 5503 } | 5505 } |
| 5504 } | 5506 } |
| 5505 | 5507 |
| 5506 // For functions check the context. | 5508 // For functions check the context. |
| 5507 if (IsJSFunction()) { | 5509 if (IsJSFunction()) { |
| 5508 // Get the constructor function for arguments array. | 5510 // Get the constructor function for arguments array. |
| 5509 Map* arguments_map = | 5511 Map* arguments_map = |
| 5510 heap->isolate()->context()->native_context()->sloppy_arguments_map(); | 5512 heap->isolate()->context()->native_context()->sloppy_arguments_map(); |
| 5511 JSFunction* arguments_function = | 5513 JSFunction* arguments_function = |
| 5512 JSFunction::cast(arguments_map->constructor()); | 5514 JSFunction::cast(arguments_map->GetConstructor()); |
| 5513 | 5515 |
| 5514 // Get the context and don't check if it is the native context. | 5516 // Get the context and don't check if it is the native context. |
| 5515 JSFunction* f = JSFunction::cast(this); | 5517 JSFunction* f = JSFunction::cast(this); |
| 5516 Context* context = f->context(); | 5518 Context* context = f->context(); |
| 5517 if (context->IsNativeContext()) { | 5519 if (context->IsNativeContext()) { |
| 5518 return false; | 5520 return false; |
| 5519 } | 5521 } |
| 5520 | 5522 |
| 5521 // Check the non-special context slots. | 5523 // Check the non-special context slots. |
| 5522 for (int i = Context::MIN_CONTEXT_SLOTS; i < context->length(); i++) { | 5524 for (int i = Context::MIN_CONTEXT_SLOTS; i < context->length(); i++) { |
| 5523 // Only check JS objects. | 5525 // Only check JS objects. |
| 5524 if (context->get(i)->IsJSObject()) { | 5526 if (context->get(i)->IsJSObject()) { |
| 5525 JSObject* ctxobj = JSObject::cast(context->get(i)); | 5527 JSObject* ctxobj = JSObject::cast(context->get(i)); |
| 5526 // If it is an arguments array check the content. | 5528 // If it is an arguments array check the content. |
| 5527 if (ctxobj->map()->constructor() == arguments_function) { | 5529 if (ctxobj->map()->GetConstructor() == arguments_function) { |
| 5528 if (ctxobj->ReferencesObject(obj)) { | 5530 if (ctxobj->ReferencesObject(obj)) { |
| 5529 return true; | 5531 return true; |
| 5530 } | 5532 } |
| 5531 } else if (ctxobj == obj) { | 5533 } else if (ctxobj == obj) { |
| 5532 return true; | 5534 return true; |
| 5533 } | 5535 } |
| 5534 } | 5536 } |
| 5535 } | 5537 } |
| 5536 | 5538 |
| 5537 // Check the context extension (if any) if it can have references. | 5539 // Check the context extension (if any) if it can have references. |
| (...skipping 703 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6241 } | 6243 } |
| 6242 } | 6244 } |
| 6243 | 6245 |
| 6244 | 6246 |
| 6245 MaybeHandle<FixedArray> JSReceiver::GetKeys(Handle<JSReceiver> object, | 6247 MaybeHandle<FixedArray> JSReceiver::GetKeys(Handle<JSReceiver> object, |
| 6246 KeyCollectionType type) { | 6248 KeyCollectionType type) { |
| 6247 USE(ContainsOnlyValidKeys); | 6249 USE(ContainsOnlyValidKeys); |
| 6248 Isolate* isolate = object->GetIsolate(); | 6250 Isolate* isolate = object->GetIsolate(); |
| 6249 Handle<FixedArray> content = isolate->factory()->empty_fixed_array(); | 6251 Handle<FixedArray> content = isolate->factory()->empty_fixed_array(); |
| 6250 Handle<JSFunction> arguments_function( | 6252 Handle<JSFunction> arguments_function( |
| 6251 JSFunction::cast(isolate->sloppy_arguments_map()->constructor())); | 6253 JSFunction::cast(isolate->sloppy_arguments_map()->GetConstructor())); |
| 6252 | 6254 |
| 6253 // Only collect keys if access is permitted. | 6255 // Only collect keys if access is permitted. |
| 6254 for (PrototypeIterator iter(isolate, object, | 6256 for (PrototypeIterator iter(isolate, object, |
| 6255 PrototypeIterator::START_AT_RECEIVER); | 6257 PrototypeIterator::START_AT_RECEIVER); |
| 6256 !iter.IsAtEnd(); iter.Advance()) { | 6258 !iter.IsAtEnd(); iter.Advance()) { |
| 6257 if (PrototypeIterator::GetCurrent(iter)->IsJSProxy()) { | 6259 if (PrototypeIterator::GetCurrent(iter)->IsJSProxy()) { |
| 6258 Handle<JSProxy> proxy(JSProxy::cast(*PrototypeIterator::GetCurrent(iter)), | 6260 Handle<JSProxy> proxy(JSProxy::cast(*PrototypeIterator::GetCurrent(iter)), |
| 6259 isolate); | 6261 isolate); |
| 6260 Handle<Object> args[] = { proxy }; | 6262 Handle<Object> args[] = { proxy }; |
| 6261 Handle<Object> names; | 6263 Handle<Object> names; |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6314 // not needed and no interceptors are involved. | 6316 // not needed and no interceptors are involved. |
| 6315 // | 6317 // |
| 6316 // We do not use the cache if the object has elements and | 6318 // We do not use the cache if the object has elements and |
| 6317 // therefore it does not make sense to cache the property names | 6319 // therefore it does not make sense to cache the property names |
| 6318 // for arguments objects. Arguments objects will always have | 6320 // for arguments objects. Arguments objects will always have |
| 6319 // elements. | 6321 // elements. |
| 6320 // Wrapped strings have elements, but don't have an elements | 6322 // Wrapped strings have elements, but don't have an elements |
| 6321 // array or dictionary. So the fast inline test for whether to | 6323 // array or dictionary. So the fast inline test for whether to |
| 6322 // use the cache says yes, so we should not create a cache. | 6324 // use the cache says yes, so we should not create a cache. |
| 6323 bool cache_enum_keys = | 6325 bool cache_enum_keys = |
| 6324 ((current->map()->constructor() != *arguments_function) && | 6326 ((current->map()->GetConstructor() != *arguments_function) && |
| 6325 !current->IsJSValue() && | 6327 !current->IsJSValue() && !current->IsAccessCheckNeeded() && |
| 6326 !current->IsAccessCheckNeeded() && | 6328 !current->HasNamedInterceptor() && !current->HasIndexedInterceptor()); |
| 6327 !current->HasNamedInterceptor() && | |
| 6328 !current->HasIndexedInterceptor()); | |
| 6329 // Compute the property keys and cache them if possible. | 6329 // Compute the property keys and cache them if possible. |
| 6330 ASSIGN_RETURN_ON_EXCEPTION( | 6330 ASSIGN_RETURN_ON_EXCEPTION( |
| 6331 isolate, content, | 6331 isolate, content, |
| 6332 FixedArray::UnionOfKeys( | 6332 FixedArray::UnionOfKeys( |
| 6333 content, GetEnumPropertyKeys(current, cache_enum_keys)), | 6333 content, GetEnumPropertyKeys(current, cache_enum_keys)), |
| 6334 FixedArray); | 6334 FixedArray); |
| 6335 DCHECK(ContainsOnlyValidKeys(content)); | 6335 DCHECK(ContainsOnlyValidKeys(content)); |
| 6336 | 6336 |
| 6337 // Add the non-symbol property keys from the interceptor. | 6337 // Add the non-symbol property keys from the interceptor. |
| 6338 if (current->HasNamedInterceptor()) { | 6338 if (current->HasNamedInterceptor()) { |
| (...skipping 495 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6834 } else { | 6834 } else { |
| 6835 return property_dictionary()->SlowReverseLookup(value); | 6835 return property_dictionary()->SlowReverseLookup(value); |
| 6836 } | 6836 } |
| 6837 } | 6837 } |
| 6838 | 6838 |
| 6839 | 6839 |
| 6840 Handle<Map> Map::RawCopy(Handle<Map> map, int instance_size) { | 6840 Handle<Map> Map::RawCopy(Handle<Map> map, int instance_size) { |
| 6841 Handle<Map> result = map->GetIsolate()->factory()->NewMap( | 6841 Handle<Map> result = map->GetIsolate()->factory()->NewMap( |
| 6842 map->instance_type(), instance_size); | 6842 map->instance_type(), instance_size); |
| 6843 result->SetPrototype(handle(map->prototype(), map->GetIsolate())); | 6843 result->SetPrototype(handle(map->prototype(), map->GetIsolate())); |
| 6844 result->set_constructor(map->constructor()); | 6844 result->set_constructor_or_backpointer(map->GetConstructor()); |
| 6845 result->set_bit_field(map->bit_field()); | 6845 result->set_bit_field(map->bit_field()); |
| 6846 result->set_bit_field2(map->bit_field2()); | 6846 result->set_bit_field2(map->bit_field2()); |
| 6847 int new_bit_field3 = map->bit_field3(); | 6847 int new_bit_field3 = map->bit_field3(); |
| 6848 new_bit_field3 = OwnsDescriptors::update(new_bit_field3, true); | 6848 new_bit_field3 = OwnsDescriptors::update(new_bit_field3, true); |
| 6849 new_bit_field3 = NumberOfOwnDescriptorsBits::update(new_bit_field3, 0); | 6849 new_bit_field3 = NumberOfOwnDescriptorsBits::update(new_bit_field3, 0); |
| 6850 new_bit_field3 = EnumLengthBits::update(new_bit_field3, | 6850 new_bit_field3 = EnumLengthBits::update(new_bit_field3, |
| 6851 kInvalidEnumCacheSentinel); | 6851 kInvalidEnumCacheSentinel); |
| 6852 new_bit_field3 = Deprecated::update(new_bit_field3, false); | 6852 new_bit_field3 = Deprecated::update(new_bit_field3, false); |
| 6853 if (!map->is_dictionary_map()) { | 6853 if (!map->is_dictionary_map()) { |
| 6854 new_bit_field3 = IsUnstable::update(new_bit_field3, false); | 6854 new_bit_field3 = IsUnstable::update(new_bit_field3, false); |
| (...skipping 2693 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9548 } | 9548 } |
| 9549 | 9549 |
| 9550 | 9550 |
| 9551 int Map::Hash() { | 9551 int Map::Hash() { |
| 9552 // For performance reasons we only hash the 3 most variable fields of a map: | 9552 // For performance reasons we only hash the 3 most variable fields of a map: |
| 9553 // constructor, prototype and bit_field2. For predictability reasons we | 9553 // constructor, prototype and bit_field2. For predictability reasons we |
| 9554 // use objects' offsets in respective pages for hashing instead of raw | 9554 // use objects' offsets in respective pages for hashing instead of raw |
| 9555 // addresses. | 9555 // addresses. |
| 9556 | 9556 |
| 9557 // Shift away the tag. | 9557 // Shift away the tag. |
| 9558 int hash = ObjectAddressForHashing(constructor()) >> 2; | 9558 int hash = ObjectAddressForHashing(GetConstructor()) >> 2; |
| 9559 | 9559 |
| 9560 // XOR-ing the prototype and constructor directly yields too many zero bits | 9560 // XOR-ing the prototype and constructor directly yields too many zero bits |
| 9561 // when the two pointers are close (which is fairly common). | 9561 // when the two pointers are close (which is fairly common). |
| 9562 // To avoid this we shift the prototype bits relatively to the constructor. | 9562 // To avoid this we shift the prototype bits relatively to the constructor. |
| 9563 hash ^= ObjectAddressForHashing(prototype()) << (32 - kPageSizeBits); | 9563 hash ^= ObjectAddressForHashing(prototype()) << (32 - kPageSizeBits); |
| 9564 | 9564 |
| 9565 return hash ^ (hash >> 16) ^ bit_field2(); | 9565 return hash ^ (hash >> 16) ^ bit_field2(); |
| 9566 } | 9566 } |
| 9567 | 9567 |
| 9568 | 9568 |
| 9569 static bool CheckEquivalent(Map* first, Map* second) { | 9569 static bool CheckEquivalent(Map* first, Map* second) { |
| 9570 return first->constructor() == second->constructor() && | 9570 return first->GetConstructor() == second->GetConstructor() && |
| 9571 first->prototype() == second->prototype() && | 9571 first->prototype() == second->prototype() && |
| 9572 first->instance_type() == second->instance_type() && | 9572 first->instance_type() == second->instance_type() && |
| 9573 first->bit_field() == second->bit_field() && | 9573 first->bit_field() == second->bit_field() && |
| 9574 first->is_extensible() == second->is_extensible() && | 9574 first->is_extensible() == second->is_extensible() && |
| 9575 first->has_instance_call_handler() == | 9575 first->has_instance_call_handler() == |
| 9576 second->has_instance_call_handler(); | 9576 second->has_instance_call_handler(); |
| 9577 } | 9577 } |
| 9578 | 9578 |
| 9579 | 9579 |
| 9580 bool Map::EquivalentToForTransition(Map* other) { | 9580 bool Map::EquivalentToForTransition(Map* other) { |
| (...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9922 if (!object->HasFastProperties()) { | 9922 if (!object->HasFastProperties()) { |
| 9923 JSObject::MigrateSlowToFast(object, 0, "OptimizeAsPrototype"); | 9923 JSObject::MigrateSlowToFast(object, 0, "OptimizeAsPrototype"); |
| 9924 has_just_copied_map = true; | 9924 has_just_copied_map = true; |
| 9925 } | 9925 } |
| 9926 if (mode == FAST_PROTOTYPE && object->HasFastProperties() && | 9926 if (mode == FAST_PROTOTYPE && object->HasFastProperties() && |
| 9927 !object->map()->is_prototype_map()) { | 9927 !object->map()->is_prototype_map()) { |
| 9928 if (!has_just_copied_map) { | 9928 if (!has_just_copied_map) { |
| 9929 Handle<Map> new_map = Map::Copy(handle(object->map()), "CopyAsPrototype"); | 9929 Handle<Map> new_map = Map::Copy(handle(object->map()), "CopyAsPrototype"); |
| 9930 JSObject::MigrateToMap(object, new_map); | 9930 JSObject::MigrateToMap(object, new_map); |
| 9931 } | 9931 } |
| 9932 if (object->map()->constructor()->IsJSFunction()) { | 9932 Object* maybe_constructor = object->map()->GetConstructor(); |
| 9933 JSFunction* constructor = JSFunction::cast(object->map()->constructor()); | 9933 if (maybe_constructor->IsJSFunction()) { |
| 9934 JSFunction* constructor = JSFunction::cast(maybe_constructor); |
| 9934 // Replace the pointer to the exact constructor with the Object function | 9935 // Replace the pointer to the exact constructor with the Object function |
| 9935 // from the same context if undetectable from JS. This is to avoid keeping | 9936 // from the same context if undetectable from JS. This is to avoid keeping |
| 9936 // memory alive unnecessarily. | 9937 // memory alive unnecessarily. |
| 9937 if (!constructor->shared()->IsApiFunction() && | 9938 if (!constructor->shared()->IsApiFunction() && |
| 9938 object->class_name() == | 9939 object->class_name() == |
| 9939 object->GetIsolate()->heap()->Object_string()) { | 9940 object->GetIsolate()->heap()->Object_string()) { |
| 9940 Context* context = constructor->context()->native_context(); | 9941 Context* context = constructor->context()->native_context(); |
| 9941 JSFunction* object_function = context->object_function(); | 9942 JSFunction* object_function = context->object_function(); |
| 9942 object->map()->set_constructor(object_function); | 9943 object->map()->SetConstructor(object_function); |
| 9943 } | 9944 } |
| 9944 } | 9945 } |
| 9945 object->map()->set_is_prototype_map(true); | 9946 object->map()->set_is_prototype_map(true); |
| 9946 } | 9947 } |
| 9947 } | 9948 } |
| 9948 | 9949 |
| 9949 | 9950 |
| 9950 void JSObject::ReoptimizeIfPrototype(Handle<JSObject> object) { | 9951 void JSObject::ReoptimizeIfPrototype(Handle<JSObject> object) { |
| 9951 if (!object->map()->is_prototype_map()) return; | 9952 if (!object->map()->is_prototype_map()) return; |
| 9952 OptimizeAsPrototype(object, FAST_PROTOTYPE); | 9953 OptimizeAsPrototype(object, FAST_PROTOTYPE); |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10119 // constructor field so it can be accessed. Also, set the prototype | 10120 // constructor field so it can be accessed. Also, set the prototype |
| 10120 // used for constructing objects to the original object prototype. | 10121 // used for constructing objects to the original object prototype. |
| 10121 // See ECMA-262 13.2.2. | 10122 // See ECMA-262 13.2.2. |
| 10122 if (!value->IsJSReceiver()) { | 10123 if (!value->IsJSReceiver()) { |
| 10123 // Copy the map so this does not affect unrelated functions. | 10124 // Copy the map so this does not affect unrelated functions. |
| 10124 // Remove map transitions because they point to maps with a | 10125 // Remove map transitions because they point to maps with a |
| 10125 // different prototype. | 10126 // different prototype. |
| 10126 Handle<Map> new_map = Map::Copy(handle(function->map()), "SetPrototype"); | 10127 Handle<Map> new_map = Map::Copy(handle(function->map()), "SetPrototype"); |
| 10127 | 10128 |
| 10128 JSObject::MigrateToMap(function, new_map); | 10129 JSObject::MigrateToMap(function, new_map); |
| 10129 new_map->set_constructor(*value); | 10130 new_map->SetConstructor(*value); |
| 10130 new_map->set_non_instance_prototype(true); | 10131 new_map->set_non_instance_prototype(true); |
| 10131 Isolate* isolate = new_map->GetIsolate(); | 10132 Isolate* isolate = new_map->GetIsolate(); |
| 10132 construct_prototype = handle( | 10133 construct_prototype = handle( |
| 10133 isolate->context()->native_context()->initial_object_prototype(), | 10134 isolate->context()->native_context()->initial_object_prototype(), |
| 10134 isolate); | 10135 isolate); |
| 10135 } else { | 10136 } else { |
| 10136 function->map()->set_non_instance_prototype(false); | 10137 function->map()->set_non_instance_prototype(false); |
| 10137 } | 10138 } |
| 10138 | 10139 |
| 10139 return SetInstancePrototype(function, construct_prototype); | 10140 return SetInstancePrototype(function, construct_prototype); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 10162 return true; | 10163 return true; |
| 10163 } | 10164 } |
| 10164 | 10165 |
| 10165 | 10166 |
| 10166 void JSFunction::SetInitialMap(Handle<JSFunction> function, Handle<Map> map, | 10167 void JSFunction::SetInitialMap(Handle<JSFunction> function, Handle<Map> map, |
| 10167 Handle<Object> prototype) { | 10168 Handle<Object> prototype) { |
| 10168 if (map->prototype() != *prototype) { | 10169 if (map->prototype() != *prototype) { |
| 10169 map->SetPrototype(prototype, FAST_PROTOTYPE); | 10170 map->SetPrototype(prototype, FAST_PROTOTYPE); |
| 10170 } | 10171 } |
| 10171 function->set_prototype_or_initial_map(*map); | 10172 function->set_prototype_or_initial_map(*map); |
| 10172 map->set_constructor(*function); | 10173 map->SetConstructor(*function); |
| 10173 #if TRACE_MAPS | 10174 #if TRACE_MAPS |
| 10174 if (FLAG_trace_maps) { | 10175 if (FLAG_trace_maps) { |
| 10175 PrintF("[TraceMaps: InitialMap map= %p SFI= %d_%s ]\n", | 10176 PrintF("[TraceMaps: InitialMap map= %p SFI= %d_%s ]\n", |
| 10176 reinterpret_cast<void*>(*map), function->shared()->unique_id(), | 10177 reinterpret_cast<void*>(*map), function->shared()->unique_id(), |
| 10177 function->shared()->DebugName()->ToCString().get()); | 10178 function->shared()->DebugName()->ToCString().get()); |
| 10178 } | 10179 } |
| 10179 #endif | 10180 #endif |
| 10180 } | 10181 } |
| 10181 | 10182 |
| 10182 | 10183 |
| (...skipping 3629 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13812 if (Dictionary::IsKey(k)) { | 13813 if (Dictionary::IsKey(k)) { |
| 13813 elements->set(pos++, ValueAt(i), mode); | 13814 elements->set(pos++, ValueAt(i), mode); |
| 13814 } | 13815 } |
| 13815 } | 13816 } |
| 13816 DCHECK(pos == elements->length()); | 13817 DCHECK(pos == elements->length()); |
| 13817 } | 13818 } |
| 13818 | 13819 |
| 13819 | 13820 |
| 13820 InterceptorInfo* JSObject::GetNamedInterceptor() { | 13821 InterceptorInfo* JSObject::GetNamedInterceptor() { |
| 13821 DCHECK(map()->has_named_interceptor()); | 13822 DCHECK(map()->has_named_interceptor()); |
| 13822 JSFunction* constructor = JSFunction::cast(map()->constructor()); | 13823 JSFunction* constructor = JSFunction::cast(map()->GetConstructor()); |
| 13823 DCHECK(constructor->shared()->IsApiFunction()); | 13824 DCHECK(constructor->shared()->IsApiFunction()); |
| 13824 Object* result = | 13825 Object* result = |
| 13825 constructor->shared()->get_api_func_data()->named_property_handler(); | 13826 constructor->shared()->get_api_func_data()->named_property_handler(); |
| 13826 return InterceptorInfo::cast(result); | 13827 return InterceptorInfo::cast(result); |
| 13827 } | 13828 } |
| 13828 | 13829 |
| 13829 | 13830 |
| 13830 InterceptorInfo* JSObject::GetIndexedInterceptor() { | 13831 InterceptorInfo* JSObject::GetIndexedInterceptor() { |
| 13831 DCHECK(map()->has_indexed_interceptor()); | 13832 DCHECK(map()->has_indexed_interceptor()); |
| 13832 JSFunction* constructor = JSFunction::cast(map()->constructor()); | 13833 JSFunction* constructor = JSFunction::cast(map()->GetConstructor()); |
| 13833 DCHECK(constructor->shared()->IsApiFunction()); | 13834 DCHECK(constructor->shared()->IsApiFunction()); |
| 13834 Object* result = | 13835 Object* result = |
| 13835 constructor->shared()->get_api_func_data()->indexed_property_handler(); | 13836 constructor->shared()->get_api_func_data()->indexed_property_handler(); |
| 13836 return InterceptorInfo::cast(result); | 13837 return InterceptorInfo::cast(result); |
| 13837 } | 13838 } |
| 13838 | 13839 |
| 13839 | 13840 |
| 13840 MaybeHandle<Object> JSObject::GetPropertyWithInterceptor( | 13841 MaybeHandle<Object> JSObject::GetPropertyWithInterceptor( |
| 13841 Handle<JSObject> holder, | 13842 Handle<JSObject> holder, |
| 13842 Handle<Object> receiver, | 13843 Handle<Object> receiver, |
| (...skipping 3324 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 17167 CompilationInfo* info) { | 17168 CompilationInfo* info) { |
| 17168 Handle<DependentCode> codes = DependentCode::InsertCompilationInfo( | 17169 Handle<DependentCode> codes = DependentCode::InsertCompilationInfo( |
| 17169 handle(cell->dependent_code(), info->isolate()), | 17170 handle(cell->dependent_code(), info->isolate()), |
| 17170 DependentCode::kPropertyCellChangedGroup, info->object_wrapper()); | 17171 DependentCode::kPropertyCellChangedGroup, info->object_wrapper()); |
| 17171 if (*codes != cell->dependent_code()) cell->set_dependent_code(*codes); | 17172 if (*codes != cell->dependent_code()) cell->set_dependent_code(*codes); |
| 17172 info->dependencies(DependentCode::kPropertyCellChangedGroup)->Add( | 17173 info->dependencies(DependentCode::kPropertyCellChangedGroup)->Add( |
| 17173 cell, info->zone()); | 17174 cell, info->zone()); |
| 17174 } | 17175 } |
| 17175 | 17176 |
| 17176 } } // namespace v8::internal | 17177 } } // namespace v8::internal |
| OLD | NEW |