Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2)

Side by Side Diff: src/objects.cc

Issue 614883003: Preserve order of fields when doing slow-to-fast object migration. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressed comments Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/objects.h ('k') | src/objects-inl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/objects-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698