OLD | NEW |
---|---|
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #include "src/accessors.h" | 7 #include "src/accessors.h" |
8 #include "src/allocation-site-scopes.h" | 8 #include "src/allocation-site-scopes.h" |
9 #include "src/api.h" | 9 #include "src/api.h" |
10 #include "src/arguments.h" | 10 #include "src/arguments.h" |
(...skipping 2202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2213 for (int i = 0; i < old_nof; i++) { | 2213 for (int i = 0; i < old_nof; i++) { |
2214 PropertyDetails details = new_descriptors->GetDetails(i); | 2214 PropertyDetails details = new_descriptors->GetDetails(i); |
2215 if (details.type() != FIELD) continue; | 2215 if (details.type() != FIELD) continue; |
2216 PropertyDetails old_details = old_descriptors->GetDetails(i); | 2216 PropertyDetails old_details = old_descriptors->GetDetails(i); |
2217 if (old_details.type() == CALLBACKS) { | 2217 if (old_details.type() == CALLBACKS) { |
2218 ASSERT(details.representation().IsTagged()); | 2218 ASSERT(details.representation().IsTagged()); |
2219 continue; | 2219 continue; |
2220 } | 2220 } |
2221 ASSERT(old_details.type() == CONSTANT || | 2221 ASSERT(old_details.type() == CONSTANT || |
2222 old_details.type() == FIELD); | 2222 old_details.type() == FIELD); |
2223 Object* raw_value = old_details.type() == CONSTANT | 2223 Handle<Object> value; |
2224 ? old_descriptors->GetValue(i) | 2224 if (old_details.type() == CONSTANT) { |
2225 : object->RawFastPropertyAt(FieldIndex::ForDescriptor(*old_map, i)); | 2225 value = handle(old_descriptors->GetValue(i), isolate); |
2226 Handle<Object> value(raw_value, isolate); | 2226 } else { |
2227 FieldIndex index = FieldIndex::ForDescriptor(*old_map, i); | |
2228 // TODO(ishell): avoid boxing if copying to unboxed double. | |
2229 value = RawFastBoxedPropertyAt(object, index); | |
2230 } | |
2227 if (!old_details.representation().IsDouble() && | 2231 if (!old_details.representation().IsDouble() && |
2228 details.representation().IsDouble()) { | 2232 details.representation().IsDouble()) { |
2229 if (old_details.representation().IsNone()) { | 2233 if (old_details.representation().IsNone()) { |
2230 value = handle(Smi::FromInt(0), isolate); | 2234 value = handle(Smi::FromInt(0), isolate); |
2231 } | 2235 } |
2232 value = Object::NewStorageFor(isolate, value, details.representation()); | 2236 value = Object::NewStorageFor(isolate, value, details.representation()); |
2233 } else if (old_details.representation().IsDouble() && | 2237 } else if (old_details.representation().IsDouble() && |
2234 !details.representation().IsDouble()) { | 2238 !details.representation().IsDouble()) { |
2235 value = Object::WrapForRead(isolate, value, old_details.representation()); | 2239 value = Object::WrapForRead(isolate, value, old_details.representation()); |
2236 } | 2240 } |
(...skipping 18 matching lines...) Expand all Loading... | |
2255 } | 2259 } |
2256 | 2260 |
2257 // From here on we cannot fail and we shouldn't GC anymore. | 2261 // From here on we cannot fail and we shouldn't GC anymore. |
2258 DisallowHeapAllocation no_allocation; | 2262 DisallowHeapAllocation no_allocation; |
2259 | 2263 |
2260 // Copy (real) inobject properties. If necessary, stop at number_of_fields to | 2264 // Copy (real) inobject properties. If necessary, stop at number_of_fields to |
2261 // avoid overwriting |one_pointer_filler_map|. | 2265 // avoid overwriting |one_pointer_filler_map|. |
2262 int limit = Min(inobject, number_of_fields); | 2266 int limit = Min(inobject, number_of_fields); |
2263 for (int i = 0; i < limit; i++) { | 2267 for (int i = 0; i < limit; i++) { |
2264 FieldIndex index = FieldIndex::ForPropertyIndex(*new_map, i); | 2268 FieldIndex index = FieldIndex::ForPropertyIndex(*new_map, i); |
2265 object->FastPropertyAtPut(index, array->get(external + i)); | 2269 object->FastPropertyAtPut(*new_map, index, array->get(external + i)); |
2266 } | 2270 } |
2267 | 2271 |
2268 Heap* heap = isolate->heap(); | 2272 Heap* heap = isolate->heap(); |
2269 | 2273 |
2270 // If there are properties in the new backing store, trim it to the correct | 2274 // If there are properties in the new backing store, trim it to the correct |
2271 // size and install the backing store into the object. | 2275 // size and install the backing store into the object. |
2272 if (external > 0) { | 2276 if (external > 0) { |
2273 RightTrimFixedArray<Heap::FROM_MUTATOR>(heap, *array, inobject); | 2277 RightTrimFixedArray<Heap::FROM_MUTATOR>(heap, *array, inobject); |
2274 object->set_properties(*array); | 2278 object->set_properties(*array); |
2275 } | 2279 } |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2389 deprecate(); | 2393 deprecate(); |
2390 dependent_code()->DeoptimizeDependentCodeGroup( | 2394 dependent_code()->DeoptimizeDependentCodeGroup( |
2391 GetIsolate(), DependentCode::kTransitionGroup); | 2395 GetIsolate(), DependentCode::kTransitionGroup); |
2392 NotifyLeafMapLayoutChange(); | 2396 NotifyLeafMapLayoutChange(); |
2393 } | 2397 } |
2394 | 2398 |
2395 | 2399 |
2396 // Invalidates a transition target at |key|, and installs |new_descriptors| over | 2400 // Invalidates a transition target at |key|, and installs |new_descriptors| over |
2397 // the current instance_descriptors to ensure proper sharing of descriptor | 2401 // the current instance_descriptors to ensure proper sharing of descriptor |
2398 // arrays. | 2402 // arrays. |
2399 void Map::DeprecateTarget(Name* key, DescriptorArray* new_descriptors) { | 2403 void Map::DeprecateTarget(Handle<Name> key, |
2404 Handle<DescriptorArray> new_descriptors) { | |
2400 if (HasTransitionArray()) { | 2405 if (HasTransitionArray()) { |
2401 TransitionArray* transitions = this->transitions(); | 2406 TransitionArray* transitions = this->transitions(); |
2402 int transition = transitions->Search(key); | 2407 int transition = transitions->Search(*key); |
2403 if (transition != TransitionArray::kNotFound) { | 2408 if (transition != TransitionArray::kNotFound) { |
2404 transitions->GetTarget(transition)->DeprecateTransitionTree(); | 2409 transitions->GetTarget(transition)->DeprecateTransitionTree(); |
2405 } | 2410 } |
2406 } | 2411 } |
2407 | 2412 |
2408 // Don't overwrite the empty descriptor array. | 2413 // Don't overwrite the empty descriptor array. |
2409 if (NumberOfOwnDescriptors() == 0) return; | 2414 if (NumberOfOwnDescriptors() == 0) return; |
2410 | 2415 |
2416 Handle<LayoutDescriptor> new_layout_descriptor = | |
2417 LayoutDescriptor::New(new_descriptors); | |
2411 DescriptorArray* to_replace = instance_descriptors(); | 2418 DescriptorArray* to_replace = instance_descriptors(); |
2412 Map* current = this; | 2419 Map* current = this; |
2413 GetHeap()->incremental_marking()->RecordWrites(to_replace); | 2420 GetHeap()->incremental_marking()->RecordWrites(to_replace); |
2414 while (current->instance_descriptors() == to_replace) { | 2421 while (current->instance_descriptors() == to_replace) { |
2415 current->SetEnumLength(kInvalidEnumCacheSentinel); | 2422 current->SetEnumLength(kInvalidEnumCacheSentinel); |
2416 current->set_instance_descriptors(new_descriptors); | 2423 current->InitializeDescriptors(*new_descriptors, *new_layout_descriptor); |
2417 Object* next = current->GetBackPointer(); | 2424 Object* next = current->GetBackPointer(); |
2418 if (next->IsUndefined()) break; | 2425 if (next->IsUndefined()) break; |
2419 current = Map::cast(next); | 2426 current = Map::cast(next); |
2420 } | 2427 } |
2421 | 2428 |
2422 set_owns_descriptors(false); | 2429 set_owns_descriptors(false); |
2423 } | 2430 } |
2424 | 2431 |
2425 | 2432 |
2426 Map* Map::FindRootMap() { | 2433 Map* Map::FindRootMap() { |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2487 | 2494 |
2488 | 2495 |
2489 void Map::UpdateDescriptor(int descriptor_number, Descriptor* desc) { | 2496 void Map::UpdateDescriptor(int descriptor_number, Descriptor* desc) { |
2490 DisallowHeapAllocation no_allocation; | 2497 DisallowHeapAllocation no_allocation; |
2491 if (HasTransitionArray()) { | 2498 if (HasTransitionArray()) { |
2492 TransitionArray* transitions = this->transitions(); | 2499 TransitionArray* transitions = this->transitions(); |
2493 for (int i = 0; i < transitions->number_of_transitions(); ++i) { | 2500 for (int i = 0; i < transitions->number_of_transitions(); ++i) { |
2494 transitions->GetTarget(i)->UpdateDescriptor(descriptor_number, desc); | 2501 transitions->GetTarget(i)->UpdateDescriptor(descriptor_number, desc); |
2495 } | 2502 } |
2496 } | 2503 } |
2497 instance_descriptors()->Replace(descriptor_number, desc);; | 2504 instance_descriptors()->Replace(descriptor_number, desc); |
2498 } | 2505 } |
2499 | 2506 |
2500 | 2507 |
2501 // static | 2508 // static |
2502 Handle<HeapType> Map::GeneralizeFieldType(Handle<HeapType> type1, | 2509 Handle<HeapType> Map::GeneralizeFieldType(Handle<HeapType> type1, |
2503 Handle<HeapType> type2, | 2510 Handle<HeapType> type2, |
2504 Isolate* isolate) { | 2511 Isolate* isolate) { |
2505 static const int kMaxClassesPerFieldType = 5; | 2512 static const int kMaxClassesPerFieldType = 5; |
2506 if (type1->NowIs(type2)) return type2; | 2513 if (type1->NowIs(type2)) return type2; |
2507 if (type2->NowIs(type1)) return type1; | 2514 if (type2->NowIs(type1)) return type1; |
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2737 ASSERT(new_descriptors->length() > target_descriptors->length() || | 2744 ASSERT(new_descriptors->length() > target_descriptors->length() || |
2738 new_descriptors->NumberOfSlackDescriptors() > 0 || | 2745 new_descriptors->NumberOfSlackDescriptors() > 0 || |
2739 new_descriptors->number_of_descriptors() == | 2746 new_descriptors->number_of_descriptors() == |
2740 old_descriptors->number_of_descriptors()); | 2747 old_descriptors->number_of_descriptors()); |
2741 ASSERT(new_descriptors->number_of_descriptors() == old_nof); | 2748 ASSERT(new_descriptors->number_of_descriptors() == old_nof); |
2742 | 2749 |
2743 // 0 -> |root_nof| | 2750 // 0 -> |root_nof| |
2744 int current_offset = 0; | 2751 int current_offset = 0; |
2745 for (int i = 0; i < root_nof; ++i) { | 2752 for (int i = 0; i < root_nof; ++i) { |
2746 PropertyDetails old_details = old_descriptors->GetDetails(i); | 2753 PropertyDetails old_details = old_descriptors->GetDetails(i); |
2747 if (old_details.type() == FIELD) current_offset++; | 2754 if (old_details.type() == FIELD) { |
2755 current_offset += old_details.field_width_in_words(); | |
2756 } | |
2748 Descriptor d(handle(old_descriptors->GetKey(i), isolate), | 2757 Descriptor d(handle(old_descriptors->GetKey(i), isolate), |
2749 handle(old_descriptors->GetValue(i), isolate), | 2758 handle(old_descriptors->GetValue(i), isolate), |
2750 old_details); | 2759 old_details); |
2751 new_descriptors->Set(i, &d); | 2760 new_descriptors->Set(i, &d); |
2752 } | 2761 } |
2753 | 2762 |
2754 // |root_nof| -> |target_nof| | 2763 // |root_nof| -> |target_nof| |
2755 for (int i = root_nof; i < target_nof; ++i) { | 2764 for (int i = root_nof; i < target_nof; ++i) { |
2756 Handle<Name> target_key(target_descriptors->GetKey(i), isolate); | 2765 Handle<Name> target_key(target_descriptors->GetKey(i), isolate); |
2757 PropertyDetails old_details = old_descriptors->GetDetails(i); | 2766 PropertyDetails old_details = old_descriptors->GetDetails(i); |
(...skipping 17 matching lines...) Expand all Loading... | |
2775 Handle<HeapType> target_field_type = (target_details.type() == FIELD) | 2784 Handle<HeapType> target_field_type = (target_details.type() == FIELD) |
2776 ? handle(target_descriptors->GetFieldType(i), isolate) | 2785 ? handle(target_descriptors->GetFieldType(i), isolate) |
2777 : target_descriptors->GetValue(i)->OptimalType( | 2786 : target_descriptors->GetValue(i)->OptimalType( |
2778 isolate, target_details.representation()); | 2787 isolate, target_details.representation()); |
2779 target_field_type = GeneralizeFieldType( | 2788 target_field_type = GeneralizeFieldType( |
2780 target_field_type, old_field_type, isolate); | 2789 target_field_type, old_field_type, isolate); |
2781 if (modify_index == i) { | 2790 if (modify_index == i) { |
2782 target_field_type = GeneralizeFieldType( | 2791 target_field_type = GeneralizeFieldType( |
2783 target_field_type, new_field_type, isolate); | 2792 target_field_type, new_field_type, isolate); |
2784 } | 2793 } |
2785 FieldDescriptor d(target_key, | 2794 FieldDescriptor d(target_key, current_offset, target_field_type, |
2786 current_offset++, | |
2787 target_field_type, | |
2788 target_details.attributes(), | 2795 target_details.attributes(), |
2789 target_details.representation()); | 2796 target_details.representation()); |
2797 current_offset += d.GetDetails().field_width_in_words(); | |
2790 new_descriptors->Set(i, &d); | 2798 new_descriptors->Set(i, &d); |
2791 } else { | 2799 } else { |
2792 ASSERT_NE(FIELD, target_details.type()); | 2800 ASSERT_NE(FIELD, target_details.type()); |
2793 Descriptor d(target_key, | 2801 Descriptor d(target_key, |
2794 handle(target_descriptors->GetValue(i), isolate), | 2802 handle(target_descriptors->GetValue(i), isolate), |
2795 target_details); | 2803 target_details); |
2796 new_descriptors->Set(i, &d); | 2804 new_descriptors->Set(i, &d); |
2797 } | 2805 } |
2798 } | 2806 } |
2799 | 2807 |
2800 // |target_nof| -> |old_nof| | 2808 // |target_nof| -> |old_nof| |
2801 for (int i = target_nof; i < old_nof; ++i) { | 2809 for (int i = target_nof; i < old_nof; ++i) { |
2802 PropertyDetails old_details = old_descriptors->GetDetails(i); | 2810 PropertyDetails old_details = old_descriptors->GetDetails(i); |
2803 Handle<Name> old_key(old_descriptors->GetKey(i), isolate); | 2811 Handle<Name> old_key(old_descriptors->GetKey(i), isolate); |
2804 if (modify_index == i) { | 2812 if (modify_index == i) { |
2805 old_details = old_details.CopyWithRepresentation( | 2813 old_details = old_details.CopyWithRepresentation( |
2806 new_representation.generalize(old_details.representation())); | 2814 new_representation.generalize(old_details.representation())); |
2807 } | 2815 } |
2808 if (old_details.type() == FIELD) { | 2816 if (old_details.type() == FIELD) { |
2809 Handle<HeapType> old_field_type( | 2817 Handle<HeapType> old_field_type( |
2810 old_descriptors->GetFieldType(i), isolate); | 2818 old_descriptors->GetFieldType(i), isolate); |
2811 if (modify_index == i) { | 2819 if (modify_index == i) { |
2812 old_field_type = GeneralizeFieldType( | 2820 old_field_type = GeneralizeFieldType( |
2813 old_field_type, new_field_type, isolate); | 2821 old_field_type, new_field_type, isolate); |
2814 } | 2822 } |
2815 FieldDescriptor d(old_key, | 2823 FieldDescriptor d(old_key, current_offset, old_field_type, |
2816 current_offset++, | 2824 old_details.attributes(), old_details.representation()); |
2817 old_field_type, | 2825 current_offset += d.GetDetails().field_width_in_words(); |
2818 old_details.attributes(), | |
2819 old_details.representation()); | |
2820 new_descriptors->Set(i, &d); | 2826 new_descriptors->Set(i, &d); |
2821 } else { | 2827 } else { |
2822 ASSERT(old_details.type() == CONSTANT || old_details.type() == CALLBACKS); | 2828 ASSERT(old_details.type() == CONSTANT || old_details.type() == CALLBACKS); |
2823 if (modify_index == i && store_mode == FORCE_FIELD) { | 2829 if (modify_index == i && store_mode == FORCE_FIELD) { |
2824 FieldDescriptor d(old_key, | 2830 FieldDescriptor d( |
2825 current_offset++, | 2831 old_key, current_offset, |
2826 GeneralizeFieldType( | 2832 GeneralizeFieldType(old_descriptors->GetValue(i)->OptimalType( |
2827 old_descriptors->GetValue(i)->OptimalType( | 2833 isolate, old_details.representation()), |
2828 isolate, old_details.representation()), | 2834 new_field_type, isolate), |
2829 new_field_type, isolate), | 2835 old_details.attributes(), old_details.representation()); |
2830 old_details.attributes(), | 2836 current_offset += d.GetDetails().field_width_in_words(); |
2831 old_details.representation()); | |
2832 new_descriptors->Set(i, &d); | 2837 new_descriptors->Set(i, &d); |
2833 } else { | 2838 } else { |
2834 ASSERT_NE(FIELD, old_details.type()); | 2839 ASSERT_NE(FIELD, old_details.type()); |
2835 Descriptor d(old_key, | 2840 Descriptor d(old_key, |
2836 handle(old_descriptors->GetValue(i), isolate), | 2841 handle(old_descriptors->GetValue(i), isolate), |
2837 old_details); | 2842 old_details); |
2838 new_descriptors->Set(i, &d); | 2843 new_descriptors->Set(i, &d); |
2839 } | 2844 } |
2840 } | 2845 } |
2841 } | 2846 } |
2842 | 2847 |
2843 new_descriptors->Sort(); | 2848 new_descriptors->Sort(); |
2844 | 2849 |
2845 ASSERT(store_mode != FORCE_FIELD || | 2850 ASSERT(store_mode != FORCE_FIELD || |
2846 new_descriptors->GetDetails(modify_index).type() == FIELD); | 2851 new_descriptors->GetDetails(modify_index).type() == FIELD); |
2847 | 2852 |
2848 Handle<Map> split_map(root_map->FindLastMatchMap( | 2853 Handle<Map> split_map(root_map->FindLastMatchMap( |
2849 root_nof, old_nof, *new_descriptors), isolate); | 2854 root_nof, old_nof, *new_descriptors), isolate); |
2850 int split_nof = split_map->NumberOfOwnDescriptors(); | 2855 int split_nof = split_map->NumberOfOwnDescriptors(); |
2851 ASSERT_NE(old_nof, split_nof); | 2856 ASSERT_NE(old_nof, split_nof); |
2852 | 2857 |
2853 split_map->DeprecateTarget( | 2858 split_map->DeprecateTarget( |
2854 old_descriptors->GetKey(split_nof), *new_descriptors); | 2859 handle(old_descriptors->GetKey(split_nof), isolate), new_descriptors); |
2855 | 2860 |
2856 if (FLAG_trace_generalization) { | 2861 if (FLAG_trace_generalization) { |
2857 PropertyDetails old_details = old_descriptors->GetDetails(modify_index); | 2862 PropertyDetails old_details = old_descriptors->GetDetails(modify_index); |
2858 PropertyDetails new_details = new_descriptors->GetDetails(modify_index); | 2863 PropertyDetails new_details = new_descriptors->GetDetails(modify_index); |
2859 Handle<HeapType> old_field_type = (old_details.type() == FIELD) | 2864 Handle<HeapType> old_field_type = (old_details.type() == FIELD) |
2860 ? handle(old_descriptors->GetFieldType(modify_index), isolate) | 2865 ? handle(old_descriptors->GetFieldType(modify_index), isolate) |
2861 : HeapType::Constant(handle(old_descriptors->GetValue(modify_index), | 2866 : HeapType::Constant(handle(old_descriptors->GetValue(modify_index), |
2862 isolate), isolate); | 2867 isolate), isolate); |
2863 Handle<HeapType> new_field_type = (new_details.type() == FIELD) | 2868 Handle<HeapType> new_field_type = (new_details.type() == FIELD) |
2864 ? handle(new_descriptors->GetFieldType(modify_index), isolate) | 2869 ? handle(new_descriptors->GetFieldType(modify_index), isolate) |
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3122 // Only supports adding slack to owned descriptors. | 3127 // Only supports adding slack to owned descriptors. |
3123 ASSERT(map->owns_descriptors()); | 3128 ASSERT(map->owns_descriptors()); |
3124 | 3129 |
3125 Handle<DescriptorArray> descriptors(map->instance_descriptors()); | 3130 Handle<DescriptorArray> descriptors(map->instance_descriptors()); |
3126 int old_size = map->NumberOfOwnDescriptors(); | 3131 int old_size = map->NumberOfOwnDescriptors(); |
3127 if (slack <= descriptors->NumberOfSlackDescriptors()) return; | 3132 if (slack <= descriptors->NumberOfSlackDescriptors()) return; |
3128 | 3133 |
3129 Handle<DescriptorArray> new_descriptors = DescriptorArray::CopyUpTo( | 3134 Handle<DescriptorArray> new_descriptors = DescriptorArray::CopyUpTo( |
3130 descriptors, old_size, slack); | 3135 descriptors, old_size, slack); |
3131 | 3136 |
3137 Handle<LayoutDescriptor> new_layout_descriptor = | |
3138 LayoutDescriptor::New(new_descriptors); | |
3139 | |
3140 DisallowHeapAllocation no_allocation; | |
3141 | |
3132 if (old_size == 0) { | 3142 if (old_size == 0) { |
3133 map->set_instance_descriptors(*new_descriptors); | 3143 map->InitializeDescriptors(*new_descriptors, *new_layout_descriptor); |
3134 return; | 3144 return; |
3135 } | 3145 } |
3136 | 3146 |
3137 // If the source descriptors had an enum cache we copy it. This ensures | 3147 // If the source descriptors had an enum cache we copy it. This ensures |
3138 // that the maps to which we push the new descriptor array back can rely | 3148 // that the maps to which we push the new descriptor array back can rely |
3139 // on a cache always being available once it is set. If the map has more | 3149 // on a cache always being available once it is set. If the map has more |
3140 // enumerated descriptors than available in the original cache, the cache | 3150 // enumerated descriptors than available in the original cache, the cache |
3141 // will be lazily replaced by the extended cache when needed. | 3151 // will be lazily replaced by the extended cache when needed. |
3142 if (descriptors->HasEnumCache()) { | 3152 if (descriptors->HasEnumCache()) { |
3143 new_descriptors->CopyEnumCacheFrom(*descriptors); | 3153 new_descriptors->CopyEnumCacheFrom(*descriptors); |
3144 } | 3154 } |
3145 | 3155 |
3146 // Replace descriptors by new_descriptors in all maps that share it. | 3156 // Replace descriptors by new_descriptors in all maps that share it. |
3147 map->GetHeap()->incremental_marking()->RecordWrites(*descriptors); | 3157 map->GetHeap()->incremental_marking()->RecordWrites(*descriptors); |
3148 | 3158 |
3149 Map* walk_map; | 3159 Map* walk_map; |
3150 for (Object* current = map->GetBackPointer(); | 3160 for (Object* current = map->GetBackPointer(); |
3151 !current->IsUndefined(); | 3161 !current->IsUndefined(); |
3152 current = walk_map->GetBackPointer()) { | 3162 current = walk_map->GetBackPointer()) { |
3153 walk_map = Map::cast(current); | 3163 walk_map = Map::cast(current); |
3154 if (walk_map->instance_descriptors() != *descriptors) break; | 3164 if (walk_map->instance_descriptors() != *descriptors) break; |
3155 walk_map->set_instance_descriptors(*new_descriptors); | 3165 walk_map->InitializeDescriptors(*new_descriptors, *new_layout_descriptor); |
3156 } | 3166 } |
3157 | 3167 |
3158 map->set_instance_descriptors(*new_descriptors); | 3168 map->InitializeDescriptors(*new_descriptors, *new_layout_descriptor); |
3159 } | 3169 } |
3160 | 3170 |
3161 | 3171 |
3162 template<class T> | 3172 template<class T> |
3163 static int AppendUniqueCallbacks(NeanderArray* callbacks, | 3173 static int AppendUniqueCallbacks(NeanderArray* callbacks, |
3164 Handle<typename T::Array> array, | 3174 Handle<typename T::Array> array, |
3165 int valid_descriptors) { | 3175 int valid_descriptors) { |
3166 int nof_callbacks = callbacks->length(); | 3176 int nof_callbacks = callbacks->length(); |
3167 | 3177 |
3168 Isolate* isolate = array->GetIsolate(); | 3178 Isolate* isolate = array->GetIsolate(); |
(...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3463 | 3473 |
3464 if (HasFastProperties()) { | 3474 if (HasFastProperties()) { |
3465 map()->LookupDescriptor(this, *name, result); | 3475 map()->LookupDescriptor(this, *name, result); |
3466 // A property or a map transition was found. We return all of these result | 3476 // A property or a map transition was found. We return all of these result |
3467 // types because LookupOwnRealNamedProperty is used when setting | 3477 // types because LookupOwnRealNamedProperty is used when setting |
3468 // properties where map transitions are handled. | 3478 // properties where map transitions are handled. |
3469 ASSERT(!result->IsFound() || | 3479 ASSERT(!result->IsFound() || |
3470 (result->holder() == this && result->IsFastPropertyType())); | 3480 (result->holder() == this && result->IsFastPropertyType())); |
3471 // Disallow caching for uninitialized constants. These can only | 3481 // Disallow caching for uninitialized constants. These can only |
3472 // occur as fields. | 3482 // occur as fields. |
3473 if (result->IsField() && | 3483 if (result->IsField() && result->IsReadOnly()) { |
3474 result->IsReadOnly() && | 3484 FieldIndex index = result->GetFieldIndex(); |
3475 RawFastPropertyAt(result->GetFieldIndex())->IsTheHole()) { | 3485 if (!map()->IsUnboxedDoubleField(index) && |
Toon Verwaest
2014/07/29 15:02:09
Unnecessary by now
Igor Sheludko
2014/10/30 14:23:44
Done.
| |
3476 result->DisallowCaching(); | 3486 RawFastPropertyAt(index)->IsTheHole()) { |
3487 result->DisallowCaching(); | |
3488 } | |
3477 } | 3489 } |
3478 return; | 3490 return; |
3479 } | 3491 } |
3480 | 3492 |
3481 int entry = property_dictionary()->FindEntry(name); | 3493 int entry = property_dictionary()->FindEntry(name); |
3482 if (entry != NameDictionary::kNotFound) { | 3494 if (entry != NameDictionary::kNotFound) { |
3483 Object* value = property_dictionary()->ValueAt(entry); | 3495 Object* value = property_dictionary()->ValueAt(entry); |
3484 if (IsGlobalObject()) { | 3496 if (IsGlobalObject()) { |
3485 PropertyDetails d = property_dictionary()->DetailsAt(entry); | 3497 PropertyDetails d = property_dictionary()->DetailsAt(entry); |
3486 if (d.IsDeleted()) { | 3498 if (d.IsDeleted()) { |
(...skipping 494 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3981 | 3993 |
3982 DescriptorArray* desc = map()->instance_descriptors(); | 3994 DescriptorArray* desc = map()->instance_descriptors(); |
3983 PropertyDetails details = desc->GetDetails(descriptor); | 3995 PropertyDetails details = desc->GetDetails(descriptor); |
3984 | 3996 |
3985 ASSERT(details.type() == FIELD); | 3997 ASSERT(details.type() == FIELD); |
3986 | 3998 |
3987 FieldIndex index = FieldIndex::ForDescriptor(map(), descriptor); | 3999 FieldIndex index = FieldIndex::ForDescriptor(map(), descriptor); |
3988 if (details.representation().IsDouble()) { | 4000 if (details.representation().IsDouble()) { |
3989 // Nothing more to be done. | 4001 // Nothing more to be done. |
3990 if (value->IsUninitialized()) return; | 4002 if (value->IsUninitialized()) return; |
3991 HeapNumber* box = HeapNumber::cast(RawFastPropertyAt(index)); | 4003 if (map()->IsUnboxedDoubleField(index)) { |
3992 ASSERT(box->IsMutableHeapNumber()); | 4004 FastDoublePropertyAtPut(index, value->Number()); |
3993 box->set_value(value->Number()); | 4005 } else { |
4006 HeapNumber* box = HeapNumber::cast(RawFastPropertyAt(index)); | |
4007 ASSERT(box->IsMutableHeapNumber()); | |
4008 box->set_value(value->Number()); | |
4009 } | |
3994 } else { | 4010 } else { |
3995 FastPropertyAtPut(index, value); | 4011 FastPropertyAtPut(index, value); |
3996 } | 4012 } |
3997 } | 4013 } |
3998 | 4014 |
3999 | 4015 |
4000 void JSObject::SetPropertyToField(LookupResult* lookup, Handle<Object> value) { | 4016 void JSObject::SetPropertyToField(LookupResult* lookup, Handle<Object> value) { |
4001 if (lookup->type() == CONSTANT || !lookup->CanHoldValue(value)) { | 4017 if (lookup->type() == CONSTANT || !lookup->CanHoldValue(value)) { |
4002 Representation field_representation = value->OptimalRepresentation(); | 4018 Representation field_representation = value->OptimalRepresentation(); |
4003 Handle<HeapType> field_type = value->OptimalType( | 4019 Handle<HeapType> field_type = value->OptimalType( |
(...skipping 645 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4649 Handle<Name> key(descs->GetKey(i)); | 4665 Handle<Name> key(descs->GetKey(i)); |
4650 Handle<Object> value(descs->GetConstant(i), isolate); | 4666 Handle<Object> value(descs->GetConstant(i), isolate); |
4651 PropertyDetails d = PropertyDetails( | 4667 PropertyDetails d = PropertyDetails( |
4652 details.attributes(), NORMAL, i + 1); | 4668 details.attributes(), NORMAL, i + 1); |
4653 dictionary = NameDictionary::Add(dictionary, key, value, d); | 4669 dictionary = NameDictionary::Add(dictionary, key, value, d); |
4654 break; | 4670 break; |
4655 } | 4671 } |
4656 case FIELD: { | 4672 case FIELD: { |
4657 Handle<Name> key(descs->GetKey(i)); | 4673 Handle<Name> key(descs->GetKey(i)); |
4658 FieldIndex index = FieldIndex::ForDescriptor(*map, i); | 4674 FieldIndex index = FieldIndex::ForDescriptor(*map, i); |
4659 Handle<Object> value( | 4675 Handle<Object> value(JSObject::RawFastBoxedPropertyAt(object, index)); |
4660 object->RawFastPropertyAt(index), isolate); | |
4661 if (details.representation().IsDouble()) { | 4676 if (details.representation().IsDouble()) { |
4662 ASSERT(value->IsMutableHeapNumber()); | 4677 ASSERT(value->IsMutableHeapNumber()); |
4663 Handle<HeapNumber> old = Handle<HeapNumber>::cast(value); | 4678 Handle<HeapNumber> old = Handle<HeapNumber>::cast(value); |
4664 value = isolate->factory()->NewHeapNumber(old->value()); | 4679 value = isolate->factory()->NewHeapNumber(old->value()); |
4665 } | 4680 } |
4666 PropertyDetails d = | 4681 PropertyDetails d = |
4667 PropertyDetails(details.attributes(), NORMAL, i + 1); | 4682 PropertyDetails(details.attributes(), NORMAL, i + 1); |
4668 dictionary = NameDictionary::Add(dictionary, key, value, d); | 4683 dictionary = NameDictionary::Add(dictionary, key, value, d); |
4669 break; | 4684 break; |
4670 } | 4685 } |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4816 descriptors->Set(enumeration_index - 1, &d); | 4831 descriptors->Set(enumeration_index - 1, &d); |
4817 } else if (type == NORMAL) { | 4832 } else if (type == NORMAL) { |
4818 if (current_offset < inobject_props) { | 4833 if (current_offset < inobject_props) { |
4819 object->InObjectPropertyAtPut(current_offset, | 4834 object->InObjectPropertyAtPut(current_offset, |
4820 value, | 4835 value, |
4821 UPDATE_WRITE_BARRIER); | 4836 UPDATE_WRITE_BARRIER); |
4822 } else { | 4837 } else { |
4823 int offset = current_offset - inobject_props; | 4838 int offset = current_offset - inobject_props; |
4824 fields->set(offset, value); | 4839 fields->set(offset, value); |
4825 } | 4840 } |
4826 FieldDescriptor d(key, | 4841 FieldDescriptor d(key, current_offset, details.attributes(), |
4827 current_offset++, | |
4828 details.attributes(), | |
4829 // TODO(verwaest): value->OptimalRepresentation(); | 4842 // TODO(verwaest): value->OptimalRepresentation(); |
4830 Representation::Tagged()); | 4843 Representation::Tagged()); |
4844 current_offset += d.GetDetails().field_width_in_words(); | |
4831 descriptors->Set(enumeration_index - 1, &d); | 4845 descriptors->Set(enumeration_index - 1, &d); |
4832 } else if (type == CALLBACKS) { | 4846 } else if (type == CALLBACKS) { |
4833 CallbacksDescriptor d(key, | 4847 CallbacksDescriptor d(key, |
4834 handle(value, isolate), | 4848 handle(value, isolate), |
4835 details.attributes()); | 4849 details.attributes()); |
4836 descriptors->Set(enumeration_index - 1, &d); | 4850 descriptors->Set(enumeration_index - 1, &d); |
4837 } else { | 4851 } else { |
4838 UNREACHABLE(); | 4852 UNREACHABLE(); |
4839 } | 4853 } |
4840 } | 4854 } |
4841 } | 4855 } |
4842 ASSERT(current_offset == number_of_fields); | 4856 ASSERT(current_offset == number_of_fields); |
4843 | 4857 |
4844 descriptors->Sort(); | 4858 descriptors->Sort(); |
4845 | 4859 |
4860 Handle<LayoutDescriptor> layout_descriptor = | |
4861 LayoutDescriptor::New(descriptors); | |
4862 | |
4846 DisallowHeapAllocation no_gc; | 4863 DisallowHeapAllocation no_gc; |
4847 new_map->InitializeDescriptors(*descriptors); | 4864 new_map->InitializeOwnDescriptors(*descriptors, *layout_descriptor); |
4848 new_map->set_unused_property_fields(unused_property_fields); | 4865 new_map->set_unused_property_fields(unused_property_fields); |
4849 | 4866 |
4850 // Transform the object. | 4867 // Transform the object. |
4851 object->synchronized_set_map(*new_map); | 4868 object->synchronized_set_map(*new_map); |
4852 | 4869 |
4853 object->set_properties(*fields); | 4870 object->set_properties(*fields); |
4854 ASSERT(object->IsJSObject()); | 4871 ASSERT(object->IsJSObject()); |
4855 | 4872 |
4856 // Check that it really works. | 4873 // Check that it really works. |
4857 ASSERT(object->HasFastProperties()); | 4874 ASSERT(object->HasFastProperties()); |
(...skipping 962 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5820 new_map->set_is_observed(); | 5837 new_map->set_is_observed(); |
5821 } | 5838 } |
5822 JSObject::MigrateToMap(object, new_map); | 5839 JSObject::MigrateToMap(object, new_map); |
5823 } | 5840 } |
5824 | 5841 |
5825 | 5842 |
5826 Handle<Object> JSObject::FastPropertyAt(Handle<JSObject> object, | 5843 Handle<Object> JSObject::FastPropertyAt(Handle<JSObject> object, |
5827 Representation representation, | 5844 Representation representation, |
5828 FieldIndex index) { | 5845 FieldIndex index) { |
5829 Isolate* isolate = object->GetIsolate(); | 5846 Isolate* isolate = object->GetIsolate(); |
5830 Handle<Object> raw_value(object->RawFastPropertyAt(index), isolate); | 5847 // TODO(ishell): unboxed double fields will be wrapped twice here. |
5848 Handle<Object> raw_value(JSObject::RawFastBoxedPropertyAt(object, index)); | |
5831 return Object::WrapForRead(isolate, raw_value, representation); | 5849 return Object::WrapForRead(isolate, raw_value, representation); |
5832 } | 5850 } |
5833 | 5851 |
5834 | 5852 |
5835 template<class ContextObject> | 5853 template<class ContextObject> |
5836 class JSObjectWalkVisitor { | 5854 class JSObjectWalkVisitor { |
5837 public: | 5855 public: |
5838 JSObjectWalkVisitor(ContextObject* site_context, bool copying, | 5856 JSObjectWalkVisitor(ContextObject* site_context, bool copying, |
5839 JSObject::DeepCopyHints hints) | 5857 JSObject::DeepCopyHints hints) |
5840 : site_context_(site_context), | 5858 : site_context_(site_context), |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5910 HandleScope scope(isolate); | 5928 HandleScope scope(isolate); |
5911 | 5929 |
5912 // Deep copy own properties. | 5930 // Deep copy own properties. |
5913 if (copy->HasFastProperties()) { | 5931 if (copy->HasFastProperties()) { |
5914 Handle<DescriptorArray> descriptors(copy->map()->instance_descriptors()); | 5932 Handle<DescriptorArray> descriptors(copy->map()->instance_descriptors()); |
5915 int limit = copy->map()->NumberOfOwnDescriptors(); | 5933 int limit = copy->map()->NumberOfOwnDescriptors(); |
5916 for (int i = 0; i < limit; i++) { | 5934 for (int i = 0; i < limit; i++) { |
5917 PropertyDetails details = descriptors->GetDetails(i); | 5935 PropertyDetails details = descriptors->GetDetails(i); |
5918 if (details.type() != FIELD) continue; | 5936 if (details.type() != FIELD) continue; |
5919 FieldIndex index = FieldIndex::ForDescriptor(copy->map(), i); | 5937 FieldIndex index = FieldIndex::ForDescriptor(copy->map(), i); |
5920 Handle<Object> value(object->RawFastPropertyAt(index), isolate); | 5938 // TODO(ishell): avoid boxing if copying to unboxed double. |
5939 Handle<Object> value = JSObject::RawFastBoxedPropertyAt(object, index); | |
5921 if (value->IsJSObject()) { | 5940 if (value->IsJSObject()) { |
5922 ASSIGN_RETURN_ON_EXCEPTION( | 5941 ASSIGN_RETURN_ON_EXCEPTION( |
5923 isolate, value, | 5942 isolate, value, |
5924 VisitElementOrProperty(copy, Handle<JSObject>::cast(value)), | 5943 VisitElementOrProperty(copy, Handle<JSObject>::cast(value)), |
5925 JSObject); | 5944 JSObject); |
5926 } else { | 5945 } else { |
5927 Representation representation = details.representation(); | 5946 Representation representation = details.representation(); |
5928 value = Object::NewStorageFor(isolate, value, representation); | 5947 value = Object::NewStorageFor(isolate, value, representation); |
5929 } | 5948 } |
5930 if (copying) { | 5949 if (copying) { |
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6153 if ((descs->GetDetails(i).attributes() & filter) == 0 && | 6172 if ((descs->GetDetails(i).attributes() & filter) == 0 && |
6154 !FilterKey(descs->GetKey(i), filter)) { | 6173 !FilterKey(descs->GetKey(i), filter)) { |
6155 result++; | 6174 result++; |
6156 } | 6175 } |
6157 } | 6176 } |
6158 return result; | 6177 return result; |
6159 } | 6178 } |
6160 | 6179 |
6161 | 6180 |
6162 int Map::NextFreePropertyIndex() { | 6181 int Map::NextFreePropertyIndex() { |
6163 int max_index = -1; | 6182 int free_index = 0; |
6164 int number_of_own_descriptors = NumberOfOwnDescriptors(); | 6183 int number_of_own_descriptors = NumberOfOwnDescriptors(); |
6165 DescriptorArray* descs = instance_descriptors(); | 6184 DescriptorArray* descs = instance_descriptors(); |
6166 for (int i = 0; i < number_of_own_descriptors; i++) { | 6185 for (int i = 0; i < number_of_own_descriptors; i++) { |
6167 if (descs->GetType(i) == FIELD) { | 6186 PropertyDetails details = descs->GetDetails(i); |
6168 int current_index = descs->GetFieldIndex(i); | 6187 if (details.type() == FIELD) { |
6169 if (current_index > max_index) max_index = current_index; | 6188 int candidate = details.field_index() + details.field_width_in_words(); |
6189 if (candidate > free_index) free_index = candidate; | |
6170 } | 6190 } |
6171 } | 6191 } |
6172 return max_index + 1; | 6192 return free_index; |
6173 } | 6193 } |
6174 | 6194 |
6175 | 6195 |
6176 void JSReceiver::LookupOwn( | 6196 void JSReceiver::LookupOwn( |
6177 Handle<Name> name, LookupResult* result, bool search_hidden_prototypes) { | 6197 Handle<Name> name, LookupResult* result, bool search_hidden_prototypes) { |
6178 DisallowHeapAllocation no_gc; | 6198 DisallowHeapAllocation no_gc; |
6179 ASSERT(name->IsName()); | 6199 ASSERT(name->IsName()); |
6180 | 6200 |
6181 if (IsJSGlobalProxy()) { | 6201 if (IsJSGlobalProxy()) { |
6182 Object* proto = GetPrototype(); | 6202 Object* proto = GetPrototype(); |
(...skipping 818 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7001 } | 7021 } |
7002 } | 7022 } |
7003 return isolate->factory()->undefined_value(); | 7023 return isolate->factory()->undefined_value(); |
7004 } | 7024 } |
7005 | 7025 |
7006 | 7026 |
7007 Object* JSObject::SlowReverseLookup(Object* value) { | 7027 Object* JSObject::SlowReverseLookup(Object* value) { |
7008 if (HasFastProperties()) { | 7028 if (HasFastProperties()) { |
7009 int number_of_own_descriptors = map()->NumberOfOwnDescriptors(); | 7029 int number_of_own_descriptors = map()->NumberOfOwnDescriptors(); |
7010 DescriptorArray* descs = map()->instance_descriptors(); | 7030 DescriptorArray* descs = map()->instance_descriptors(); |
7031 bool value_is_number = value->IsNumber(); | |
7011 for (int i = 0; i < number_of_own_descriptors; i++) { | 7032 for (int i = 0; i < number_of_own_descriptors; i++) { |
7012 if (descs->GetType(i) == FIELD) { | 7033 if (descs->GetType(i) == FIELD) { |
7013 Object* property = | 7034 FieldIndex field_index = FieldIndex::ForDescriptor(map(), i); |
7014 RawFastPropertyAt(FieldIndex::ForDescriptor(map(), i)); | 7035 if (map()->IsUnboxedDoubleField(field_index)) { |
7015 if (descs->GetDetails(i).representation().IsDouble()) { | 7036 if (value_is_number) { |
7016 ASSERT(property->IsMutableHeapNumber()); | 7037 double property = RawFastDoublePropertyAt(field_index); |
7017 if (value->IsNumber() && property->Number() == value->Number()) { | 7038 if (property == value->Number()) { |
7039 return descs->GetKey(i); | |
7040 } | |
7041 } | |
7042 } else { | |
7043 Object* property = RawFastPropertyAt(field_index); | |
7044 if (field_index.is_double()) { | |
7045 ASSERT(property->IsMutableHeapNumber()); | |
7046 if (value_is_number && property->Number() == value->Number()) { | |
7047 return descs->GetKey(i); | |
7048 } | |
7049 } else if (property == value) { | |
7018 return descs->GetKey(i); | 7050 return descs->GetKey(i); |
7019 } | 7051 } |
7020 } else if (property == value) { | |
7021 return descs->GetKey(i); | |
7022 } | 7052 } |
7023 } else if (descs->GetType(i) == CONSTANT) { | 7053 } else if (descs->GetType(i) == CONSTANT) { |
7024 if (descs->GetConstant(i) == value) { | 7054 if (descs->GetConstant(i) == value) { |
7025 return descs->GetKey(i); | 7055 return descs->GetKey(i); |
7026 } | 7056 } |
7027 } | 7057 } |
7028 } | 7058 } |
7029 return GetHeap()->undefined_value(); | 7059 return GetHeap()->undefined_value(); |
7030 } else { | 7060 } else { |
7031 return property_dictionary()->SlowReverseLookup(value); | 7061 return property_dictionary()->SlowReverseLookup(value); |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7162 if (descriptors->NumberOfSlackDescriptors() == 0) { | 7192 if (descriptors->NumberOfSlackDescriptors() == 0) { |
7163 int old_size = descriptors->number_of_descriptors(); | 7193 int old_size = descriptors->number_of_descriptors(); |
7164 if (old_size == 0) { | 7194 if (old_size == 0) { |
7165 descriptors = DescriptorArray::Allocate(map->GetIsolate(), 0, 1); | 7195 descriptors = DescriptorArray::Allocate(map->GetIsolate(), 0, 1); |
7166 } else { | 7196 } else { |
7167 EnsureDescriptorSlack(map, old_size < 4 ? 1 : old_size / 2); | 7197 EnsureDescriptorSlack(map, old_size < 4 ? 1 : old_size / 2); |
7168 descriptors = handle(map->instance_descriptors()); | 7198 descriptors = handle(map->instance_descriptors()); |
7169 } | 7199 } |
7170 } | 7200 } |
7171 | 7201 |
7202 descriptors->Append(descriptor); | |
7203 Handle<LayoutDescriptor> layout_descriptor = | |
7204 LayoutDescriptor::New(descriptors); | |
7205 | |
7172 // Commit the state atomically. | 7206 // Commit the state atomically. |
7173 DisallowHeapAllocation no_gc; | 7207 DisallowHeapAllocation no_gc; |
7174 | 7208 |
7175 descriptors->Append(descriptor); | |
7176 result->SetBackPointer(*map); | 7209 result->SetBackPointer(*map); |
7177 result->InitializeDescriptors(*descriptors); | 7210 result->InitializeOwnDescriptors(*descriptors, *layout_descriptor); |
7178 | 7211 |
7179 ASSERT(result->NumberOfOwnDescriptors() == map->NumberOfOwnDescriptors() + 1); | 7212 ASSERT(result->NumberOfOwnDescriptors() == map->NumberOfOwnDescriptors() + 1); |
7180 | 7213 |
7181 map->set_transitions(*transitions); | 7214 map->set_transitions(*transitions); |
7182 map->set_owns_descriptors(false); | 7215 map->set_owns_descriptors(false); |
7183 | 7216 |
7184 return result; | 7217 return result; |
7185 } | 7218 } |
7186 | 7219 |
7187 | 7220 |
7188 Handle<Map> Map::CopyReplaceDescriptors(Handle<Map> map, | 7221 Handle<Map> Map::CopyReplaceDescriptors(Handle<Map> map, |
7189 Handle<DescriptorArray> descriptors, | 7222 Handle<DescriptorArray> descriptors, |
7190 TransitionFlag flag, | 7223 TransitionFlag flag, |
7191 MaybeHandle<Name> maybe_name, | 7224 MaybeHandle<Name> maybe_name, |
7192 SimpleTransitionFlag simple_flag) { | 7225 SimpleTransitionFlag simple_flag) { |
7193 ASSERT(descriptors->IsSortedNoDuplicates()); | 7226 ASSERT(descriptors->IsSortedNoDuplicates()); |
7194 | 7227 |
7195 Handle<Map> result = CopyDropDescriptors(map); | 7228 Handle<Map> result = CopyDropDescriptors(map); |
7196 result->InitializeDescriptors(*descriptors); | |
7197 | 7229 |
7198 if (flag == INSERT_TRANSITION && map->CanHaveMoreTransitions()) { | 7230 if (flag == INSERT_TRANSITION && map->CanHaveMoreTransitions()) { |
7231 Handle<LayoutDescriptor> layout_descriptor = | |
7232 LayoutDescriptor::New(descriptors); | |
7233 result->InitializeOwnDescriptors(*descriptors, *layout_descriptor); | |
7234 | |
7199 Handle<Name> name; | 7235 Handle<Name> name; |
7200 CHECK(maybe_name.ToHandle(&name)); | 7236 CHECK(maybe_name.ToHandle(&name)); |
7201 Handle<TransitionArray> transitions = TransitionArray::CopyInsert( | 7237 Handle<TransitionArray> transitions = TransitionArray::CopyInsert( |
7202 map, name, result, simple_flag); | 7238 map, name, result, simple_flag); |
7203 map->set_transitions(*transitions); | 7239 map->set_transitions(*transitions); |
7204 result->SetBackPointer(*map); | 7240 result->SetBackPointer(*map); |
7205 } else { | 7241 } else { |
7206 int length = descriptors->number_of_descriptors(); | 7242 int length = descriptors->number_of_descriptors(); |
7207 for (int i = 0; i < length; i++) { | 7243 for (int i = 0; i < length; i++) { |
7208 descriptors->SetRepresentation(i, Representation::Tagged()); | 7244 descriptors->SetRepresentation(i, Representation::Tagged()); |
7209 if (descriptors->GetDetails(i).type() == FIELD) { | 7245 if (descriptors->GetDetails(i).type() == FIELD) { |
7210 descriptors->SetValue(i, HeapType::Any()); | 7246 descriptors->SetValue(i, HeapType::Any()); |
7211 } | 7247 } |
7212 } | 7248 } |
7249 result->InitializeOwnDescriptors(*descriptors, | |
7250 LayoutDescriptor::FastPointerLayout()); | |
7213 } | 7251 } |
7214 | 7252 |
7215 return result; | 7253 return result; |
7216 } | 7254 } |
7217 | 7255 |
7218 | 7256 |
7219 // Since this method is used to rewrite an existing transition tree, it can | 7257 // Since this method is used to rewrite an existing transition tree, it can |
7220 // always insert transitions without checking. | 7258 // always insert transitions without checking. |
7221 Handle<Map> Map::CopyInstallDescriptors(Handle<Map> map, | 7259 Handle<Map> Map::CopyInstallDescriptors(Handle<Map> map, |
7222 int new_descriptor, | 7260 int new_descriptor, |
7223 Handle<DescriptorArray> descriptors) { | 7261 Handle<DescriptorArray> descriptors) { |
7224 ASSERT(descriptors->IsSortedNoDuplicates()); | 7262 ASSERT(descriptors->IsSortedNoDuplicates()); |
7225 | 7263 |
7226 Handle<Map> result = CopyDropDescriptors(map); | 7264 Handle<Map> result = CopyDropDescriptors(map); |
7227 | 7265 |
7228 result->InitializeDescriptors(*descriptors); | 7266 result->set_instance_descriptors(*descriptors); |
7229 result->SetNumberOfOwnDescriptors(new_descriptor + 1); | 7267 result->SetNumberOfOwnDescriptors(new_descriptor + 1); |
7268 if (FLAG_unbox_double_fields) { | |
7269 Handle<LayoutDescriptor> layout_descriptor = | |
7270 LayoutDescriptor::New(descriptors); | |
7271 result->set_layout_descriptor(layout_descriptor->OptimizeFor(*result)); | |
7272 result->set_visitor_id(StaticVisitorBase::GetVisitorId(*result)); | |
7273 } | |
7230 | 7274 |
7231 int unused_property_fields = map->unused_property_fields(); | 7275 int unused_property_fields = map->unused_property_fields(); |
7232 if (descriptors->GetDetails(new_descriptor).type() == FIELD) { | 7276 if (descriptors->GetDetails(new_descriptor).type() == FIELD) { |
7233 unused_property_fields = map->unused_property_fields() - 1; | 7277 unused_property_fields = map->unused_property_fields() - 1; |
7234 if (unused_property_fields < 0) { | 7278 if (unused_property_fields < 0) { |
7235 unused_property_fields += JSObject::kFieldsAdded; | 7279 unused_property_fields += JSObject::kFieldsAdded; |
7236 } | 7280 } |
7237 } | 7281 } |
7238 | 7282 |
7239 result->set_unused_property_fields(unused_property_fields); | 7283 result->set_unused_property_fields(unused_property_fields); |
(...skipping 26 matching lines...) Expand all Loading... | |
7266 } | 7310 } |
7267 | 7311 |
7268 bool insert_transition = | 7312 bool insert_transition = |
7269 flag == INSERT_TRANSITION && !map->HasElementsTransition(); | 7313 flag == INSERT_TRANSITION && !map->HasElementsTransition(); |
7270 | 7314 |
7271 if (insert_transition && map->owns_descriptors()) { | 7315 if (insert_transition && map->owns_descriptors()) { |
7272 // In case the map owned its own descriptors, share the descriptors and | 7316 // In case the map owned its own descriptors, share the descriptors and |
7273 // transfer ownership to the new map. | 7317 // transfer ownership to the new map. |
7274 Handle<Map> new_map = CopyDropDescriptors(map); | 7318 Handle<Map> new_map = CopyDropDescriptors(map); |
7275 | 7319 |
7320 Handle<DescriptorArray> descriptors(map->instance_descriptors()); | |
7321 Handle<LayoutDescriptor> layout_descriptor = | |
7322 LayoutDescriptor::New(descriptors); | |
7323 | |
7276 SetElementsTransitionMap(map, new_map); | 7324 SetElementsTransitionMap(map, new_map); |
7277 | 7325 |
7278 new_map->set_elements_kind(kind); | 7326 new_map->set_elements_kind(kind); |
7279 new_map->InitializeDescriptors(map->instance_descriptors()); | 7327 new_map->InitializeOwnDescriptors(*descriptors, *layout_descriptor); |
7280 new_map->SetBackPointer(*map); | 7328 new_map->SetBackPointer(*map); |
7281 map->set_owns_descriptors(false); | 7329 map->set_owns_descriptors(false); |
7282 return new_map; | 7330 return new_map; |
7283 } | 7331 } |
7284 | 7332 |
7285 // In case the map did not own its own descriptors, a split is forced by | 7333 // In case the map did not own its own descriptors, a split is forced by |
7286 // copying the map; creating a new descriptor array cell. | 7334 // copying the map; creating a new descriptor array cell. |
7287 // Create a new free-floating map only if we are not allowed to store it. | 7335 // Create a new free-floating map only if we are not allowed to store it. |
7288 Handle<Map> new_map = Copy(map); | 7336 Handle<Map> new_map = Copy(map); |
7289 | 7337 |
(...skipping 23 matching lines...) Expand all Loading... | |
7313 } | 7361 } |
7314 | 7362 |
7315 Handle<TransitionArray> transitions = TransitionArray::CopyInsert( | 7363 Handle<TransitionArray> transitions = TransitionArray::CopyInsert( |
7316 map, isolate->factory()->observed_symbol(), new_map, FULL_TRANSITION); | 7364 map, isolate->factory()->observed_symbol(), new_map, FULL_TRANSITION); |
7317 | 7365 |
7318 map->set_transitions(*transitions); | 7366 map->set_transitions(*transitions); |
7319 | 7367 |
7320 new_map->set_is_observed(); | 7368 new_map->set_is_observed(); |
7321 | 7369 |
7322 if (map->owns_descriptors()) { | 7370 if (map->owns_descriptors()) { |
7323 new_map->InitializeDescriptors(map->instance_descriptors()); | 7371 Handle<DescriptorArray> descriptors(map->instance_descriptors()); |
Toon Verwaest
2014/07/29 15:02:09
This is overkill, set_instance_descriptors should
Igor Sheludko
2014/10/30 14:23:44
Done.
| |
7372 Handle<LayoutDescriptor> layout_descriptor = | |
7373 LayoutDescriptor::New(descriptors); | |
7374 new_map->InitializeOwnDescriptors(*descriptors, *layout_descriptor); | |
7324 map->set_owns_descriptors(false); | 7375 map->set_owns_descriptors(false); |
7325 } | 7376 } |
7326 | 7377 |
7327 new_map->SetBackPointer(*map); | 7378 new_map->SetBackPointer(*map); |
7328 return new_map; | 7379 return new_map; |
7329 } | 7380 } |
7330 | 7381 |
7331 | 7382 |
7332 Handle<Map> Map::Copy(Handle<Map> map) { | 7383 Handle<Map> Map::Copy(Handle<Map> map) { |
7333 Handle<DescriptorArray> descriptors(map->instance_descriptors()); | 7384 Handle<DescriptorArray> descriptors(map->instance_descriptors()); |
(...skipping 932 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
8266 int slack) { | 8317 int slack) { |
8267 ASSERT(0 <= number_of_descriptors); | 8318 ASSERT(0 <= number_of_descriptors); |
8268 Factory* factory = isolate->factory(); | 8319 Factory* factory = isolate->factory(); |
8269 // Do not use DescriptorArray::cast on incomplete object. | 8320 // Do not use DescriptorArray::cast on incomplete object. |
8270 int size = number_of_descriptors + slack; | 8321 int size = number_of_descriptors + slack; |
8271 if (size == 0) return factory->empty_descriptor_array(); | 8322 if (size == 0) return factory->empty_descriptor_array(); |
8272 // Allocate the array of keys. | 8323 // Allocate the array of keys. |
8273 Handle<FixedArray> result = factory->NewFixedArray(LengthFor(size)); | 8324 Handle<FixedArray> result = factory->NewFixedArray(LengthFor(size)); |
8274 | 8325 |
8275 result->set(kDescriptorLengthIndex, Smi::FromInt(number_of_descriptors)); | 8326 result->set(kDescriptorLengthIndex, Smi::FromInt(number_of_descriptors)); |
8327 if (FLAG_unbox_double_fields) { | |
8328 result->set(kLayoutDescriptorCacheIndex, *factory->undefined_value()); | |
8329 } | |
8276 result->set(kEnumCacheIndex, Smi::FromInt(0)); | 8330 result->set(kEnumCacheIndex, Smi::FromInt(0)); |
8277 return Handle<DescriptorArray>::cast(result); | 8331 return Handle<DescriptorArray>::cast(result); |
8278 } | 8332 } |
8279 | 8333 |
8280 | 8334 |
8281 void DescriptorArray::ClearEnumCache() { | 8335 void DescriptorArray::ClearEnumCache() { |
8282 set(kEnumCacheIndex, Smi::FromInt(0)); | 8336 set(kEnumCacheIndex, Smi::FromInt(0)); |
8283 } | 8337 } |
8284 | 8338 |
8285 | 8339 |
(...skipping 11 matching lines...) Expand all Loading... | |
8297 ASSERT(!IsEmpty()); | 8351 ASSERT(!IsEmpty()); |
8298 ASSERT(!HasEnumCache() || new_cache->length() > GetEnumCache()->length()); | 8352 ASSERT(!HasEnumCache() || new_cache->length() > GetEnumCache()->length()); |
8299 FixedArray::cast(bridge_storage)-> | 8353 FixedArray::cast(bridge_storage)-> |
8300 set(kEnumCacheBridgeCacheIndex, new_cache); | 8354 set(kEnumCacheBridgeCacheIndex, new_cache); |
8301 FixedArray::cast(bridge_storage)-> | 8355 FixedArray::cast(bridge_storage)-> |
8302 set(kEnumCacheBridgeIndicesCacheIndex, new_index_cache); | 8356 set(kEnumCacheBridgeIndicesCacheIndex, new_index_cache); |
8303 set(kEnumCacheIndex, bridge_storage); | 8357 set(kEnumCacheIndex, bridge_storage); |
8304 } | 8358 } |
8305 | 8359 |
8306 | 8360 |
8307 void DescriptorArray::CopyFrom(int index, | 8361 void DescriptorArray::CopyFrom(int index, DescriptorArray* src, |
8308 DescriptorArray* src, | |
8309 const WhitenessWitness& witness) { | 8362 const WhitenessWitness& witness) { |
8310 Object* value = src->GetValue(index); | 8363 Object* value = src->GetValue(index); |
8311 PropertyDetails details = src->GetDetails(index); | 8364 PropertyDetails details = src->GetDetails(index); |
8312 Descriptor desc(handle(src->GetKey(index)), | 8365 Descriptor desc(handle(src->GetKey(index)), |
8313 handle(value, src->GetIsolate()), | 8366 handle(value, src->GetIsolate()), |
8314 details); | 8367 details); |
8315 Set(index, &desc, witness); | 8368 Set(index, &desc, witness); |
8316 } | 8369 } |
8317 | 8370 |
8318 | 8371 |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
8368 } | 8421 } |
8369 if (child_hash <= parent_hash) break; | 8422 if (child_hash <= parent_hash) break; |
8370 SwapSortedKeys(parent_index, child_index); | 8423 SwapSortedKeys(parent_index, child_index); |
8371 parent_index = child_index; | 8424 parent_index = child_index; |
8372 } | 8425 } |
8373 } | 8426 } |
8374 ASSERT(IsSortedNoDuplicates()); | 8427 ASSERT(IsSortedNoDuplicates()); |
8375 } | 8428 } |
8376 | 8429 |
8377 | 8430 |
8431 Handle<LayoutDescriptor> LayoutDescriptor::New( | |
8432 Handle<DescriptorArray> descriptors) { | |
8433 Isolate* isolate = descriptors->GetIsolate(); | |
8434 if (!FLAG_unbox_double_fields) return handle(FastPointerLayout(), isolate); | |
8435 | |
8436 // Check cached layout descriptor in descriptors array. | |
8437 Object* cached = descriptors->cached_layout_descriptor(); | |
8438 if (cached != isolate->heap()->undefined_value()) { | |
8439 LayoutDescriptor* layout_descriptor = LayoutDescriptor::cast(cached); | |
8440 return handle(layout_descriptor, isolate); | |
8441 } | |
8442 | |
8443 int num_descriptors = descriptors->number_of_descriptors(); | |
8444 | |
8445 int layout_descriptor_length; | |
8446 | |
8447 const int kMaxWordsPerField = kDoubleSize / kPointerSize; | |
8448 | |
8449 if (num_descriptors <= kSmiValueSize / kMaxWordsPerField) { | |
8450 // Even in the "worst" case (all fields are doubles) it would fit into | |
8451 // a Smi, so no need to calculate length. | |
8452 layout_descriptor_length = kSmiValueSize; | |
8453 | |
8454 } else { | |
8455 layout_descriptor_length = 0; | |
8456 | |
8457 for (int i = 0; i < num_descriptors; i++) { | |
8458 PropertyDetails details = descriptors->GetDetails(i); | |
8459 if (details.type() == FIELD) { | |
8460 if (layout_descriptor_length <= details.field_index()) { | |
8461 layout_descriptor_length = | |
8462 details.field_index() + details.field_width_in_words(); | |
8463 } | |
8464 } | |
8465 } | |
8466 } | |
8467 | |
8468 Handle<LayoutDescriptor> layout_descriptor_handle = | |
8469 LayoutDescriptor::New(isolate, layout_descriptor_length); | |
8470 | |
8471 DisallowHeapAllocation no_allocation; | |
8472 LayoutDescriptor* layout_descriptor = *layout_descriptor_handle; | |
8473 | |
8474 for (int i = 0; i < num_descriptors; i++) { | |
8475 PropertyDetails details = descriptors->GetDetails(i); | |
8476 if (details.type() == FIELD) { | |
8477 int field_index = details.field_index(); | |
8478 bool tagged = !details.representation().IsDouble(); | |
8479 layout_descriptor = layout_descriptor->SetTagged(field_index, tagged); | |
8480 if (details.field_width_in_words() > 1) { | |
8481 layout_descriptor = | |
8482 layout_descriptor->SetTagged(field_index + 1, tagged); | |
8483 } | |
8484 } | |
8485 } | |
8486 descriptors->set_cached_layout_descriptor(layout_descriptor); | |
8487 return handle(layout_descriptor, isolate); | |
8488 } | |
8489 | |
8490 | |
8378 Handle<AccessorPair> AccessorPair::Copy(Handle<AccessorPair> pair) { | 8491 Handle<AccessorPair> AccessorPair::Copy(Handle<AccessorPair> pair) { |
8379 Handle<AccessorPair> copy = pair->GetIsolate()->factory()->NewAccessorPair(); | 8492 Handle<AccessorPair> copy = pair->GetIsolate()->factory()->NewAccessorPair(); |
8380 copy->set_getter(pair->getter()); | 8493 copy->set_getter(pair->getter()); |
8381 copy->set_setter(pair->setter()); | 8494 copy->set_setter(pair->setter()); |
8382 return copy; | 8495 return copy; |
8383 } | 8496 } |
8384 | 8497 |
8385 | 8498 |
8386 Object* AccessorPair::GetComponent(AccessorComponent component) { | 8499 Object* AccessorPair::GetComponent(AccessorComponent component) { |
8387 Object* accessor = get(component); | 8500 Object* accessor = get(component); |
(...skipping 8602 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
16990 #define ERROR_MESSAGES_TEXTS(C, T) T, | 17103 #define ERROR_MESSAGES_TEXTS(C, T) T, |
16991 static const char* error_messages_[] = { | 17104 static const char* error_messages_[] = { |
16992 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 17105 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
16993 }; | 17106 }; |
16994 #undef ERROR_MESSAGES_TEXTS | 17107 #undef ERROR_MESSAGES_TEXTS |
16995 return error_messages_[reason]; | 17108 return error_messages_[reason]; |
16996 } | 17109 } |
16997 | 17110 |
16998 | 17111 |
16999 } } // namespace v8::internal | 17112 } } // namespace v8::internal |
OLD | NEW |