| 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 |