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