| 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 <cmath> | 7 #include <cmath> |
| 8 #include <iomanip> | 8 #include <iomanip> |
| 9 #include <sstream> | 9 #include <sstream> |
| 10 | 10 |
| (...skipping 713 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 724 | 724 |
| 725 | 725 |
| 726 Handle<Object> JSReceiver::GetDataProperty(LookupIterator* it) { | 726 Handle<Object> JSReceiver::GetDataProperty(LookupIterator* it) { |
| 727 for (; it->IsFound(); it->Next()) { | 727 for (; it->IsFound(); it->Next()) { |
| 728 switch (it->state()) { | 728 switch (it->state()) { |
| 729 case LookupIterator::INTERCEPTOR: | 729 case LookupIterator::INTERCEPTOR: |
| 730 case LookupIterator::NOT_FOUND: | 730 case LookupIterator::NOT_FOUND: |
| 731 case LookupIterator::TRANSITION: | 731 case LookupIterator::TRANSITION: |
| 732 UNREACHABLE(); | 732 UNREACHABLE(); |
| 733 case LookupIterator::ACCESS_CHECK: | 733 case LookupIterator::ACCESS_CHECK: |
| 734 if (it->HasAccess()) continue; | 734 // Support calling this method without an active context, but refuse |
| 735 // access to access-checked objects in that case. |
| 736 if (it->isolate()->context() != nullptr && it->HasAccess()) continue; |
| 735 // Fall through. | 737 // Fall through. |
| 736 case LookupIterator::JSPROXY: | 738 case LookupIterator::JSPROXY: |
| 737 it->NotFound(); | 739 it->NotFound(); |
| 738 return it->isolate()->factory()->undefined_value(); | 740 return it->isolate()->factory()->undefined_value(); |
| 739 case LookupIterator::ACCESSOR: | 741 case LookupIterator::ACCESSOR: |
| 740 // TODO(verwaest): For now this doesn't call into | 742 // TODO(verwaest): For now this doesn't call into |
| 741 // ExecutableAccessorInfo, since clients don't need it. Update once | 743 // ExecutableAccessorInfo, since clients don't need it. Update once |
| 742 // relevant. | 744 // relevant. |
| 743 it->NotFound(); | 745 it->NotFound(); |
| 744 return it->isolate()->factory()->undefined_value(); | 746 return it->isolate()->factory()->undefined_value(); |
| (...skipping 1063 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1808 JSFunction::cast(native_context->get(constructor_function_index))); | 1810 JSFunction::cast(native_context->get(constructor_function_index))); |
| 1809 } | 1811 } |
| 1810 } | 1812 } |
| 1811 return MaybeHandle<JSFunction>(); | 1813 return MaybeHandle<JSFunction>(); |
| 1812 } | 1814 } |
| 1813 | 1815 |
| 1814 | 1816 |
| 1815 void Map::PrintReconfiguration(FILE* file, int modify_index, PropertyKind kind, | 1817 void Map::PrintReconfiguration(FILE* file, int modify_index, PropertyKind kind, |
| 1816 PropertyAttributes attributes) { | 1818 PropertyAttributes attributes) { |
| 1817 OFStream os(file); | 1819 OFStream os(file); |
| 1818 os << "[reconfiguring "; | 1820 os << "[reconfiguring]"; |
| 1819 constructor_name()->PrintOn(file); | |
| 1820 os << "] "; | |
| 1821 Name* name = instance_descriptors()->GetKey(modify_index); | 1821 Name* name = instance_descriptors()->GetKey(modify_index); |
| 1822 if (name->IsString()) { | 1822 if (name->IsString()) { |
| 1823 String::cast(name)->PrintOn(file); | 1823 String::cast(name)->PrintOn(file); |
| 1824 } else { | 1824 } else { |
| 1825 os << "{symbol " << static_cast<void*>(name) << "}"; | 1825 os << "{symbol " << static_cast<void*>(name) << "}"; |
| 1826 } | 1826 } |
| 1827 os << ": " << (kind == kData ? "kData" : "ACCESSORS") << ", attrs: "; | 1827 os << ": " << (kind == kData ? "kData" : "ACCESSORS") << ", attrs: "; |
| 1828 os << attributes << " ["; | 1828 os << attributes << " ["; |
| 1829 JavaScriptFrame::PrintTop(GetIsolate(), file, false, true); | 1829 JavaScriptFrame::PrintTop(GetIsolate(), file, false, true); |
| 1830 os << "]\n"; | 1830 os << "]\n"; |
| 1831 } | 1831 } |
| 1832 | 1832 |
| 1833 | 1833 |
| 1834 void Map::PrintGeneralization(FILE* file, | 1834 void Map::PrintGeneralization(FILE* file, |
| 1835 const char* reason, | 1835 const char* reason, |
| 1836 int modify_index, | 1836 int modify_index, |
| 1837 int split, | 1837 int split, |
| 1838 int descriptors, | 1838 int descriptors, |
| 1839 bool constant_to_field, | 1839 bool constant_to_field, |
| 1840 Representation old_representation, | 1840 Representation old_representation, |
| 1841 Representation new_representation, | 1841 Representation new_representation, |
| 1842 HeapType* old_field_type, | 1842 HeapType* old_field_type, |
| 1843 HeapType* new_field_type) { | 1843 HeapType* new_field_type) { |
| 1844 OFStream os(file); | 1844 OFStream os(file); |
| 1845 os << "[generalizing "; | 1845 os << "[generalizing]"; |
| 1846 constructor_name()->PrintOn(file); | |
| 1847 os << "] "; | |
| 1848 Name* name = instance_descriptors()->GetKey(modify_index); | 1846 Name* name = instance_descriptors()->GetKey(modify_index); |
| 1849 if (name->IsString()) { | 1847 if (name->IsString()) { |
| 1850 String::cast(name)->PrintOn(file); | 1848 String::cast(name)->PrintOn(file); |
| 1851 } else { | 1849 } else { |
| 1852 os << "{symbol " << static_cast<void*>(name) << "}"; | 1850 os << "{symbol " << static_cast<void*>(name) << "}"; |
| 1853 } | 1851 } |
| 1854 os << ":"; | 1852 os << ":"; |
| 1855 if (constant_to_field) { | 1853 if (constant_to_field) { |
| 1856 os << "c"; | 1854 os << "c"; |
| 1857 } else { | 1855 } else { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1869 } | 1867 } |
| 1870 os << ") ["; | 1868 os << ") ["; |
| 1871 JavaScriptFrame::PrintTop(GetIsolate(), file, false, true); | 1869 JavaScriptFrame::PrintTop(GetIsolate(), file, false, true); |
| 1872 os << "]\n"; | 1870 os << "]\n"; |
| 1873 } | 1871 } |
| 1874 | 1872 |
| 1875 | 1873 |
| 1876 void JSObject::PrintInstanceMigration(FILE* file, | 1874 void JSObject::PrintInstanceMigration(FILE* file, |
| 1877 Map* original_map, | 1875 Map* original_map, |
| 1878 Map* new_map) { | 1876 Map* new_map) { |
| 1879 PrintF(file, "[migrating "); | 1877 PrintF(file, "[migrating]"); |
| 1880 map()->constructor_name()->PrintOn(file); | |
| 1881 PrintF(file, "] "); | |
| 1882 DescriptorArray* o = original_map->instance_descriptors(); | 1878 DescriptorArray* o = original_map->instance_descriptors(); |
| 1883 DescriptorArray* n = new_map->instance_descriptors(); | 1879 DescriptorArray* n = new_map->instance_descriptors(); |
| 1884 for (int i = 0; i < original_map->NumberOfOwnDescriptors(); i++) { | 1880 for (int i = 0; i < original_map->NumberOfOwnDescriptors(); i++) { |
| 1885 Representation o_r = o->GetDetails(i).representation(); | 1881 Representation o_r = o->GetDetails(i).representation(); |
| 1886 Representation n_r = n->GetDetails(i).representation(); | 1882 Representation n_r = n->GetDetails(i).representation(); |
| 1887 if (!o_r.Equals(n_r)) { | 1883 if (!o_r.Equals(n_r)) { |
| 1888 String::cast(o->GetKey(i))->PrintOn(file); | 1884 String::cast(o->GetKey(i))->PrintOn(file); |
| 1889 PrintF(file, ":%s->%s ", o_r.Mnemonic(), n_r.Mnemonic()); | 1885 PrintF(file, ":%s->%s ", o_r.Mnemonic(), n_r.Mnemonic()); |
| 1890 } else if (o->GetDetails(i).type() == DATA_CONSTANT && | 1886 } else if (o->GetDetails(i).type() == DATA_CONSTANT && |
| 1891 n->GetDetails(i).type() == DATA) { | 1887 n->GetDetails(i).type() == DATA) { |
| (...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2223 Object* maybe_constructor = map()->GetConstructor(); | 2219 Object* maybe_constructor = map()->GetConstructor(); |
| 2224 if (maybe_constructor->IsJSFunction()) { | 2220 if (maybe_constructor->IsJSFunction()) { |
| 2225 JSFunction* constructor = JSFunction::cast(maybe_constructor); | 2221 JSFunction* constructor = JSFunction::cast(maybe_constructor); |
| 2226 return String::cast(constructor->shared()->instance_class_name()); | 2222 return String::cast(constructor->shared()->instance_class_name()); |
| 2227 } | 2223 } |
| 2228 // If the constructor is not present, return "Object". | 2224 // If the constructor is not present, return "Object". |
| 2229 return GetHeap()->Object_string(); | 2225 return GetHeap()->Object_string(); |
| 2230 } | 2226 } |
| 2231 | 2227 |
| 2232 | 2228 |
| 2233 String* Map::constructor_name() { | 2229 // static |
| 2234 if (is_prototype_map() && prototype_info()->IsPrototypeInfo()) { | 2230 Handle<String> JSReceiver::GetConstructorName(Handle<JSReceiver> receiver) { |
| 2235 PrototypeInfo* proto_info = PrototypeInfo::cast(prototype_info()); | 2231 Isolate* isolate = receiver->GetIsolate(); |
| 2236 if (proto_info->constructor_name()->IsString()) { | 2232 if (FLAG_harmony_tostring) { |
| 2237 return String::cast(proto_info->constructor_name()); | 2233 Handle<Object> maybe_tag = JSReceiver::GetDataProperty( |
| 2234 receiver, isolate->factory()->to_string_tag_symbol()); |
| 2235 if (maybe_tag->IsString()) return Handle<String>::cast(maybe_tag); |
| 2236 } |
| 2237 |
| 2238 PrototypeIterator iter(isolate, receiver); |
| 2239 if (iter.IsAtEnd()) return handle(receiver->class_name()); |
| 2240 Handle<JSReceiver> start = PrototypeIterator::GetCurrent<JSReceiver>(iter); |
| 2241 LookupIterator it(receiver, isolate->factory()->constructor_string(), start, |
| 2242 LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR); |
| 2243 Handle<Object> maybe_constructor = JSReceiver::GetDataProperty(&it); |
| 2244 Handle<String> result = isolate->factory()->Object_string(); |
| 2245 if (maybe_constructor->IsJSFunction()) { |
| 2246 JSFunction* constructor = JSFunction::cast(*maybe_constructor); |
| 2247 String* name = String::cast(constructor->shared()->name()); |
| 2248 if (name->length() > 0) { |
| 2249 result = handle(name, isolate); |
| 2250 } else { |
| 2251 String* inferred_name = constructor->shared()->inferred_name(); |
| 2252 if (inferred_name->length() > 0) { |
| 2253 result = handle(inferred_name, isolate); |
| 2254 } |
| 2238 } | 2255 } |
| 2239 } | 2256 } |
| 2240 Object* maybe_constructor = GetConstructor(); | 2257 |
| 2241 if (maybe_constructor->IsJSFunction()) { | 2258 return result.is_identical_to(isolate->factory()->Object_string()) |
| 2242 JSFunction* constructor = JSFunction::cast(maybe_constructor); | 2259 ? handle(receiver->class_name()) |
| 2243 String* name = String::cast(constructor->shared()->name()); | 2260 : result; |
| 2244 if (name->length() > 0) return name; | |
| 2245 String* inferred_name = constructor->shared()->inferred_name(); | |
| 2246 if (inferred_name->length() > 0) return inferred_name; | |
| 2247 Object* proto = prototype(); | |
| 2248 if (proto->IsJSObject()) return JSObject::cast(proto)->constructor_name(); | |
| 2249 } | |
| 2250 // TODO(rossberg): what about proxies? | |
| 2251 // If the constructor is not present, return "Object". | |
| 2252 return GetHeap()->Object_string(); | |
| 2253 } | 2261 } |
| 2254 | 2262 |
| 2255 | 2263 |
| 2256 String* JSReceiver::constructor_name() { | |
| 2257 return map()->constructor_name(); | |
| 2258 } | |
| 2259 | |
| 2260 | |
| 2261 Context* JSReceiver::GetCreationContext() { | 2264 Context* JSReceiver::GetCreationContext() { |
| 2262 Object* constructor = map()->GetConstructor(); | 2265 Object* constructor = map()->GetConstructor(); |
| 2263 JSFunction* function; | 2266 JSFunction* function; |
| 2264 if (!constructor->IsJSFunction()) { | 2267 if (!constructor->IsJSFunction()) { |
| 2265 // Functions have null as a constructor, | 2268 // Functions have null as a constructor, |
| 2266 // but any JSFunction knows its context immediately. | 2269 // but any JSFunction knows its context immediately. |
| 2267 function = JSFunction::cast(this); | 2270 function = JSFunction::cast(this); |
| 2268 } else { | 2271 } else { |
| 2269 function = JSFunction::cast(constructor); | 2272 function = JSFunction::cast(constructor); |
| 2270 } | 2273 } |
| (...skipping 9431 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11702 | 11705 |
| 11703 // Replace the pointer to the exact constructor with the Object function | 11706 // Replace the pointer to the exact constructor with the Object function |
| 11704 // from the same context if undetectable from JS. This is to avoid keeping | 11707 // from the same context if undetectable from JS. This is to avoid keeping |
| 11705 // memory alive unnecessarily. | 11708 // memory alive unnecessarily. |
| 11706 Object* maybe_constructor = object->map()->GetConstructor(); | 11709 Object* maybe_constructor = object->map()->GetConstructor(); |
| 11707 if (maybe_constructor->IsJSFunction()) { | 11710 if (maybe_constructor->IsJSFunction()) { |
| 11708 JSFunction* constructor = JSFunction::cast(maybe_constructor); | 11711 JSFunction* constructor = JSFunction::cast(maybe_constructor); |
| 11709 Isolate* isolate = object->GetIsolate(); | 11712 Isolate* isolate = object->GetIsolate(); |
| 11710 if (!constructor->shared()->IsApiFunction() && | 11713 if (!constructor->shared()->IsApiFunction() && |
| 11711 object->class_name() == isolate->heap()->Object_string()) { | 11714 object->class_name() == isolate->heap()->Object_string()) { |
| 11712 Handle<String> constructor_name(object->constructor_name(), isolate); | |
| 11713 Context* context = constructor->context()->native_context(); | 11715 Context* context = constructor->context()->native_context(); |
| 11714 JSFunction* object_function = context->object_function(); | 11716 JSFunction* object_function = context->object_function(); |
| 11715 object->map()->SetConstructor(object_function); | 11717 object->map()->SetConstructor(object_function); |
| 11716 Handle<PrototypeInfo> proto_info = | |
| 11717 Map::GetOrCreatePrototypeInfo(object, isolate); | |
| 11718 proto_info->set_constructor_name(*constructor_name); | |
| 11719 } | 11718 } |
| 11720 } | 11719 } |
| 11721 } | 11720 } |
| 11722 } | 11721 } |
| 11723 | 11722 |
| 11724 | 11723 |
| 11725 // static | 11724 // static |
| 11726 void JSObject::ReoptimizeIfPrototype(Handle<JSObject> object) { | 11725 void JSObject::ReoptimizeIfPrototype(Handle<JSObject> object) { |
| 11727 if (!object->map()->is_prototype_map()) return; | 11726 if (!object->map()->is_prototype_map()) return; |
| 11728 OptimizeAsPrototype(object, FAST_PROTOTYPE); | 11727 OptimizeAsPrototype(object, FAST_PROTOTYPE); |
| (...skipping 6872 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 18601 if (cell->value() != *new_value) { | 18600 if (cell->value() != *new_value) { |
| 18602 cell->set_value(*new_value); | 18601 cell->set_value(*new_value); |
| 18603 Isolate* isolate = cell->GetIsolate(); | 18602 Isolate* isolate = cell->GetIsolate(); |
| 18604 cell->dependent_code()->DeoptimizeDependentCodeGroup( | 18603 cell->dependent_code()->DeoptimizeDependentCodeGroup( |
| 18605 isolate, DependentCode::kPropertyCellChangedGroup); | 18604 isolate, DependentCode::kPropertyCellChangedGroup); |
| 18606 } | 18605 } |
| 18607 } | 18606 } |
| 18608 | 18607 |
| 18609 } // namespace internal | 18608 } // namespace internal |
| 18610 } // namespace v8 | 18609 } // namespace v8 |
| OLD | NEW |