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 <iomanip> | 5 #include <iomanip> |
6 #include <sstream> | 6 #include <sstream> |
7 | 7 |
8 #include "src/v8.h" | 8 #include "src/v8.h" |
9 | 9 |
10 #include "src/accessors.h" | 10 #include "src/accessors.h" |
(...skipping 1686 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1697 // If the constructor is not present, return "Object". | 1697 // If the constructor is not present, return "Object". |
1698 return GetHeap()->Object_string(); | 1698 return GetHeap()->Object_string(); |
1699 } | 1699 } |
1700 | 1700 |
1701 | 1701 |
1702 String* JSReceiver::constructor_name() { | 1702 String* JSReceiver::constructor_name() { |
1703 return map()->constructor_name(); | 1703 return map()->constructor_name(); |
1704 } | 1704 } |
1705 | 1705 |
1706 | 1706 |
| 1707 static Handle<Object> WrapType(Handle<HeapType> type) { |
| 1708 if (type->IsClass()) return Map::WeakCellForMap(type->AsClass()->Map()); |
| 1709 return type; |
| 1710 } |
| 1711 |
| 1712 |
1707 MaybeHandle<Map> Map::CopyWithField(Handle<Map> map, | 1713 MaybeHandle<Map> Map::CopyWithField(Handle<Map> map, |
1708 Handle<Name> name, | 1714 Handle<Name> name, |
1709 Handle<HeapType> type, | 1715 Handle<HeapType> type, |
1710 PropertyAttributes attributes, | 1716 PropertyAttributes attributes, |
1711 Representation representation, | 1717 Representation representation, |
1712 TransitionFlag flag) { | 1718 TransitionFlag flag) { |
1713 DCHECK(DescriptorArray::kNotFound == | 1719 DCHECK(DescriptorArray::kNotFound == |
1714 map->instance_descriptors()->Search( | 1720 map->instance_descriptors()->Search( |
1715 *name, map->NumberOfOwnDescriptors())); | 1721 *name, map->NumberOfOwnDescriptors())); |
1716 | 1722 |
1717 // Ensure the descriptor array does not get too big. | 1723 // Ensure the descriptor array does not get too big. |
1718 if (map->NumberOfOwnDescriptors() >= kMaxNumberOfDescriptors) { | 1724 if (map->NumberOfOwnDescriptors() >= kMaxNumberOfDescriptors) { |
1719 return MaybeHandle<Map>(); | 1725 return MaybeHandle<Map>(); |
1720 } | 1726 } |
1721 | 1727 |
1722 Isolate* isolate = map->GetIsolate(); | 1728 Isolate* isolate = map->GetIsolate(); |
1723 | 1729 |
1724 // Compute the new index for new field. | 1730 // Compute the new index for new field. |
1725 int index = map->NextFreePropertyIndex(); | 1731 int index = map->NextFreePropertyIndex(); |
1726 | 1732 |
1727 if (map->instance_type() == JS_CONTEXT_EXTENSION_OBJECT_TYPE) { | 1733 if (map->instance_type() == JS_CONTEXT_EXTENSION_OBJECT_TYPE) { |
1728 representation = Representation::Tagged(); | 1734 representation = Representation::Tagged(); |
1729 type = HeapType::Any(isolate); | 1735 type = HeapType::Any(isolate); |
1730 } | 1736 } |
1731 | 1737 |
1732 DataDescriptor new_field_desc(name, index, type, attributes, representation); | 1738 Handle<Object> wrapped_type(WrapType(type)); |
| 1739 |
| 1740 DataDescriptor new_field_desc(name, index, wrapped_type, attributes, |
| 1741 representation); |
1733 Handle<Map> new_map = Map::CopyAddDescriptor(map, &new_field_desc, flag); | 1742 Handle<Map> new_map = Map::CopyAddDescriptor(map, &new_field_desc, flag); |
1734 int unused_property_fields = new_map->unused_property_fields() - 1; | 1743 int unused_property_fields = new_map->unused_property_fields() - 1; |
1735 if (unused_property_fields < 0) { | 1744 if (unused_property_fields < 0) { |
1736 unused_property_fields += JSObject::kFieldsAdded; | 1745 unused_property_fields += JSObject::kFieldsAdded; |
1737 } | 1746 } |
1738 new_map->set_unused_property_fields(unused_property_fields); | 1747 new_map->set_unused_property_fields(unused_property_fields); |
1739 return new_map; | 1748 return new_map; |
1740 } | 1749 } |
1741 | 1750 |
1742 | 1751 |
(...skipping 555 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2298 Map* parent = Map::cast(back); | 2307 Map* parent = Map::cast(back); |
2299 if (parent->NumberOfOwnDescriptors() <= descriptor) break; | 2308 if (parent->NumberOfOwnDescriptors() <= descriptor) break; |
2300 result = parent; | 2309 result = parent; |
2301 } | 2310 } |
2302 return result; | 2311 return result; |
2303 } | 2312 } |
2304 | 2313 |
2305 | 2314 |
2306 void Map::UpdateFieldType(int descriptor, Handle<Name> name, | 2315 void Map::UpdateFieldType(int descriptor, Handle<Name> name, |
2307 Representation new_representation, | 2316 Representation new_representation, |
2308 Handle<HeapType> new_type) { | 2317 Handle<Object> new_wrapped_type) { |
| 2318 DCHECK(new_wrapped_type->IsSmi() || new_wrapped_type->IsWeakCell()); |
2309 DisallowHeapAllocation no_allocation; | 2319 DisallowHeapAllocation no_allocation; |
2310 PropertyDetails details = instance_descriptors()->GetDetails(descriptor); | 2320 PropertyDetails details = instance_descriptors()->GetDetails(descriptor); |
2311 if (details.type() != DATA) return; | 2321 if (details.type() != DATA) return; |
2312 if (HasTransitionArray()) { | 2322 if (HasTransitionArray()) { |
2313 TransitionArray* transitions = this->transitions(); | 2323 TransitionArray* transitions = this->transitions(); |
2314 for (int i = 0; i < transitions->number_of_transitions(); ++i) { | 2324 for (int i = 0; i < transitions->number_of_transitions(); ++i) { |
2315 transitions->GetTarget(i) | 2325 transitions->GetTarget(i)->UpdateFieldType( |
2316 ->UpdateFieldType(descriptor, name, new_representation, new_type); | 2326 descriptor, name, new_representation, new_wrapped_type); |
2317 } | 2327 } |
2318 } | 2328 } |
2319 // It is allowed to change representation here only from None to something. | 2329 // It is allowed to change representation here only from None to something. |
2320 DCHECK(details.representation().Equals(new_representation) || | 2330 DCHECK(details.representation().Equals(new_representation) || |
2321 details.representation().IsNone()); | 2331 details.representation().IsNone()); |
2322 | 2332 |
2323 // Skip if already updated the shared descriptor. | 2333 // Skip if already updated the shared descriptor. |
2324 if (instance_descriptors()->GetFieldType(descriptor) == *new_type) return; | 2334 if (instance_descriptors()->GetValue(descriptor) == *new_wrapped_type) return; |
2325 DataDescriptor d(name, instance_descriptors()->GetFieldIndex(descriptor), | 2335 DataDescriptor d(name, instance_descriptors()->GetFieldIndex(descriptor), |
2326 new_type, details.attributes(), new_representation); | 2336 new_wrapped_type, details.attributes(), new_representation); |
2327 instance_descriptors()->Replace(descriptor, &d); | 2337 instance_descriptors()->Replace(descriptor, &d); |
2328 } | 2338 } |
2329 | 2339 |
2330 | 2340 |
2331 // static | 2341 // static |
2332 Handle<HeapType> Map::GeneralizeFieldType(Handle<HeapType> type1, | 2342 Handle<HeapType> Map::GeneralizeFieldType(Handle<HeapType> type1, |
2333 Handle<HeapType> type2, | 2343 Handle<HeapType> type2, |
2334 Isolate* isolate) { | 2344 Isolate* isolate) { |
2335 if (type1->NowIs(type2)) return type2; | 2345 if (type1->NowIs(type2)) return type2; |
2336 if (type2->NowIs(type1)) return type1; | 2346 if (type2->NowIs(type1)) return type1; |
(...skipping 27 matching lines...) Expand all Loading... |
2364 Handle<DescriptorArray> descriptors( | 2374 Handle<DescriptorArray> descriptors( |
2365 field_owner->instance_descriptors(), isolate); | 2375 field_owner->instance_descriptors(), isolate); |
2366 DCHECK_EQ(*old_field_type, descriptors->GetFieldType(modify_index)); | 2376 DCHECK_EQ(*old_field_type, descriptors->GetFieldType(modify_index)); |
2367 | 2377 |
2368 // Determine the generalized new field type. | 2378 // Determine the generalized new field type. |
2369 new_field_type = Map::GeneralizeFieldType( | 2379 new_field_type = Map::GeneralizeFieldType( |
2370 old_field_type, new_field_type, isolate); | 2380 old_field_type, new_field_type, isolate); |
2371 | 2381 |
2372 PropertyDetails details = descriptors->GetDetails(modify_index); | 2382 PropertyDetails details = descriptors->GetDetails(modify_index); |
2373 Handle<Name> name(descriptors->GetKey(modify_index)); | 2383 Handle<Name> name(descriptors->GetKey(modify_index)); |
| 2384 |
| 2385 Handle<Object> wrapped_type(WrapType(new_field_type)); |
2374 field_owner->UpdateFieldType(modify_index, name, new_representation, | 2386 field_owner->UpdateFieldType(modify_index, name, new_representation, |
2375 new_field_type); | 2387 wrapped_type); |
2376 field_owner->dependent_code()->DeoptimizeDependentCodeGroup( | 2388 field_owner->dependent_code()->DeoptimizeDependentCodeGroup( |
2377 isolate, DependentCode::kFieldTypeGroup); | 2389 isolate, DependentCode::kFieldTypeGroup); |
2378 | 2390 |
2379 if (FLAG_trace_generalization) { | 2391 if (FLAG_trace_generalization) { |
2380 map->PrintGeneralization( | 2392 map->PrintGeneralization( |
2381 stdout, "field type generalization", | 2393 stdout, "field type generalization", |
2382 modify_index, map->NumberOfOwnDescriptors(), | 2394 modify_index, map->NumberOfOwnDescriptors(), |
2383 map->NumberOfOwnDescriptors(), false, | 2395 map->NumberOfOwnDescriptors(), false, |
2384 details.representation(), details.representation(), | 2396 details.representation(), details.representation(), |
2385 *old_field_type, *new_field_type); | 2397 *old_field_type, *new_field_type); |
(...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2757 next_field_type = | 2769 next_field_type = |
2758 GeneralizeFieldType(next_field_type, old_field_type, isolate); | 2770 GeneralizeFieldType(next_field_type, old_field_type, isolate); |
2759 } | 2771 } |
2760 } else { | 2772 } else { |
2761 Handle<HeapType> old_field_type = | 2773 Handle<HeapType> old_field_type = |
2762 GetFieldType(isolate, old_descriptors, i, old_details.location(), | 2774 GetFieldType(isolate, old_descriptors, i, old_details.location(), |
2763 next_representation); | 2775 next_representation); |
2764 next_field_type = | 2776 next_field_type = |
2765 GeneralizeFieldType(target_field_type, old_field_type, isolate); | 2777 GeneralizeFieldType(target_field_type, old_field_type, isolate); |
2766 } | 2778 } |
2767 DataDescriptor d(target_key, current_offset, next_field_type, | 2779 Handle<Object> wrapped_type(WrapType(next_field_type)); |
| 2780 DataDescriptor d(target_key, current_offset, wrapped_type, |
2768 next_attributes, next_representation); | 2781 next_attributes, next_representation); |
2769 current_offset += d.GetDetails().field_width_in_words(); | 2782 current_offset += d.GetDetails().field_width_in_words(); |
2770 new_descriptors->Set(i, &d); | 2783 new_descriptors->Set(i, &d); |
2771 } else { | 2784 } else { |
2772 UNIMPLEMENTED(); // TODO(ishell): implement. | 2785 UNIMPLEMENTED(); // TODO(ishell): implement. |
2773 } | 2786 } |
2774 } else { | 2787 } else { |
2775 PropertyDetails details(next_attributes, next_kind, next_location, | 2788 PropertyDetails details(next_attributes, next_kind, next_location, |
2776 next_representation); | 2789 next_representation); |
2777 Descriptor d(target_key, handle(target_descriptors->GetValue(i), isolate), | 2790 Descriptor d(target_key, handle(target_descriptors->GetValue(i), isolate), |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2825 next_field_type = | 2838 next_field_type = |
2826 GeneralizeFieldType(next_field_type, old_field_type, isolate); | 2839 GeneralizeFieldType(next_field_type, old_field_type, isolate); |
2827 } | 2840 } |
2828 } else { | 2841 } else { |
2829 Handle<HeapType> old_field_type = | 2842 Handle<HeapType> old_field_type = |
2830 GetFieldType(isolate, old_descriptors, i, old_details.location(), | 2843 GetFieldType(isolate, old_descriptors, i, old_details.location(), |
2831 next_representation); | 2844 next_representation); |
2832 next_field_type = old_field_type; | 2845 next_field_type = old_field_type; |
2833 } | 2846 } |
2834 | 2847 |
2835 DataDescriptor d(old_key, current_offset, next_field_type, | 2848 Handle<Object> wrapped_type(WrapType(next_field_type)); |
2836 next_attributes, next_representation); | 2849 |
| 2850 DataDescriptor d(old_key, current_offset, wrapped_type, next_attributes, |
| 2851 next_representation); |
2837 current_offset += d.GetDetails().field_width_in_words(); | 2852 current_offset += d.GetDetails().field_width_in_words(); |
2838 new_descriptors->Set(i, &d); | 2853 new_descriptors->Set(i, &d); |
2839 } else { | 2854 } else { |
2840 UNIMPLEMENTED(); // TODO(ishell): implement. | 2855 UNIMPLEMENTED(); // TODO(ishell): implement. |
2841 } | 2856 } |
2842 } else { | 2857 } else { |
2843 PropertyDetails details(next_attributes, next_kind, next_location, | 2858 PropertyDetails details(next_attributes, next_kind, next_location, |
2844 next_representation); | 2859 next_representation); |
2845 Descriptor d(old_key, handle(old_descriptors->GetValue(i), isolate), | 2860 Descriptor d(old_key, handle(old_descriptors->GetValue(i), isolate), |
2846 details); | 2861 details); |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2957 if (j == TransitionArray::kNotFound) return MaybeHandle<Map>(); | 2972 if (j == TransitionArray::kNotFound) return MaybeHandle<Map>(); |
2958 new_map = new_map->GetTransition(j); | 2973 new_map = new_map->GetTransition(j); |
2959 DescriptorArray* new_descriptors = new_map->instance_descriptors(); | 2974 DescriptorArray* new_descriptors = new_map->instance_descriptors(); |
2960 | 2975 |
2961 PropertyDetails new_details = new_descriptors->GetDetails(i); | 2976 PropertyDetails new_details = new_descriptors->GetDetails(i); |
2962 DCHECK_EQ(old_details.kind(), new_details.kind()); | 2977 DCHECK_EQ(old_details.kind(), new_details.kind()); |
2963 DCHECK_EQ(old_details.attributes(), new_details.attributes()); | 2978 DCHECK_EQ(old_details.attributes(), new_details.attributes()); |
2964 if (!old_details.representation().fits_into(new_details.representation())) { | 2979 if (!old_details.representation().fits_into(new_details.representation())) { |
2965 return MaybeHandle<Map>(); | 2980 return MaybeHandle<Map>(); |
2966 } | 2981 } |
2967 Object* new_value = new_descriptors->GetValue(i); | |
2968 Object* old_value = old_descriptors->GetValue(i); | |
2969 switch (new_details.type()) { | 2982 switch (new_details.type()) { |
2970 case DATA: { | 2983 case DATA: { |
2971 PropertyType old_type = old_details.type(); | 2984 HeapType* new_type = new_descriptors->GetFieldType(i); |
2972 if (old_type == DATA) { | 2985 PropertyType old_property_type = old_details.type(); |
2973 if (!HeapType::cast(old_value)->NowIs(HeapType::cast(new_value))) { | 2986 if (old_property_type == DATA) { |
| 2987 HeapType* old_type = old_descriptors->GetFieldType(i); |
| 2988 if (!old_type->NowIs(new_type)) { |
2974 return MaybeHandle<Map>(); | 2989 return MaybeHandle<Map>(); |
2975 } | 2990 } |
2976 } else { | 2991 } else { |
2977 DCHECK(old_type == DATA_CONSTANT); | 2992 DCHECK(old_property_type == DATA_CONSTANT); |
2978 if (!HeapType::cast(new_value)->NowContains(old_value)) { | 2993 Object* old_value = old_descriptors->GetValue(i); |
| 2994 if (!new_type->NowContains(old_value)) { |
2979 return MaybeHandle<Map>(); | 2995 return MaybeHandle<Map>(); |
2980 } | 2996 } |
2981 } | 2997 } |
2982 break; | 2998 break; |
2983 } | 2999 } |
2984 case ACCESSOR: | 3000 case ACCESSOR: { |
2985 DCHECK(HeapType::Any()->Is(HeapType::cast(new_value))); | 3001 #ifdef DEBUG |
| 3002 HeapType* new_type = new_descriptors->GetFieldType(i); |
| 3003 DCHECK(HeapType::Any()->Is(new_type)); |
| 3004 #endif |
2986 break; | 3005 break; |
| 3006 } |
2987 | 3007 |
2988 case DATA_CONSTANT: | 3008 case DATA_CONSTANT: |
2989 case ACCESSOR_CONSTANT: | 3009 case ACCESSOR_CONSTANT: { |
| 3010 Object* old_value = old_descriptors->GetValue(i); |
| 3011 Object* new_value = new_descriptors->GetValue(i); |
2990 if (old_details.location() == kField || old_value != new_value) { | 3012 if (old_details.location() == kField || old_value != new_value) { |
2991 return MaybeHandle<Map>(); | 3013 return MaybeHandle<Map>(); |
2992 } | 3014 } |
2993 break; | 3015 break; |
| 3016 } |
2994 } | 3017 } |
2995 } | 3018 } |
2996 if (new_map->NumberOfOwnDescriptors() != old_nof) return MaybeHandle<Map>(); | 3019 if (new_map->NumberOfOwnDescriptors() != old_nof) return MaybeHandle<Map>(); |
2997 return handle(new_map); | 3020 return handle(new_map); |
2998 } | 3021 } |
2999 | 3022 |
3000 | 3023 |
3001 // static | 3024 // static |
3002 Handle<Map> Map::Update(Handle<Map> map) { | 3025 Handle<Map> Map::Update(Handle<Map> map) { |
3003 if (!map->is_deprecated()) return map; | 3026 if (!map->is_deprecated()) return map; |
(...skipping 14132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
17136 CompilationInfo* info) { | 17159 CompilationInfo* info) { |
17137 Handle<DependentCode> codes = DependentCode::InsertCompilationInfo( | 17160 Handle<DependentCode> codes = DependentCode::InsertCompilationInfo( |
17138 handle(cell->dependent_code(), info->isolate()), | 17161 handle(cell->dependent_code(), info->isolate()), |
17139 DependentCode::kPropertyCellChangedGroup, info->object_wrapper()); | 17162 DependentCode::kPropertyCellChangedGroup, info->object_wrapper()); |
17140 if (*codes != cell->dependent_code()) cell->set_dependent_code(*codes); | 17163 if (*codes != cell->dependent_code()) cell->set_dependent_code(*codes); |
17141 info->dependencies(DependentCode::kPropertyCellChangedGroup)->Add( | 17164 info->dependencies(DependentCode::kPropertyCellChangedGroup)->Add( |
17142 cell, info->zone()); | 17165 cell, info->zone()); |
17143 } | 17166 } |
17144 | 17167 |
17145 } } // namespace v8::internal | 17168 } } // namespace v8::internal |
OLD | NEW |