Chromium Code Reviews| 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 |