OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <sstream> | 5 #include <sstream> |
6 | 6 |
7 #include "src/v8.h" | 7 #include "src/v8.h" |
8 | 8 |
9 #include "src/accessors.h" | 9 #include "src/accessors.h" |
10 #include "src/allocation-site-scopes.h" | 10 #include "src/allocation-site-scopes.h" |
(...skipping 4262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4273 DCHECK(!object->IsGlobalObject()); | 4273 DCHECK(!object->IsGlobalObject()); |
4274 Isolate* isolate = object->GetIsolate(); | 4274 Isolate* isolate = object->GetIsolate(); |
4275 Factory* factory = isolate->factory(); | 4275 Factory* factory = isolate->factory(); |
4276 Handle<NameDictionary> dictionary(object->property_dictionary()); | 4276 Handle<NameDictionary> dictionary(object->property_dictionary()); |
4277 | 4277 |
4278 // Make sure we preserve dictionary representation if there are too many | 4278 // Make sure we preserve dictionary representation if there are too many |
4279 // descriptors. | 4279 // descriptors. |
4280 int number_of_elements = dictionary->NumberOfElements(); | 4280 int number_of_elements = dictionary->NumberOfElements(); |
4281 if (number_of_elements > kMaxNumberOfDescriptors) return; | 4281 if (number_of_elements > kMaxNumberOfDescriptors) return; |
4282 | 4282 |
| 4283 Handle<FixedArray> iteration_order; |
4283 if (number_of_elements != dictionary->NextEnumerationIndex()) { | 4284 if (number_of_elements != dictionary->NextEnumerationIndex()) { |
4284 NameDictionary::DoGenerateNewEnumerationIndices(dictionary); | 4285 iteration_order = |
| 4286 NameDictionary::DoGenerateNewEnumerationIndices(dictionary); |
| 4287 } else { |
| 4288 iteration_order = NameDictionary::BuildIterationIndicesArray(dictionary); |
4285 } | 4289 } |
4286 | 4290 |
4287 int instance_descriptor_length = 0; | 4291 int instance_descriptor_length = iteration_order->length(); |
4288 int number_of_fields = 0; | 4292 int number_of_fields = 0; |
4289 | 4293 |
4290 // Compute the length of the instance descriptor. | 4294 // Compute the length of the instance descriptor. |
4291 int capacity = dictionary->Capacity(); | 4295 for (int i = 0; i < instance_descriptor_length; i++) { |
4292 for (int i = 0; i < capacity; i++) { | 4296 int index = Smi::cast(iteration_order->get(i))->value(); |
4293 Object* k = dictionary->KeyAt(i); | 4297 DCHECK(dictionary->IsKey(dictionary->KeyAt(index))); |
4294 if (dictionary->IsKey(k)) { | 4298 |
4295 Object* value = dictionary->ValueAt(i); | 4299 Object* value = dictionary->ValueAt(index); |
4296 PropertyType type = dictionary->DetailsAt(i).type(); | 4300 PropertyType type = dictionary->DetailsAt(index).type(); |
4297 DCHECK(type != FIELD); | 4301 DCHECK(type != FIELD); |
4298 instance_descriptor_length++; | 4302 if (type == NORMAL && !value->IsJSFunction()) { |
4299 if (type == NORMAL && !value->IsJSFunction()) { | 4303 number_of_fields += 1; |
4300 number_of_fields += 1; | |
4301 } | |
4302 } | 4304 } |
4303 } | 4305 } |
4304 | 4306 |
4305 int inobject_props = object->map()->inobject_properties(); | 4307 int inobject_props = object->map()->inobject_properties(); |
4306 | 4308 |
4307 // Allocate new map. | 4309 // Allocate new map. |
4308 Handle<Map> new_map = Map::CopyDropDescriptors(handle(object->map())); | 4310 Handle<Map> new_map = Map::CopyDropDescriptors(handle(object->map())); |
4309 new_map->set_dictionary_map(false); | 4311 new_map->set_dictionary_map(false); |
4310 | 4312 |
4311 if (instance_descriptor_length == 0) { | 4313 if (instance_descriptor_length == 0) { |
(...skipping 19 matching lines...) Expand all Loading... |
4331 number_of_allocated_fields = 0; | 4333 number_of_allocated_fields = 0; |
4332 unused_property_fields = inobject_props - number_of_fields; | 4334 unused_property_fields = inobject_props - number_of_fields; |
4333 } | 4335 } |
4334 | 4336 |
4335 // Allocate the fixed array for the fields. | 4337 // Allocate the fixed array for the fields. |
4336 Handle<FixedArray> fields = factory->NewFixedArray( | 4338 Handle<FixedArray> fields = factory->NewFixedArray( |
4337 number_of_allocated_fields); | 4339 number_of_allocated_fields); |
4338 | 4340 |
4339 // Fill in the instance descriptor and the fields. | 4341 // Fill in the instance descriptor and the fields. |
4340 int current_offset = 0; | 4342 int current_offset = 0; |
4341 for (int i = 0; i < capacity; i++) { | 4343 for (int i = 0; i < instance_descriptor_length; i++) { |
4342 Object* k = dictionary->KeyAt(i); | 4344 int index = Smi::cast(iteration_order->get(i))->value(); |
4343 if (dictionary->IsKey(k)) { | 4345 Object* k = dictionary->KeyAt(index); |
4344 Object* value = dictionary->ValueAt(i); | 4346 DCHECK(dictionary->IsKey(k)); |
4345 Handle<Name> key; | 4347 |
4346 if (k->IsSymbol()) { | 4348 Object* value = dictionary->ValueAt(index); |
4347 key = handle(Symbol::cast(k)); | 4349 Handle<Name> key; |
| 4350 if (k->IsSymbol()) { |
| 4351 key = handle(Symbol::cast(k)); |
| 4352 } else { |
| 4353 // Ensure the key is a unique name before writing into the |
| 4354 // instance descriptor. |
| 4355 key = factory->InternalizeString(handle(String::cast(k))); |
| 4356 } |
| 4357 |
| 4358 PropertyDetails details = dictionary->DetailsAt(index); |
| 4359 int enumeration_index = details.dictionary_index(); |
| 4360 PropertyType type = details.type(); |
| 4361 |
| 4362 if (value->IsJSFunction()) { |
| 4363 ConstantDescriptor d(key, handle(value, isolate), details.attributes()); |
| 4364 descriptors->Set(enumeration_index - 1, &d); |
| 4365 } else if (type == NORMAL) { |
| 4366 if (current_offset < inobject_props) { |
| 4367 object->InObjectPropertyAtPut(current_offset, value, |
| 4368 UPDATE_WRITE_BARRIER); |
4348 } else { | 4369 } else { |
4349 // Ensure the key is a unique name before writing into the | 4370 int offset = current_offset - inobject_props; |
4350 // instance descriptor. | 4371 fields->set(offset, value); |
4351 key = factory->InternalizeString(handle(String::cast(k))); | |
4352 } | 4372 } |
4353 | 4373 FieldDescriptor d(key, current_offset++, details.attributes(), |
4354 PropertyDetails details = dictionary->DetailsAt(i); | 4374 // TODO(verwaest): value->OptimalRepresentation(); |
4355 int enumeration_index = details.dictionary_index(); | 4375 Representation::Tagged()); |
4356 PropertyType type = details.type(); | 4376 descriptors->Set(enumeration_index - 1, &d); |
4357 | 4377 } else if (type == CALLBACKS) { |
4358 if (value->IsJSFunction()) { | 4378 CallbacksDescriptor d(key, handle(value, isolate), details.attributes()); |
4359 ConstantDescriptor d(key, | 4379 descriptors->Set(enumeration_index - 1, &d); |
4360 handle(value, isolate), | 4380 } else { |
4361 details.attributes()); | 4381 UNREACHABLE(); |
4362 descriptors->Set(enumeration_index - 1, &d); | |
4363 } else if (type == NORMAL) { | |
4364 if (current_offset < inobject_props) { | |
4365 object->InObjectPropertyAtPut(current_offset, | |
4366 value, | |
4367 UPDATE_WRITE_BARRIER); | |
4368 } else { | |
4369 int offset = current_offset - inobject_props; | |
4370 fields->set(offset, value); | |
4371 } | |
4372 FieldDescriptor d(key, | |
4373 current_offset++, | |
4374 details.attributes(), | |
4375 // TODO(verwaest): value->OptimalRepresentation(); | |
4376 Representation::Tagged()); | |
4377 descriptors->Set(enumeration_index - 1, &d); | |
4378 } else if (type == CALLBACKS) { | |
4379 CallbacksDescriptor d(key, | |
4380 handle(value, isolate), | |
4381 details.attributes()); | |
4382 descriptors->Set(enumeration_index - 1, &d); | |
4383 } else { | |
4384 UNREACHABLE(); | |
4385 } | |
4386 } | 4382 } |
4387 } | 4383 } |
4388 DCHECK(current_offset == number_of_fields); | 4384 DCHECK(current_offset == number_of_fields); |
4389 | 4385 |
4390 descriptors->Sort(); | 4386 descriptors->Sort(); |
4391 | 4387 |
4392 DisallowHeapAllocation no_gc; | 4388 DisallowHeapAllocation no_gc; |
4393 new_map->InitializeDescriptors(*descriptors); | 4389 new_map->InitializeDescriptors(*descriptors); |
4394 new_map->set_unused_property_fields(unused_property_fields); | 4390 new_map->set_unused_property_fields(unused_property_fields); |
4395 | 4391 |
(...skipping 9703 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
14099 NameDictionary, NameDictionaryShape, Handle<Name> >::SortMode); | 14095 NameDictionary, NameDictionaryShape, Handle<Name> >::SortMode); |
14100 | 14096 |
14101 template int | 14097 template int |
14102 Dictionary<NameDictionary, NameDictionaryShape, Handle<Name> >:: | 14098 Dictionary<NameDictionary, NameDictionaryShape, Handle<Name> >:: |
14103 NumberOfElementsFilterAttributes(PropertyAttributes); | 14099 NumberOfElementsFilterAttributes(PropertyAttributes); |
14104 | 14100 |
14105 template Handle<NameDictionary> | 14101 template Handle<NameDictionary> |
14106 Dictionary<NameDictionary, NameDictionaryShape, Handle<Name> >::Add( | 14102 Dictionary<NameDictionary, NameDictionaryShape, Handle<Name> >::Add( |
14107 Handle<NameDictionary>, Handle<Name>, Handle<Object>, PropertyDetails); | 14103 Handle<NameDictionary>, Handle<Name>, Handle<Object>, PropertyDetails); |
14108 | 14104 |
14109 template void | 14105 template Handle<FixedArray> Dictionary< |
14110 Dictionary<NameDictionary, NameDictionaryShape, Handle<Name> >:: | 14106 NameDictionary, NameDictionaryShape, |
14111 GenerateNewEnumerationIndices(Handle<NameDictionary>); | 14107 Handle<Name> >::BuildIterationIndicesArray(Handle<NameDictionary>); |
| 14108 |
| 14109 template Handle<FixedArray> Dictionary< |
| 14110 NameDictionary, NameDictionaryShape, |
| 14111 Handle<Name> >::GenerateNewEnumerationIndices(Handle<NameDictionary>); |
14112 | 14112 |
14113 template int | 14113 template int |
14114 Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>:: | 14114 Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>:: |
14115 NumberOfElementsFilterAttributes(PropertyAttributes); | 14115 NumberOfElementsFilterAttributes(PropertyAttributes); |
14116 | 14116 |
14117 template Handle<SeededNumberDictionary> | 14117 template Handle<SeededNumberDictionary> |
14118 Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>:: | 14118 Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>:: |
14119 Add(Handle<SeededNumberDictionary>, | 14119 Add(Handle<SeededNumberDictionary>, |
14120 uint32_t, | 14120 uint32_t, |
14121 Handle<Object>, | 14121 Handle<Object>, |
(...skipping 785 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
14907 at_least_space_for, | 14907 at_least_space_for, |
14908 USE_DEFAULT_MINIMUM_CAPACITY, | 14908 USE_DEFAULT_MINIMUM_CAPACITY, |
14909 pretenure); | 14909 pretenure); |
14910 | 14910 |
14911 // Initialize the next enumeration index. | 14911 // Initialize the next enumeration index. |
14912 dict->SetNextEnumerationIndex(PropertyDetails::kInitialIndex); | 14912 dict->SetNextEnumerationIndex(PropertyDetails::kInitialIndex); |
14913 return dict; | 14913 return dict; |
14914 } | 14914 } |
14915 | 14915 |
14916 | 14916 |
14917 template<typename Derived, typename Shape, typename Key> | 14917 template <typename Derived, typename Shape, typename Key> |
14918 void Dictionary<Derived, Shape, Key>::GenerateNewEnumerationIndices( | 14918 Handle<FixedArray> Dictionary<Derived, Shape, Key>::BuildIterationIndicesArray( |
14919 Handle<Derived> dictionary) { | 14919 Handle<Derived> dictionary) { |
14920 Factory* factory = dictionary->GetIsolate()->factory(); | 14920 Factory* factory = dictionary->GetIsolate()->factory(); |
14921 int length = dictionary->NumberOfElements(); | 14921 int length = dictionary->NumberOfElements(); |
14922 | 14922 |
14923 // Allocate and initialize iteration order array. | |
14924 Handle<FixedArray> iteration_order = factory->NewFixedArray(length); | 14923 Handle<FixedArray> iteration_order = factory->NewFixedArray(length); |
14925 for (int i = 0; i < length; i++) { | |
14926 iteration_order->set(i, Smi::FromInt(i)); | |
14927 } | |
14928 | |
14929 // Allocate array with enumeration order. | |
14930 Handle<FixedArray> enumeration_order = factory->NewFixedArray(length); | 14924 Handle<FixedArray> enumeration_order = factory->NewFixedArray(length); |
14931 | 14925 |
14932 // Fill the enumeration order array with property details. | 14926 // Fill both the iteration order array and the enumeration order array |
| 14927 // with property details. |
14933 int capacity = dictionary->Capacity(); | 14928 int capacity = dictionary->Capacity(); |
14934 int pos = 0; | 14929 int pos = 0; |
14935 for (int i = 0; i < capacity; i++) { | 14930 for (int i = 0; i < capacity; i++) { |
14936 if (dictionary->IsKey(dictionary->KeyAt(i))) { | 14931 if (dictionary->IsKey(dictionary->KeyAt(i))) { |
14937 int index = dictionary->DetailsAt(i).dictionary_index(); | 14932 int index = dictionary->DetailsAt(i).dictionary_index(); |
14938 enumeration_order->set(pos++, Smi::FromInt(index)); | 14933 iteration_order->set(pos, Smi::FromInt(i)); |
| 14934 enumeration_order->set(pos, Smi::FromInt(index)); |
| 14935 pos++; |
14939 } | 14936 } |
14940 } | 14937 } |
| 14938 DCHECK(pos == length); |
14941 | 14939 |
14942 // Sort the arrays wrt. enumeration order. | 14940 // Sort the arrays wrt. enumeration order. |
14943 iteration_order->SortPairs(*enumeration_order, enumeration_order->length()); | 14941 iteration_order->SortPairs(*enumeration_order, enumeration_order->length()); |
| 14942 return iteration_order; |
| 14943 } |
14944 | 14944 |
14945 // Overwrite the enumeration_order with the enumeration indices. | 14945 |
| 14946 template <typename Derived, typename Shape, typename Key> |
| 14947 Handle<FixedArray> |
| 14948 Dictionary<Derived, Shape, Key>::GenerateNewEnumerationIndices( |
| 14949 Handle<Derived> dictionary) { |
| 14950 int length = dictionary->NumberOfElements(); |
| 14951 |
| 14952 Handle<FixedArray> iteration_order = BuildIterationIndicesArray(dictionary); |
| 14953 DCHECK(iteration_order->length() == length); |
| 14954 |
| 14955 // Iterate over the dictionary using the enumeration order and update |
| 14956 // the dictionary with new enumeration indices. |
14946 for (int i = 0; i < length; i++) { | 14957 for (int i = 0; i < length; i++) { |
14947 int index = Smi::cast(iteration_order->get(i))->value(); | 14958 int index = Smi::cast(iteration_order->get(i))->value(); |
| 14959 DCHECK(dictionary->IsKey(dictionary->KeyAt(index))); |
| 14960 |
14948 int enum_index = PropertyDetails::kInitialIndex + i; | 14961 int enum_index = PropertyDetails::kInitialIndex + i; |
14949 enumeration_order->set(index, Smi::FromInt(enum_index)); | |
14950 } | |
14951 | 14962 |
14952 // Update the dictionary with new indices. | 14963 PropertyDetails details = dictionary->DetailsAt(index); |
14953 capacity = dictionary->Capacity(); | 14964 PropertyDetails new_details = |
14954 pos = 0; | 14965 PropertyDetails(details.attributes(), details.type(), enum_index); |
14955 for (int i = 0; i < capacity; i++) { | 14966 dictionary->DetailsAtPut(index, new_details); |
14956 if (dictionary->IsKey(dictionary->KeyAt(i))) { | |
14957 int enum_index = Smi::cast(enumeration_order->get(pos++))->value(); | |
14958 PropertyDetails details = dictionary->DetailsAt(i); | |
14959 PropertyDetails new_details = PropertyDetails( | |
14960 details.attributes(), details.type(), enum_index); | |
14961 dictionary->DetailsAtPut(i, new_details); | |
14962 } | |
14963 } | 14967 } |
14964 | 14968 |
14965 // Set the next enumeration index. | 14969 // Set the next enumeration index. |
14966 dictionary->SetNextEnumerationIndex(PropertyDetails::kInitialIndex+length); | 14970 dictionary->SetNextEnumerationIndex(PropertyDetails::kInitialIndex+length); |
| 14971 return iteration_order; |
14967 } | 14972 } |
14968 | 14973 |
14969 | 14974 |
14970 template<typename Derived, typename Shape, typename Key> | 14975 template<typename Derived, typename Shape, typename Key> |
14971 Handle<Derived> Dictionary<Derived, Shape, Key>::EnsureCapacity( | 14976 Handle<Derived> Dictionary<Derived, Shape, Key>::EnsureCapacity( |
14972 Handle<Derived> dictionary, int n, Key key) { | 14977 Handle<Derived> dictionary, int n, Key key) { |
14973 // Check whether there are enough enumeration indices to add n elements. | 14978 // Check whether there are enough enumeration indices to add n elements. |
14974 if (Shape::kIsEnumerable && | 14979 if (Shape::kIsEnumerable && |
14975 !PropertyDetails::IsValidIndex(dictionary->NextEnumerationIndex() + n)) { | 14980 !PropertyDetails::IsValidIndex(dictionary->NextEnumerationIndex() + n)) { |
14976 // If not, we generate new indices for the properties. | 14981 // If not, we generate new indices for the properties. |
(...skipping 1405 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
16382 Handle<DependentCode> codes = | 16387 Handle<DependentCode> codes = |
16383 DependentCode::Insert(handle(cell->dependent_code(), info->isolate()), | 16388 DependentCode::Insert(handle(cell->dependent_code(), info->isolate()), |
16384 DependentCode::kPropertyCellChangedGroup, | 16389 DependentCode::kPropertyCellChangedGroup, |
16385 info->object_wrapper()); | 16390 info->object_wrapper()); |
16386 if (*codes != cell->dependent_code()) cell->set_dependent_code(*codes); | 16391 if (*codes != cell->dependent_code()) cell->set_dependent_code(*codes); |
16387 info->dependencies(DependentCode::kPropertyCellChangedGroup)->Add( | 16392 info->dependencies(DependentCode::kPropertyCellChangedGroup)->Add( |
16388 cell, info->zone()); | 16393 cell, info->zone()); |
16389 } | 16394 } |
16390 | 16395 |
16391 } } // namespace v8::internal | 16396 } } // namespace v8::internal |
OLD | NEW |