Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3)

Side by Side Diff: src/objects.cc

Issue 1018283002: Reland "Fix memory leak caused by field type in descriptor array." (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Rebase Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/objects-debug.cc » ('j') | src/objects-debug.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698