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 |