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 10879013: Make order of addition the primary order of descriptor arrays. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 8 years, 4 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-debug.cc » ('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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 465 matching lines...) Expand 10 before | Expand all | Expand 10 after
476 } 476 }
477 Object* dict; 477 Object* dict;
478 { MaybeObject* maybe_dict = 478 { MaybeObject* maybe_dict =
479 property_dictionary()->Add(name, store_value, details); 479 property_dictionary()->Add(name, store_value, details);
480 if (!maybe_dict->ToObject(&dict)) return maybe_dict; 480 if (!maybe_dict->ToObject(&dict)) return maybe_dict;
481 } 481 }
482 set_properties(StringDictionary::cast(dict)); 482 set_properties(StringDictionary::cast(dict));
483 return value; 483 return value;
484 } 484 }
485 // Preserve enumeration index. 485 // Preserve enumeration index.
486 details = PropertyDetails(details.attributes(), 486 details = PropertyDetails(
487 details.type(), 487 details.attributes(),
488 property_dictionary()->DetailsAt(entry).index()); 488 details.type(),
489 property_dictionary()->DetailsAt(entry).dictionary_index());
490
489 if (IsGlobalObject()) { 491 if (IsGlobalObject()) {
490 JSGlobalPropertyCell* cell = 492 JSGlobalPropertyCell* cell =
491 JSGlobalPropertyCell::cast(property_dictionary()->ValueAt(entry)); 493 JSGlobalPropertyCell::cast(property_dictionary()->ValueAt(entry));
492 cell->set_value(value); 494 cell->set_value(value);
493 // Please note we have to update the property details. 495 // Please note we have to update the property details.
494 property_dictionary()->DetailsAtPut(entry, details); 496 property_dictionary()->DetailsAtPut(entry, details);
495 } else { 497 } else {
496 property_dictionary()->SetEntry(entry, name, value, details); 498 property_dictionary()->SetEntry(entry, name, value, details);
497 } 499 }
498 return value; 500 return value;
(...skipping 1226 matching lines...) Expand 10 before | Expand all | Expand 10 after
1725 1727
1726 1728
1727 MaybeObject* JSObject::ReplaceSlowProperty(String* name, 1729 MaybeObject* JSObject::ReplaceSlowProperty(String* name,
1728 Object* value, 1730 Object* value,
1729 PropertyAttributes attributes) { 1731 PropertyAttributes attributes) {
1730 StringDictionary* dictionary = property_dictionary(); 1732 StringDictionary* dictionary = property_dictionary();
1731 int old_index = dictionary->FindEntry(name); 1733 int old_index = dictionary->FindEntry(name);
1732 int new_enumeration_index = 0; // 0 means "Use the next available index." 1734 int new_enumeration_index = 0; // 0 means "Use the next available index."
1733 if (old_index != -1) { 1735 if (old_index != -1) {
1734 // All calls to ReplaceSlowProperty have had all transitions removed. 1736 // All calls to ReplaceSlowProperty have had all transitions removed.
1735 new_enumeration_index = dictionary->DetailsAt(old_index).index(); 1737 new_enumeration_index = dictionary->DetailsAt(old_index).dictionary_index();
1736 } 1738 }
1737 1739
1738 PropertyDetails new_details(attributes, NORMAL, new_enumeration_index); 1740 PropertyDetails new_details(attributes, NORMAL, new_enumeration_index);
1739 return SetNormalizedProperty(name, value, new_details); 1741 return SetNormalizedProperty(name, value, new_details);
1740 } 1742 }
1741 1743
1742 1744
1743 MaybeObject* JSObject::ConvertTransitionToMapTransition( 1745 MaybeObject* JSObject::ConvertTransitionToMapTransition(
1744 int transition_index, 1746 int transition_index,
1745 String* name, 1747 String* name,
(...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after
2073 if (*done) { 2075 if (*done) {
2074 if (strict_mode == kNonStrictMode) return value; 2076 if (strict_mode == kNonStrictMode) return value;
2075 Handle<Object> args[] = { Handle<Object>(name), Handle<Object>(this)}; 2077 Handle<Object> args[] = { Handle<Object>(name), Handle<Object>(this)};
2076 return isolate->Throw(*isolate->factory()->NewTypeError( 2078 return isolate->Throw(*isolate->factory()->NewTypeError(
2077 "strict_read_only_property", HandleVector(args, ARRAY_SIZE(args)))); 2079 "strict_read_only_property", HandleVector(args, ARRAY_SIZE(args))));
2078 } 2080 }
2079 return heap->the_hole_value(); 2081 return heap->the_hole_value();
2080 } 2082 }
2081 2083
2082 2084
2083 void Map::LookupDescriptor(JSObject* holder,
2084 String* name,
2085 LookupResult* result) {
2086 DescriptorArray* descriptors = this->instance_descriptors();
2087 int number = descriptors->SearchWithCache(name);
2088 if (number != DescriptorArray::kNotFound) {
2089 result->DescriptorResult(holder, descriptors->GetDetails(number), number);
2090 } else {
2091 result->NotFound();
2092 }
2093 }
2094
2095
2096 void Map::LookupTransition(JSObject* holder,
2097 String* name,
2098 LookupResult* result) {
2099 if (HasTransitionArray()) {
2100 TransitionArray* transition_array = transitions();
2101 int number = transition_array->Search(name);
2102 if (number != TransitionArray::kNotFound) {
2103 return result->TransitionResult(holder, number);
2104 }
2105 }
2106 result->NotFound();
2107 }
2108
2109
2110 enum RightTrimMode { FROM_GC, FROM_MUTATOR }; 2085 enum RightTrimMode { FROM_GC, FROM_MUTATOR };
2111 2086
2112 2087
2113 static void ZapEndOfFixedArray(Address new_end, int to_trim) { 2088 static void ZapEndOfFixedArray(Address new_end, int to_trim) {
2114 // If we are doing a big trim in old space then we zap the space. 2089 // If we are doing a big trim in old space then we zap the space.
2115 Object** zap = reinterpret_cast<Object**>(new_end); 2090 Object** zap = reinterpret_cast<Object**>(new_end);
2116 for (int i = 1; i < to_trim; i++) { 2091 for (int i = 1; i < to_trim; i++) {
2117 *zap++ = Smi::FromInt(0); 2092 *zap++ = Smi::FromInt(0);
2118 } 2093 }
2119 } 2094 }
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
2195 // descriptor array is trimmed to the right size. 2170 // descriptor array is trimmed to the right size.
2196 Map::SetDescriptors(map, result); 2171 Map::SetDescriptors(map, result);
2197 2172
2198 // Fill in new callback descriptors. Process the callbacks from 2173 // Fill in new callback descriptors. Process the callbacks from
2199 // back to front so that the last callback with a given name takes 2174 // back to front so that the last callback with a given name takes
2200 // precedence over previously added callbacks with that name. 2175 // precedence over previously added callbacks with that name.
2201 for (int i = nof_callbacks - 1; i >= 0; i--) { 2176 for (int i = nof_callbacks - 1; i >= 0; i--) {
2202 AccessorInfo* entry = AccessorInfo::cast(callbacks.get(i)); 2177 AccessorInfo* entry = AccessorInfo::cast(callbacks.get(i));
2203 String* key = String::cast(entry->name()); 2178 String* key = String::cast(entry->name());
2204 // Check if a descriptor with this name already exists before writing. 2179 // Check if a descriptor with this name already exists before writing.
2205 if (LinearSearch(*result, key, map->NumberOfSetDescriptors()) == 2180 if (LinearSearch(*result, key, map->NumberOfOwnDescriptors()) ==
2206 DescriptorArray::kNotFound) { 2181 DescriptorArray::kNotFound) {
2207 CallbacksDescriptor desc(key, entry, entry->property_attributes()); 2182 CallbacksDescriptor desc(key, entry, entry->property_attributes());
2208 map->AppendDescriptor(&desc, witness); 2183 map->AppendDescriptor(&desc, witness);
2209 } 2184 }
2210 } 2185 }
2211 2186
2212 int new_number_of_descriptors = map->NumberOfSetDescriptors(); 2187 int new_number_of_descriptors = map->NumberOfOwnDescriptors();
2213 // Reinstall the original descriptor array if no new elements were added. 2188 // Reinstall the original descriptor array if no new elements were added.
2214 if (new_number_of_descriptors == descriptor_count) { 2189 if (new_number_of_descriptors == descriptor_count) {
2215 Map::SetDescriptors(map, array); 2190 Map::SetDescriptors(map, array);
2216 return; 2191 return;
2217 } 2192 }
2218 2193
2219 // If duplicates were detected, trim the descriptor array to the right size. 2194 // If duplicates were detected, trim the descriptor array to the right size.
2220 int new_array_size = DescriptorArray::LengthFor(new_number_of_descriptors); 2195 int new_array_size = DescriptorArray::LengthFor(new_number_of_descriptors);
2221 if (new_array_size < result->length()) { 2196 if (new_array_size < result->length()) {
2222 RightTrimFixedArray<FROM_MUTATOR>( 2197 RightTrimFixedArray<FROM_MUTATOR>(
(...skipping 1070 matching lines...) Expand 10 before | Expand all | Expand 10 after
3293 StringDictionary* dictionary; 3268 StringDictionary* dictionary;
3294 { MaybeObject* maybe_dictionary = StringDictionary::Allocate(property_count); 3269 { MaybeObject* maybe_dictionary = StringDictionary::Allocate(property_count);
3295 if (!maybe_dictionary->To(&dictionary)) return maybe_dictionary; 3270 if (!maybe_dictionary->To(&dictionary)) return maybe_dictionary;
3296 } 3271 }
3297 3272
3298 DescriptorArray* descs = map_of_this->instance_descriptors(); 3273 DescriptorArray* descs = map_of_this->instance_descriptors();
3299 for (int i = 0; i < descs->number_of_descriptors(); i++) { 3274 for (int i = 0; i < descs->number_of_descriptors(); i++) {
3300 PropertyDetails details = descs->GetDetails(i); 3275 PropertyDetails details = descs->GetDetails(i);
3301 switch (details.type()) { 3276 switch (details.type()) {
3302 case CONSTANT_FUNCTION: { 3277 case CONSTANT_FUNCTION: {
3303 PropertyDetails d = 3278 PropertyDetails d = PropertyDetails(details.attributes(),
3304 PropertyDetails(details.attributes(), NORMAL, details.index()); 3279 NORMAL,
3280 details.descriptor_index());
3305 Object* value = descs->GetConstantFunction(i); 3281 Object* value = descs->GetConstantFunction(i);
3306 MaybeObject* maybe_dictionary = 3282 MaybeObject* maybe_dictionary =
3307 dictionary->Add(descs->GetKey(i), value, d); 3283 dictionary->Add(descs->GetKey(i), value, d);
3308 if (!maybe_dictionary->To(&dictionary)) return maybe_dictionary; 3284 if (!maybe_dictionary->To(&dictionary)) return maybe_dictionary;
3309 break; 3285 break;
3310 } 3286 }
3311 case FIELD: { 3287 case FIELD: {
3312 PropertyDetails d = 3288 PropertyDetails d = PropertyDetails(details.attributes(),
3313 PropertyDetails(details.attributes(), NORMAL, details.index()); 3289 NORMAL,
3290 details.descriptor_index());
3314 Object* value = FastPropertyAt(descs->GetFieldIndex(i)); 3291 Object* value = FastPropertyAt(descs->GetFieldIndex(i));
3315 MaybeObject* maybe_dictionary = 3292 MaybeObject* maybe_dictionary =
3316 dictionary->Add(descs->GetKey(i), value, d); 3293 dictionary->Add(descs->GetKey(i), value, d);
3317 if (!maybe_dictionary->To(&dictionary)) return maybe_dictionary; 3294 if (!maybe_dictionary->To(&dictionary)) return maybe_dictionary;
3318 break; 3295 break;
3319 } 3296 }
3320 case CALLBACKS: { 3297 case CALLBACKS: {
3321 Object* value = descs->GetCallbacksObject(i); 3298 Object* value = descs->GetCallbacksObject(i);
3322 MaybeObject* maybe_dictionary = 3299 MaybeObject* maybe_dictionary =
3323 dictionary->Add(descs->GetKey(i), value, details); 3300 dictionary->Add(descs->GetKey(i), value, details);
(...skipping 352 matching lines...) Expand 10 before | Expand all | Expand 10 after
3676 MaybeObject* JSObject::GetHiddenPropertiesHashTable( 3653 MaybeObject* JSObject::GetHiddenPropertiesHashTable(
3677 InitializeHiddenProperties init_option) { 3654 InitializeHiddenProperties init_option) {
3678 ASSERT(!IsJSGlobalProxy()); 3655 ASSERT(!IsJSGlobalProxy());
3679 Object* inline_value; 3656 Object* inline_value;
3680 if (HasFastProperties()) { 3657 if (HasFastProperties()) {
3681 // If the object has fast properties, check whether the first slot 3658 // If the object has fast properties, check whether the first slot
3682 // in the descriptor array matches the hidden symbol. Since the 3659 // in the descriptor array matches the hidden symbol. Since the
3683 // hidden symbols hash code is zero (and no other string has hash 3660 // hidden symbols hash code is zero (and no other string has hash
3684 // code zero) it will always occupy the first entry if present. 3661 // code zero) it will always occupy the first entry if present.
3685 DescriptorArray* descriptors = this->map()->instance_descriptors(); 3662 DescriptorArray* descriptors = this->map()->instance_descriptors();
3686 if ((descriptors->number_of_descriptors() > 0) && 3663 if (descriptors->number_of_descriptors() > 0) {
3687 (descriptors->GetKey(0) == GetHeap()->hidden_symbol())) { 3664 int sorted_index = descriptors->GetSortedKeyIndex(0);
3688 ASSERT(descriptors->GetType(0) == FIELD); 3665 if (descriptors->GetKey(sorted_index) == GetHeap()->hidden_symbol()) {
3689 inline_value = this->FastPropertyAt(descriptors->GetFieldIndex(0)); 3666 ASSERT(descriptors->GetType(sorted_index) == FIELD);
3667 inline_value = this->FastPropertyAt(
3668 descriptors->GetFieldIndex(sorted_index));
3669 } else {
3670 inline_value = GetHeap()->undefined_value();
3671 }
3690 } else { 3672 } else {
3691 inline_value = GetHeap()->undefined_value(); 3673 inline_value = GetHeap()->undefined_value();
3692 } 3674 }
3693 } else { 3675 } else {
3694 PropertyAttributes attributes; 3676 PropertyAttributes attributes;
3695 // You can't install a getter on a property indexed by the hidden symbol, 3677 // You can't install a getter on a property indexed by the hidden symbol,
3696 // so we can be sure that GetLocalPropertyPostInterceptor returns a real 3678 // so we can be sure that GetLocalPropertyPostInterceptor returns a real
3697 // object. 3679 // object.
3698 inline_value = 3680 inline_value =
3699 GetLocalPropertyPostInterceptor(this, 3681 GetLocalPropertyPostInterceptor(this,
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
3739 ASSERT(!IsJSGlobalProxy()); 3721 ASSERT(!IsJSGlobalProxy());
3740 // We can store the identity hash inline iff there is no backing store 3722 // We can store the identity hash inline iff there is no backing store
3741 // for hidden properties yet. 3723 // for hidden properties yet.
3742 ASSERT(HasHiddenProperties() != value->IsSmi()); 3724 ASSERT(HasHiddenProperties() != value->IsSmi());
3743 if (HasFastProperties()) { 3725 if (HasFastProperties()) {
3744 // If the object has fast properties, check whether the first slot 3726 // If the object has fast properties, check whether the first slot
3745 // in the descriptor array matches the hidden symbol. Since the 3727 // in the descriptor array matches the hidden symbol. Since the
3746 // hidden symbols hash code is zero (and no other string has hash 3728 // hidden symbols hash code is zero (and no other string has hash
3747 // code zero) it will always occupy the first entry if present. 3729 // code zero) it will always occupy the first entry if present.
3748 DescriptorArray* descriptors = this->map()->instance_descriptors(); 3730 DescriptorArray* descriptors = this->map()->instance_descriptors();
3749 if ((descriptors->number_of_descriptors() > 0) && 3731 if (descriptors->number_of_descriptors() > 0) {
3750 (descriptors->GetKey(0) == GetHeap()->hidden_symbol())) { 3732 int sorted_index = descriptors->GetSortedKeyIndex(0);
3751 ASSERT(descriptors->GetType(0) == FIELD); 3733 if (descriptors->GetKey(sorted_index) == GetHeap()->hidden_symbol()) {
3752 this->FastPropertyAtPut(descriptors->GetFieldIndex(0), value); 3734 ASSERT(descriptors->GetType(sorted_index) == FIELD);
3753 return this; 3735 this->FastPropertyAtPut(descriptors->GetFieldIndex(sorted_index),
3736 value);
3737 return this;
3738 }
3754 } 3739 }
3755 } 3740 }
3756 MaybeObject* store_result = 3741 MaybeObject* store_result =
3757 SetPropertyPostInterceptor(GetHeap()->hidden_symbol(), 3742 SetPropertyPostInterceptor(GetHeap()->hidden_symbol(),
3758 value, 3743 value,
3759 DONT_ENUM, 3744 DONT_ENUM,
3760 kNonStrictMode, 3745 kNonStrictMode,
3761 OMIT_EXTENSIBILITY_CHECK); 3746 OMIT_EXTENSIBILITY_CHECK);
3762 if (store_result->IsFailure()) return store_result; 3747 if (store_result->IsFailure()) return store_result;
3763 return this; 3748 return this;
(...skipping 1092 matching lines...) Expand 10 before | Expand all | Expand 10 after
4856 Map* result; 4841 Map* result;
4857 MaybeObject* maybe_result = 4842 MaybeObject* maybe_result =
4858 GetHeap()->AllocateMap(instance_type(), instance_size); 4843 GetHeap()->AllocateMap(instance_type(), instance_size);
4859 if (!maybe_result->To(&result)) return maybe_result; 4844 if (!maybe_result->To(&result)) return maybe_result;
4860 4845
4861 result->set_prototype(prototype()); 4846 result->set_prototype(prototype());
4862 result->set_constructor(constructor()); 4847 result->set_constructor(constructor());
4863 result->set_bit_field(bit_field()); 4848 result->set_bit_field(bit_field());
4864 result->set_bit_field2(bit_field2()); 4849 result->set_bit_field2(bit_field2());
4865 result->set_bit_field3(bit_field3()); 4850 result->set_bit_field3(bit_field3());
4866 result->SetLastAdded(kNoneAdded); 4851 result->SetNumberOfOwnDescriptors(0);
4867 return result; 4852 return result;
4868 } 4853 }
4869 4854
4870 4855
4871 MaybeObject* Map::CopyNormalized(PropertyNormalizationMode mode, 4856 MaybeObject* Map::CopyNormalized(PropertyNormalizationMode mode,
4872 NormalizedMapSharingMode sharing) { 4857 NormalizedMapSharingMode sharing) {
4873 int new_instance_size = instance_size(); 4858 int new_instance_size = instance_size();
4874 if (mode == CLEAR_INOBJECT_PROPERTIES) { 4859 if (mode == CLEAR_INOBJECT_PROPERTIES) {
4875 new_instance_size -= inobject_properties() * kPointerSize; 4860 new_instance_size -= inobject_properties() * kPointerSize;
4876 } 4861 }
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
4908 4893
4909 result->set_pre_allocated_property_fields(pre_allocated_property_fields()); 4894 result->set_pre_allocated_property_fields(pre_allocated_property_fields());
4910 result->set_is_shared(false); 4895 result->set_is_shared(false);
4911 result->ClearCodeCache(GetHeap()); 4896 result->ClearCodeCache(GetHeap());
4912 return result; 4897 return result;
4913 } 4898 }
4914 4899
4915 4900
4916 MaybeObject* Map::CopyReplaceDescriptors(DescriptorArray* descriptors, 4901 MaybeObject* Map::CopyReplaceDescriptors(DescriptorArray* descriptors,
4917 String* name, 4902 String* name,
4918 int last_added,
4919 TransitionFlag flag) { 4903 TransitionFlag flag) {
4920 Map* result; 4904 Map* result;
4921 MaybeObject* maybe_result = CopyDropDescriptors(); 4905 MaybeObject* maybe_result = CopyDropDescriptors();
4922 if (!maybe_result->To(&result)) return maybe_result; 4906 if (!maybe_result->To(&result)) return maybe_result;
4923 4907
4924 if (last_added == kNoneAdded) { 4908 if (descriptors->number_of_descriptors() != 0) {
4925 ASSERT(descriptors->number_of_descriptors() == 0);
4926 } else {
4927 ASSERT(descriptors->GetDetails(last_added).index() ==
4928 descriptors->number_of_descriptors());
4929 MaybeObject* maybe_failure = result->SetDescriptors(descriptors); 4909 MaybeObject* maybe_failure = result->SetDescriptors(descriptors);
4930 if (maybe_failure->IsFailure()) return maybe_failure; 4910 if (maybe_failure->IsFailure()) return maybe_failure;
4931 result->SetLastAdded(last_added); 4911 result->SetNumberOfOwnDescriptors(descriptors->number_of_descriptors());
4932 } 4912 }
4933 4913
4934 if (flag == INSERT_TRANSITION && CanHaveMoreTransitions()) { 4914 if (flag == INSERT_TRANSITION && CanHaveMoreTransitions()) {
4935 TransitionArray* transitions; 4915 TransitionArray* transitions;
4936 MaybeObject* maybe_transitions = AddTransition(name, result); 4916 MaybeObject* maybe_transitions = AddTransition(name, result);
4937 if (!maybe_transitions->To(&transitions)) return maybe_transitions; 4917 if (!maybe_transitions->To(&transitions)) return maybe_transitions;
4938 4918
4939 set_transitions(transitions); 4919 set_transitions(transitions);
4940 result->SetBackPointer(this); 4920 result->SetBackPointer(this);
4941 } 4921 }
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
4975 MaybeObject* Map::CopyWithPreallocatedFieldDescriptors() { 4955 MaybeObject* Map::CopyWithPreallocatedFieldDescriptors() {
4976 if (pre_allocated_property_fields() == 0) return CopyDropDescriptors(); 4956 if (pre_allocated_property_fields() == 0) return CopyDropDescriptors();
4977 4957
4978 // If the map has pre-allocated properties always start out with a descriptor 4958 // If the map has pre-allocated properties always start out with a descriptor
4979 // array describing these properties. 4959 // array describing these properties.
4980 ASSERT(constructor()->IsJSFunction()); 4960 ASSERT(constructor()->IsJSFunction());
4981 JSFunction* ctor = JSFunction::cast(constructor()); 4961 JSFunction* ctor = JSFunction::cast(constructor());
4982 Map* map = ctor->initial_map(); 4962 Map* map = ctor->initial_map();
4983 DescriptorArray* descriptors = map->instance_descriptors(); 4963 DescriptorArray* descriptors = map->instance_descriptors();
4984 4964
4985 int last_added = map->LastAdded(); 4965 return CopyReplaceDescriptors(descriptors, NULL, OMIT_TRANSITION);
4986
4987 return CopyReplaceDescriptors(descriptors, NULL, last_added, OMIT_TRANSITION);
4988 } 4966 }
4989 4967
4990 4968
4991 MaybeObject* Map::Copy() { 4969 MaybeObject* Map::Copy() {
4992 DescriptorArray* descriptors = instance_descriptors(); 4970 DescriptorArray* descriptors = instance_descriptors();
4993 int last_added = LastAdded(); 4971 return CopyReplaceDescriptors(descriptors, NULL, OMIT_TRANSITION);
4994
4995 return CopyReplaceDescriptors(descriptors, NULL, last_added, OMIT_TRANSITION);
4996 } 4972 }
4997 4973
4998 4974
4999 static bool InsertionPointFound(String* key1, String* key2) {
5000 return key1->Hash() > key2->Hash() || key1 == key2;
5001 }
5002
5003
5004 MaybeObject* Map::CopyAddDescriptor(Descriptor* descriptor, 4975 MaybeObject* Map::CopyAddDescriptor(Descriptor* descriptor,
5005 TransitionFlag flag) { 4976 TransitionFlag flag) {
5006 DescriptorArray* descriptors = instance_descriptors(); 4977 DescriptorArray* descriptors = instance_descriptors();
5007 4978
5008 // Ensure the key is a symbol. 4979 // Ensure the key is a symbol.
5009 MaybeObject* maybe_failure = descriptor->KeyToSymbol(); 4980 MaybeObject* maybe_failure = descriptor->KeyToSymbol();
5010 if (maybe_failure->IsFailure()) return maybe_failure; 4981 if (maybe_failure->IsFailure()) return maybe_failure;
5011 4982
5012 String* key = descriptor->GetKey(); 4983 String* key = descriptor->GetKey();
5013 ASSERT(descriptors->Search(key) == DescriptorArray::kNotFound); 4984 ASSERT(descriptors->Search(key) == DescriptorArray::kNotFound);
5014 4985
5015 int old_size = descriptors->number_of_descriptors(); 4986 int old_size = descriptors->number_of_descriptors();
5016 int new_size = old_size + 1; 4987 int new_size = old_size + 1;
5017 4988
5018 DescriptorArray* new_descriptors; 4989 DescriptorArray* new_descriptors;
5019 MaybeObject* maybe_descriptors = DescriptorArray::Allocate(new_size); 4990 MaybeObject* maybe_descriptors = DescriptorArray::Allocate(new_size);
5020 if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors; 4991 if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors;
5021 4992
5022 FixedArray::WhitenessWitness witness(new_descriptors); 4993 FixedArray::WhitenessWitness witness(new_descriptors);
5023 4994
5024 // Copy the descriptors, inserting a descriptor. 4995 // Copy the descriptors, inserting a descriptor.
5025 int insertion_index = -1; 4996 for (int i = 0; i < old_size; ++i) {
5026 int to = 0; 4997 new_descriptors->CopyFrom(i, descriptors, i, witness);
5027 for (int from = 0; from < old_size; ++from) {
5028 if (insertion_index < 0 &&
5029 InsertionPointFound(descriptors->GetKey(from), key)) {
5030 insertion_index = to++;
5031 }
5032 new_descriptors->CopyFrom(to++, descriptors, from, witness);
5033 } 4998 }
5034 if (insertion_index < 0) insertion_index = to++;
5035 4999
5036 ASSERT(to == new_size); 5000 new_descriptors->Append(descriptor, witness, old_size);
5037 ASSERT(new_size == descriptors->NextEnumerationIndex());
5038
5039 descriptor->SetEnumerationIndex(new_size);
5040 new_descriptors->Set(insertion_index, descriptor, witness);
5041 5001
5042 SLOW_ASSERT(new_descriptors->IsSortedNoDuplicates()); 5002 SLOW_ASSERT(new_descriptors->IsSortedNoDuplicates());
5043 5003
5044 return CopyReplaceDescriptors(new_descriptors, key, insertion_index, flag); 5004 return CopyReplaceDescriptors(new_descriptors, key, flag);
5045 } 5005 }
5046 5006
5047 5007
5048 MaybeObject* Map::CopyInsertDescriptor(Descriptor* descriptor, 5008 MaybeObject* Map::CopyInsertDescriptor(Descriptor* descriptor,
5049 TransitionFlag flag) { 5009 TransitionFlag flag) {
5050 DescriptorArray* old_descriptors = instance_descriptors(); 5010 DescriptorArray* old_descriptors = instance_descriptors();
5051 5011
5052 // Ensure the key is a symbol. 5012 // Ensure the key is a symbol.
5053 MaybeObject* maybe_result = descriptor->KeyToSymbol(); 5013 MaybeObject* maybe_result = descriptor->KeyToSymbol();
5054 if (maybe_result->IsFailure()) return maybe_result; 5014 if (maybe_result->IsFailure()) return maybe_result;
(...skipping 26 matching lines...) Expand all
5081 if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors; 5041 if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors;
5082 5042
5083 FixedArray::WhitenessWitness witness(new_descriptors); 5043 FixedArray::WhitenessWitness witness(new_descriptors);
5084 5044
5085 // Copy the descriptors, replacing a descriptor. 5045 // Copy the descriptors, replacing a descriptor.
5086 for (int index = 0; index < size; ++index) { 5046 for (int index = 0; index < size; ++index) {
5087 if (index == insertion_index) continue; 5047 if (index == insertion_index) continue;
5088 new_descriptors->CopyFrom(index, descriptors, index, witness); 5048 new_descriptors->CopyFrom(index, descriptors, index, witness);
5089 } 5049 }
5090 5050
5091 descriptor->SetEnumerationIndex( 5051 PropertyDetails original_details = descriptors->GetDetails(insertion_index);
5092 descriptors->GetDetails(insertion_index).index()); 5052 descriptor->SetEnumerationIndex(original_details.descriptor_index());
5053 descriptor->SetSortedKey(original_details.pointer());
5054
5093 new_descriptors->Set(insertion_index, descriptor, witness); 5055 new_descriptors->Set(insertion_index, descriptor, witness);
5094 5056
5095 SLOW_ASSERT(new_descriptors->IsSortedNoDuplicates()); 5057 SLOW_ASSERT(new_descriptors->IsSortedNoDuplicates());
5096 5058
5097 return CopyReplaceDescriptors(new_descriptors, key, LastAdded(), flag); 5059 return CopyReplaceDescriptors(new_descriptors, key, flag);
5098 } 5060 }
5099 5061
5100 5062
5101 void Map::UpdateCodeCache(Handle<Map> map, 5063 void Map::UpdateCodeCache(Handle<Map> map,
5102 Handle<String> name, 5064 Handle<String> name,
5103 Handle<Code> code) { 5065 Handle<Code> code) {
5104 Isolate* isolate = map->GetIsolate(); 5066 Isolate* isolate = map->GetIsolate();
5105 CALL_HEAP_FUNCTION_VOID(isolate, 5067 CALL_HEAP_FUNCTION_VOID(isolate,
5106 map->UpdateCodeCache(*name, *code)); 5068 map->UpdateCodeCache(*name, *code));
5107 } 5069 }
(...skipping 805 matching lines...) Expand 10 before | Expand all | Expand 10 after
5913 PropertyDetails details = src->GetDetails(src_index); 5875 PropertyDetails details = src->GetDetails(src_index);
5914 Descriptor desc(src->GetKey(src_index), value, details); 5876 Descriptor desc(src->GetKey(src_index), value, details);
5915 Set(dst_index, &desc, witness); 5877 Set(dst_index, &desc, witness);
5916 } 5878 }
5917 5879
5918 5880
5919 // We need the whiteness witness since sort will reshuffle the entries in the 5881 // We need the whiteness witness since sort will reshuffle the entries in the
5920 // descriptor array. If the descriptor array were to be black, the shuffling 5882 // descriptor array. If the descriptor array were to be black, the shuffling
5921 // would move a slot that was already recorded as pointing into an evacuation 5883 // would move a slot that was already recorded as pointing into an evacuation
5922 // candidate. This would result in missing updates upon evacuation. 5884 // candidate. This would result in missing updates upon evacuation.
5923 void DescriptorArray::Sort(const WhitenessWitness& witness) { 5885 void DescriptorArray::Sort() {
5924 // In-place heap sort. 5886 // In-place heap sort.
5925 int len = number_of_descriptors(); 5887 int len = number_of_descriptors();
5888 // Reset sorting since the descriptor array might contain invalid pointers.
5889 for (int i = 0; i < len; ++i) SetSortedKey(i, i);
5926 // Bottom-up max-heap construction. 5890 // Bottom-up max-heap construction.
5927 // Index of the last node with children 5891 // Index of the last node with children
5928 const int max_parent_index = (len / 2) - 1; 5892 const int max_parent_index = (len / 2) - 1;
5929 for (int i = max_parent_index; i >= 0; --i) { 5893 for (int i = max_parent_index; i >= 0; --i) {
5930 int parent_index = i; 5894 int parent_index = i;
5931 const uint32_t parent_hash = GetKey(i)->Hash(); 5895 const uint32_t parent_hash = GetSortedKey(i)->Hash();
5932 while (parent_index <= max_parent_index) { 5896 while (parent_index <= max_parent_index) {
5933 int child_index = 2 * parent_index + 1; 5897 int child_index = 2 * parent_index + 1;
5934 uint32_t child_hash = GetKey(child_index)->Hash(); 5898 uint32_t child_hash = GetSortedKey(child_index)->Hash();
5935 if (child_index + 1 < len) { 5899 if (child_index + 1 < len) {
5936 uint32_t right_child_hash = GetKey(child_index + 1)->Hash(); 5900 uint32_t right_child_hash = GetSortedKey(child_index + 1)->Hash();
5937 if (right_child_hash > child_hash) { 5901 if (right_child_hash > child_hash) {
5938 child_index++; 5902 child_index++;
5939 child_hash = right_child_hash; 5903 child_hash = right_child_hash;
5940 } 5904 }
5941 } 5905 }
5942 if (child_hash <= parent_hash) break; 5906 if (child_hash <= parent_hash) break;
5943 NoIncrementalWriteBarrierSwapDescriptors(parent_index, child_index); 5907 SwapSortedKeys(parent_index, child_index);
5944 // Now element at child_index could be < its children. 5908 // Now element at child_index could be < its children.
5945 parent_index = child_index; // parent_hash remains correct. 5909 parent_index = child_index; // parent_hash remains correct.
5946 } 5910 }
5947 } 5911 }
5948 5912
5949 // Extract elements and create sorted array. 5913 // Extract elements and create sorted array.
5950 for (int i = len - 1; i > 0; --i) { 5914 for (int i = len - 1; i > 0; --i) {
5951 // Put max element at the back of the array. 5915 // Put max element at the back of the array.
5952 NoIncrementalWriteBarrierSwapDescriptors(0, i); 5916 SwapSortedKeys(0, i);
5953 // Shift down the new top element. 5917 // Shift down the new top element.
5954 int parent_index = 0; 5918 int parent_index = 0;
5955 const uint32_t parent_hash = GetKey(parent_index)->Hash(); 5919 const uint32_t parent_hash = GetSortedKey(parent_index)->Hash();
5956 const int max_parent_index = (i / 2) - 1; 5920 const int max_parent_index = (i / 2) - 1;
5957 while (parent_index <= max_parent_index) { 5921 while (parent_index <= max_parent_index) {
5958 int child_index = parent_index * 2 + 1; 5922 int child_index = parent_index * 2 + 1;
5959 uint32_t child_hash = GetKey(child_index)->Hash(); 5923 uint32_t child_hash = GetSortedKey(child_index)->Hash();
5960 if (child_index + 1 < i) { 5924 if (child_index + 1 < i) {
5961 uint32_t right_child_hash = GetKey(child_index + 1)->Hash(); 5925 uint32_t right_child_hash = GetSortedKey(child_index + 1)->Hash();
5962 if (right_child_hash > child_hash) { 5926 if (right_child_hash > child_hash) {
5963 child_index++; 5927 child_index++;
5964 child_hash = right_child_hash; 5928 child_hash = right_child_hash;
5965 } 5929 }
5966 } 5930 }
5967 if (child_hash <= parent_hash) break; 5931 if (child_hash <= parent_hash) break;
5968 NoIncrementalWriteBarrierSwapDescriptors(parent_index, child_index); 5932 SwapSortedKeys(parent_index, child_index);
5969 parent_index = child_index; 5933 parent_index = child_index;
5970 } 5934 }
5971 } 5935 }
5972 } 5936 }
5973 5937
5974 5938
5975 MaybeObject* AccessorPair::Copy() { 5939 MaybeObject* AccessorPair::Copy() {
5976 Heap* heap = GetHeap(); 5940 Heap* heap = GetHeap();
5977 AccessorPair* copy; 5941 AccessorPair* copy;
5978 MaybeObject* maybe_copy = heap->AllocateAccessorPair(); 5942 MaybeObject* maybe_copy = heap->AllocateAccessorPair();
(...skipping 1324 matching lines...) Expand 10 before | Expand all | Expand 10 after
7303 PropertyNormalizationMode mode) { 7267 PropertyNormalizationMode mode) {
7304 return 7268 return
7305 constructor() == other->constructor() && 7269 constructor() == other->constructor() &&
7306 prototype() == other->prototype() && 7270 prototype() == other->prototype() &&
7307 inobject_properties() == ((mode == CLEAR_INOBJECT_PROPERTIES) ? 7271 inobject_properties() == ((mode == CLEAR_INOBJECT_PROPERTIES) ?
7308 0 : 7272 0 :
7309 other->inobject_properties()) && 7273 other->inobject_properties()) &&
7310 instance_type() == other->instance_type() && 7274 instance_type() == other->instance_type() &&
7311 bit_field() == other->bit_field() && 7275 bit_field() == other->bit_field() &&
7312 bit_field2() == other->bit_field2() && 7276 bit_field2() == other->bit_field2() &&
7313 static_cast<uint32_t>(bit_field3()) == 7277 function_with_prototype() == other->function_with_prototype();
7314 LastAddedBits::update(
7315 IsShared::update(DictionaryMap::update(other->bit_field3(), true),
7316 true),
7317 kNoneAdded);
7318 } 7278 }
7319 7279
7320 7280
7321 void JSFunction::JSFunctionIterateBody(int object_size, ObjectVisitor* v) { 7281 void JSFunction::JSFunctionIterateBody(int object_size, ObjectVisitor* v) {
7322 // Iterate over all fields in the body but take care in dealing with 7282 // Iterate over all fields in the body but take care in dealing with
7323 // the code entry. 7283 // the code entry.
7324 IteratePointers(v, kPropertiesOffset, kCodeEntryOffset); 7284 IteratePointers(v, kPropertiesOffset, kCodeEntryOffset);
7325 v->VisitCodeEntry(this->address() + kCodeEntryOffset); 7285 v->VisitCodeEntry(this->address() + kCodeEntryOffset);
7326 IteratePointers(v, kCodeEntryOffset + kPointerSize, object_size); 7286 IteratePointers(v, kCodeEntryOffset + kPointerSize, object_size);
7327 } 7287 }
(...skipping 2076 matching lines...) Expand 10 before | Expand all | Expand 10 after
9404 Object* element = dictionary->ValueAt(entry); 9364 Object* element = dictionary->ValueAt(entry);
9405 PropertyDetails details = dictionary->DetailsAt(entry); 9365 PropertyDetails details = dictionary->DetailsAt(entry);
9406 if (details.type() == CALLBACKS && set_mode == SET_PROPERTY) { 9366 if (details.type() == CALLBACKS && set_mode == SET_PROPERTY) {
9407 return SetElementWithCallback(element, index, value, this, strict_mode); 9367 return SetElementWithCallback(element, index, value, this, strict_mode);
9408 } else { 9368 } else {
9409 dictionary->UpdateMaxNumberKey(index); 9369 dictionary->UpdateMaxNumberKey(index);
9410 // If a value has not been initialized we allow writing to it even if it 9370 // If a value has not been initialized we allow writing to it even if it
9411 // is read-only (a declared const that has not been initialized). If a 9371 // is read-only (a declared const that has not been initialized). If a
9412 // value is being defined we skip attribute checks completely. 9372 // value is being defined we skip attribute checks completely.
9413 if (set_mode == DEFINE_PROPERTY) { 9373 if (set_mode == DEFINE_PROPERTY) {
9414 details = PropertyDetails(attributes, NORMAL, details.index()); 9374 details = PropertyDetails(
9375 attributes, NORMAL, details.dictionary_index());
9415 dictionary->DetailsAtPut(entry, details); 9376 dictionary->DetailsAtPut(entry, details);
9416 } else if (details.IsReadOnly() && !element->IsTheHole()) { 9377 } else if (details.IsReadOnly() && !element->IsTheHole()) {
9417 if (strict_mode == kNonStrictMode) { 9378 if (strict_mode == kNonStrictMode) {
9418 return isolate->heap()->undefined_value(); 9379 return isolate->heap()->undefined_value();
9419 } else { 9380 } else {
9420 Handle<Object> holder(this); 9381 Handle<Object> holder(this);
9421 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); 9382 Handle<Object> number = isolate->factory()->NewNumberFromUint(index);
9422 Handle<Object> args[2] = { number, holder }; 9383 Handle<Object> args[2] = { number, holder };
9423 Handle<Object> error = 9384 Handle<Object> error =
9424 isolate->factory()->NewTypeError("strict_read_only_property", 9385 isolate->factory()->NewTypeError("strict_read_only_property",
(...skipping 2747 matching lines...) Expand 10 before | Expand all | Expand 10 after
12172 { MaybeObject* maybe_obj = heap->AllocateFixedArray(length); 12133 { MaybeObject* maybe_obj = heap->AllocateFixedArray(length);
12173 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 12134 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
12174 } 12135 }
12175 FixedArray* enumeration_order = FixedArray::cast(obj); 12136 FixedArray* enumeration_order = FixedArray::cast(obj);
12176 12137
12177 // Fill the enumeration order array with property details. 12138 // Fill the enumeration order array with property details.
12178 int capacity = HashTable<Shape, Key>::Capacity(); 12139 int capacity = HashTable<Shape, Key>::Capacity();
12179 int pos = 0; 12140 int pos = 0;
12180 for (int i = 0; i < capacity; i++) { 12141 for (int i = 0; i < capacity; i++) {
12181 if (Dictionary<Shape, Key>::IsKey(Dictionary<Shape, Key>::KeyAt(i))) { 12142 if (Dictionary<Shape, Key>::IsKey(Dictionary<Shape, Key>::KeyAt(i))) {
12182 enumeration_order->set(pos++, Smi::FromInt(DetailsAt(i).index())); 12143 enumeration_order->set(
12144 pos++, Smi::FromInt(DetailsAt(i).dictionary_index()));
12183 } 12145 }
12184 } 12146 }
12185 12147
12186 // Sort the arrays wrt. enumeration order. 12148 // Sort the arrays wrt. enumeration order.
12187 iteration_order->SortPairs(enumeration_order, enumeration_order->length()); 12149 iteration_order->SortPairs(enumeration_order, enumeration_order->length());
12188 12150
12189 // Overwrite the enumeration_order with the enumeration indices. 12151 // Overwrite the enumeration_order with the enumeration indices.
12190 for (int i = 0; i < length; i++) { 12152 for (int i = 0; i < length; i++) {
12191 int index = Smi::cast(iteration_order->get(i))->value(); 12153 int index = Smi::cast(iteration_order->get(i))->value();
12192 int enum_index = PropertyDetails::kInitialIndex + i; 12154 int enum_index = PropertyDetails::kInitialIndex + i;
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
12298 PropertyDetails details, 12260 PropertyDetails details,
12299 uint32_t hash) { 12261 uint32_t hash) {
12300 // Compute the key object. 12262 // Compute the key object.
12301 Object* k; 12263 Object* k;
12302 { MaybeObject* maybe_k = Shape::AsObject(key); 12264 { MaybeObject* maybe_k = Shape::AsObject(key);
12303 if (!maybe_k->ToObject(&k)) return maybe_k; 12265 if (!maybe_k->ToObject(&k)) return maybe_k;
12304 } 12266 }
12305 12267
12306 uint32_t entry = Dictionary<Shape, Key>::FindInsertionEntry(hash); 12268 uint32_t entry = Dictionary<Shape, Key>::FindInsertionEntry(hash);
12307 // Insert element at empty or deleted entry 12269 // Insert element at empty or deleted entry
12308 if (!details.IsDeleted() && details.index() == 0 && Shape::kIsEnumerable) { 12270 if (!details.IsDeleted() &&
12271 details.dictionary_index() == 0 && Shape::kIsEnumerable) {
12309 // Assign an enumeration index to the property and update 12272 // Assign an enumeration index to the property and update
12310 // SetNextEnumerationIndex. 12273 // SetNextEnumerationIndex.
12311 int index = NextEnumerationIndex(); 12274 int index = NextEnumerationIndex();
12312 details = PropertyDetails(details.attributes(), details.type(), index); 12275 details = PropertyDetails(details.attributes(), details.type(), index);
12313 SetNextEnumerationIndex(index + 1); 12276 SetNextEnumerationIndex(index + 1);
12314 } 12277 }
12315 SetEntry(entry, k, value, details); 12278 SetEntry(entry, k, value, details);
12316 ASSERT((Dictionary<Shape, Key>::KeyAt(entry)->IsNumber() 12279 ASSERT((Dictionary<Shape, Key>::KeyAt(entry)->IsNumber()
12317 || Dictionary<Shape, Key>::KeyAt(entry)->IsString())); 12280 || Dictionary<Shape, Key>::KeyAt(entry)->IsString()));
12318 HashTable<Shape, Key>::ElementAdded(); 12281 HashTable<Shape, Key>::ElementAdded();
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
12389 12352
12390 12353
12391 MaybeObject* SeededNumberDictionary::Set(uint32_t key, 12354 MaybeObject* SeededNumberDictionary::Set(uint32_t key,
12392 Object* value, 12355 Object* value,
12393 PropertyDetails details) { 12356 PropertyDetails details) {
12394 int entry = FindEntry(key); 12357 int entry = FindEntry(key);
12395 if (entry == kNotFound) return AddNumberEntry(key, value, details); 12358 if (entry == kNotFound) return AddNumberEntry(key, value, details);
12396 // Preserve enumeration index. 12359 // Preserve enumeration index.
12397 details = PropertyDetails(details.attributes(), 12360 details = PropertyDetails(details.attributes(),
12398 details.type(), 12361 details.type(),
12399 DetailsAt(entry).index()); 12362 DetailsAt(entry).dictionary_index());
12400 MaybeObject* maybe_object_key = SeededNumberDictionaryShape::AsObject(key); 12363 MaybeObject* maybe_object_key = SeededNumberDictionaryShape::AsObject(key);
12401 Object* object_key; 12364 Object* object_key;
12402 if (!maybe_object_key->ToObject(&object_key)) return maybe_object_key; 12365 if (!maybe_object_key->ToObject(&object_key)) return maybe_object_key;
12403 SetEntry(entry, object_key, value, details); 12366 SetEntry(entry, object_key, value, details);
12404 return this; 12367 return this;
12405 } 12368 }
12406 12369
12407 12370
12408 MaybeObject* UnseededNumberDictionary::Set(uint32_t key, 12371 MaybeObject* UnseededNumberDictionary::Set(uint32_t key,
12409 Object* value) { 12372 Object* value) {
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
12471 FixedArray* sort_array) { 12434 FixedArray* sort_array) {
12472 ASSERT(storage->length() >= NumberOfEnumElements()); 12435 ASSERT(storage->length() >= NumberOfEnumElements());
12473 int capacity = Capacity(); 12436 int capacity = Capacity();
12474 int index = 0; 12437 int index = 0;
12475 for (int i = 0; i < capacity; i++) { 12438 for (int i = 0; i < capacity; i++) {
12476 Object* k = KeyAt(i); 12439 Object* k = KeyAt(i);
12477 if (IsKey(k)) { 12440 if (IsKey(k)) {
12478 PropertyDetails details = DetailsAt(i); 12441 PropertyDetails details = DetailsAt(i);
12479 if (details.IsDeleted() || details.IsDontEnum()) continue; 12442 if (details.IsDeleted() || details.IsDontEnum()) continue;
12480 storage->set(index, k); 12443 storage->set(index, k);
12481 sort_array->set(index, Smi::FromInt(details.index())); 12444 sort_array->set(index, Smi::FromInt(details.dictionary_index()));
12482 index++; 12445 index++;
12483 } 12446 }
12484 } 12447 }
12485 storage->SortPairs(sort_array, sort_array->length()); 12448 storage->SortPairs(sort_array, sort_array->length());
12486 ASSERT(storage->length() >= index); 12449 ASSERT(storage->length() >= index);
12487 } 12450 }
12488 12451
12489 12452
12490 template<typename Shape, typename Key> 12453 template<typename Shape, typename Key>
12491 void Dictionary<Shape, Key>::CopyKeysTo( 12454 void Dictionary<Shape, Key>::CopyKeysTo(
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
12596 unused_property_fields = inobject_props - number_of_fields; 12559 unused_property_fields = inobject_props - number_of_fields;
12597 } 12560 }
12598 12561
12599 // Allocate the fixed array for the fields. 12562 // Allocate the fixed array for the fields.
12600 FixedArray* fields; 12563 FixedArray* fields;
12601 MaybeObject* maybe_fields = 12564 MaybeObject* maybe_fields =
12602 heap->AllocateFixedArray(number_of_allocated_fields); 12565 heap->AllocateFixedArray(number_of_allocated_fields);
12603 if (!maybe_fields->To(&fields)) return maybe_fields; 12566 if (!maybe_fields->To(&fields)) return maybe_fields;
12604 12567
12605 // Fill in the instance descriptor and the fields. 12568 // Fill in the instance descriptor and the fields.
12606 int next_descriptor = 0;
12607 int current_offset = 0; 12569 int current_offset = 0;
12608 for (int i = 0; i < capacity; i++) { 12570 for (int i = 0; i < capacity; i++) {
12609 Object* k = KeyAt(i); 12571 Object* k = KeyAt(i);
12610 if (IsKey(k)) { 12572 if (IsKey(k)) {
12611 Object* value = ValueAt(i); 12573 Object* value = ValueAt(i);
12612 // Ensure the key is a symbol before writing into the instance descriptor. 12574 // Ensure the key is a symbol before writing into the instance descriptor.
12613 String* key; 12575 String* key;
12614 MaybeObject* maybe_key = heap->LookupSymbol(String::cast(k)); 12576 MaybeObject* maybe_key = heap->LookupSymbol(String::cast(k));
12615 if (!maybe_key->To(&key)) return maybe_key; 12577 if (!maybe_key->To(&key)) return maybe_key;
12616 12578
12617 PropertyDetails details = DetailsAt(i); 12579 PropertyDetails details = DetailsAt(i);
12580 int enumeration_index = details.dictionary_index();
12618 PropertyType type = details.type(); 12581 PropertyType type = details.type();
12619 12582
12620 if (value->IsJSFunction() && !heap->InNewSpace(value)) { 12583 if (value->IsJSFunction() && !heap->InNewSpace(value)) {
12621 ConstantFunctionDescriptor d(key, 12584 ConstantFunctionDescriptor d(key,
12622 JSFunction::cast(value), 12585 JSFunction::cast(value),
12623 details.attributes(), 12586 details.attributes(),
12624 details.index()); 12587 enumeration_index);
12625 descriptors->Set(next_descriptor, &d, witness); 12588 descriptors->Set(enumeration_index - 1, &d, witness);
12626 } else if (type == NORMAL) { 12589 } else if (type == NORMAL) {
12627 if (current_offset < inobject_props) { 12590 if (current_offset < inobject_props) {
12628 obj->InObjectPropertyAtPut(current_offset, 12591 obj->InObjectPropertyAtPut(current_offset,
12629 value, 12592 value,
12630 UPDATE_WRITE_BARRIER); 12593 UPDATE_WRITE_BARRIER);
12631 } else { 12594 } else {
12632 int offset = current_offset - inobject_props; 12595 int offset = current_offset - inobject_props;
12633 fields->set(offset, value); 12596 fields->set(offset, value);
12634 } 12597 }
12635 FieldDescriptor d(key, 12598 FieldDescriptor d(key,
12636 current_offset++, 12599 current_offset++,
12637 details.attributes(), 12600 details.attributes(),
12638 details.index()); 12601 enumeration_index);
12639 descriptors->Set(next_descriptor, &d, witness); 12602 descriptors->Set(enumeration_index - 1, &d, witness);
12640 } else if (type == CALLBACKS) { 12603 } else if (type == CALLBACKS) {
12641 CallbacksDescriptor d(key, 12604 CallbacksDescriptor d(key,
12642 value, 12605 value,
12643 details.attributes(), 12606 details.attributes(),
12644 details.index()); 12607 enumeration_index);
12645 descriptors->Set(next_descriptor, &d, witness); 12608 descriptors->Set(enumeration_index - 1, &d, witness);
12646 } else { 12609 } else {
12647 UNREACHABLE(); 12610 UNREACHABLE();
12648 } 12611 }
12649 ++next_descriptor;
12650 } 12612 }
12651 } 12613 }
12652 ASSERT(current_offset == number_of_fields); 12614 ASSERT(current_offset == number_of_fields);
12653 12615
12654 descriptors->Sort(witness); 12616 descriptors->Sort();
12655 12617
12656 MaybeObject* maybe_failure = new_map->InitializeDescriptors(descriptors); 12618 MaybeObject* maybe_failure = new_map->InitializeDescriptors(descriptors);
12657 if (maybe_failure->IsFailure()) return maybe_failure; 12619 if (maybe_failure->IsFailure()) return maybe_failure;
12658 new_map->set_unused_property_fields(unused_property_fields); 12620 new_map->set_unused_property_fields(unused_property_fields);
12659 12621
12660 // Transform the object. 12622 // Transform the object.
12661 obj->set_map(new_map); 12623 obj->set_map(new_map);
12662 12624
12663 obj->set_properties(fields); 12625 obj->set_properties(fields);
12664 ASSERT(obj->IsJSObject()); 12626 ASSERT(obj->IsJSObject());
(...skipping 502 matching lines...) Expand 10 before | Expand all | Expand 10 after
13167 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER); 13129 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER);
13168 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER); 13130 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER);
13169 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER); 13131 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER);
13170 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER); 13132 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER);
13171 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER); 13133 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER);
13172 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER); 13134 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER);
13173 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER); 13135 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER);
13174 } 13136 }
13175 13137
13176 } } // namespace v8::internal 13138 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/objects-debug.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698