OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |