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 712 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
723 | 723 |
724 | 724 |
725 Handle<Object> JSReceiver::GetDataProperty(LookupIterator* it) { | 725 Handle<Object> JSReceiver::GetDataProperty(LookupIterator* it) { |
726 for (; it->IsFound(); it->Next()) { | 726 for (; it->IsFound(); it->Next()) { |
727 switch (it->state()) { | 727 switch (it->state()) { |
728 case LookupIterator::INTERCEPTOR: | 728 case LookupIterator::INTERCEPTOR: |
729 case LookupIterator::NOT_FOUND: | 729 case LookupIterator::NOT_FOUND: |
730 case LookupIterator::TRANSITION: | 730 case LookupIterator::TRANSITION: |
731 UNREACHABLE(); | 731 UNREACHABLE(); |
732 case LookupIterator::ACCESS_CHECK: | 732 case LookupIterator::ACCESS_CHECK: |
733 if (it->HasAccess()) continue; | 733 if (it->isolate()->context() != nullptr && it->HasAccess()) continue; |
Camillo Bruni
2015/11/12 12:43:08
nit: maybe add a comment that you check for the mi
| |
734 // Fall through. | 734 // Fall through. |
735 case LookupIterator::JSPROXY: | 735 case LookupIterator::JSPROXY: |
736 it->NotFound(); | 736 it->NotFound(); |
737 return it->isolate()->factory()->undefined_value(); | 737 return it->isolate()->factory()->undefined_value(); |
738 case LookupIterator::ACCESSOR: | 738 case LookupIterator::ACCESSOR: |
739 // TODO(verwaest): For now this doesn't call into | 739 // TODO(verwaest): For now this doesn't call into |
740 // ExecutableAccessorInfo, since clients don't need it. Update once | 740 // ExecutableAccessorInfo, since clients don't need it. Update once |
741 // relevant. | 741 // relevant. |
742 it->NotFound(); | 742 it->NotFound(); |
743 return it->isolate()->factory()->undefined_value(); | 743 return it->isolate()->factory()->undefined_value(); |
(...skipping 994 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1738 JSFunction::cast(native_context->get(constructor_function_index))); | 1738 JSFunction::cast(native_context->get(constructor_function_index))); |
1739 } | 1739 } |
1740 } | 1740 } |
1741 return MaybeHandle<JSFunction>(); | 1741 return MaybeHandle<JSFunction>(); |
1742 } | 1742 } |
1743 | 1743 |
1744 | 1744 |
1745 void Map::PrintReconfiguration(FILE* file, int modify_index, PropertyKind kind, | 1745 void Map::PrintReconfiguration(FILE* file, int modify_index, PropertyKind kind, |
1746 PropertyAttributes attributes) { | 1746 PropertyAttributes attributes) { |
1747 OFStream os(file); | 1747 OFStream os(file); |
1748 os << "[reconfiguring "; | 1748 os << "[reconfiguring]"; |
1749 constructor_name()->PrintOn(file); | |
1750 os << "] "; | |
1751 Name* name = instance_descriptors()->GetKey(modify_index); | 1749 Name* name = instance_descriptors()->GetKey(modify_index); |
1752 if (name->IsString()) { | 1750 if (name->IsString()) { |
1753 String::cast(name)->PrintOn(file); | 1751 String::cast(name)->PrintOn(file); |
1754 } else { | 1752 } else { |
1755 os << "{symbol " << static_cast<void*>(name) << "}"; | 1753 os << "{symbol " << static_cast<void*>(name) << "}"; |
1756 } | 1754 } |
1757 os << ": " << (kind == kData ? "kData" : "ACCESSORS") << ", attrs: "; | 1755 os << ": " << (kind == kData ? "kData" : "ACCESSORS") << ", attrs: "; |
1758 os << attributes << " ["; | 1756 os << attributes << " ["; |
1759 JavaScriptFrame::PrintTop(GetIsolate(), file, false, true); | 1757 JavaScriptFrame::PrintTop(GetIsolate(), file, false, true); |
1760 os << "]\n"; | 1758 os << "]\n"; |
1761 } | 1759 } |
1762 | 1760 |
1763 | 1761 |
1764 void Map::PrintGeneralization(FILE* file, | 1762 void Map::PrintGeneralization(FILE* file, |
1765 const char* reason, | 1763 const char* reason, |
1766 int modify_index, | 1764 int modify_index, |
1767 int split, | 1765 int split, |
1768 int descriptors, | 1766 int descriptors, |
1769 bool constant_to_field, | 1767 bool constant_to_field, |
1770 Representation old_representation, | 1768 Representation old_representation, |
1771 Representation new_representation, | 1769 Representation new_representation, |
1772 HeapType* old_field_type, | 1770 HeapType* old_field_type, |
1773 HeapType* new_field_type) { | 1771 HeapType* new_field_type) { |
1774 OFStream os(file); | 1772 OFStream os(file); |
1775 os << "[generalizing "; | 1773 os << "[generalizing]"; |
1776 constructor_name()->PrintOn(file); | |
1777 os << "] "; | |
1778 Name* name = instance_descriptors()->GetKey(modify_index); | 1774 Name* name = instance_descriptors()->GetKey(modify_index); |
1779 if (name->IsString()) { | 1775 if (name->IsString()) { |
1780 String::cast(name)->PrintOn(file); | 1776 String::cast(name)->PrintOn(file); |
1781 } else { | 1777 } else { |
1782 os << "{symbol " << static_cast<void*>(name) << "}"; | 1778 os << "{symbol " << static_cast<void*>(name) << "}"; |
1783 } | 1779 } |
1784 os << ":"; | 1780 os << ":"; |
1785 if (constant_to_field) { | 1781 if (constant_to_field) { |
1786 os << "c"; | 1782 os << "c"; |
1787 } else { | 1783 } else { |
(...skipping 11 matching lines...) Expand all Loading... | |
1799 } | 1795 } |
1800 os << ") ["; | 1796 os << ") ["; |
1801 JavaScriptFrame::PrintTop(GetIsolate(), file, false, true); | 1797 JavaScriptFrame::PrintTop(GetIsolate(), file, false, true); |
1802 os << "]\n"; | 1798 os << "]\n"; |
1803 } | 1799 } |
1804 | 1800 |
1805 | 1801 |
1806 void JSObject::PrintInstanceMigration(FILE* file, | 1802 void JSObject::PrintInstanceMigration(FILE* file, |
1807 Map* original_map, | 1803 Map* original_map, |
1808 Map* new_map) { | 1804 Map* new_map) { |
1809 PrintF(file, "[migrating "); | 1805 PrintF(file, "[migrating]"); |
1810 map()->constructor_name()->PrintOn(file); | |
1811 PrintF(file, "] "); | |
1812 DescriptorArray* o = original_map->instance_descriptors(); | 1806 DescriptorArray* o = original_map->instance_descriptors(); |
1813 DescriptorArray* n = new_map->instance_descriptors(); | 1807 DescriptorArray* n = new_map->instance_descriptors(); |
1814 for (int i = 0; i < original_map->NumberOfOwnDescriptors(); i++) { | 1808 for (int i = 0; i < original_map->NumberOfOwnDescriptors(); i++) { |
1815 Representation o_r = o->GetDetails(i).representation(); | 1809 Representation o_r = o->GetDetails(i).representation(); |
1816 Representation n_r = n->GetDetails(i).representation(); | 1810 Representation n_r = n->GetDetails(i).representation(); |
1817 if (!o_r.Equals(n_r)) { | 1811 if (!o_r.Equals(n_r)) { |
1818 String::cast(o->GetKey(i))->PrintOn(file); | 1812 String::cast(o->GetKey(i))->PrintOn(file); |
1819 PrintF(file, ":%s->%s ", o_r.Mnemonic(), n_r.Mnemonic()); | 1813 PrintF(file, ":%s->%s ", o_r.Mnemonic(), n_r.Mnemonic()); |
1820 } else if (o->GetDetails(i).type() == DATA_CONSTANT && | 1814 } else if (o->GetDetails(i).type() == DATA_CONSTANT && |
1821 n->GetDetails(i).type() == DATA) { | 1815 n->GetDetails(i).type() == DATA) { |
(...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2132 Object* maybe_constructor = map()->GetConstructor(); | 2126 Object* maybe_constructor = map()->GetConstructor(); |
2133 if (maybe_constructor->IsJSFunction()) { | 2127 if (maybe_constructor->IsJSFunction()) { |
2134 JSFunction* constructor = JSFunction::cast(maybe_constructor); | 2128 JSFunction* constructor = JSFunction::cast(maybe_constructor); |
2135 return String::cast(constructor->shared()->instance_class_name()); | 2129 return String::cast(constructor->shared()->instance_class_name()); |
2136 } | 2130 } |
2137 // If the constructor is not present, return "Object". | 2131 // If the constructor is not present, return "Object". |
2138 return GetHeap()->Object_string(); | 2132 return GetHeap()->Object_string(); |
2139 } | 2133 } |
2140 | 2134 |
2141 | 2135 |
2142 String* Map::constructor_name() { | 2136 // static |
2143 if (is_prototype_map() && prototype_info()->IsPrototypeInfo()) { | 2137 Handle<String> JSReceiver::GetConstructorName(Handle<JSReceiver> receiver) { |
2144 PrototypeInfo* proto_info = PrototypeInfo::cast(prototype_info()); | 2138 Isolate* isolate = receiver->GetIsolate(); |
2145 if (proto_info->constructor_name()->IsString()) { | 2139 if (FLAG_harmony_tostring) { |
2146 return String::cast(proto_info->constructor_name()); | 2140 Handle<Object> maybe_tag = JSReceiver::GetDataProperty( |
2141 receiver, isolate->factory()->to_string_tag_symbol()); | |
2142 if (maybe_tag->IsString()) return Handle<String>::cast(maybe_tag); | |
2143 } | |
2144 | |
2145 PrototypeIterator iter(isolate, receiver); | |
2146 if (iter.IsAtEnd()) return handle(receiver->class_name()); | |
2147 Handle<JSReceiver> start = PrototypeIterator::GetCurrent<JSReceiver>(iter); | |
2148 LookupIterator it(receiver, isolate->factory()->constructor_string(), start, | |
2149 LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR); | |
2150 Handle<Object> maybe_constructor = JSReceiver::GetDataProperty(&it); | |
2151 Handle<String> result = isolate->factory()->Object_string(); | |
2152 if (maybe_constructor->IsJSFunction()) { | |
2153 JSFunction* constructor = JSFunction::cast(*maybe_constructor); | |
2154 String* name = String::cast(constructor->shared()->name()); | |
2155 if (name->length() > 0) { | |
2156 result = handle(name, isolate); | |
2157 } else { | |
2158 String* inferred_name = constructor->shared()->inferred_name(); | |
Camillo Bruni
2015/11/12 12:43:08
I would have expected to check for the inferred_na
| |
2159 if (inferred_name->length() > 0) { | |
2160 result = handle(inferred_name, isolate); | |
2161 } | |
2147 } | 2162 } |
2148 } | 2163 } |
2149 Object* maybe_constructor = GetConstructor(); | 2164 |
2150 if (maybe_constructor->IsJSFunction()) { | 2165 return result.is_identical_to(isolate->factory()->Object_string()) |
2151 JSFunction* constructor = JSFunction::cast(maybe_constructor); | 2166 ? handle(receiver->class_name()) |
2152 String* name = String::cast(constructor->shared()->name()); | 2167 : result; |
2153 if (name->length() > 0) return name; | |
2154 String* inferred_name = constructor->shared()->inferred_name(); | |
2155 if (inferred_name->length() > 0) return inferred_name; | |
2156 Object* proto = prototype(); | |
2157 if (proto->IsJSObject()) return JSObject::cast(proto)->constructor_name(); | |
2158 } | |
2159 // TODO(rossberg): what about proxies? | |
2160 // If the constructor is not present, return "Object". | |
2161 return GetHeap()->Object_string(); | |
2162 } | 2168 } |
2163 | 2169 |
2164 | 2170 |
2165 String* JSReceiver::constructor_name() { | |
2166 return map()->constructor_name(); | |
2167 } | |
2168 | |
2169 | |
2170 static Handle<Object> WrapType(Handle<HeapType> type) { | 2171 static Handle<Object> WrapType(Handle<HeapType> type) { |
2171 if (type->IsClass()) return Map::WeakCellForMap(type->AsClass()->Map()); | 2172 if (type->IsClass()) return Map::WeakCellForMap(type->AsClass()->Map()); |
2172 return type; | 2173 return type; |
2173 } | 2174 } |
2174 | 2175 |
2175 | 2176 |
2176 MaybeHandle<Map> Map::CopyWithField(Handle<Map> map, | 2177 MaybeHandle<Map> Map::CopyWithField(Handle<Map> map, |
2177 Handle<Name> name, | 2178 Handle<Name> name, |
2178 Handle<HeapType> type, | 2179 Handle<HeapType> type, |
2179 PropertyAttributes attributes, | 2180 PropertyAttributes attributes, |
(...skipping 9117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
11297 | 11298 |
11298 // Replace the pointer to the exact constructor with the Object function | 11299 // Replace the pointer to the exact constructor with the Object function |
11299 // from the same context if undetectable from JS. This is to avoid keeping | 11300 // from the same context if undetectable from JS. This is to avoid keeping |
11300 // memory alive unnecessarily. | 11301 // memory alive unnecessarily. |
11301 Object* maybe_constructor = object->map()->GetConstructor(); | 11302 Object* maybe_constructor = object->map()->GetConstructor(); |
11302 if (maybe_constructor->IsJSFunction()) { | 11303 if (maybe_constructor->IsJSFunction()) { |
11303 JSFunction* constructor = JSFunction::cast(maybe_constructor); | 11304 JSFunction* constructor = JSFunction::cast(maybe_constructor); |
11304 Isolate* isolate = object->GetIsolate(); | 11305 Isolate* isolate = object->GetIsolate(); |
11305 if (!constructor->shared()->IsApiFunction() && | 11306 if (!constructor->shared()->IsApiFunction() && |
11306 object->class_name() == isolate->heap()->Object_string()) { | 11307 object->class_name() == isolate->heap()->Object_string()) { |
11307 Handle<String> constructor_name(object->constructor_name(), isolate); | |
11308 Context* context = constructor->context()->native_context(); | 11308 Context* context = constructor->context()->native_context(); |
11309 JSFunction* object_function = context->object_function(); | 11309 JSFunction* object_function = context->object_function(); |
11310 object->map()->SetConstructor(object_function); | 11310 object->map()->SetConstructor(object_function); |
11311 Handle<PrototypeInfo> proto_info = | |
11312 Map::GetOrCreatePrototypeInfo(object, isolate); | |
11313 proto_info->set_constructor_name(*constructor_name); | |
11314 } | 11311 } |
11315 } | 11312 } |
11316 } | 11313 } |
11317 } | 11314 } |
11318 | 11315 |
11319 | 11316 |
11320 // static | 11317 // static |
11321 void JSObject::ReoptimizeIfPrototype(Handle<JSObject> object) { | 11318 void JSObject::ReoptimizeIfPrototype(Handle<JSObject> object) { |
11322 if (!object->map()->is_prototype_map()) return; | 11319 if (!object->map()->is_prototype_map()) return; |
11323 OptimizeAsPrototype(object, FAST_PROTOTYPE); | 11320 OptimizeAsPrototype(object, FAST_PROTOTYPE); |
(...skipping 6577 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
17901 if (cell->value() != *new_value) { | 17898 if (cell->value() != *new_value) { |
17902 cell->set_value(*new_value); | 17899 cell->set_value(*new_value); |
17903 Isolate* isolate = cell->GetIsolate(); | 17900 Isolate* isolate = cell->GetIsolate(); |
17904 cell->dependent_code()->DeoptimizeDependentCodeGroup( | 17901 cell->dependent_code()->DeoptimizeDependentCodeGroup( |
17905 isolate, DependentCode::kPropertyCellChangedGroup); | 17902 isolate, DependentCode::kPropertyCellChangedGroup); |
17906 } | 17903 } |
17907 } | 17904 } |
17908 | 17905 |
17909 } // namespace internal | 17906 } // namespace internal |
17910 } // namespace v8 | 17907 } // namespace v8 |
OLD | NEW |