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 <memory> | 9 #include <memory> |
10 #include <sstream> | 10 #include <sstream> |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
42 #include "src/identity-map.h" | 42 #include "src/identity-map.h" |
43 #include "src/interpreter/bytecode-array-iterator.h" | 43 #include "src/interpreter/bytecode-array-iterator.h" |
44 #include "src/interpreter/bytecode-decoder.h" | 44 #include "src/interpreter/bytecode-decoder.h" |
45 #include "src/interpreter/interpreter.h" | 45 #include "src/interpreter/interpreter.h" |
46 #include "src/isolate-inl.h" | 46 #include "src/isolate-inl.h" |
47 #include "src/keys.h" | 47 #include "src/keys.h" |
48 #include "src/list.h" | 48 #include "src/list.h" |
49 #include "src/log.h" | 49 #include "src/log.h" |
50 #include "src/lookup.h" | 50 #include "src/lookup.h" |
51 #include "src/macro-assembler.h" | 51 #include "src/macro-assembler.h" |
| 52 #include "src/map-updater.h" |
52 #include "src/messages.h" | 53 #include "src/messages.h" |
53 #include "src/objects-body-descriptors-inl.h" | 54 #include "src/objects-body-descriptors-inl.h" |
54 #include "src/property-descriptor.h" | 55 #include "src/property-descriptor.h" |
55 #include "src/prototype.h" | 56 #include "src/prototype.h" |
56 #include "src/regexp/jsregexp.h" | 57 #include "src/regexp/jsregexp.h" |
57 #include "src/safepoint-table.h" | 58 #include "src/safepoint-table.h" |
58 #include "src/snapshot/code-serializer.h" | 59 #include "src/snapshot/code-serializer.h" |
59 #include "src/source-position-table.h" | 60 #include "src/source-position-table.h" |
60 #include "src/string-builder.h" | 61 #include "src/string-builder.h" |
61 #include "src/string-search.h" | 62 #include "src/string-search.h" |
(...skipping 3257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3319 } else { | 3320 } else { |
3320 // Functions have null as a constructor, | 3321 // Functions have null as a constructor, |
3321 // but any JSFunction knows its context immediately. | 3322 // but any JSFunction knows its context immediately. |
3322 CHECK(receiver->IsJSFunction()); | 3323 CHECK(receiver->IsJSFunction()); |
3323 function = JSFunction::cast(receiver); | 3324 function = JSFunction::cast(receiver); |
3324 } | 3325 } |
3325 | 3326 |
3326 return function->context()->native_context(); | 3327 return function->context()->native_context(); |
3327 } | 3328 } |
3328 | 3329 |
3329 static Handle<Object> WrapType(Handle<FieldType> type) { | 3330 Handle<Object> Map::WrapType(Handle<FieldType> type) { |
3330 if (type->IsClass()) return Map::WeakCellForMap(type->AsClass()); | 3331 if (type->IsClass()) return Map::WeakCellForMap(type->AsClass()); |
3331 return type; | 3332 return type; |
3332 } | 3333 } |
3333 | 3334 |
3334 MaybeHandle<Map> Map::CopyWithField(Handle<Map> map, Handle<Name> name, | 3335 MaybeHandle<Map> Map::CopyWithField(Handle<Map> map, Handle<Name> name, |
3335 Handle<FieldType> type, | 3336 Handle<FieldType> type, |
3336 PropertyAttributes attributes, | 3337 PropertyAttributes attributes, |
3337 Representation representation, | 3338 Representation representation, |
3338 TransitionFlag flag) { | 3339 TransitionFlag flag) { |
3339 DCHECK(DescriptorArray::kNotFound == | 3340 DCHECK(DescriptorArray::kNotFound == |
(...skipping 622 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3962 for (int i = 0; i < num_transitions; ++i) { | 3963 for (int i = 0; i < num_transitions; ++i) { |
3963 TransitionArray::GetTarget(transitions, i)->DeprecateTransitionTree(); | 3964 TransitionArray::GetTarget(transitions, i)->DeprecateTransitionTree(); |
3964 } | 3965 } |
3965 deprecate(); | 3966 deprecate(); |
3966 dependent_code()->DeoptimizeDependentCodeGroup( | 3967 dependent_code()->DeoptimizeDependentCodeGroup( |
3967 GetIsolate(), DependentCode::kTransitionGroup); | 3968 GetIsolate(), DependentCode::kTransitionGroup); |
3968 NotifyLeafMapLayoutChange(); | 3969 NotifyLeafMapLayoutChange(); |
3969 } | 3970 } |
3970 | 3971 |
3971 | 3972 |
3972 static inline bool EqualImmutableValues(Object* obj1, Object* obj2) { | |
3973 if (obj1 == obj2) return true; // Valid for both kData and kAccessor kinds. | |
3974 // TODO(ishell): compare AccessorPairs. | |
3975 return false; | |
3976 } | |
3977 | |
3978 | |
3979 // Installs |new_descriptors| over the current instance_descriptors to ensure | 3973 // Installs |new_descriptors| over the current instance_descriptors to ensure |
3980 // proper sharing of descriptor arrays. | 3974 // proper sharing of descriptor arrays. |
3981 void Map::ReplaceDescriptors(DescriptorArray* new_descriptors, | 3975 void Map::ReplaceDescriptors(DescriptorArray* new_descriptors, |
3982 LayoutDescriptor* new_layout_descriptor) { | 3976 LayoutDescriptor* new_layout_descriptor) { |
3983 Isolate* isolate = GetIsolate(); | 3977 Isolate* isolate = GetIsolate(); |
3984 // Don't overwrite the empty descriptor array or initial map's descriptors. | 3978 // Don't overwrite the empty descriptor array or initial map's descriptors. |
3985 if (NumberOfOwnDescriptors() == 0 || GetBackPointer()->IsUndefined(isolate)) { | 3979 if (NumberOfOwnDescriptors() == 0 || GetBackPointer()->IsUndefined(isolate)) { |
3986 return; | 3980 return; |
3987 } | 3981 } |
3988 | 3982 |
(...skipping 22 matching lines...) Expand all Loading... |
4011 DCHECK(result->owns_descriptors()); | 4005 DCHECK(result->owns_descriptors()); |
4012 DCHECK_EQ(result->NumberOfOwnDescriptors(), | 4006 DCHECK_EQ(result->NumberOfOwnDescriptors(), |
4013 result->instance_descriptors()->number_of_descriptors()); | 4007 result->instance_descriptors()->number_of_descriptors()); |
4014 return result; | 4008 return result; |
4015 } | 4009 } |
4016 result = Map::cast(back); | 4010 result = Map::cast(back); |
4017 } | 4011 } |
4018 } | 4012 } |
4019 | 4013 |
4020 | 4014 |
4021 Map* Map::FindLastMatchMap(int verbatim, | |
4022 int length, | |
4023 DescriptorArray* descriptors) { | |
4024 DisallowHeapAllocation no_allocation; | |
4025 | |
4026 // This can only be called on roots of transition trees. | |
4027 DCHECK_EQ(verbatim, NumberOfOwnDescriptors()); | |
4028 | |
4029 Map* current = this; | |
4030 | |
4031 for (int i = verbatim; i < length; i++) { | |
4032 Name* name = descriptors->GetKey(i); | |
4033 PropertyDetails details = descriptors->GetDetails(i); | |
4034 Map* next = TransitionArray::SearchTransition(current, details.kind(), name, | |
4035 details.attributes()); | |
4036 if (next == NULL) break; | |
4037 DescriptorArray* next_descriptors = next->instance_descriptors(); | |
4038 | |
4039 PropertyDetails next_details = next_descriptors->GetDetails(i); | |
4040 DCHECK_EQ(details.kind(), next_details.kind()); | |
4041 DCHECK_EQ(details.attributes(), next_details.attributes()); | |
4042 if (details.location() != next_details.location()) break; | |
4043 if (!details.representation().Equals(next_details.representation())) break; | |
4044 | |
4045 if (next_details.location() == kField) { | |
4046 FieldType* next_field_type = next_descriptors->GetFieldType(i); | |
4047 if (!descriptors->GetFieldType(i)->NowIs(next_field_type)) { | |
4048 break; | |
4049 } | |
4050 } else { | |
4051 if (!EqualImmutableValues(descriptors->GetValue(i), | |
4052 next_descriptors->GetValue(i))) { | |
4053 break; | |
4054 } | |
4055 } | |
4056 current = next; | |
4057 } | |
4058 return current; | |
4059 } | |
4060 | |
4061 | |
4062 Map* Map::FindFieldOwner(int descriptor) { | 4015 Map* Map::FindFieldOwner(int descriptor) { |
4063 DisallowHeapAllocation no_allocation; | 4016 DisallowHeapAllocation no_allocation; |
4064 DCHECK_EQ(DATA, instance_descriptors()->GetDetails(descriptor).type()); | 4017 DCHECK_EQ(DATA, instance_descriptors()->GetDetails(descriptor).type()); |
4065 Map* result = this; | 4018 Map* result = this; |
4066 Isolate* isolate = GetIsolate(); | 4019 Isolate* isolate = GetIsolate(); |
4067 while (true) { | 4020 while (true) { |
4068 Object* back = result->GetBackPointer(); | 4021 Object* back = result->GetBackPointer(); |
4069 if (back->IsUndefined(isolate)) break; | 4022 if (back->IsUndefined(isolate)) break; |
4070 Map* parent = Map::cast(back); | 4023 Map* parent = Map::cast(back); |
4071 if (parent->NumberOfOwnDescriptors() <= descriptor) break; | 4024 if (parent->NumberOfOwnDescriptors() <= descriptor) break; |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4132 if (FieldTypeIsCleared(rep1, *type1) || FieldTypeIsCleared(rep2, *type2)) { | 4085 if (FieldTypeIsCleared(rep1, *type1) || FieldTypeIsCleared(rep2, *type2)) { |
4133 return FieldType::Any(isolate); | 4086 return FieldType::Any(isolate); |
4134 } | 4087 } |
4135 if (type1->NowIs(type2)) return type2; | 4088 if (type1->NowIs(type2)) return type2; |
4136 if (type2->NowIs(type1)) return type1; | 4089 if (type2->NowIs(type1)) return type1; |
4137 return FieldType::Any(isolate); | 4090 return FieldType::Any(isolate); |
4138 } | 4091 } |
4139 | 4092 |
4140 | 4093 |
4141 // static | 4094 // static |
4142 void Map::GeneralizeFieldType(Handle<Map> map, int modify_index, | 4095 void Map::GeneralizeField(Handle<Map> map, int modify_index, |
4143 Representation new_representation, | 4096 Representation new_representation, |
4144 Handle<FieldType> new_field_type) { | 4097 Handle<FieldType> new_field_type) { |
4145 Isolate* isolate = map->GetIsolate(); | 4098 Isolate* isolate = map->GetIsolate(); |
4146 | 4099 |
4147 // Check if we actually need to generalize the field type at all. | 4100 // Check if we actually need to generalize the field type at all. |
4148 Handle<DescriptorArray> old_descriptors(map->instance_descriptors(), isolate); | 4101 Handle<DescriptorArray> old_descriptors(map->instance_descriptors(), isolate); |
4149 Representation old_representation = | 4102 Representation old_representation = |
4150 old_descriptors->GetDetails(modify_index).representation(); | 4103 old_descriptors->GetDetails(modify_index).representation(); |
4151 Handle<FieldType> old_field_type(old_descriptors->GetFieldType(modify_index), | 4104 Handle<FieldType> old_field_type(old_descriptors->GetFieldType(modify_index), |
4152 isolate); | 4105 isolate); |
4153 | 4106 |
4154 if (old_representation.Equals(new_representation) && | 4107 if (old_representation.Equals(new_representation) && |
4155 !FieldTypeIsCleared(new_representation, *new_field_type) && | 4108 !FieldTypeIsCleared(new_representation, *new_field_type) && |
4156 // Checking old_field_type for being cleared is not necessary because | 4109 // Checking old_field_type for being cleared is not necessary because |
4157 // the NowIs check below would fail anyway in that case. | 4110 // the NowIs check below would fail anyway in that case. |
4158 new_field_type->NowIs(old_field_type)) { | 4111 new_field_type->NowIs(old_field_type)) { |
4159 DCHECK(Map::GeneralizeFieldType(old_representation, old_field_type, | 4112 DCHECK(GeneralizeFieldType(old_representation, old_field_type, |
4160 new_representation, new_field_type, isolate) | 4113 new_representation, new_field_type, isolate) |
4161 ->NowIs(old_field_type)); | 4114 ->NowIs(old_field_type)); |
4162 return; | 4115 return; |
4163 } | 4116 } |
4164 | 4117 |
4165 // Determine the field owner. | 4118 // Determine the field owner. |
4166 Handle<Map> field_owner(map->FindFieldOwner(modify_index), isolate); | 4119 Handle<Map> field_owner(map->FindFieldOwner(modify_index), isolate); |
4167 Handle<DescriptorArray> descriptors( | 4120 Handle<DescriptorArray> descriptors( |
4168 field_owner->instance_descriptors(), isolate); | 4121 field_owner->instance_descriptors(), isolate); |
4169 DCHECK_EQ(*old_field_type, descriptors->GetFieldType(modify_index)); | 4122 DCHECK_EQ(*old_field_type, descriptors->GetFieldType(modify_index)); |
4170 | 4123 |
(...skipping 12 matching lines...) Expand all Loading... |
4183 | 4136 |
4184 if (FLAG_trace_generalization) { | 4137 if (FLAG_trace_generalization) { |
4185 map->PrintGeneralization( | 4138 map->PrintGeneralization( |
4186 stdout, "field type generalization", modify_index, | 4139 stdout, "field type generalization", modify_index, |
4187 map->NumberOfOwnDescriptors(), map->NumberOfOwnDescriptors(), false, | 4140 map->NumberOfOwnDescriptors(), map->NumberOfOwnDescriptors(), false, |
4188 details.representation(), details.representation(), old_field_type, | 4141 details.representation(), details.representation(), old_field_type, |
4189 MaybeHandle<Object>(), new_field_type, MaybeHandle<Object>()); | 4142 MaybeHandle<Object>(), new_field_type, MaybeHandle<Object>()); |
4190 } | 4143 } |
4191 } | 4144 } |
4192 | 4145 |
4193 static inline Handle<FieldType> GetFieldType( | 4146 // TODO(ishell): remove. |
4194 Isolate* isolate, Handle<DescriptorArray> descriptors, int descriptor, | 4147 // static |
4195 PropertyLocation location, Representation representation) { | 4148 Handle<Map> Map::ReconfigureProperty(Handle<Map> map, int modify_index, |
4196 #ifdef DEBUG | 4149 PropertyKind new_kind, |
4197 PropertyDetails details = descriptors->GetDetails(descriptor); | 4150 PropertyAttributes new_attributes, |
4198 DCHECK_EQ(kData, details.kind()); | 4151 Representation new_representation, |
4199 DCHECK_EQ(details.location(), location); | 4152 Handle<FieldType> new_field_type, |
4200 #endif | 4153 StoreMode store_mode) { |
4201 if (location == kField) { | 4154 DCHECK_EQ(kData, new_kind); // Only kData case is supported. |
4202 return handle(descriptors->GetFieldType(descriptor), isolate); | 4155 MapUpdater mu(map->GetIsolate(), map); |
4203 } else { | 4156 return mu.ReconfigureToDataField(modify_index, new_attributes, |
4204 return descriptors->GetValue(descriptor) | 4157 new_representation, new_field_type); |
4205 ->OptimalType(isolate, representation); | |
4206 } | |
4207 } | 4158 } |
4208 | 4159 |
4209 // Reconfigures elements kind to |new_elements_kind| and/or property at | 4160 // TODO(ishell): remove. |
4210 // |modify_index| with |new_kind|, |new_attributes|, |store_mode| and/or | 4161 // static |
4211 // |new_representation|/|new_field_type|. | 4162 Handle<Map> Map::ReconfigureElementsKind(Handle<Map> map, |
4212 // If |modify_index| is negative then no properties are reconfigured but the | 4163 ElementsKind new_elements_kind) { |
4213 // map is migrated to the up-to-date non-deprecated state. | 4164 MapUpdater mu(map->GetIsolate(), map); |
4214 // | 4165 return mu.ReconfigureElementsKind(new_elements_kind); |
4215 // This method rewrites or completes the transition tree to reflect the new | |
4216 // change. To avoid high degrees over polymorphism, and to stabilize quickly, | |
4217 // on every rewrite the new type is deduced by merging the current type with | |
4218 // any potential new (partial) version of the type in the transition tree. | |
4219 // To do this, on each rewrite: | |
4220 // - Search the root of the transition tree using FindRootMap. | |
4221 // - Find/create a |root_map| with requested |new_elements_kind|. | |
4222 // - Find |target_map|, the newest matching version of this map using the | |
4223 // virtually "enhanced" |old_map|'s descriptor array (i.e. whose entry at | |
4224 // |modify_index| is considered to be of |new_kind| and having | |
4225 // |new_attributes|) to walk the transition tree. | |
4226 // - Merge/generalize the "enhanced" descriptor array of the |old_map| and | |
4227 // descriptor array of the |target_map|. | |
4228 // - Generalize the |modify_index| descriptor using |new_representation| and | |
4229 // |new_field_type|. | |
4230 // - Walk the tree again starting from the root towards |target_map|. Stop at | |
4231 // |split_map|, the first map who's descriptor array does not match the merged | |
4232 // descriptor array. | |
4233 // - If |target_map| == |split_map|, |target_map| is in the expected state. | |
4234 // Return it. | |
4235 // - Otherwise, invalidate the outdated transition target from |target_map|, and | |
4236 // replace its transition tree with a new branch for the updated descriptors. | |
4237 Handle<Map> Map::Reconfigure(Handle<Map> old_map, | |
4238 ElementsKind new_elements_kind, int modify_index, | |
4239 PropertyKind new_kind, | |
4240 PropertyAttributes new_attributes, | |
4241 Representation new_representation, | |
4242 Handle<FieldType> new_field_type, | |
4243 StoreMode store_mode) { | |
4244 DCHECK_NE(kAccessor, new_kind); // TODO(ishell): not supported yet. | |
4245 DCHECK(store_mode != FORCE_FIELD || modify_index >= 0); | |
4246 Isolate* isolate = old_map->GetIsolate(); | |
4247 | |
4248 Handle<DescriptorArray> old_descriptors( | |
4249 old_map->instance_descriptors(), isolate); | |
4250 int old_nof = old_map->NumberOfOwnDescriptors(); | |
4251 | |
4252 // If it's just a representation generalization case (i.e. property kind and | |
4253 // attributes stays unchanged) it's fine to transition from None to anything | |
4254 // but double without any modification to the object, because the default | |
4255 // uninitialized value for representation None can be overwritten by both | |
4256 // smi and tagged values. Doubles, however, would require a box allocation. | |
4257 if (modify_index >= 0 && !new_representation.IsNone() && | |
4258 !new_representation.IsDouble() && | |
4259 old_map->elements_kind() == new_elements_kind) { | |
4260 PropertyDetails old_details = old_descriptors->GetDetails(modify_index); | |
4261 Representation old_representation = old_details.representation(); | |
4262 | |
4263 if (old_representation.IsNone()) { | |
4264 DCHECK_EQ(new_kind, old_details.kind()); | |
4265 DCHECK_EQ(new_attributes, old_details.attributes()); | |
4266 DCHECK_EQ(DATA, old_details.type()); | |
4267 if (FLAG_trace_generalization) { | |
4268 old_map->PrintGeneralization( | |
4269 stdout, "uninitialized field", modify_index, | |
4270 old_map->NumberOfOwnDescriptors(), | |
4271 old_map->NumberOfOwnDescriptors(), false, old_representation, | |
4272 new_representation, | |
4273 handle(old_descriptors->GetFieldType(modify_index), isolate), | |
4274 MaybeHandle<Object>(), new_field_type, MaybeHandle<Object>()); | |
4275 } | |
4276 Handle<Map> field_owner(old_map->FindFieldOwner(modify_index), isolate); | |
4277 | |
4278 GeneralizeFieldType(field_owner, modify_index, new_representation, | |
4279 new_field_type); | |
4280 DCHECK(old_descriptors->GetDetails(modify_index) | |
4281 .representation() | |
4282 .Equals(new_representation)); | |
4283 DCHECK( | |
4284 old_descriptors->GetFieldType(modify_index)->NowIs(new_field_type)); | |
4285 return old_map; | |
4286 } | |
4287 } | |
4288 | |
4289 // Check the state of the root map. | |
4290 Handle<Map> root_map(old_map->FindRootMap(), isolate); | |
4291 if (!old_map->EquivalentToForTransition(*root_map)) { | |
4292 return CopyGeneralizeAllRepresentations( | |
4293 old_map, new_elements_kind, modify_index, store_mode, new_kind, | |
4294 new_attributes, "GenAll_NotEquivalent"); | |
4295 } | |
4296 | |
4297 ElementsKind from_kind = root_map->elements_kind(); | |
4298 ElementsKind to_kind = new_elements_kind; | |
4299 // TODO(ishell): Add a test for SLOW_SLOPPY_ARGUMENTS_ELEMENTS. | |
4300 if (from_kind != to_kind && to_kind != DICTIONARY_ELEMENTS && | |
4301 to_kind != SLOW_STRING_WRAPPER_ELEMENTS && | |
4302 to_kind != SLOW_SLOPPY_ARGUMENTS_ELEMENTS && | |
4303 !(IsTransitionableFastElementsKind(from_kind) && | |
4304 IsMoreGeneralElementsKindTransition(from_kind, to_kind))) { | |
4305 return CopyGeneralizeAllRepresentations( | |
4306 old_map, to_kind, modify_index, store_mode, new_kind, new_attributes, | |
4307 "GenAll_InvalidElementsTransition"); | |
4308 } | |
4309 int root_nof = root_map->NumberOfOwnDescriptors(); | |
4310 if (modify_index >= 0 && modify_index < root_nof) { | |
4311 PropertyDetails old_details = old_descriptors->GetDetails(modify_index); | |
4312 if (old_details.kind() != new_kind || | |
4313 old_details.attributes() != new_attributes) { | |
4314 return CopyGeneralizeAllRepresentations( | |
4315 old_map, to_kind, modify_index, store_mode, new_kind, new_attributes, | |
4316 "GenAll_RootModification1"); | |
4317 } | |
4318 if ((old_details.type() != DATA && store_mode == FORCE_FIELD) || | |
4319 (old_details.type() == DATA && | |
4320 (!new_field_type->NowIs(old_descriptors->GetFieldType(modify_index)) || | |
4321 !new_representation.fits_into(old_details.representation())))) { | |
4322 return CopyGeneralizeAllRepresentations( | |
4323 old_map, to_kind, modify_index, store_mode, new_kind, new_attributes, | |
4324 "GenAll_RootModification2"); | |
4325 } | |
4326 } | |
4327 | |
4328 // From here on, use the map with correct elements kind as root map. | |
4329 if (from_kind != to_kind) { | |
4330 root_map = Map::AsElementsKind(root_map, to_kind); | |
4331 } | |
4332 | |
4333 Handle<Map> target_map = root_map; | |
4334 for (int i = root_nof; i < old_nof; ++i) { | |
4335 PropertyDetails old_details = old_descriptors->GetDetails(i); | |
4336 PropertyKind next_kind; | |
4337 PropertyLocation next_location; | |
4338 PropertyAttributes next_attributes; | |
4339 Representation next_representation; | |
4340 bool property_kind_reconfiguration = false; | |
4341 | |
4342 if (modify_index == i) { | |
4343 DCHECK_EQ(FORCE_FIELD, store_mode); | |
4344 property_kind_reconfiguration = old_details.kind() != new_kind; | |
4345 | |
4346 next_kind = new_kind; | |
4347 next_location = kField; | |
4348 next_attributes = new_attributes; | |
4349 // If property kind is not reconfigured merge the result with | |
4350 // representation/field type from the old descriptor. | |
4351 next_representation = new_representation; | |
4352 if (!property_kind_reconfiguration) { | |
4353 next_representation = | |
4354 next_representation.generalize(old_details.representation()); | |
4355 } | |
4356 | |
4357 } else { | |
4358 next_kind = old_details.kind(); | |
4359 next_location = old_details.location(); | |
4360 next_attributes = old_details.attributes(); | |
4361 next_representation = old_details.representation(); | |
4362 } | |
4363 Map* transition = TransitionArray::SearchTransition( | |
4364 *target_map, next_kind, old_descriptors->GetKey(i), next_attributes); | |
4365 if (transition == NULL) break; | |
4366 Handle<Map> tmp_map(transition, isolate); | |
4367 | |
4368 Handle<DescriptorArray> tmp_descriptors = handle( | |
4369 tmp_map->instance_descriptors(), isolate); | |
4370 | |
4371 // Check if target map is incompatible. | |
4372 PropertyDetails tmp_details = tmp_descriptors->GetDetails(i); | |
4373 DCHECK_EQ(next_kind, tmp_details.kind()); | |
4374 DCHECK_EQ(next_attributes, tmp_details.attributes()); | |
4375 if (next_kind == kAccessor && | |
4376 !EqualImmutableValues(old_descriptors->GetValue(i), | |
4377 tmp_descriptors->GetValue(i))) { | |
4378 return CopyGeneralizeAllRepresentations( | |
4379 old_map, to_kind, modify_index, store_mode, new_kind, new_attributes, | |
4380 "GenAll_Incompatible"); | |
4381 } | |
4382 if (next_location == kField && tmp_details.location() == kDescriptor) break; | |
4383 | |
4384 Representation tmp_representation = tmp_details.representation(); | |
4385 if (!next_representation.fits_into(tmp_representation)) break; | |
4386 | |
4387 PropertyLocation old_location = old_details.location(); | |
4388 PropertyLocation tmp_location = tmp_details.location(); | |
4389 if (tmp_location == kField) { | |
4390 if (next_kind == kData) { | |
4391 Handle<FieldType> next_field_type; | |
4392 if (modify_index == i) { | |
4393 next_field_type = new_field_type; | |
4394 if (!property_kind_reconfiguration) { | |
4395 Handle<FieldType> old_field_type = | |
4396 GetFieldType(isolate, old_descriptors, i, | |
4397 old_details.location(), tmp_representation); | |
4398 Representation old_representation = old_details.representation(); | |
4399 next_field_type = GeneralizeFieldType( | |
4400 old_representation, old_field_type, new_representation, | |
4401 next_field_type, isolate); | |
4402 } | |
4403 } else { | |
4404 Handle<FieldType> old_field_type = | |
4405 GetFieldType(isolate, old_descriptors, i, old_details.location(), | |
4406 tmp_representation); | |
4407 next_field_type = old_field_type; | |
4408 } | |
4409 GeneralizeFieldType(tmp_map, i, tmp_representation, next_field_type); | |
4410 } | |
4411 } else if (old_location == kField || | |
4412 !EqualImmutableValues(old_descriptors->GetValue(i), | |
4413 tmp_descriptors->GetValue(i))) { | |
4414 break; | |
4415 } | |
4416 DCHECK(!tmp_map->is_deprecated()); | |
4417 target_map = tmp_map; | |
4418 } | |
4419 | |
4420 // Directly change the map if the target map is more general. | |
4421 Handle<DescriptorArray> target_descriptors( | |
4422 target_map->instance_descriptors(), isolate); | |
4423 int target_nof = target_map->NumberOfOwnDescriptors(); | |
4424 if (target_nof == old_nof && | |
4425 (store_mode != FORCE_FIELD || | |
4426 (modify_index >= 0 && | |
4427 target_descriptors->GetDetails(modify_index).location() == kField))) { | |
4428 #ifdef DEBUG | |
4429 if (modify_index >= 0) { | |
4430 PropertyDetails details = target_descriptors->GetDetails(modify_index); | |
4431 DCHECK_EQ(new_kind, details.kind()); | |
4432 DCHECK_EQ(new_attributes, details.attributes()); | |
4433 DCHECK(new_representation.fits_into(details.representation())); | |
4434 DCHECK(details.location() != kField || | |
4435 new_field_type->NowIs( | |
4436 target_descriptors->GetFieldType(modify_index))); | |
4437 } | |
4438 #endif | |
4439 if (*target_map != *old_map) { | |
4440 old_map->NotifyLeafMapLayoutChange(); | |
4441 } | |
4442 return target_map; | |
4443 } | |
4444 | |
4445 // Find the last compatible target map in the transition tree. | |
4446 for (int i = target_nof; i < old_nof; ++i) { | |
4447 PropertyDetails old_details = old_descriptors->GetDetails(i); | |
4448 PropertyKind next_kind; | |
4449 PropertyAttributes next_attributes; | |
4450 if (modify_index == i) { | |
4451 next_kind = new_kind; | |
4452 next_attributes = new_attributes; | |
4453 } else { | |
4454 next_kind = old_details.kind(); | |
4455 next_attributes = old_details.attributes(); | |
4456 } | |
4457 Map* transition = TransitionArray::SearchTransition( | |
4458 *target_map, next_kind, old_descriptors->GetKey(i), next_attributes); | |
4459 if (transition == NULL) break; | |
4460 Handle<Map> tmp_map(transition, isolate); | |
4461 Handle<DescriptorArray> tmp_descriptors( | |
4462 tmp_map->instance_descriptors(), isolate); | |
4463 | |
4464 // Check if target map is compatible. | |
4465 #ifdef DEBUG | |
4466 PropertyDetails tmp_details = tmp_descriptors->GetDetails(i); | |
4467 DCHECK_EQ(next_kind, tmp_details.kind()); | |
4468 DCHECK_EQ(next_attributes, tmp_details.attributes()); | |
4469 #endif | |
4470 if (next_kind == kAccessor && | |
4471 !EqualImmutableValues(old_descriptors->GetValue(i), | |
4472 tmp_descriptors->GetValue(i))) { | |
4473 return CopyGeneralizeAllRepresentations( | |
4474 old_map, to_kind, modify_index, store_mode, new_kind, new_attributes, | |
4475 "GenAll_Incompatible"); | |
4476 } | |
4477 DCHECK(!tmp_map->is_deprecated()); | |
4478 target_map = tmp_map; | |
4479 } | |
4480 target_nof = target_map->NumberOfOwnDescriptors(); | |
4481 target_descriptors = handle(target_map->instance_descriptors(), isolate); | |
4482 | |
4483 // Allocate a new descriptor array large enough to hold the required | |
4484 // descriptors, with minimally the exact same size as the old descriptor | |
4485 // array. | |
4486 int new_slack = Max( | |
4487 old_nof, old_descriptors->number_of_descriptors()) - old_nof; | |
4488 Handle<DescriptorArray> new_descriptors = DescriptorArray::Allocate( | |
4489 isolate, old_nof, new_slack); | |
4490 DCHECK(new_descriptors->length() > target_descriptors->length() || | |
4491 new_descriptors->NumberOfSlackDescriptors() > 0 || | |
4492 new_descriptors->number_of_descriptors() == | |
4493 old_descriptors->number_of_descriptors()); | |
4494 DCHECK(new_descriptors->number_of_descriptors() == old_nof); | |
4495 | |
4496 // 0 -> |root_nof| | |
4497 int current_offset = 0; | |
4498 for (int i = 0; i < root_nof; ++i) { | |
4499 PropertyDetails old_details = old_descriptors->GetDetails(i); | |
4500 if (old_details.location() == kField) { | |
4501 current_offset += old_details.field_width_in_words(); | |
4502 } | |
4503 Descriptor d(handle(old_descriptors->GetKey(i), isolate), | |
4504 handle(old_descriptors->GetValue(i), isolate), | |
4505 old_details); | |
4506 new_descriptors->Set(i, &d); | |
4507 } | |
4508 | |
4509 // |root_nof| -> |target_nof| | |
4510 for (int i = root_nof; i < target_nof; ++i) { | |
4511 Handle<Name> target_key(target_descriptors->GetKey(i), isolate); | |
4512 PropertyDetails old_details = old_descriptors->GetDetails(i); | |
4513 PropertyDetails target_details = target_descriptors->GetDetails(i); | |
4514 | |
4515 PropertyKind next_kind; | |
4516 PropertyAttributes next_attributes; | |
4517 PropertyLocation next_location; | |
4518 Representation next_representation; | |
4519 bool property_kind_reconfiguration = false; | |
4520 | |
4521 if (modify_index == i) { | |
4522 DCHECK_EQ(FORCE_FIELD, store_mode); | |
4523 property_kind_reconfiguration = old_details.kind() != new_kind; | |
4524 | |
4525 next_kind = new_kind; | |
4526 next_attributes = new_attributes; | |
4527 next_location = kField; | |
4528 | |
4529 // Merge new representation/field type with ones from the target | |
4530 // descriptor. If property kind is not reconfigured merge the result with | |
4531 // representation/field type from the old descriptor. | |
4532 next_representation = | |
4533 new_representation.generalize(target_details.representation()); | |
4534 if (!property_kind_reconfiguration) { | |
4535 next_representation = | |
4536 next_representation.generalize(old_details.representation()); | |
4537 } | |
4538 } else { | |
4539 // Merge old_descriptor and target_descriptor entries. | |
4540 DCHECK_EQ(target_details.kind(), old_details.kind()); | |
4541 next_kind = target_details.kind(); | |
4542 next_attributes = target_details.attributes(); | |
4543 next_location = | |
4544 old_details.location() == kField || | |
4545 target_details.location() == kField || | |
4546 !EqualImmutableValues(target_descriptors->GetValue(i), | |
4547 old_descriptors->GetValue(i)) | |
4548 ? kField | |
4549 : kDescriptor; | |
4550 | |
4551 next_representation = old_details.representation().generalize( | |
4552 target_details.representation()); | |
4553 } | |
4554 DCHECK_EQ(next_kind, target_details.kind()); | |
4555 DCHECK_EQ(next_attributes, target_details.attributes()); | |
4556 | |
4557 if (next_location == kField) { | |
4558 if (next_kind == kData) { | |
4559 Handle<FieldType> target_field_type = | |
4560 GetFieldType(isolate, target_descriptors, i, | |
4561 target_details.location(), next_representation); | |
4562 | |
4563 Handle<FieldType> next_field_type; | |
4564 if (modify_index == i) { | |
4565 next_field_type = GeneralizeFieldType( | |
4566 target_details.representation(), target_field_type, | |
4567 new_representation, new_field_type, isolate); | |
4568 if (!property_kind_reconfiguration) { | |
4569 Handle<FieldType> old_field_type = | |
4570 GetFieldType(isolate, old_descriptors, i, | |
4571 old_details.location(), next_representation); | |
4572 next_field_type = GeneralizeFieldType( | |
4573 old_details.representation(), old_field_type, | |
4574 next_representation, next_field_type, isolate); | |
4575 } | |
4576 } else { | |
4577 Handle<FieldType> old_field_type = | |
4578 GetFieldType(isolate, old_descriptors, i, old_details.location(), | |
4579 next_representation); | |
4580 next_field_type = GeneralizeFieldType( | |
4581 old_details.representation(), old_field_type, next_representation, | |
4582 target_field_type, isolate); | |
4583 } | |
4584 Handle<Object> wrapped_type(WrapType(next_field_type)); | |
4585 Descriptor d = | |
4586 Descriptor::DataField(target_key, current_offset, wrapped_type, | |
4587 next_attributes, next_representation); | |
4588 current_offset += d.GetDetails().field_width_in_words(); | |
4589 new_descriptors->Set(i, &d); | |
4590 } else { | |
4591 UNIMPLEMENTED(); // TODO(ishell): implement. | |
4592 } | |
4593 } else { | |
4594 PropertyDetails details(next_attributes, next_kind, next_location, | |
4595 next_representation); | |
4596 Descriptor d(target_key, handle(target_descriptors->GetValue(i), isolate), | |
4597 details); | |
4598 new_descriptors->Set(i, &d); | |
4599 } | |
4600 } | |
4601 | |
4602 // |target_nof| -> |old_nof| | |
4603 for (int i = target_nof; i < old_nof; ++i) { | |
4604 PropertyDetails old_details = old_descriptors->GetDetails(i); | |
4605 Handle<Name> old_key(old_descriptors->GetKey(i), isolate); | |
4606 | |
4607 // Merge old_descriptor entry and modified details together. | |
4608 PropertyKind next_kind; | |
4609 PropertyAttributes next_attributes; | |
4610 PropertyLocation next_location; | |
4611 Representation next_representation; | |
4612 bool property_kind_reconfiguration = false; | |
4613 | |
4614 if (modify_index == i) { | |
4615 DCHECK_EQ(FORCE_FIELD, store_mode); | |
4616 // In case of property kind reconfiguration it is not necessary to | |
4617 // take into account representation/field type of the old descriptor. | |
4618 property_kind_reconfiguration = old_details.kind() != new_kind; | |
4619 | |
4620 next_kind = new_kind; | |
4621 next_attributes = new_attributes; | |
4622 next_location = kField; | |
4623 next_representation = new_representation; | |
4624 if (!property_kind_reconfiguration) { | |
4625 next_representation = | |
4626 next_representation.generalize(old_details.representation()); | |
4627 } | |
4628 } else { | |
4629 next_kind = old_details.kind(); | |
4630 next_attributes = old_details.attributes(); | |
4631 next_location = old_details.location(); | |
4632 next_representation = old_details.representation(); | |
4633 } | |
4634 | |
4635 if (next_location == kField) { | |
4636 if (next_kind == kData) { | |
4637 Handle<FieldType> next_field_type; | |
4638 if (modify_index == i) { | |
4639 next_field_type = new_field_type; | |
4640 if (!property_kind_reconfiguration) { | |
4641 Handle<FieldType> old_field_type = | |
4642 GetFieldType(isolate, old_descriptors, i, | |
4643 old_details.location(), next_representation); | |
4644 next_field_type = GeneralizeFieldType( | |
4645 old_details.representation(), old_field_type, | |
4646 next_representation, next_field_type, isolate); | |
4647 } | |
4648 } else { | |
4649 Handle<FieldType> old_field_type = | |
4650 GetFieldType(isolate, old_descriptors, i, old_details.location(), | |
4651 next_representation); | |
4652 next_field_type = old_field_type; | |
4653 } | |
4654 | |
4655 Handle<Object> wrapped_type(WrapType(next_field_type)); | |
4656 | |
4657 Descriptor d = | |
4658 Descriptor::DataField(old_key, current_offset, wrapped_type, | |
4659 next_attributes, next_representation); | |
4660 current_offset += d.GetDetails().field_width_in_words(); | |
4661 new_descriptors->Set(i, &d); | |
4662 } else { | |
4663 UNIMPLEMENTED(); // TODO(ishell): implement. | |
4664 } | |
4665 } else { | |
4666 PropertyDetails details(next_attributes, next_kind, next_location, | |
4667 next_representation); | |
4668 Descriptor d(old_key, handle(old_descriptors->GetValue(i), isolate), | |
4669 details); | |
4670 new_descriptors->Set(i, &d); | |
4671 } | |
4672 } | |
4673 | |
4674 new_descriptors->Sort(); | |
4675 | |
4676 DCHECK(store_mode != FORCE_FIELD || | |
4677 new_descriptors->GetDetails(modify_index).location() == kField); | |
4678 | |
4679 Handle<Map> split_map(root_map->FindLastMatchMap( | |
4680 root_nof, old_nof, *new_descriptors), isolate); | |
4681 int split_nof = split_map->NumberOfOwnDescriptors(); | |
4682 DCHECK_NE(old_nof, split_nof); | |
4683 | |
4684 PropertyKind split_kind; | |
4685 PropertyAttributes split_attributes; | |
4686 if (modify_index == split_nof) { | |
4687 split_kind = new_kind; | |
4688 split_attributes = new_attributes; | |
4689 } else { | |
4690 PropertyDetails split_prop_details = old_descriptors->GetDetails(split_nof); | |
4691 split_kind = split_prop_details.kind(); | |
4692 split_attributes = split_prop_details.attributes(); | |
4693 } | |
4694 | |
4695 // Invalidate a transition target at |key|. | |
4696 Map* maybe_transition = TransitionArray::SearchTransition( | |
4697 *split_map, split_kind, old_descriptors->GetKey(split_nof), | |
4698 split_attributes); | |
4699 if (maybe_transition != NULL) { | |
4700 maybe_transition->DeprecateTransitionTree(); | |
4701 } | |
4702 | |
4703 // If |maybe_transition| is not NULL then the transition array already | |
4704 // contains entry for given descriptor. This means that the transition | |
4705 // could be inserted regardless of whether transitions array is full or not. | |
4706 if (maybe_transition == NULL && | |
4707 !TransitionArray::CanHaveMoreTransitions(split_map)) { | |
4708 return CopyGeneralizeAllRepresentations( | |
4709 old_map, to_kind, modify_index, store_mode, new_kind, new_attributes, | |
4710 "GenAll_CantHaveMoreTransitions"); | |
4711 } | |
4712 | |
4713 old_map->NotifyLeafMapLayoutChange(); | |
4714 | |
4715 if (FLAG_trace_generalization && modify_index >= 0) { | |
4716 PropertyDetails old_details = old_descriptors->GetDetails(modify_index); | |
4717 PropertyDetails new_details = new_descriptors->GetDetails(modify_index); | |
4718 MaybeHandle<FieldType> old_field_type; | |
4719 MaybeHandle<FieldType> new_field_type; | |
4720 MaybeHandle<Object> old_value; | |
4721 MaybeHandle<Object> new_value; | |
4722 if (old_details.type() == DATA) { | |
4723 old_field_type = | |
4724 handle(old_descriptors->GetFieldType(modify_index), isolate); | |
4725 } else { | |
4726 old_value = handle(old_descriptors->GetValue(modify_index), isolate); | |
4727 } | |
4728 if (new_details.type() == DATA) { | |
4729 new_field_type = | |
4730 handle(new_descriptors->GetFieldType(modify_index), isolate); | |
4731 } else { | |
4732 new_value = handle(new_descriptors->GetValue(modify_index), isolate); | |
4733 } | |
4734 | |
4735 old_map->PrintGeneralization( | |
4736 stdout, "", modify_index, split_nof, old_nof, | |
4737 old_details.location() == kDescriptor && store_mode == FORCE_FIELD, | |
4738 old_details.representation(), new_details.representation(), | |
4739 old_field_type, old_value, new_field_type, new_value); | |
4740 } | |
4741 | |
4742 Handle<LayoutDescriptor> new_layout_descriptor = | |
4743 LayoutDescriptor::New(split_map, new_descriptors, old_nof); | |
4744 | |
4745 Handle<Map> new_map = | |
4746 AddMissingTransitions(split_map, new_descriptors, new_layout_descriptor); | |
4747 | |
4748 // Deprecated part of the transition tree is no longer reachable, so replace | |
4749 // current instance descriptors in the "survived" part of the tree with | |
4750 // the new descriptors to maintain descriptors sharing invariant. | |
4751 split_map->ReplaceDescriptors(*new_descriptors, *new_layout_descriptor); | |
4752 return new_map; | |
4753 } | 4166 } |
4754 | 4167 |
4755 | |
4756 // Generalize the representation of all DATA descriptors. | 4168 // Generalize the representation of all DATA descriptors. |
4757 Handle<Map> Map::GeneralizeAllFieldRepresentations( | 4169 Handle<Map> Map::GeneralizeAllFieldRepresentations( |
4758 Handle<Map> map) { | 4170 Handle<Map> map) { |
| 4171 Isolate* isolate = map->GetIsolate(); |
| 4172 Handle<FieldType> any_type = FieldType::Any(isolate); |
| 4173 |
4759 Handle<DescriptorArray> descriptors(map->instance_descriptors()); | 4174 Handle<DescriptorArray> descriptors(map->instance_descriptors()); |
4760 for (int i = 0; i < map->NumberOfOwnDescriptors(); ++i) { | 4175 for (int i = 0; i < map->NumberOfOwnDescriptors(); ++i) { |
4761 PropertyDetails details = descriptors->GetDetails(i); | 4176 PropertyDetails details = descriptors->GetDetails(i); |
4762 if (details.type() == DATA) { | 4177 if (details.type() == DATA) { |
4763 map = ReconfigureProperty(map, i, kData, details.attributes(), | 4178 MapUpdater mu(isolate, map); |
4764 Representation::Tagged(), | 4179 map = mu.ReconfigureToDataField(i, details.attributes(), |
4765 FieldType::Any(map->GetIsolate()), FORCE_FIELD); | 4180 Representation::Tagged(), any_type); |
4766 } | 4181 } |
4767 } | 4182 } |
4768 return map; | 4183 return map; |
4769 } | 4184 } |
4770 | 4185 |
4771 | 4186 |
4772 // static | 4187 // static |
4773 MaybeHandle<Map> Map::TryUpdate(Handle<Map> old_map) { | 4188 MaybeHandle<Map> Map::TryUpdate(Handle<Map> old_map) { |
4774 DisallowHeapAllocation no_allocation; | 4189 DisallowHeapAllocation no_allocation; |
4775 DisallowDeoptimization no_deoptimization(old_map->GetIsolate()); | 4190 DisallowDeoptimization no_deoptimization(old_map->GetIsolate()); |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4862 } | 4277 } |
4863 } | 4278 } |
4864 if (new_map->NumberOfOwnDescriptors() != old_nof) return nullptr; | 4279 if (new_map->NumberOfOwnDescriptors() != old_nof) return nullptr; |
4865 return new_map; | 4280 return new_map; |
4866 } | 4281 } |
4867 | 4282 |
4868 | 4283 |
4869 // static | 4284 // static |
4870 Handle<Map> Map::Update(Handle<Map> map) { | 4285 Handle<Map> Map::Update(Handle<Map> map) { |
4871 if (!map->is_deprecated()) return map; | 4286 if (!map->is_deprecated()) return map; |
4872 return ReconfigureProperty(map, -1, kData, NONE, Representation::None(), | 4287 MapUpdater mu(map->GetIsolate(), map); |
4873 FieldType::None(map->GetIsolate()), | 4288 return mu.Update(); |
4874 ALLOW_IN_DESCRIPTOR); | |
4875 } | 4289 } |
4876 | 4290 |
4877 Maybe<bool> JSObject::SetPropertyWithInterceptor(LookupIterator* it, | 4291 Maybe<bool> JSObject::SetPropertyWithInterceptor(LookupIterator* it, |
4878 ShouldThrow should_throw, | 4292 ShouldThrow should_throw, |
4879 Handle<Object> value) { | 4293 Handle<Object> value) { |
4880 DCHECK_EQ(LookupIterator::INTERCEPTOR, it->state()); | 4294 DCHECK_EQ(LookupIterator::INTERCEPTOR, it->state()); |
4881 return SetPropertyWithInterceptorInternal(it, it->GetInterceptor(), | 4295 return SetPropertyWithInterceptorInternal(it, it->GetInterceptor(), |
4882 should_throw, value); | 4296 should_throw, value); |
4883 } | 4297 } |
4884 | 4298 |
(...skipping 4861 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9746 Handle<Map> UpdateDescriptorForValue(Handle<Map> map, int descriptor, | 9160 Handle<Map> UpdateDescriptorForValue(Handle<Map> map, int descriptor, |
9747 Handle<Object> value) { | 9161 Handle<Object> value) { |
9748 if (CanHoldValue(map->instance_descriptors(), descriptor, *value)) return map; | 9162 if (CanHoldValue(map->instance_descriptors(), descriptor, *value)) return map; |
9749 | 9163 |
9750 Isolate* isolate = map->GetIsolate(); | 9164 Isolate* isolate = map->GetIsolate(); |
9751 PropertyAttributes attributes = | 9165 PropertyAttributes attributes = |
9752 map->instance_descriptors()->GetDetails(descriptor).attributes(); | 9166 map->instance_descriptors()->GetDetails(descriptor).attributes(); |
9753 Representation representation = value->OptimalRepresentation(); | 9167 Representation representation = value->OptimalRepresentation(); |
9754 Handle<FieldType> type = value->OptimalType(isolate, representation); | 9168 Handle<FieldType> type = value->OptimalType(isolate, representation); |
9755 | 9169 |
9756 return Map::ReconfigureProperty(map, descriptor, kData, attributes, | 9170 MapUpdater mu(isolate, map); |
9757 representation, type, FORCE_FIELD); | 9171 return mu.ReconfigureToDataField(descriptor, attributes, representation, |
| 9172 type); |
9758 } | 9173 } |
9759 | 9174 |
9760 } // namespace | 9175 } // namespace |
9761 | 9176 |
9762 // static | 9177 // static |
9763 Handle<Map> Map::PrepareForDataProperty(Handle<Map> map, int descriptor, | 9178 Handle<Map> Map::PrepareForDataProperty(Handle<Map> map, int descriptor, |
9764 Handle<Object> value) { | 9179 Handle<Object> value) { |
9765 // Dictionaries can store any property value. | 9180 // Dictionaries can store any property value. |
9766 DCHECK(!map->is_dictionary_map()); | 9181 DCHECK(!map->is_dictionary_map()); |
9767 // Update to the newest map before storing the property. | 9182 // Update to the newest map before storing the property. |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9840 return CopyGeneralizeAllRepresentations( | 9255 return CopyGeneralizeAllRepresentations( |
9841 map, map->elements_kind(), descriptor, FORCE_FIELD, kind, attributes, | 9256 map, map->elements_kind(), descriptor, FORCE_FIELD, kind, attributes, |
9842 "GenAll_AttributesMismatchProtoMap"); | 9257 "GenAll_AttributesMismatchProtoMap"); |
9843 } | 9258 } |
9844 | 9259 |
9845 if (FLAG_trace_generalization) { | 9260 if (FLAG_trace_generalization) { |
9846 map->PrintReconfiguration(stdout, descriptor, kind, attributes); | 9261 map->PrintReconfiguration(stdout, descriptor, kind, attributes); |
9847 } | 9262 } |
9848 | 9263 |
9849 Isolate* isolate = map->GetIsolate(); | 9264 Isolate* isolate = map->GetIsolate(); |
9850 Handle<Map> new_map = ReconfigureProperty( | 9265 |
9851 map, descriptor, kind, attributes, Representation::None(), | 9266 MapUpdater mu(isolate, map); |
9852 FieldType::None(isolate), FORCE_FIELD); | 9267 DCHECK_EQ(kData, kind); // Only kData case is supported so far. |
| 9268 Handle<Map> new_map = mu.ReconfigureToDataField( |
| 9269 descriptor, attributes, Representation::None(), FieldType::None(isolate)); |
9853 return new_map; | 9270 return new_map; |
9854 } | 9271 } |
9855 | 9272 |
9856 Handle<Map> Map::TransitionToAccessorProperty(Isolate* isolate, Handle<Map> map, | 9273 Handle<Map> Map::TransitionToAccessorProperty(Isolate* isolate, Handle<Map> map, |
9857 Handle<Name> name, int descriptor, | 9274 Handle<Name> name, int descriptor, |
9858 Handle<Object> getter, | 9275 Handle<Object> getter, |
9859 Handle<Object> setter, | 9276 Handle<Object> setter, |
9860 PropertyAttributes attributes) { | 9277 PropertyAttributes attributes) { |
9861 RuntimeCallTimerScope stats_scope( | 9278 RuntimeCallTimerScope stats_scope( |
9862 isolate, | 9279 isolate, |
(...skipping 10628 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
20491 // depend on this. | 19908 // depend on this. |
20492 return DICTIONARY_ELEMENTS; | 19909 return DICTIONARY_ELEMENTS; |
20493 } | 19910 } |
20494 DCHECK_LE(kind, LAST_ELEMENTS_KIND); | 19911 DCHECK_LE(kind, LAST_ELEMENTS_KIND); |
20495 return kind; | 19912 return kind; |
20496 } | 19913 } |
20497 } | 19914 } |
20498 | 19915 |
20499 } // namespace internal | 19916 } // namespace internal |
20500 } // namespace v8 | 19917 } // namespace v8 |
OLD | NEW |