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 4524 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4535 } else { | 4535 } else { |
4536 // Migrate to the most up-to-date map that will be able to store |value| | 4536 // Migrate to the most up-to-date map that will be able to store |value| |
4537 // under it->name() with |attributes|. | 4537 // under it->name() with |attributes|. |
4538 it->PrepareTransitionToDataProperty(receiver, value, attributes, | 4538 it->PrepareTransitionToDataProperty(receiver, value, attributes, |
4539 store_mode); | 4539 store_mode); |
4540 DCHECK_EQ(LookupIterator::TRANSITION, it->state()); | 4540 DCHECK_EQ(LookupIterator::TRANSITION, it->state()); |
4541 it->ApplyTransitionToDataProperty(receiver); | 4541 it->ApplyTransitionToDataProperty(receiver); |
4542 | 4542 |
4543 // TODO(verwaest): Encapsulate dictionary handling better. | 4543 // TODO(verwaest): Encapsulate dictionary handling better. |
4544 if (receiver->map()->is_dictionary_map()) { | 4544 if (receiver->map()->is_dictionary_map()) { |
4545 // TODO(verwaest): Probably should ensure this is done beforehand. | |
4546 it->InternalizeName(); | |
4547 // TODO(dcarney): just populate TransitionPropertyCell here? | 4545 // TODO(dcarney): just populate TransitionPropertyCell here? |
4548 JSObject::AddSlowProperty(receiver, it->name(), value, attributes); | 4546 JSObject::AddSlowProperty(receiver, it->name(), value, attributes); |
4549 } else { | 4547 } else { |
4550 // Write the property value. | 4548 // Write the property value. |
4551 it->WriteDataValue(value); | 4549 it->WriteDataValue(value); |
4552 } | 4550 } |
4553 | 4551 |
4554 // Send the change record if there are observers. | 4552 // Send the change record if there are observers. |
4555 if (receiver->map()->is_observed() && !it->name()->IsPrivate()) { | 4553 if (receiver->map()->is_observed() && !it->name()->IsPrivate()) { |
4556 RETURN_ON_EXCEPTION_VALUE(isolate, JSObject::EnqueueChangeRecord( | 4554 RETURN_ON_EXCEPTION_VALUE(isolate, JSObject::EnqueueChangeRecord( |
(...skipping 5299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9856 DCHECK(!map->is_dictionary_map()); | 9854 DCHECK(!map->is_dictionary_map()); |
9857 // Update to the newest map before storing the property. | 9855 // Update to the newest map before storing the property. |
9858 return UpdateDescriptorForValue(Update(map), descriptor, value); | 9856 return UpdateDescriptorForValue(Update(map), descriptor, value); |
9859 } | 9857 } |
9860 | 9858 |
9861 | 9859 |
9862 Handle<Map> Map::TransitionToDataProperty(Handle<Map> map, Handle<Name> name, | 9860 Handle<Map> Map::TransitionToDataProperty(Handle<Map> map, Handle<Name> name, |
9863 Handle<Object> value, | 9861 Handle<Object> value, |
9864 PropertyAttributes attributes, | 9862 PropertyAttributes attributes, |
9865 StoreFromKeyed store_mode) { | 9863 StoreFromKeyed store_mode) { |
| 9864 DCHECK(name->IsUniqueName()); |
9866 DCHECK(!map->is_dictionary_map()); | 9865 DCHECK(!map->is_dictionary_map()); |
9867 | 9866 |
9868 // Migrate to the newest map before storing the property. | 9867 // Migrate to the newest map before storing the property. |
9869 map = Update(map); | 9868 map = Update(map); |
9870 | 9869 |
9871 Map* maybe_transition = | 9870 Map* maybe_transition = |
9872 TransitionArray::SearchTransition(*map, kData, *name, attributes); | 9871 TransitionArray::SearchTransition(*map, kData, *name, attributes); |
9873 if (maybe_transition != NULL) { | 9872 if (maybe_transition != NULL) { |
9874 Handle<Map> transition(maybe_transition); | 9873 Handle<Map> transition(maybe_transition); |
9875 int descriptor = transition->LastAdded(); | 9874 int descriptor = transition->LastAdded(); |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9936 FieldType::None(isolate), FORCE_FIELD); | 9935 FieldType::None(isolate), FORCE_FIELD); |
9937 return new_map; | 9936 return new_map; |
9938 } | 9937 } |
9939 | 9938 |
9940 | 9939 |
9941 Handle<Map> Map::TransitionToAccessorProperty(Handle<Map> map, | 9940 Handle<Map> Map::TransitionToAccessorProperty(Handle<Map> map, |
9942 Handle<Name> name, | 9941 Handle<Name> name, |
9943 AccessorComponent component, | 9942 AccessorComponent component, |
9944 Handle<Object> accessor, | 9943 Handle<Object> accessor, |
9945 PropertyAttributes attributes) { | 9944 PropertyAttributes attributes) { |
| 9945 DCHECK(name->IsUniqueName()); |
9946 Isolate* isolate = name->GetIsolate(); | 9946 Isolate* isolate = name->GetIsolate(); |
9947 | 9947 |
9948 // Dictionary maps can always have additional data properties. | 9948 // Dictionary maps can always have additional data properties. |
9949 if (map->is_dictionary_map()) return map; | 9949 if (map->is_dictionary_map()) return map; |
9950 | 9950 |
9951 // Migrate to the newest map before transitioning to the new property. | 9951 // Migrate to the newest map before transitioning to the new property. |
9952 map = Update(map); | 9952 map = Update(map); |
9953 | 9953 |
9954 PropertyNormalizationMode mode = map->is_prototype_map() | 9954 PropertyNormalizationMode mode = map->is_prototype_map() |
9955 ? KEEP_INOBJECT_PROPERTIES | 9955 ? KEEP_INOBJECT_PROPERTIES |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10020 AccessorConstantDescriptor new_desc(name, pair, attributes); | 10020 AccessorConstantDescriptor new_desc(name, pair, attributes); |
10021 return Map::CopyInsertDescriptor(map, &new_desc, flag); | 10021 return Map::CopyInsertDescriptor(map, &new_desc, flag); |
10022 } | 10022 } |
10023 | 10023 |
10024 | 10024 |
10025 Handle<Map> Map::CopyAddDescriptor(Handle<Map> map, | 10025 Handle<Map> Map::CopyAddDescriptor(Handle<Map> map, |
10026 Descriptor* descriptor, | 10026 Descriptor* descriptor, |
10027 TransitionFlag flag) { | 10027 TransitionFlag flag) { |
10028 Handle<DescriptorArray> descriptors(map->instance_descriptors()); | 10028 Handle<DescriptorArray> descriptors(map->instance_descriptors()); |
10029 | 10029 |
10030 // Ensure the key is unique. | |
10031 descriptor->KeyToUniqueName(); | |
10032 | |
10033 // Share descriptors only if map owns descriptors and it not an initial map. | 10030 // Share descriptors only if map owns descriptors and it not an initial map. |
10034 if (flag == INSERT_TRANSITION && map->owns_descriptors() && | 10031 if (flag == INSERT_TRANSITION && map->owns_descriptors() && |
10035 !map->GetBackPointer()->IsUndefined() && | 10032 !map->GetBackPointer()->IsUndefined() && |
10036 TransitionArray::CanHaveMoreTransitions(map)) { | 10033 TransitionArray::CanHaveMoreTransitions(map)) { |
10037 return ShareDescriptor(map, descriptors, descriptor); | 10034 return ShareDescriptor(map, descriptors, descriptor); |
10038 } | 10035 } |
10039 | 10036 |
10040 int nof = map->NumberOfOwnDescriptors(); | 10037 int nof = map->NumberOfOwnDescriptors(); |
10041 Handle<DescriptorArray> new_descriptors = | 10038 Handle<DescriptorArray> new_descriptors = |
10042 DescriptorArray::CopyUpTo(descriptors, nof, 1); | 10039 DescriptorArray::CopyUpTo(descriptors, nof, 1); |
10043 new_descriptors->Append(descriptor); | 10040 new_descriptors->Append(descriptor); |
10044 | 10041 |
10045 Handle<LayoutDescriptor> new_layout_descriptor = | 10042 Handle<LayoutDescriptor> new_layout_descriptor = |
10046 FLAG_unbox_double_fields | 10043 FLAG_unbox_double_fields |
10047 ? LayoutDescriptor::New(map, new_descriptors, nof + 1) | 10044 ? LayoutDescriptor::New(map, new_descriptors, nof + 1) |
10048 : handle(LayoutDescriptor::FastPointerLayout(), map->GetIsolate()); | 10045 : handle(LayoutDescriptor::FastPointerLayout(), map->GetIsolate()); |
10049 | 10046 |
10050 return CopyReplaceDescriptors(map, new_descriptors, new_layout_descriptor, | 10047 return CopyReplaceDescriptors(map, new_descriptors, new_layout_descriptor, |
10051 flag, descriptor->GetKey(), "CopyAddDescriptor", | 10048 flag, descriptor->GetKey(), "CopyAddDescriptor", |
10052 SIMPLE_PROPERTY_TRANSITION); | 10049 SIMPLE_PROPERTY_TRANSITION); |
10053 } | 10050 } |
10054 | 10051 |
10055 | 10052 |
10056 Handle<Map> Map::CopyInsertDescriptor(Handle<Map> map, | 10053 Handle<Map> Map::CopyInsertDescriptor(Handle<Map> map, |
10057 Descriptor* descriptor, | 10054 Descriptor* descriptor, |
10058 TransitionFlag flag) { | 10055 TransitionFlag flag) { |
10059 Handle<DescriptorArray> old_descriptors(map->instance_descriptors()); | 10056 Handle<DescriptorArray> old_descriptors(map->instance_descriptors()); |
10060 | 10057 |
10061 // Ensure the key is unique. | |
10062 descriptor->KeyToUniqueName(); | |
10063 | |
10064 // We replace the key if it is already present. | 10058 // We replace the key if it is already present. |
10065 int index = old_descriptors->SearchWithCache(map->GetIsolate(), | 10059 int index = old_descriptors->SearchWithCache(map->GetIsolate(), |
10066 *descriptor->GetKey(), *map); | 10060 *descriptor->GetKey(), *map); |
10067 if (index != DescriptorArray::kNotFound) { | 10061 if (index != DescriptorArray::kNotFound) { |
10068 return CopyReplaceDescriptor(map, old_descriptors, descriptor, index, flag); | 10062 return CopyReplaceDescriptor(map, old_descriptors, descriptor, index, flag); |
10069 } | 10063 } |
10070 return CopyAddDescriptor(map, descriptor, flag); | 10064 return CopyAddDescriptor(map, descriptor, flag); |
10071 } | 10065 } |
10072 | 10066 |
10073 | 10067 |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10139 } | 10133 } |
10140 return true; | 10134 return true; |
10141 } | 10135 } |
10142 | 10136 |
10143 | 10137 |
10144 Handle<Map> Map::CopyReplaceDescriptor(Handle<Map> map, | 10138 Handle<Map> Map::CopyReplaceDescriptor(Handle<Map> map, |
10145 Handle<DescriptorArray> descriptors, | 10139 Handle<DescriptorArray> descriptors, |
10146 Descriptor* descriptor, | 10140 Descriptor* descriptor, |
10147 int insertion_index, | 10141 int insertion_index, |
10148 TransitionFlag flag) { | 10142 TransitionFlag flag) { |
10149 // Ensure the key is unique. | |
10150 descriptor->KeyToUniqueName(); | |
10151 | |
10152 Handle<Name> key = descriptor->GetKey(); | 10143 Handle<Name> key = descriptor->GetKey(); |
10153 DCHECK(*key == descriptors->GetKey(insertion_index)); | 10144 DCHECK(*key == descriptors->GetKey(insertion_index)); |
10154 | 10145 |
10155 Handle<DescriptorArray> new_descriptors = DescriptorArray::CopyUpTo( | 10146 Handle<DescriptorArray> new_descriptors = DescriptorArray::CopyUpTo( |
10156 descriptors, map->NumberOfOwnDescriptors()); | 10147 descriptors, map->NumberOfOwnDescriptors()); |
10157 | 10148 |
10158 new_descriptors->Replace(insertion_index, descriptor); | 10149 new_descriptors->Replace(insertion_index, descriptor); |
10159 Handle<LayoutDescriptor> new_layout_descriptor = LayoutDescriptor::New( | 10150 Handle<LayoutDescriptor> new_layout_descriptor = LayoutDescriptor::New( |
10160 map, new_descriptors, new_descriptors->number_of_descriptors()); | 10151 map, new_descriptors, new_descriptors->number_of_descriptors()); |
10161 | 10152 |
(...skipping 9725 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
19887 if (cell->value() != *new_value) { | 19878 if (cell->value() != *new_value) { |
19888 cell->set_value(*new_value); | 19879 cell->set_value(*new_value); |
19889 Isolate* isolate = cell->GetIsolate(); | 19880 Isolate* isolate = cell->GetIsolate(); |
19890 cell->dependent_code()->DeoptimizeDependentCodeGroup( | 19881 cell->dependent_code()->DeoptimizeDependentCodeGroup( |
19891 isolate, DependentCode::kPropertyCellChangedGroup); | 19882 isolate, DependentCode::kPropertyCellChangedGroup); |
19892 } | 19883 } |
19893 } | 19884 } |
19894 | 19885 |
19895 } // namespace internal | 19886 } // namespace internal |
19896 } // namespace v8 | 19887 } // namespace v8 |
OLD | NEW |