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