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

Side by Side Diff: src/objects.cc

Issue 391693002: In-object double fields unboxing (for 64-bit only). (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698