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 1681 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1692 // If the constructor is not present, return "Object". | 1692 // If the constructor is not present, return "Object". |
1693 return GetHeap()->Object_string(); | 1693 return GetHeap()->Object_string(); |
1694 } | 1694 } |
1695 | 1695 |
1696 | 1696 |
1697 String* JSReceiver::constructor_name() { | 1697 String* JSReceiver::constructor_name() { |
1698 return map()->constructor_name(); | 1698 return map()->constructor_name(); |
1699 } | 1699 } |
1700 | 1700 |
1701 | 1701 |
| 1702 static Handle<Object> WrapType(Handle<HeapType> type) { |
| 1703 if (type->IsClass()) return Map::WeakCellForMap(type->AsClass()->Map()); |
| 1704 return type; |
| 1705 } |
| 1706 |
| 1707 |
1702 MaybeHandle<Map> Map::CopyWithField(Handle<Map> map, | 1708 MaybeHandle<Map> Map::CopyWithField(Handle<Map> map, |
1703 Handle<Name> name, | 1709 Handle<Name> name, |
1704 Handle<HeapType> type, | 1710 Handle<HeapType> type, |
1705 PropertyAttributes attributes, | 1711 PropertyAttributes attributes, |
1706 Representation representation, | 1712 Representation representation, |
1707 TransitionFlag flag) { | 1713 TransitionFlag flag) { |
1708 DCHECK(DescriptorArray::kNotFound == | 1714 DCHECK(DescriptorArray::kNotFound == |
1709 map->instance_descriptors()->Search( | 1715 map->instance_descriptors()->Search( |
1710 *name, map->NumberOfOwnDescriptors())); | 1716 *name, map->NumberOfOwnDescriptors())); |
1711 | 1717 |
1712 // Ensure the descriptor array does not get too big. | 1718 // Ensure the descriptor array does not get too big. |
1713 if (map->NumberOfOwnDescriptors() >= kMaxNumberOfDescriptors) { | 1719 if (map->NumberOfOwnDescriptors() >= kMaxNumberOfDescriptors) { |
1714 return MaybeHandle<Map>(); | 1720 return MaybeHandle<Map>(); |
1715 } | 1721 } |
1716 | 1722 |
1717 Isolate* isolate = map->GetIsolate(); | 1723 Isolate* isolate = map->GetIsolate(); |
1718 | 1724 |
1719 // Compute the new index for new field. | 1725 // Compute the new index for new field. |
1720 int index = map->NextFreePropertyIndex(); | 1726 int index = map->NextFreePropertyIndex(); |
1721 | 1727 |
1722 if (map->instance_type() == JS_CONTEXT_EXTENSION_OBJECT_TYPE) { | 1728 if (map->instance_type() == JS_CONTEXT_EXTENSION_OBJECT_TYPE) { |
1723 representation = Representation::Tagged(); | 1729 representation = Representation::Tagged(); |
1724 type = HeapType::Any(isolate); | 1730 type = HeapType::Any(isolate); |
1725 } | 1731 } |
1726 | 1732 |
1727 DataDescriptor new_field_desc(name, index, type, attributes, representation); | 1733 Handle<Object> wrapped_type(WrapType(type)); |
| 1734 |
| 1735 DataDescriptor new_field_desc(name, index, wrapped_type, attributes, |
| 1736 representation); |
1728 Handle<Map> new_map = Map::CopyAddDescriptor(map, &new_field_desc, flag); | 1737 Handle<Map> new_map = Map::CopyAddDescriptor(map, &new_field_desc, flag); |
1729 int unused_property_fields = new_map->unused_property_fields() - 1; | 1738 int unused_property_fields = new_map->unused_property_fields() - 1; |
1730 if (unused_property_fields < 0) { | 1739 if (unused_property_fields < 0) { |
1731 unused_property_fields += JSObject::kFieldsAdded; | 1740 unused_property_fields += JSObject::kFieldsAdded; |
1732 } | 1741 } |
1733 new_map->set_unused_property_fields(unused_property_fields); | 1742 new_map->set_unused_property_fields(unused_property_fields); |
1734 return new_map; | 1743 return new_map; |
1735 } | 1744 } |
1736 | 1745 |
1737 | 1746 |
(...skipping 553 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2291 Map* parent = Map::cast(back); | 2300 Map* parent = Map::cast(back); |
2292 if (parent->NumberOfOwnDescriptors() <= descriptor) break; | 2301 if (parent->NumberOfOwnDescriptors() <= descriptor) break; |
2293 result = parent; | 2302 result = parent; |
2294 } | 2303 } |
2295 return result; | 2304 return result; |
2296 } | 2305 } |
2297 | 2306 |
2298 | 2307 |
2299 void Map::UpdateFieldType(int descriptor, Handle<Name> name, | 2308 void Map::UpdateFieldType(int descriptor, Handle<Name> name, |
2300 Representation new_representation, | 2309 Representation new_representation, |
2301 Handle<HeapType> new_type) { | 2310 Handle<Object> new_wrapped_type) { |
| 2311 DCHECK(new_wrapped_type->IsSmi() || new_wrapped_type->IsWeakCell()); |
2302 DisallowHeapAllocation no_allocation; | 2312 DisallowHeapAllocation no_allocation; |
2303 PropertyDetails details = instance_descriptors()->GetDetails(descriptor); | 2313 PropertyDetails details = instance_descriptors()->GetDetails(descriptor); |
2304 if (details.type() != DATA) return; | 2314 if (details.type() != DATA) return; |
2305 Object* transitions = raw_transitions(); | 2315 Object* transitions = raw_transitions(); |
2306 int num_transitions = TransitionArray::NumberOfTransitions(transitions); | 2316 int num_transitions = TransitionArray::NumberOfTransitions(transitions); |
2307 for (int i = 0; i < num_transitions; ++i) { | 2317 for (int i = 0; i < num_transitions; ++i) { |
2308 Map* target = TransitionArray::GetTarget(transitions, i); | 2318 Map* target = TransitionArray::GetTarget(transitions, i); |
2309 target->UpdateFieldType(descriptor, name, new_representation, new_type); | 2319 target->UpdateFieldType(descriptor, name, new_representation, |
| 2320 new_wrapped_type); |
2310 } | 2321 } |
2311 // It is allowed to change representation here only from None to something. | 2322 // It is allowed to change representation here only from None to something. |
2312 DCHECK(details.representation().Equals(new_representation) || | 2323 DCHECK(details.representation().Equals(new_representation) || |
2313 details.representation().IsNone()); | 2324 details.representation().IsNone()); |
2314 | 2325 |
2315 // Skip if already updated the shared descriptor. | 2326 // Skip if already updated the shared descriptor. |
2316 if (instance_descriptors()->GetFieldType(descriptor) == *new_type) return; | 2327 if (instance_descriptors()->GetValue(descriptor) == *new_wrapped_type) return; |
2317 DataDescriptor d(name, instance_descriptors()->GetFieldIndex(descriptor), | 2328 DataDescriptor d(name, instance_descriptors()->GetFieldIndex(descriptor), |
2318 new_type, details.attributes(), new_representation); | 2329 new_wrapped_type, details.attributes(), new_representation); |
2319 instance_descriptors()->Replace(descriptor, &d); | 2330 instance_descriptors()->Replace(descriptor, &d); |
2320 } | 2331 } |
2321 | 2332 |
2322 | 2333 |
2323 // static | 2334 // static |
2324 Handle<HeapType> Map::GeneralizeFieldType(Handle<HeapType> type1, | 2335 Handle<HeapType> Map::GeneralizeFieldType(Handle<HeapType> type1, |
2325 Handle<HeapType> type2, | 2336 Handle<HeapType> type2, |
2326 Isolate* isolate) { | 2337 Isolate* isolate) { |
2327 if (type1->NowIs(type2)) return type2; | 2338 if (type1->NowIs(type2)) return type2; |
2328 if (type2->NowIs(type1)) return type1; | 2339 if (type2->NowIs(type1)) return type1; |
(...skipping 27 matching lines...) Expand all Loading... |
2356 Handle<DescriptorArray> descriptors( | 2367 Handle<DescriptorArray> descriptors( |
2357 field_owner->instance_descriptors(), isolate); | 2368 field_owner->instance_descriptors(), isolate); |
2358 DCHECK_EQ(*old_field_type, descriptors->GetFieldType(modify_index)); | 2369 DCHECK_EQ(*old_field_type, descriptors->GetFieldType(modify_index)); |
2359 | 2370 |
2360 // Determine the generalized new field type. | 2371 // Determine the generalized new field type. |
2361 new_field_type = Map::GeneralizeFieldType( | 2372 new_field_type = Map::GeneralizeFieldType( |
2362 old_field_type, new_field_type, isolate); | 2373 old_field_type, new_field_type, isolate); |
2363 | 2374 |
2364 PropertyDetails details = descriptors->GetDetails(modify_index); | 2375 PropertyDetails details = descriptors->GetDetails(modify_index); |
2365 Handle<Name> name(descriptors->GetKey(modify_index)); | 2376 Handle<Name> name(descriptors->GetKey(modify_index)); |
| 2377 |
| 2378 Handle<Object> wrapped_type(WrapType(new_field_type)); |
2366 field_owner->UpdateFieldType(modify_index, name, new_representation, | 2379 field_owner->UpdateFieldType(modify_index, name, new_representation, |
2367 new_field_type); | 2380 wrapped_type); |
2368 field_owner->dependent_code()->DeoptimizeDependentCodeGroup( | 2381 field_owner->dependent_code()->DeoptimizeDependentCodeGroup( |
2369 isolate, DependentCode::kFieldTypeGroup); | 2382 isolate, DependentCode::kFieldTypeGroup); |
2370 | 2383 |
2371 if (FLAG_trace_generalization) { | 2384 if (FLAG_trace_generalization) { |
2372 map->PrintGeneralization( | 2385 map->PrintGeneralization( |
2373 stdout, "field type generalization", | 2386 stdout, "field type generalization", |
2374 modify_index, map->NumberOfOwnDescriptors(), | 2387 modify_index, map->NumberOfOwnDescriptors(), |
2375 map->NumberOfOwnDescriptors(), false, | 2388 map->NumberOfOwnDescriptors(), false, |
2376 details.representation(), details.representation(), | 2389 details.representation(), details.representation(), |
2377 *old_field_type, *new_field_type); | 2390 *old_field_type, *new_field_type); |
(...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2750 next_field_type = | 2763 next_field_type = |
2751 GeneralizeFieldType(next_field_type, old_field_type, isolate); | 2764 GeneralizeFieldType(next_field_type, old_field_type, isolate); |
2752 } | 2765 } |
2753 } else { | 2766 } else { |
2754 Handle<HeapType> old_field_type = | 2767 Handle<HeapType> old_field_type = |
2755 GetFieldType(isolate, old_descriptors, i, old_details.location(), | 2768 GetFieldType(isolate, old_descriptors, i, old_details.location(), |
2756 next_representation); | 2769 next_representation); |
2757 next_field_type = | 2770 next_field_type = |
2758 GeneralizeFieldType(target_field_type, old_field_type, isolate); | 2771 GeneralizeFieldType(target_field_type, old_field_type, isolate); |
2759 } | 2772 } |
2760 DataDescriptor d(target_key, current_offset, next_field_type, | 2773 Handle<Object> wrapped_type(WrapType(next_field_type)); |
| 2774 DataDescriptor d(target_key, current_offset, wrapped_type, |
2761 next_attributes, next_representation); | 2775 next_attributes, next_representation); |
2762 current_offset += d.GetDetails().field_width_in_words(); | 2776 current_offset += d.GetDetails().field_width_in_words(); |
2763 new_descriptors->Set(i, &d); | 2777 new_descriptors->Set(i, &d); |
2764 } else { | 2778 } else { |
2765 UNIMPLEMENTED(); // TODO(ishell): implement. | 2779 UNIMPLEMENTED(); // TODO(ishell): implement. |
2766 } | 2780 } |
2767 } else { | 2781 } else { |
2768 PropertyDetails details(next_attributes, next_kind, next_location, | 2782 PropertyDetails details(next_attributes, next_kind, next_location, |
2769 next_representation); | 2783 next_representation); |
2770 Descriptor d(target_key, handle(target_descriptors->GetValue(i), isolate), | 2784 Descriptor d(target_key, handle(target_descriptors->GetValue(i), isolate), |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2818 next_field_type = | 2832 next_field_type = |
2819 GeneralizeFieldType(next_field_type, old_field_type, isolate); | 2833 GeneralizeFieldType(next_field_type, old_field_type, isolate); |
2820 } | 2834 } |
2821 } else { | 2835 } else { |
2822 Handle<HeapType> old_field_type = | 2836 Handle<HeapType> old_field_type = |
2823 GetFieldType(isolate, old_descriptors, i, old_details.location(), | 2837 GetFieldType(isolate, old_descriptors, i, old_details.location(), |
2824 next_representation); | 2838 next_representation); |
2825 next_field_type = old_field_type; | 2839 next_field_type = old_field_type; |
2826 } | 2840 } |
2827 | 2841 |
2828 DataDescriptor d(old_key, current_offset, next_field_type, | 2842 Handle<Object> wrapped_type(WrapType(next_field_type)); |
2829 next_attributes, next_representation); | 2843 |
| 2844 DataDescriptor d(old_key, current_offset, wrapped_type, next_attributes, |
| 2845 next_representation); |
2830 current_offset += d.GetDetails().field_width_in_words(); | 2846 current_offset += d.GetDetails().field_width_in_words(); |
2831 new_descriptors->Set(i, &d); | 2847 new_descriptors->Set(i, &d); |
2832 } else { | 2848 } else { |
2833 UNIMPLEMENTED(); // TODO(ishell): implement. | 2849 UNIMPLEMENTED(); // TODO(ishell): implement. |
2834 } | 2850 } |
2835 } else { | 2851 } else { |
2836 PropertyDetails details(next_attributes, next_kind, next_location, | 2852 PropertyDetails details(next_attributes, next_kind, next_location, |
2837 next_representation); | 2853 next_representation); |
2838 Descriptor d(old_key, handle(old_descriptors->GetValue(i), isolate), | 2854 Descriptor d(old_key, handle(old_descriptors->GetValue(i), isolate), |
2839 details); | 2855 details); |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2951 if (transition == NULL) return MaybeHandle<Map>(); | 2967 if (transition == NULL) return MaybeHandle<Map>(); |
2952 new_map = transition; | 2968 new_map = transition; |
2953 DescriptorArray* new_descriptors = new_map->instance_descriptors(); | 2969 DescriptorArray* new_descriptors = new_map->instance_descriptors(); |
2954 | 2970 |
2955 PropertyDetails new_details = new_descriptors->GetDetails(i); | 2971 PropertyDetails new_details = new_descriptors->GetDetails(i); |
2956 DCHECK_EQ(old_details.kind(), new_details.kind()); | 2972 DCHECK_EQ(old_details.kind(), new_details.kind()); |
2957 DCHECK_EQ(old_details.attributes(), new_details.attributes()); | 2973 DCHECK_EQ(old_details.attributes(), new_details.attributes()); |
2958 if (!old_details.representation().fits_into(new_details.representation())) { | 2974 if (!old_details.representation().fits_into(new_details.representation())) { |
2959 return MaybeHandle<Map>(); | 2975 return MaybeHandle<Map>(); |
2960 } | 2976 } |
2961 Object* new_value = new_descriptors->GetValue(i); | |
2962 Object* old_value = old_descriptors->GetValue(i); | |
2963 switch (new_details.type()) { | 2977 switch (new_details.type()) { |
2964 case DATA: { | 2978 case DATA: { |
2965 PropertyType old_type = old_details.type(); | 2979 HeapType* new_type = new_descriptors->GetFieldType(i); |
2966 if (old_type == DATA) { | 2980 PropertyType old_property_type = old_details.type(); |
2967 if (!HeapType::cast(old_value)->NowIs(HeapType::cast(new_value))) { | 2981 if (old_property_type == DATA) { |
| 2982 HeapType* old_type = old_descriptors->GetFieldType(i); |
| 2983 if (!old_type->NowIs(new_type)) { |
2968 return MaybeHandle<Map>(); | 2984 return MaybeHandle<Map>(); |
2969 } | 2985 } |
2970 } else { | 2986 } else { |
2971 DCHECK(old_type == DATA_CONSTANT); | 2987 DCHECK(old_property_type == DATA_CONSTANT); |
2972 if (!HeapType::cast(new_value)->NowContains(old_value)) { | 2988 Object* old_value = old_descriptors->GetValue(i); |
| 2989 if (!new_type->NowContains(old_value)) { |
2973 return MaybeHandle<Map>(); | 2990 return MaybeHandle<Map>(); |
2974 } | 2991 } |
2975 } | 2992 } |
2976 break; | 2993 break; |
2977 } | 2994 } |
2978 case ACCESSOR: | 2995 case ACCESSOR: { |
2979 DCHECK(HeapType::Any()->Is(HeapType::cast(new_value))); | 2996 #ifdef DEBUG |
| 2997 HeapType* new_type = new_descriptors->GetFieldType(i); |
| 2998 DCHECK(HeapType::Any()->Is(new_type)); |
| 2999 #endif |
2980 break; | 3000 break; |
| 3001 } |
2981 | 3002 |
2982 case DATA_CONSTANT: | 3003 case DATA_CONSTANT: |
2983 case ACCESSOR_CONSTANT: | 3004 case ACCESSOR_CONSTANT: { |
| 3005 Object* old_value = old_descriptors->GetValue(i); |
| 3006 Object* new_value = new_descriptors->GetValue(i); |
2984 if (old_details.location() == kField || old_value != new_value) { | 3007 if (old_details.location() == kField || old_value != new_value) { |
2985 return MaybeHandle<Map>(); | 3008 return MaybeHandle<Map>(); |
2986 } | 3009 } |
2987 break; | 3010 break; |
| 3011 } |
2988 } | 3012 } |
2989 } | 3013 } |
2990 if (new_map->NumberOfOwnDescriptors() != old_nof) return MaybeHandle<Map>(); | 3014 if (new_map->NumberOfOwnDescriptors() != old_nof) return MaybeHandle<Map>(); |
2991 return handle(new_map); | 3015 return handle(new_map); |
2992 } | 3016 } |
2993 | 3017 |
2994 | 3018 |
2995 // static | 3019 // static |
2996 Handle<Map> Map::Update(Handle<Map> map) { | 3020 Handle<Map> Map::Update(Handle<Map> map) { |
2997 if (!map->is_deprecated()) return map; | 3021 if (!map->is_deprecated()) return map; |
(...skipping 14086 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
17084 CompilationInfo* info) { | 17108 CompilationInfo* info) { |
17085 Handle<DependentCode> codes = DependentCode::InsertCompilationInfo( | 17109 Handle<DependentCode> codes = DependentCode::InsertCompilationInfo( |
17086 handle(cell->dependent_code(), info->isolate()), | 17110 handle(cell->dependent_code(), info->isolate()), |
17087 DependentCode::kPropertyCellChangedGroup, info->object_wrapper()); | 17111 DependentCode::kPropertyCellChangedGroup, info->object_wrapper()); |
17088 if (*codes != cell->dependent_code()) cell->set_dependent_code(*codes); | 17112 if (*codes != cell->dependent_code()) cell->set_dependent_code(*codes); |
17089 info->dependencies(DependentCode::kPropertyCellChangedGroup)->Add( | 17113 info->dependencies(DependentCode::kPropertyCellChangedGroup)->Add( |
17090 cell, info->zone()); | 17114 cell, info->zone()); |
17091 } | 17115 } |
17092 | 17116 |
17093 } } // namespace v8::internal | 17117 } } // namespace v8::internal |
OLD | NEW |