OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 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 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
63 #define WRITE_TYPE(TYPE) \ | 63 #define WRITE_TYPE(TYPE) \ |
64 case TYPE: \ | 64 case TYPE: \ |
65 return os << #TYPE; | 65 return os << #TYPE; |
66 INSTANCE_TYPE_LIST(WRITE_TYPE) | 66 INSTANCE_TYPE_LIST(WRITE_TYPE) |
67 #undef WRITE_TYPE | 67 #undef WRITE_TYPE |
68 } | 68 } |
69 UNREACHABLE(); | 69 UNREACHABLE(); |
70 return os << "UNKNOWN"; // Keep the compiler happy. | 70 return os << "UNKNOWN"; // Keep the compiler happy. |
71 } | 71 } |
72 | 72 |
73 | 73 Handle<FieldType> Object::OptimalType(Isolate* isolate, |
74 Handle<HeapType> Object::OptimalType(Isolate* isolate, | 74 Representation representation) { |
75 Representation representation) { | 75 if (representation.IsNone()) return FieldType::None(isolate); |
76 if (representation.IsNone()) return HeapType::None(isolate); | |
77 if (FLAG_track_field_types) { | 76 if (FLAG_track_field_types) { |
78 if (representation.IsHeapObject() && IsHeapObject()) { | 77 if (representation.IsHeapObject() && IsHeapObject()) { |
79 // We can track only JavaScript objects with stable maps. | 78 // We can track only JavaScript objects with stable maps. |
80 Handle<Map> map(HeapObject::cast(this)->map(), isolate); | 79 Handle<Map> map(HeapObject::cast(this)->map(), isolate); |
81 if (map->is_stable() && map->IsJSReceiverMap()) { | 80 if (map->is_stable() && map->IsJSReceiverMap()) { |
82 return HeapType::Class(map, isolate); | 81 return FieldType::Class(map, isolate); |
83 } | 82 } |
84 } | 83 } |
85 } | 84 } |
86 return HeapType::Any(isolate); | 85 return FieldType::Any(isolate); |
87 } | 86 } |
88 | 87 |
89 | 88 |
90 MaybeHandle<JSReceiver> Object::ToObject(Isolate* isolate, | 89 MaybeHandle<JSReceiver> Object::ToObject(Isolate* isolate, |
91 Handle<Object> object, | 90 Handle<Object> object, |
92 Handle<Context> native_context) { | 91 Handle<Context> native_context) { |
93 if (object->IsJSReceiver()) return Handle<JSReceiver>::cast(object); | 92 if (object->IsJSReceiver()) return Handle<JSReceiver>::cast(object); |
94 Handle<JSFunction> constructor; | 93 Handle<JSFunction> constructor; |
95 if (object->IsSmi()) { | 94 if (object->IsSmi()) { |
96 constructor = handle(native_context->number_function(), isolate); | 95 constructor = handle(native_context->number_function(), isolate); |
(...skipping 2001 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2098 String::cast(name)->PrintOn(file); | 2097 String::cast(name)->PrintOn(file); |
2099 } else { | 2098 } else { |
2100 os << "{symbol " << static_cast<void*>(name) << "}"; | 2099 os << "{symbol " << static_cast<void*>(name) << "}"; |
2101 } | 2100 } |
2102 os << ": " << (kind == kData ? "kData" : "ACCESSORS") << ", attrs: "; | 2101 os << ": " << (kind == kData ? "kData" : "ACCESSORS") << ", attrs: "; |
2103 os << attributes << " ["; | 2102 os << attributes << " ["; |
2104 JavaScriptFrame::PrintTop(GetIsolate(), file, false, true); | 2103 JavaScriptFrame::PrintTop(GetIsolate(), file, false, true); |
2105 os << "]\n"; | 2104 os << "]\n"; |
2106 } | 2105 } |
2107 | 2106 |
2108 | 2107 void Map::PrintGeneralization( |
2109 void Map::PrintGeneralization(FILE* file, | 2108 FILE* file, const char* reason, int modify_index, int split, |
2110 const char* reason, | 2109 int descriptors, bool constant_to_field, Representation old_representation, |
2111 int modify_index, | 2110 Representation new_representation, MaybeHandle<FieldType> old_field_type, |
2112 int split, | 2111 MaybeHandle<Object> old_value, MaybeHandle<FieldType> new_field_type, |
2113 int descriptors, | 2112 MaybeHandle<Object> new_value) { |
2114 bool constant_to_field, | |
2115 Representation old_representation, | |
2116 Representation new_representation, | |
2117 HeapType* old_field_type, | |
2118 HeapType* new_field_type) { | |
2119 OFStream os(file); | 2113 OFStream os(file); |
2120 os << "[generalizing]"; | 2114 os << "[generalizing]"; |
2121 Name* name = instance_descriptors()->GetKey(modify_index); | 2115 Name* name = instance_descriptors()->GetKey(modify_index); |
2122 if (name->IsString()) { | 2116 if (name->IsString()) { |
2123 String::cast(name)->PrintOn(file); | 2117 String::cast(name)->PrintOn(file); |
2124 } else { | 2118 } else { |
2125 os << "{symbol " << static_cast<void*>(name) << "}"; | 2119 os << "{symbol " << static_cast<void*>(name) << "}"; |
2126 } | 2120 } |
2127 os << ":"; | 2121 os << ":"; |
2128 if (constant_to_field) { | 2122 if (constant_to_field) { |
2129 os << "c"; | 2123 os << "c"; |
2130 } else { | 2124 } else { |
2131 os << old_representation.Mnemonic() << "{"; | 2125 os << old_representation.Mnemonic() << "{"; |
2132 old_field_type->PrintTo(os, HeapType::SEMANTIC_DIM); | 2126 if (old_field_type.is_null()) { |
| 2127 os << Brief(*(old_value.ToHandleChecked())); |
| 2128 } else { |
| 2129 old_field_type.ToHandleChecked()->PrintTo(os); |
| 2130 } |
2133 os << "}"; | 2131 os << "}"; |
2134 } | 2132 } |
2135 os << "->" << new_representation.Mnemonic() << "{"; | 2133 os << "->" << new_representation.Mnemonic() << "{"; |
2136 new_field_type->PrintTo(os, HeapType::SEMANTIC_DIM); | 2134 if (new_field_type.is_null()) { |
| 2135 os << Brief(*(new_value.ToHandleChecked())); |
| 2136 } else { |
| 2137 new_field_type.ToHandleChecked()->PrintTo(os); |
| 2138 } |
2137 os << "} ("; | 2139 os << "} ("; |
2138 if (strlen(reason) > 0) { | 2140 if (strlen(reason) > 0) { |
2139 os << reason; | 2141 os << reason; |
2140 } else { | 2142 } else { |
2141 os << "+" << (descriptors - split) << " maps"; | 2143 os << "+" << (descriptors - split) << " maps"; |
2142 } | 2144 } |
2143 os << ") ["; | 2145 os << ") ["; |
2144 JavaScriptFrame::PrintTop(GetIsolate(), file, false, true); | 2146 JavaScriptFrame::PrintTop(GetIsolate(), file, false, true); |
2145 os << "]\n"; | 2147 os << "]\n"; |
2146 } | 2148 } |
(...skipping 434 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2581 } else { | 2583 } else { |
2582 // Functions have null as a constructor, | 2584 // Functions have null as a constructor, |
2583 // but any JSFunction knows its context immediately. | 2585 // but any JSFunction knows its context immediately. |
2584 CHECK(receiver->IsJSFunction()); | 2586 CHECK(receiver->IsJSFunction()); |
2585 function = JSFunction::cast(receiver); | 2587 function = JSFunction::cast(receiver); |
2586 } | 2588 } |
2587 | 2589 |
2588 return function->context()->native_context(); | 2590 return function->context()->native_context(); |
2589 } | 2591 } |
2590 | 2592 |
2591 | 2593 static Handle<Object> WrapType(Handle<FieldType> type) { |
2592 static Handle<Object> WrapType(Handle<HeapType> type) { | 2594 if (type->IsClass()) return Map::WeakCellForMap(type->AsClass()); |
2593 if (type->IsClass()) return Map::WeakCellForMap(type->AsClass()->Map()); | |
2594 return type; | 2595 return type; |
2595 } | 2596 } |
2596 | 2597 |
2597 | 2598 MaybeHandle<Map> Map::CopyWithField(Handle<Map> map, Handle<Name> name, |
2598 MaybeHandle<Map> Map::CopyWithField(Handle<Map> map, | 2599 Handle<FieldType> type, |
2599 Handle<Name> name, | |
2600 Handle<HeapType> type, | |
2601 PropertyAttributes attributes, | 2600 PropertyAttributes attributes, |
2602 Representation representation, | 2601 Representation representation, |
2603 TransitionFlag flag) { | 2602 TransitionFlag flag) { |
2604 DCHECK(DescriptorArray::kNotFound == | 2603 DCHECK(DescriptorArray::kNotFound == |
2605 map->instance_descriptors()->Search( | 2604 map->instance_descriptors()->Search( |
2606 *name, map->NumberOfOwnDescriptors())); | 2605 *name, map->NumberOfOwnDescriptors())); |
2607 | 2606 |
2608 // Ensure the descriptor array does not get too big. | 2607 // Ensure the descriptor array does not get too big. |
2609 if (map->NumberOfOwnDescriptors() >= kMaxNumberOfDescriptors) { | 2608 if (map->NumberOfOwnDescriptors() >= kMaxNumberOfDescriptors) { |
2610 return MaybeHandle<Map>(); | 2609 return MaybeHandle<Map>(); |
2611 } | 2610 } |
2612 | 2611 |
2613 Isolate* isolate = map->GetIsolate(); | 2612 Isolate* isolate = map->GetIsolate(); |
2614 | 2613 |
2615 // Compute the new index for new field. | 2614 // Compute the new index for new field. |
2616 int index = map->NextFreePropertyIndex(); | 2615 int index = map->NextFreePropertyIndex(); |
2617 | 2616 |
2618 if (map->instance_type() == JS_CONTEXT_EXTENSION_OBJECT_TYPE) { | 2617 if (map->instance_type() == JS_CONTEXT_EXTENSION_OBJECT_TYPE) { |
2619 representation = Representation::Tagged(); | 2618 representation = Representation::Tagged(); |
2620 type = HeapType::Any(isolate); | 2619 type = FieldType::Any(isolate); |
2621 } | 2620 } |
2622 | 2621 |
2623 Handle<Object> wrapped_type(WrapType(type)); | 2622 Handle<Object> wrapped_type(WrapType(type)); |
2624 | 2623 |
2625 DataDescriptor new_field_desc(name, index, wrapped_type, attributes, | 2624 DataDescriptor new_field_desc(name, index, wrapped_type, attributes, |
2626 representation); | 2625 representation); |
2627 Handle<Map> new_map = Map::CopyAddDescriptor(map, &new_field_desc, flag); | 2626 Handle<Map> new_map = Map::CopyAddDescriptor(map, &new_field_desc, flag); |
2628 int unused_property_fields = new_map->unused_property_fields() - 1; | 2627 int unused_property_fields = new_map->unused_property_fields() - 1; |
2629 if (unused_property_fields < 0) { | 2628 if (unused_property_fields < 0) { |
2630 unused_property_fields += JSObject::kFieldsAdded; | 2629 unused_property_fields += JSObject::kFieldsAdded; |
(...skipping 425 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3056 PropertyAttributes attributes, const char* reason) { | 3055 PropertyAttributes attributes, const char* reason) { |
3057 Isolate* isolate = map->GetIsolate(); | 3056 Isolate* isolate = map->GetIsolate(); |
3058 Handle<DescriptorArray> old_descriptors(map->instance_descriptors(), isolate); | 3057 Handle<DescriptorArray> old_descriptors(map->instance_descriptors(), isolate); |
3059 int number_of_own_descriptors = map->NumberOfOwnDescriptors(); | 3058 int number_of_own_descriptors = map->NumberOfOwnDescriptors(); |
3060 Handle<DescriptorArray> descriptors = | 3059 Handle<DescriptorArray> descriptors = |
3061 DescriptorArray::CopyUpTo(old_descriptors, number_of_own_descriptors); | 3060 DescriptorArray::CopyUpTo(old_descriptors, number_of_own_descriptors); |
3062 | 3061 |
3063 for (int i = 0; i < number_of_own_descriptors; i++) { | 3062 for (int i = 0; i < number_of_own_descriptors; i++) { |
3064 descriptors->SetRepresentation(i, Representation::Tagged()); | 3063 descriptors->SetRepresentation(i, Representation::Tagged()); |
3065 if (descriptors->GetDetails(i).type() == DATA) { | 3064 if (descriptors->GetDetails(i).type() == DATA) { |
3066 descriptors->SetValue(i, HeapType::Any()); | 3065 descriptors->SetValue(i, FieldType::Any()); |
3067 } | 3066 } |
3068 } | 3067 } |
3069 | 3068 |
3070 Handle<LayoutDescriptor> new_layout_descriptor( | 3069 Handle<LayoutDescriptor> new_layout_descriptor( |
3071 LayoutDescriptor::FastPointerLayout(), isolate); | 3070 LayoutDescriptor::FastPointerLayout(), isolate); |
3072 Handle<Map> new_map = CopyReplaceDescriptors( | 3071 Handle<Map> new_map = CopyReplaceDescriptors( |
3073 map, descriptors, new_layout_descriptor, OMIT_TRANSITION, | 3072 map, descriptors, new_layout_descriptor, OMIT_TRANSITION, |
3074 MaybeHandle<Name>(), reason, SPECIAL_TRANSITION); | 3073 MaybeHandle<Name>(), reason, SPECIAL_TRANSITION); |
3075 | 3074 |
3076 // Unless the instance is being migrated, ensure that modify_index is a field. | 3075 // Unless the instance is being migrated, ensure that modify_index is a field. |
(...skipping 11 matching lines...) Expand all Loading... |
3088 if (unused_property_fields < 0) { | 3087 if (unused_property_fields < 0) { |
3089 unused_property_fields += JSObject::kFieldsAdded; | 3088 unused_property_fields += JSObject::kFieldsAdded; |
3090 } | 3089 } |
3091 new_map->set_unused_property_fields(unused_property_fields); | 3090 new_map->set_unused_property_fields(unused_property_fields); |
3092 } | 3091 } |
3093 } else { | 3092 } else { |
3094 DCHECK(details.attributes() == attributes); | 3093 DCHECK(details.attributes() == attributes); |
3095 } | 3094 } |
3096 | 3095 |
3097 if (FLAG_trace_generalization) { | 3096 if (FLAG_trace_generalization) { |
3098 HeapType* field_type = | 3097 MaybeHandle<FieldType> field_type = FieldType::None(isolate); |
3099 (details.type() == DATA) | 3098 if (details.type() == DATA) { |
3100 ? map->instance_descriptors()->GetFieldType(modify_index) | 3099 field_type = handle( |
3101 : NULL; | 3100 map->instance_descriptors()->GetFieldType(modify_index), isolate); |
| 3101 } |
3102 map->PrintGeneralization( | 3102 map->PrintGeneralization( |
3103 stdout, reason, modify_index, new_map->NumberOfOwnDescriptors(), | 3103 stdout, reason, modify_index, new_map->NumberOfOwnDescriptors(), |
3104 new_map->NumberOfOwnDescriptors(), | 3104 new_map->NumberOfOwnDescriptors(), |
3105 details.type() == DATA_CONSTANT && store_mode == FORCE_FIELD, | 3105 details.type() == DATA_CONSTANT && store_mode == FORCE_FIELD, |
3106 details.representation(), Representation::Tagged(), field_type, | 3106 details.representation(), Representation::Tagged(), field_type, |
3107 HeapType::Any()); | 3107 MaybeHandle<Object>(), FieldType::Any(isolate), |
| 3108 MaybeHandle<Object>()); |
3108 } | 3109 } |
3109 } | 3110 } |
3110 return new_map; | 3111 return new_map; |
3111 } | 3112 } |
3112 | 3113 |
3113 | 3114 |
3114 void Map::DeprecateTransitionTree() { | 3115 void Map::DeprecateTransitionTree() { |
3115 if (is_deprecated()) return; | 3116 if (is_deprecated()) return; |
3116 Object* transitions = raw_transitions(); | 3117 Object* transitions = raw_transitions(); |
3117 int num_transitions = TransitionArray::NumberOfTransitions(transitions); | 3118 int num_transitions = TransitionArray::NumberOfTransitions(transitions); |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3190 if (next == NULL) break; | 3191 if (next == NULL) break; |
3191 DescriptorArray* next_descriptors = next->instance_descriptors(); | 3192 DescriptorArray* next_descriptors = next->instance_descriptors(); |
3192 | 3193 |
3193 PropertyDetails next_details = next_descriptors->GetDetails(i); | 3194 PropertyDetails next_details = next_descriptors->GetDetails(i); |
3194 DCHECK_EQ(details.kind(), next_details.kind()); | 3195 DCHECK_EQ(details.kind(), next_details.kind()); |
3195 DCHECK_EQ(details.attributes(), next_details.attributes()); | 3196 DCHECK_EQ(details.attributes(), next_details.attributes()); |
3196 if (details.location() != next_details.location()) break; | 3197 if (details.location() != next_details.location()) break; |
3197 if (!details.representation().Equals(next_details.representation())) break; | 3198 if (!details.representation().Equals(next_details.representation())) break; |
3198 | 3199 |
3199 if (next_details.location() == kField) { | 3200 if (next_details.location() == kField) { |
3200 HeapType* next_field_type = next_descriptors->GetFieldType(i); | 3201 FieldType* next_field_type = next_descriptors->GetFieldType(i); |
3201 if (!descriptors->GetFieldType(i)->NowIs(next_field_type)) { | 3202 if (!descriptors->GetFieldType(i)->NowIs(next_field_type)) { |
3202 break; | 3203 break; |
3203 } | 3204 } |
3204 } else { | 3205 } else { |
3205 if (!EqualImmutableValues(descriptors->GetValue(i), | 3206 if (!EqualImmutableValues(descriptors->GetValue(i), |
3206 next_descriptors->GetValue(i))) { | 3207 next_descriptors->GetValue(i))) { |
3207 break; | 3208 break; |
3208 } | 3209 } |
3209 } | 3210 } |
3210 current = next; | 3211 current = next; |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3246 DCHECK(details.representation().Equals(new_representation) || | 3247 DCHECK(details.representation().Equals(new_representation) || |
3247 details.representation().IsNone()); | 3248 details.representation().IsNone()); |
3248 | 3249 |
3249 // Skip if already updated the shared descriptor. | 3250 // Skip if already updated the shared descriptor. |
3250 if (instance_descriptors()->GetValue(descriptor) == *new_wrapped_type) return; | 3251 if (instance_descriptors()->GetValue(descriptor) == *new_wrapped_type) return; |
3251 DataDescriptor d(name, instance_descriptors()->GetFieldIndex(descriptor), | 3252 DataDescriptor d(name, instance_descriptors()->GetFieldIndex(descriptor), |
3252 new_wrapped_type, details.attributes(), new_representation); | 3253 new_wrapped_type, details.attributes(), new_representation); |
3253 instance_descriptors()->Replace(descriptor, &d); | 3254 instance_descriptors()->Replace(descriptor, &d); |
3254 } | 3255 } |
3255 | 3256 |
3256 | 3257 bool FieldTypeIsCleared(Representation rep, FieldType* type) { |
3257 bool FieldTypeIsCleared(Representation rep, HeapType* type) { | 3258 return type->IsNone() && rep.IsHeapObject(); |
3258 return type->Is(HeapType::None()) && rep.IsHeapObject(); | |
3259 } | 3259 } |
3260 | 3260 |
3261 | 3261 |
3262 // static | 3262 // static |
3263 Handle<HeapType> Map::GeneralizeFieldType(Representation rep1, | 3263 Handle<FieldType> Map::GeneralizeFieldType(Representation rep1, |
3264 Handle<HeapType> type1, | 3264 Handle<FieldType> type1, |
3265 Representation rep2, | 3265 Representation rep2, |
3266 Handle<HeapType> type2, | 3266 Handle<FieldType> type2, |
3267 Isolate* isolate) { | 3267 Isolate* isolate) { |
3268 // Cleared field types need special treatment. They represent lost knowledge, | 3268 // Cleared field types need special treatment. They represent lost knowledge, |
3269 // so we must be conservative, so their generalization with any other type | 3269 // so we must be conservative, so their generalization with any other type |
3270 // is "Any". | 3270 // is "Any". |
3271 if (FieldTypeIsCleared(rep1, *type1) || FieldTypeIsCleared(rep2, *type2)) { | 3271 if (FieldTypeIsCleared(rep1, *type1) || FieldTypeIsCleared(rep2, *type2)) { |
3272 return HeapType::Any(isolate); | 3272 return FieldType::Any(isolate); |
3273 } | 3273 } |
3274 if (type1->NowIs(type2)) return type2; | 3274 if (type1->NowIs(type2)) return type2; |
3275 if (type2->NowIs(type1)) return type1; | 3275 if (type2->NowIs(type1)) return type1; |
3276 return HeapType::Any(isolate); | 3276 return FieldType::Any(isolate); |
3277 } | 3277 } |
3278 | 3278 |
3279 | 3279 |
3280 // static | 3280 // static |
3281 void Map::GeneralizeFieldType(Handle<Map> map, int modify_index, | 3281 void Map::GeneralizeFieldType(Handle<Map> map, int modify_index, |
3282 Representation new_representation, | 3282 Representation new_representation, |
3283 Handle<HeapType> new_field_type) { | 3283 Handle<FieldType> new_field_type) { |
3284 Isolate* isolate = map->GetIsolate(); | 3284 Isolate* isolate = map->GetIsolate(); |
3285 | 3285 |
3286 // Check if we actually need to generalize the field type at all. | 3286 // Check if we actually need to generalize the field type at all. |
3287 Handle<DescriptorArray> old_descriptors(map->instance_descriptors(), isolate); | 3287 Handle<DescriptorArray> old_descriptors(map->instance_descriptors(), isolate); |
3288 Representation old_representation = | 3288 Representation old_representation = |
3289 old_descriptors->GetDetails(modify_index).representation(); | 3289 old_descriptors->GetDetails(modify_index).representation(); |
3290 Handle<HeapType> old_field_type(old_descriptors->GetFieldType(modify_index), | 3290 Handle<FieldType> old_field_type(old_descriptors->GetFieldType(modify_index), |
3291 isolate); | 3291 isolate); |
3292 | 3292 |
3293 if (old_representation.Equals(new_representation) && | 3293 if (old_representation.Equals(new_representation) && |
3294 !FieldTypeIsCleared(new_representation, *new_field_type) && | 3294 !FieldTypeIsCleared(new_representation, *new_field_type) && |
3295 // Checking old_field_type for being cleared is not necessary because | 3295 // Checking old_field_type for being cleared is not necessary because |
3296 // the NowIs check below would fail anyway in that case. | 3296 // the NowIs check below would fail anyway in that case. |
3297 new_field_type->NowIs(old_field_type)) { | 3297 new_field_type->NowIs(old_field_type)) { |
3298 DCHECK(Map::GeneralizeFieldType(old_representation, old_field_type, | 3298 DCHECK(Map::GeneralizeFieldType(old_representation, old_field_type, |
3299 new_representation, new_field_type, isolate) | 3299 new_representation, new_field_type, isolate) |
3300 ->NowIs(old_field_type)); | 3300 ->NowIs(old_field_type)); |
3301 return; | 3301 return; |
(...skipping 13 matching lines...) Expand all Loading... |
3315 Handle<Name> name(descriptors->GetKey(modify_index)); | 3315 Handle<Name> name(descriptors->GetKey(modify_index)); |
3316 | 3316 |
3317 Handle<Object> wrapped_type(WrapType(new_field_type)); | 3317 Handle<Object> wrapped_type(WrapType(new_field_type)); |
3318 field_owner->UpdateFieldType(modify_index, name, new_representation, | 3318 field_owner->UpdateFieldType(modify_index, name, new_representation, |
3319 wrapped_type); | 3319 wrapped_type); |
3320 field_owner->dependent_code()->DeoptimizeDependentCodeGroup( | 3320 field_owner->dependent_code()->DeoptimizeDependentCodeGroup( |
3321 isolate, DependentCode::kFieldTypeGroup); | 3321 isolate, DependentCode::kFieldTypeGroup); |
3322 | 3322 |
3323 if (FLAG_trace_generalization) { | 3323 if (FLAG_trace_generalization) { |
3324 map->PrintGeneralization( | 3324 map->PrintGeneralization( |
3325 stdout, "field type generalization", | 3325 stdout, "field type generalization", modify_index, |
3326 modify_index, map->NumberOfOwnDescriptors(), | 3326 map->NumberOfOwnDescriptors(), map->NumberOfOwnDescriptors(), false, |
3327 map->NumberOfOwnDescriptors(), false, | 3327 details.representation(), details.representation(), old_field_type, |
3328 details.representation(), details.representation(), | 3328 MaybeHandle<Object>(), new_field_type, MaybeHandle<Object>()); |
3329 *old_field_type, *new_field_type); | |
3330 } | 3329 } |
3331 } | 3330 } |
3332 | 3331 |
3333 | 3332 static inline Handle<FieldType> GetFieldType( |
3334 static inline Handle<HeapType> GetFieldType(Isolate* isolate, | 3333 Isolate* isolate, Handle<DescriptorArray> descriptors, int descriptor, |
3335 Handle<DescriptorArray> descriptors, | 3334 PropertyLocation location, Representation representation) { |
3336 int descriptor, | |
3337 PropertyLocation location, | |
3338 Representation representation) { | |
3339 #ifdef DEBUG | 3335 #ifdef DEBUG |
3340 PropertyDetails details = descriptors->GetDetails(descriptor); | 3336 PropertyDetails details = descriptors->GetDetails(descriptor); |
3341 DCHECK_EQ(kData, details.kind()); | 3337 DCHECK_EQ(kData, details.kind()); |
3342 DCHECK_EQ(details.location(), location); | 3338 DCHECK_EQ(details.location(), location); |
3343 #endif | 3339 #endif |
3344 if (location == kField) { | 3340 if (location == kField) { |
3345 return handle(descriptors->GetFieldType(descriptor), isolate); | 3341 return handle(descriptors->GetFieldType(descriptor), isolate); |
3346 } else { | 3342 } else { |
3347 return descriptors->GetValue(descriptor) | 3343 return descriptors->GetValue(descriptor) |
3348 ->OptimalType(isolate, representation); | 3344 ->OptimalType(isolate, representation); |
(...skipping 24 matching lines...) Expand all Loading... |
3373 // |split_map|, the first map who's descriptor array does not match the merged | 3369 // |split_map|, the first map who's descriptor array does not match the merged |
3374 // descriptor array. | 3370 // descriptor array. |
3375 // - If |target_map| == |split_map|, |target_map| is in the expected state. | 3371 // - If |target_map| == |split_map|, |target_map| is in the expected state. |
3376 // Return it. | 3372 // Return it. |
3377 // - Otherwise, invalidate the outdated transition target from |target_map|, and | 3373 // - Otherwise, invalidate the outdated transition target from |target_map|, and |
3378 // replace its transition tree with a new branch for the updated descriptors. | 3374 // replace its transition tree with a new branch for the updated descriptors. |
3379 Handle<Map> Map::ReconfigureProperty(Handle<Map> old_map, int modify_index, | 3375 Handle<Map> Map::ReconfigureProperty(Handle<Map> old_map, int modify_index, |
3380 PropertyKind new_kind, | 3376 PropertyKind new_kind, |
3381 PropertyAttributes new_attributes, | 3377 PropertyAttributes new_attributes, |
3382 Representation new_representation, | 3378 Representation new_representation, |
3383 Handle<HeapType> new_field_type, | 3379 Handle<FieldType> new_field_type, |
3384 StoreMode store_mode) { | 3380 StoreMode store_mode) { |
3385 DCHECK_NE(kAccessor, new_kind); // TODO(ishell): not supported yet. | 3381 DCHECK_NE(kAccessor, new_kind); // TODO(ishell): not supported yet. |
3386 DCHECK(store_mode != FORCE_FIELD || modify_index >= 0); | 3382 DCHECK(store_mode != FORCE_FIELD || modify_index >= 0); |
3387 Isolate* isolate = old_map->GetIsolate(); | 3383 Isolate* isolate = old_map->GetIsolate(); |
3388 | 3384 |
3389 Handle<DescriptorArray> old_descriptors( | 3385 Handle<DescriptorArray> old_descriptors( |
3390 old_map->instance_descriptors(), isolate); | 3386 old_map->instance_descriptors(), isolate); |
3391 int old_nof = old_map->NumberOfOwnDescriptors(); | 3387 int old_nof = old_map->NumberOfOwnDescriptors(); |
3392 | 3388 |
3393 // If it's just a representation generalization case (i.e. property kind and | 3389 // If it's just a representation generalization case (i.e. property kind and |
3394 // attributes stays unchanged) it's fine to transition from None to anything | 3390 // attributes stays unchanged) it's fine to transition from None to anything |
3395 // but double without any modification to the object, because the default | 3391 // but double without any modification to the object, because the default |
3396 // uninitialized value for representation None can be overwritten by both | 3392 // uninitialized value for representation None can be overwritten by both |
3397 // smi and tagged values. Doubles, however, would require a box allocation. | 3393 // smi and tagged values. Doubles, however, would require a box allocation. |
3398 if (modify_index >= 0 && !new_representation.IsNone() && | 3394 if (modify_index >= 0 && !new_representation.IsNone() && |
3399 !new_representation.IsDouble()) { | 3395 !new_representation.IsDouble()) { |
3400 PropertyDetails old_details = old_descriptors->GetDetails(modify_index); | 3396 PropertyDetails old_details = old_descriptors->GetDetails(modify_index); |
3401 Representation old_representation = old_details.representation(); | 3397 Representation old_representation = old_details.representation(); |
3402 | 3398 |
3403 if (old_representation.IsNone()) { | 3399 if (old_representation.IsNone()) { |
3404 DCHECK_EQ(new_kind, old_details.kind()); | 3400 DCHECK_EQ(new_kind, old_details.kind()); |
3405 DCHECK_EQ(new_attributes, old_details.attributes()); | 3401 DCHECK_EQ(new_attributes, old_details.attributes()); |
3406 DCHECK_EQ(DATA, old_details.type()); | 3402 DCHECK_EQ(DATA, old_details.type()); |
3407 if (FLAG_trace_generalization) { | 3403 if (FLAG_trace_generalization) { |
3408 old_map->PrintGeneralization( | 3404 old_map->PrintGeneralization( |
3409 stdout, "uninitialized field", modify_index, | 3405 stdout, "uninitialized field", modify_index, |
3410 old_map->NumberOfOwnDescriptors(), | 3406 old_map->NumberOfOwnDescriptors(), |
3411 old_map->NumberOfOwnDescriptors(), false, old_representation, | 3407 old_map->NumberOfOwnDescriptors(), false, old_representation, |
3412 new_representation, old_descriptors->GetFieldType(modify_index), | 3408 new_representation, |
3413 *new_field_type); | 3409 handle(old_descriptors->GetFieldType(modify_index), isolate), |
| 3410 MaybeHandle<Object>(), new_field_type, MaybeHandle<Object>()); |
3414 } | 3411 } |
3415 Handle<Map> field_owner(old_map->FindFieldOwner(modify_index), isolate); | 3412 Handle<Map> field_owner(old_map->FindFieldOwner(modify_index), isolate); |
3416 | 3413 |
3417 GeneralizeFieldType(field_owner, modify_index, new_representation, | 3414 GeneralizeFieldType(field_owner, modify_index, new_representation, |
3418 new_field_type); | 3415 new_field_type); |
3419 DCHECK(old_descriptors->GetDetails(modify_index) | 3416 DCHECK(old_descriptors->GetDetails(modify_index) |
3420 .representation() | 3417 .representation() |
3421 .Equals(new_representation)); | 3418 .Equals(new_representation)); |
3422 DCHECK( | 3419 DCHECK( |
3423 old_descriptors->GetFieldType(modify_index)->NowIs(new_field_type)); | 3420 old_descriptors->GetFieldType(modify_index)->NowIs(new_field_type)); |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3519 } | 3516 } |
3520 if (next_location == kField && tmp_details.location() == kDescriptor) break; | 3517 if (next_location == kField && tmp_details.location() == kDescriptor) break; |
3521 | 3518 |
3522 Representation tmp_representation = tmp_details.representation(); | 3519 Representation tmp_representation = tmp_details.representation(); |
3523 if (!next_representation.fits_into(tmp_representation)) break; | 3520 if (!next_representation.fits_into(tmp_representation)) break; |
3524 | 3521 |
3525 PropertyLocation old_location = old_details.location(); | 3522 PropertyLocation old_location = old_details.location(); |
3526 PropertyLocation tmp_location = tmp_details.location(); | 3523 PropertyLocation tmp_location = tmp_details.location(); |
3527 if (tmp_location == kField) { | 3524 if (tmp_location == kField) { |
3528 if (next_kind == kData) { | 3525 if (next_kind == kData) { |
3529 Handle<HeapType> next_field_type; | 3526 Handle<FieldType> next_field_type; |
3530 if (modify_index == i) { | 3527 if (modify_index == i) { |
3531 next_field_type = new_field_type; | 3528 next_field_type = new_field_type; |
3532 if (!property_kind_reconfiguration) { | 3529 if (!property_kind_reconfiguration) { |
3533 Handle<HeapType> old_field_type = | 3530 Handle<FieldType> old_field_type = |
3534 GetFieldType(isolate, old_descriptors, i, | 3531 GetFieldType(isolate, old_descriptors, i, |
3535 old_details.location(), tmp_representation); | 3532 old_details.location(), tmp_representation); |
3536 Representation old_representation = old_details.representation(); | 3533 Representation old_representation = old_details.representation(); |
3537 next_field_type = GeneralizeFieldType( | 3534 next_field_type = GeneralizeFieldType( |
3538 old_representation, old_field_type, new_representation, | 3535 old_representation, old_field_type, new_representation, |
3539 next_field_type, isolate); | 3536 next_field_type, isolate); |
3540 } | 3537 } |
3541 } else { | 3538 } else { |
3542 Handle<HeapType> old_field_type = | 3539 Handle<FieldType> old_field_type = |
3543 GetFieldType(isolate, old_descriptors, i, old_details.location(), | 3540 GetFieldType(isolate, old_descriptors, i, old_details.location(), |
3544 tmp_representation); | 3541 tmp_representation); |
3545 next_field_type = old_field_type; | 3542 next_field_type = old_field_type; |
3546 } | 3543 } |
3547 GeneralizeFieldType(tmp_map, i, tmp_representation, next_field_type); | 3544 GeneralizeFieldType(tmp_map, i, tmp_representation, next_field_type); |
3548 } | 3545 } |
3549 } else if (old_location == kField || | 3546 } else if (old_location == kField || |
3550 !EqualImmutableValues(old_descriptors->GetValue(i), | 3547 !EqualImmutableValues(old_descriptors->GetValue(i), |
3551 tmp_descriptors->GetValue(i))) { | 3548 tmp_descriptors->GetValue(i))) { |
3552 break; | 3549 break; |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3687 : kDescriptor; | 3684 : kDescriptor; |
3688 | 3685 |
3689 next_representation = old_details.representation().generalize( | 3686 next_representation = old_details.representation().generalize( |
3690 target_details.representation()); | 3687 target_details.representation()); |
3691 } | 3688 } |
3692 DCHECK_EQ(next_kind, target_details.kind()); | 3689 DCHECK_EQ(next_kind, target_details.kind()); |
3693 DCHECK_EQ(next_attributes, target_details.attributes()); | 3690 DCHECK_EQ(next_attributes, target_details.attributes()); |
3694 | 3691 |
3695 if (next_location == kField) { | 3692 if (next_location == kField) { |
3696 if (next_kind == kData) { | 3693 if (next_kind == kData) { |
3697 Handle<HeapType> target_field_type = | 3694 Handle<FieldType> target_field_type = |
3698 GetFieldType(isolate, target_descriptors, i, | 3695 GetFieldType(isolate, target_descriptors, i, |
3699 target_details.location(), next_representation); | 3696 target_details.location(), next_representation); |
3700 | 3697 |
3701 Handle<HeapType> next_field_type; | 3698 Handle<FieldType> next_field_type; |
3702 if (modify_index == i) { | 3699 if (modify_index == i) { |
3703 next_field_type = GeneralizeFieldType( | 3700 next_field_type = GeneralizeFieldType( |
3704 target_details.representation(), target_field_type, | 3701 target_details.representation(), target_field_type, |
3705 new_representation, new_field_type, isolate); | 3702 new_representation, new_field_type, isolate); |
3706 if (!property_kind_reconfiguration) { | 3703 if (!property_kind_reconfiguration) { |
3707 Handle<HeapType> old_field_type = | 3704 Handle<FieldType> old_field_type = |
3708 GetFieldType(isolate, old_descriptors, i, | 3705 GetFieldType(isolate, old_descriptors, i, |
3709 old_details.location(), next_representation); | 3706 old_details.location(), next_representation); |
3710 next_field_type = GeneralizeFieldType( | 3707 next_field_type = GeneralizeFieldType( |
3711 old_details.representation(), old_field_type, | 3708 old_details.representation(), old_field_type, |
3712 next_representation, next_field_type, isolate); | 3709 next_representation, next_field_type, isolate); |
3713 } | 3710 } |
3714 } else { | 3711 } else { |
3715 Handle<HeapType> old_field_type = | 3712 Handle<FieldType> old_field_type = |
3716 GetFieldType(isolate, old_descriptors, i, old_details.location(), | 3713 GetFieldType(isolate, old_descriptors, i, old_details.location(), |
3717 next_representation); | 3714 next_representation); |
3718 next_field_type = GeneralizeFieldType( | 3715 next_field_type = GeneralizeFieldType( |
3719 old_details.representation(), old_field_type, next_representation, | 3716 old_details.representation(), old_field_type, next_representation, |
3720 target_field_type, isolate); | 3717 target_field_type, isolate); |
3721 } | 3718 } |
3722 Handle<Object> wrapped_type(WrapType(next_field_type)); | 3719 Handle<Object> wrapped_type(WrapType(next_field_type)); |
3723 DataDescriptor d(target_key, current_offset, wrapped_type, | 3720 DataDescriptor d(target_key, current_offset, wrapped_type, |
3724 next_attributes, next_representation); | 3721 next_attributes, next_representation); |
3725 current_offset += d.GetDetails().field_width_in_words(); | 3722 current_offset += d.GetDetails().field_width_in_words(); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3764 } | 3761 } |
3765 } else { | 3762 } else { |
3766 next_kind = old_details.kind(); | 3763 next_kind = old_details.kind(); |
3767 next_attributes = old_details.attributes(); | 3764 next_attributes = old_details.attributes(); |
3768 next_location = old_details.location(); | 3765 next_location = old_details.location(); |
3769 next_representation = old_details.representation(); | 3766 next_representation = old_details.representation(); |
3770 } | 3767 } |
3771 | 3768 |
3772 if (next_location == kField) { | 3769 if (next_location == kField) { |
3773 if (next_kind == kData) { | 3770 if (next_kind == kData) { |
3774 Handle<HeapType> next_field_type; | 3771 Handle<FieldType> next_field_type; |
3775 if (modify_index == i) { | 3772 if (modify_index == i) { |
3776 next_field_type = new_field_type; | 3773 next_field_type = new_field_type; |
3777 if (!property_kind_reconfiguration) { | 3774 if (!property_kind_reconfiguration) { |
3778 Handle<HeapType> old_field_type = | 3775 Handle<FieldType> old_field_type = |
3779 GetFieldType(isolate, old_descriptors, i, | 3776 GetFieldType(isolate, old_descriptors, i, |
3780 old_details.location(), next_representation); | 3777 old_details.location(), next_representation); |
3781 next_field_type = GeneralizeFieldType( | 3778 next_field_type = GeneralizeFieldType( |
3782 old_details.representation(), old_field_type, | 3779 old_details.representation(), old_field_type, |
3783 next_representation, next_field_type, isolate); | 3780 next_representation, next_field_type, isolate); |
3784 } | 3781 } |
3785 } else { | 3782 } else { |
3786 Handle<HeapType> old_field_type = | 3783 Handle<FieldType> old_field_type = |
3787 GetFieldType(isolate, old_descriptors, i, old_details.location(), | 3784 GetFieldType(isolate, old_descriptors, i, old_details.location(), |
3788 next_representation); | 3785 next_representation); |
3789 next_field_type = old_field_type; | 3786 next_field_type = old_field_type; |
3790 } | 3787 } |
3791 | 3788 |
3792 Handle<Object> wrapped_type(WrapType(next_field_type)); | 3789 Handle<Object> wrapped_type(WrapType(next_field_type)); |
3793 | 3790 |
3794 DataDescriptor d(old_key, current_offset, wrapped_type, next_attributes, | 3791 DataDescriptor d(old_key, current_offset, wrapped_type, next_attributes, |
3795 next_representation); | 3792 next_representation); |
3796 current_offset += d.GetDetails().field_width_in_words(); | 3793 current_offset += d.GetDetails().field_width_in_words(); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3844 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, | 3841 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, |
3845 new_kind, new_attributes, | 3842 new_kind, new_attributes, |
3846 "GenAll_CantHaveMoreTransitions"); | 3843 "GenAll_CantHaveMoreTransitions"); |
3847 } | 3844 } |
3848 | 3845 |
3849 old_map->NotifyLeafMapLayoutChange(); | 3846 old_map->NotifyLeafMapLayoutChange(); |
3850 | 3847 |
3851 if (FLAG_trace_generalization && modify_index >= 0) { | 3848 if (FLAG_trace_generalization && modify_index >= 0) { |
3852 PropertyDetails old_details = old_descriptors->GetDetails(modify_index); | 3849 PropertyDetails old_details = old_descriptors->GetDetails(modify_index); |
3853 PropertyDetails new_details = new_descriptors->GetDetails(modify_index); | 3850 PropertyDetails new_details = new_descriptors->GetDetails(modify_index); |
3854 Handle<HeapType> old_field_type = | 3851 MaybeHandle<FieldType> old_field_type; |
3855 (old_details.type() == DATA) | 3852 MaybeHandle<FieldType> new_field_type; |
3856 ? handle(old_descriptors->GetFieldType(modify_index), isolate) | 3853 MaybeHandle<Object> old_value; |
3857 : HeapType::Constant( | 3854 MaybeHandle<Object> new_value; |
3858 handle(old_descriptors->GetValue(modify_index), isolate), | 3855 if (old_details.type() == DATA) { |
3859 isolate); | 3856 old_field_type = |
3860 Handle<HeapType> new_field_type = | 3857 handle(old_descriptors->GetFieldType(modify_index), isolate); |
3861 (new_details.type() == DATA) | 3858 } else { |
3862 ? handle(new_descriptors->GetFieldType(modify_index), isolate) | 3859 old_value = handle(old_descriptors->GetValue(modify_index), isolate); |
3863 : HeapType::Constant( | 3860 } |
3864 handle(new_descriptors->GetValue(modify_index), isolate), | 3861 if (new_details.type() == DATA) { |
3865 isolate); | 3862 new_field_type = |
| 3863 handle(new_descriptors->GetFieldType(modify_index), isolate); |
| 3864 } else { |
| 3865 new_value = handle(new_descriptors->GetValue(modify_index), isolate); |
| 3866 } |
| 3867 |
3866 old_map->PrintGeneralization( | 3868 old_map->PrintGeneralization( |
3867 stdout, "", modify_index, split_nof, old_nof, | 3869 stdout, "", modify_index, split_nof, old_nof, |
3868 old_details.location() == kDescriptor && store_mode == FORCE_FIELD, | 3870 old_details.location() == kDescriptor && store_mode == FORCE_FIELD, |
3869 old_details.representation(), new_details.representation(), | 3871 old_details.representation(), new_details.representation(), |
3870 *old_field_type, *new_field_type); | 3872 old_field_type, old_value, new_field_type, new_value); |
3871 } | 3873 } |
3872 | 3874 |
3873 Handle<LayoutDescriptor> new_layout_descriptor = | 3875 Handle<LayoutDescriptor> new_layout_descriptor = |
3874 LayoutDescriptor::New(split_map, new_descriptors, old_nof); | 3876 LayoutDescriptor::New(split_map, new_descriptors, old_nof); |
3875 | 3877 |
3876 Handle<Map> new_map = | 3878 Handle<Map> new_map = |
3877 AddMissingTransitions(split_map, new_descriptors, new_layout_descriptor); | 3879 AddMissingTransitions(split_map, new_descriptors, new_layout_descriptor); |
3878 | 3880 |
3879 // Deprecated part of the transition tree is no longer reachable, so replace | 3881 // Deprecated part of the transition tree is no longer reachable, so replace |
3880 // current instance descriptors in the "survived" part of the tree with | 3882 // current instance descriptors in the "survived" part of the tree with |
3881 // the new descriptors to maintain descriptors sharing invariant. | 3883 // the new descriptors to maintain descriptors sharing invariant. |
3882 split_map->ReplaceDescriptors(*new_descriptors, *new_layout_descriptor); | 3884 split_map->ReplaceDescriptors(*new_descriptors, *new_layout_descriptor); |
3883 return new_map; | 3885 return new_map; |
3884 } | 3886 } |
3885 | 3887 |
3886 | 3888 |
3887 // Generalize the representation of all DATA descriptors. | 3889 // Generalize the representation of all DATA descriptors. |
3888 Handle<Map> Map::GeneralizeAllFieldRepresentations( | 3890 Handle<Map> Map::GeneralizeAllFieldRepresentations( |
3889 Handle<Map> map) { | 3891 Handle<Map> map) { |
3890 Handle<DescriptorArray> descriptors(map->instance_descriptors()); | 3892 Handle<DescriptorArray> descriptors(map->instance_descriptors()); |
3891 for (int i = 0; i < map->NumberOfOwnDescriptors(); ++i) { | 3893 for (int i = 0; i < map->NumberOfOwnDescriptors(); ++i) { |
3892 PropertyDetails details = descriptors->GetDetails(i); | 3894 PropertyDetails details = descriptors->GetDetails(i); |
3893 if (details.type() == DATA) { | 3895 if (details.type() == DATA) { |
3894 map = ReconfigureProperty(map, i, kData, details.attributes(), | 3896 map = ReconfigureProperty(map, i, kData, details.attributes(), |
3895 Representation::Tagged(), | 3897 Representation::Tagged(), |
3896 HeapType::Any(map->GetIsolate()), FORCE_FIELD); | 3898 FieldType::Any(map->GetIsolate()), FORCE_FIELD); |
3897 } | 3899 } |
3898 } | 3900 } |
3899 return map; | 3901 return map; |
3900 } | 3902 } |
3901 | 3903 |
3902 | 3904 |
3903 // static | 3905 // static |
3904 MaybeHandle<Map> Map::TryUpdate(Handle<Map> old_map) { | 3906 MaybeHandle<Map> Map::TryUpdate(Handle<Map> old_map) { |
3905 DisallowHeapAllocation no_allocation; | 3907 DisallowHeapAllocation no_allocation; |
3906 DisallowDeoptimization no_deoptimization(old_map->GetIsolate()); | 3908 DisallowDeoptimization no_deoptimization(old_map->GetIsolate()); |
(...skipping 28 matching lines...) Expand all Loading... |
3935 DescriptorArray* new_descriptors = new_map->instance_descriptors(); | 3937 DescriptorArray* new_descriptors = new_map->instance_descriptors(); |
3936 | 3938 |
3937 PropertyDetails new_details = new_descriptors->GetDetails(i); | 3939 PropertyDetails new_details = new_descriptors->GetDetails(i); |
3938 DCHECK_EQ(old_details.kind(), new_details.kind()); | 3940 DCHECK_EQ(old_details.kind(), new_details.kind()); |
3939 DCHECK_EQ(old_details.attributes(), new_details.attributes()); | 3941 DCHECK_EQ(old_details.attributes(), new_details.attributes()); |
3940 if (!old_details.representation().fits_into(new_details.representation())) { | 3942 if (!old_details.representation().fits_into(new_details.representation())) { |
3941 return MaybeHandle<Map>(); | 3943 return MaybeHandle<Map>(); |
3942 } | 3944 } |
3943 switch (new_details.type()) { | 3945 switch (new_details.type()) { |
3944 case DATA: { | 3946 case DATA: { |
3945 HeapType* new_type = new_descriptors->GetFieldType(i); | 3947 FieldType* new_type = new_descriptors->GetFieldType(i); |
3946 // Cleared field types need special treatment. They represent lost | 3948 // Cleared field types need special treatment. They represent lost |
3947 // knowledge, so we must first generalize the new_type to "Any". | 3949 // knowledge, so we must first generalize the new_type to "Any". |
3948 if (FieldTypeIsCleared(new_details.representation(), new_type)) { | 3950 if (FieldTypeIsCleared(new_details.representation(), new_type)) { |
3949 return MaybeHandle<Map>(); | 3951 return MaybeHandle<Map>(); |
3950 } | 3952 } |
3951 PropertyType old_property_type = old_details.type(); | 3953 PropertyType old_property_type = old_details.type(); |
3952 if (old_property_type == DATA) { | 3954 if (old_property_type == DATA) { |
3953 HeapType* old_type = old_descriptors->GetFieldType(i); | 3955 FieldType* old_type = old_descriptors->GetFieldType(i); |
3954 if (FieldTypeIsCleared(old_details.representation(), old_type) || | 3956 if (FieldTypeIsCleared(old_details.representation(), old_type) || |
3955 !old_type->NowIs(new_type)) { | 3957 !old_type->NowIs(new_type)) { |
3956 return MaybeHandle<Map>(); | 3958 return MaybeHandle<Map>(); |
3957 } | 3959 } |
3958 } else { | 3960 } else { |
3959 DCHECK(old_property_type == DATA_CONSTANT); | 3961 DCHECK(old_property_type == DATA_CONSTANT); |
3960 Object* old_value = old_descriptors->GetValue(i); | 3962 Object* old_value = old_descriptors->GetValue(i); |
3961 if (!new_type->NowContains(old_value)) { | 3963 if (!new_type->NowContains(old_value)) { |
3962 return MaybeHandle<Map>(); | 3964 return MaybeHandle<Map>(); |
3963 } | 3965 } |
3964 } | 3966 } |
3965 break; | 3967 break; |
3966 } | 3968 } |
3967 case ACCESSOR: { | 3969 case ACCESSOR: { |
3968 #ifdef DEBUG | 3970 #ifdef DEBUG |
3969 HeapType* new_type = new_descriptors->GetFieldType(i); | 3971 FieldType* new_type = new_descriptors->GetFieldType(i); |
3970 DCHECK(HeapType::Any()->Is(new_type)); | 3972 DCHECK(new_type->IsAny()); |
3971 #endif | 3973 #endif |
3972 break; | 3974 break; |
3973 } | 3975 } |
3974 | 3976 |
3975 case DATA_CONSTANT: | 3977 case DATA_CONSTANT: |
3976 case ACCESSOR_CONSTANT: { | 3978 case ACCESSOR_CONSTANT: { |
3977 Object* old_value = old_descriptors->GetValue(i); | 3979 Object* old_value = old_descriptors->GetValue(i); |
3978 Object* new_value = new_descriptors->GetValue(i); | 3980 Object* new_value = new_descriptors->GetValue(i); |
3979 if (old_details.location() == kField || old_value != new_value) { | 3981 if (old_details.location() == kField || old_value != new_value) { |
3980 return MaybeHandle<Map>(); | 3982 return MaybeHandle<Map>(); |
3981 } | 3983 } |
3982 break; | 3984 break; |
3983 } | 3985 } |
3984 } | 3986 } |
3985 } | 3987 } |
3986 if (new_map->NumberOfOwnDescriptors() != old_nof) return MaybeHandle<Map>(); | 3988 if (new_map->NumberOfOwnDescriptors() != old_nof) return MaybeHandle<Map>(); |
3987 return handle(new_map); | 3989 return handle(new_map); |
3988 } | 3990 } |
3989 | 3991 |
3990 | 3992 |
3991 // static | 3993 // static |
3992 Handle<Map> Map::Update(Handle<Map> map) { | 3994 Handle<Map> Map::Update(Handle<Map> map) { |
3993 if (!map->is_deprecated()) return map; | 3995 if (!map->is_deprecated()) return map; |
3994 return ReconfigureProperty(map, -1, kData, NONE, Representation::None(), | 3996 return ReconfigureProperty(map, -1, kData, NONE, Representation::None(), |
3995 HeapType::None(map->GetIsolate()), | 3997 FieldType::None(map->GetIsolate()), |
3996 ALLOW_IN_DESCRIPTOR); | 3998 ALLOW_IN_DESCRIPTOR); |
3997 } | 3999 } |
3998 | 4000 |
3999 | 4001 |
4000 Maybe<bool> JSObject::SetPropertyWithInterceptor(LookupIterator* it, | 4002 Maybe<bool> JSObject::SetPropertyWithInterceptor(LookupIterator* it, |
4001 ShouldThrow should_throw, | 4003 ShouldThrow should_throw, |
4002 Handle<Object> value) { | 4004 Handle<Object> value) { |
4003 Isolate* isolate = it->isolate(); | 4005 Isolate* isolate = it->isolate(); |
4004 // Make sure that the top context does not change when doing callbacks or | 4006 // Make sure that the top context does not change when doing callbacks or |
4005 // interceptor calls. | 4007 // interceptor calls. |
(...skipping 5425 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9431 result->InitializeDescriptors(*descriptors, *layout_descriptor); | 9433 result->InitializeDescriptors(*descriptors, *layout_descriptor); |
9432 | 9434 |
9433 Handle<Name> name; | 9435 Handle<Name> name; |
9434 CHECK(maybe_name.ToHandle(&name)); | 9436 CHECK(maybe_name.ToHandle(&name)); |
9435 ConnectTransition(map, result, name, simple_flag); | 9437 ConnectTransition(map, result, name, simple_flag); |
9436 } else { | 9438 } else { |
9437 int length = descriptors->number_of_descriptors(); | 9439 int length = descriptors->number_of_descriptors(); |
9438 for (int i = 0; i < length; i++) { | 9440 for (int i = 0; i < length; i++) { |
9439 descriptors->SetRepresentation(i, Representation::Tagged()); | 9441 descriptors->SetRepresentation(i, Representation::Tagged()); |
9440 if (descriptors->GetDetails(i).type() == DATA) { | 9442 if (descriptors->GetDetails(i).type() == DATA) { |
9441 descriptors->SetValue(i, HeapType::Any()); | 9443 descriptors->SetValue(i, FieldType::Any()); |
9442 } | 9444 } |
9443 } | 9445 } |
9444 result->InitializeDescriptors(*descriptors, | 9446 result->InitializeDescriptors(*descriptors, |
9445 LayoutDescriptor::FastPointerLayout()); | 9447 LayoutDescriptor::FastPointerLayout()); |
9446 } | 9448 } |
9447 } else { | 9449 } else { |
9448 result->InitializeDescriptors(*descriptors, *layout_descriptor); | 9450 result->InitializeDescriptors(*descriptors, *layout_descriptor); |
9449 } | 9451 } |
9450 #if TRACE_MAPS | 9452 #if TRACE_MAPS |
9451 if (FLAG_trace_maps && | 9453 if (FLAG_trace_maps && |
(...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9783 map = Update(map); | 9785 map = Update(map); |
9784 | 9786 |
9785 Handle<DescriptorArray> descriptors(map->instance_descriptors()); | 9787 Handle<DescriptorArray> descriptors(map->instance_descriptors()); |
9786 | 9788 |
9787 if (descriptors->CanHoldValue(descriptor, *value)) return map; | 9789 if (descriptors->CanHoldValue(descriptor, *value)) return map; |
9788 | 9790 |
9789 Isolate* isolate = map->GetIsolate(); | 9791 Isolate* isolate = map->GetIsolate(); |
9790 PropertyAttributes attributes = | 9792 PropertyAttributes attributes = |
9791 descriptors->GetDetails(descriptor).attributes(); | 9793 descriptors->GetDetails(descriptor).attributes(); |
9792 Representation representation = value->OptimalRepresentation(); | 9794 Representation representation = value->OptimalRepresentation(); |
9793 Handle<HeapType> type = value->OptimalType(isolate, representation); | 9795 Handle<FieldType> type = value->OptimalType(isolate, representation); |
9794 | 9796 |
9795 return ReconfigureProperty(map, descriptor, kData, attributes, representation, | 9797 return ReconfigureProperty(map, descriptor, kData, attributes, representation, |
9796 type, FORCE_FIELD); | 9798 type, FORCE_FIELD); |
9797 } | 9799 } |
9798 | 9800 |
9799 | 9801 |
9800 Handle<Map> Map::TransitionToDataProperty(Handle<Map> map, Handle<Name> name, | 9802 Handle<Map> Map::TransitionToDataProperty(Handle<Map> map, Handle<Name> name, |
9801 Handle<Object> value, | 9803 Handle<Object> value, |
9802 PropertyAttributes attributes, | 9804 PropertyAttributes attributes, |
9803 StoreFromKeyed store_mode) { | 9805 StoreFromKeyed store_mode) { |
(...skipping 16 matching lines...) Expand all Loading... |
9820 return Map::PrepareForDataProperty(transition, descriptor, value); | 9822 return Map::PrepareForDataProperty(transition, descriptor, value); |
9821 } | 9823 } |
9822 | 9824 |
9823 TransitionFlag flag = INSERT_TRANSITION; | 9825 TransitionFlag flag = INSERT_TRANSITION; |
9824 MaybeHandle<Map> maybe_map; | 9826 MaybeHandle<Map> maybe_map; |
9825 if (value->IsJSFunction()) { | 9827 if (value->IsJSFunction()) { |
9826 maybe_map = Map::CopyWithConstant(map, name, value, attributes, flag); | 9828 maybe_map = Map::CopyWithConstant(map, name, value, attributes, flag); |
9827 } else if (!map->TooManyFastProperties(store_mode)) { | 9829 } else if (!map->TooManyFastProperties(store_mode)) { |
9828 Isolate* isolate = name->GetIsolate(); | 9830 Isolate* isolate = name->GetIsolate(); |
9829 Representation representation = value->OptimalRepresentation(); | 9831 Representation representation = value->OptimalRepresentation(); |
9830 Handle<HeapType> type = value->OptimalType(isolate, representation); | 9832 Handle<FieldType> type = value->OptimalType(isolate, representation); |
9831 maybe_map = | 9833 maybe_map = |
9832 Map::CopyWithField(map, name, type, attributes, representation, flag); | 9834 Map::CopyWithField(map, name, type, attributes, representation, flag); |
9833 } | 9835 } |
9834 | 9836 |
9835 Handle<Map> result; | 9837 Handle<Map> result; |
9836 if (!maybe_map.ToHandle(&result)) { | 9838 if (!maybe_map.ToHandle(&result)) { |
9837 #if TRACE_MAPS | 9839 #if TRACE_MAPS |
9838 if (FLAG_trace_maps) { | 9840 if (FLAG_trace_maps) { |
9839 Vector<char> name_buffer = Vector<char>::New(100); | 9841 Vector<char> name_buffer = Vector<char>::New(100); |
9840 name->NameShortPrint(name_buffer); | 9842 name->NameShortPrint(name_buffer); |
(...skipping 24 matching lines...) Expand all Loading... |
9865 "GenAll_AttributesMismatchProtoMap"); | 9867 "GenAll_AttributesMismatchProtoMap"); |
9866 } | 9868 } |
9867 | 9869 |
9868 if (FLAG_trace_generalization) { | 9870 if (FLAG_trace_generalization) { |
9869 map->PrintReconfiguration(stdout, descriptor, kind, attributes); | 9871 map->PrintReconfiguration(stdout, descriptor, kind, attributes); |
9870 } | 9872 } |
9871 | 9873 |
9872 Isolate* isolate = map->GetIsolate(); | 9874 Isolate* isolate = map->GetIsolate(); |
9873 Handle<Map> new_map = ReconfigureProperty( | 9875 Handle<Map> new_map = ReconfigureProperty( |
9874 map, descriptor, kind, attributes, Representation::None(), | 9876 map, descriptor, kind, attributes, Representation::None(), |
9875 HeapType::None(isolate), FORCE_FIELD); | 9877 FieldType::None(isolate), FORCE_FIELD); |
9876 return new_map; | 9878 return new_map; |
9877 } | 9879 } |
9878 | 9880 |
9879 | 9881 |
9880 Handle<Map> Map::TransitionToAccessorProperty(Handle<Map> map, | 9882 Handle<Map> Map::TransitionToAccessorProperty(Handle<Map> map, |
9881 Handle<Name> name, | 9883 Handle<Name> name, |
9882 AccessorComponent component, | 9884 AccessorComponent component, |
9883 Handle<Object> accessor, | 9885 Handle<Object> accessor, |
9884 PropertyAttributes attributes) { | 9886 PropertyAttributes attributes) { |
9885 Isolate* isolate = name->GetIsolate(); | 9887 Isolate* isolate = name->GetIsolate(); |
(...skipping 9859 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
19745 if (cell->value() != *new_value) { | 19747 if (cell->value() != *new_value) { |
19746 cell->set_value(*new_value); | 19748 cell->set_value(*new_value); |
19747 Isolate* isolate = cell->GetIsolate(); | 19749 Isolate* isolate = cell->GetIsolate(); |
19748 cell->dependent_code()->DeoptimizeDependentCodeGroup( | 19750 cell->dependent_code()->DeoptimizeDependentCodeGroup( |
19749 isolate, DependentCode::kPropertyCellChangedGroup); | 19751 isolate, DependentCode::kPropertyCellChangedGroup); |
19750 } | 19752 } |
19751 } | 19753 } |
19752 | 19754 |
19753 } // namespace internal | 19755 } // namespace internal |
19754 } // namespace v8 | 19756 } // namespace v8 |
OLD | NEW |