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

Side by Side Diff: src/objects.cc

Issue 1697173002: [runtime] Optimize MigrateFastToFast for the transition case (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 10 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 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/objects.h" 5 #include "src/objects.h"
6 6
7 #include <cmath> 7 #include <cmath>
8 #include <iomanip> 8 #include <iomanip>
9 #include <sstream> 9 #include <sstream>
10 10
(...skipping 2865 matching lines...) Expand 10 before | Expand all | Expand 10 after
2876 // * Copy inobject properties from the backing store back into the object. 2876 // * Copy inobject properties from the backing store back into the object.
2877 // * Trim the difference in instance size of the object. This also cleanly 2877 // * Trim the difference in instance size of the object. This also cleanly
2878 // frees inobject properties that moved to the backing store. 2878 // frees inobject properties that moved to the backing store.
2879 // * If there are properties left in the backing store, trim of the space used 2879 // * If there are properties left in the backing store, trim of the space used
2880 // to temporarily store the inobject properties. 2880 // to temporarily store the inobject properties.
2881 // * If there are properties left in the backing store, install the backing 2881 // * If there are properties left in the backing store, install the backing
2882 // store. 2882 // store.
2883 void JSObject::MigrateFastToFast(Handle<JSObject> object, Handle<Map> new_map) { 2883 void JSObject::MigrateFastToFast(Handle<JSObject> object, Handle<Map> new_map) {
2884 Isolate* isolate = object->GetIsolate(); 2884 Isolate* isolate = object->GetIsolate();
2885 Handle<Map> old_map(object->map()); 2885 Handle<Map> old_map(object->map());
2886 int old_number_of_fields; 2886 // In case of a regular transition.
2887 int number_of_fields = new_map->NumberOfFields(); 2887 if (new_map->GetBackPointer() == *old_map) {
2888 int inobject = new_map->GetInObjectProperties(); 2888 // If the map does not add named properties, simply set the map.
2889 int unused = new_map->unused_property_fields(); 2889 if (old_map->NumberOfOwnDescriptors() ==
2890 2890 new_map->NumberOfOwnDescriptors()) {
2891 // Nothing to do if no functions were converted to fields and no smis were
2892 // converted to doubles.
2893 if (!old_map->InstancesNeedRewriting(*new_map, number_of_fields, inobject,
2894 unused, &old_number_of_fields)) {
2895 object->synchronized_set_map(*new_map);
2896 return;
2897 }
2898
2899 int total_size = number_of_fields + unused;
2900 int external = total_size - inobject;
2901
2902 if (number_of_fields != old_number_of_fields &&
2903 new_map->GetBackPointer() == *old_map) {
2904 PropertyDetails details = new_map->GetLastDescriptorDetails();
2905
2906 if (old_map->unused_property_fields() > 0) {
2907 if (details.representation().IsDouble()) {
2908 FieldIndex index =
2909 FieldIndex::ForDescriptor(*new_map, new_map->LastAdded());
2910 if (new_map->IsUnboxedDoubleField(index)) {
2911 object->RawFastDoublePropertyAtPut(index, 0);
2912 } else {
2913 Handle<Object> value = isolate->factory()->NewHeapNumber(0, MUTABLE);
2914 object->RawFastPropertyAtPut(index, *value);
2915 }
2916 }
2917 object->synchronized_set_map(*new_map); 2891 object->synchronized_set_map(*new_map);
2918 return; 2892 return;
2919 } 2893 }
2920 2894
2921 DCHECK(number_of_fields == old_number_of_fields + 1); 2895 PropertyDetails details = new_map->GetLastDescriptorDetails();
2896 // Either new_map adds an kDescriptor property, or a kField property for
2897 // which there is still space, and which does not require a mutable double
2898 // box (an out-of-object double).
2899 if (details.location() == kDescriptor ||
2900 (old_map->unused_property_fields() > 0 &&
2901 ((FLAG_unbox_double_fields && object->properties()->length() == 0) ||
2902 !details.representation().IsDouble()))) {
2903 object->synchronized_set_map(*new_map);
2904 return;
2905 }
2906
2907 // If there is still space in the object, we need to allocate a mutable
2908 // double box.
2909 if (old_map->unused_property_fields() > 0) {
2910 FieldIndex index =
2911 FieldIndex::ForDescriptor(*new_map, new_map->LastAdded());
2912 DCHECK(details.representation().IsDouble());
2913 DCHECK(!new_map->IsUnboxedDoubleField(index));
2914 Handle<Object> value = isolate->factory()->NewHeapNumber(0, MUTABLE);
2915 object->RawFastPropertyAtPut(index, *value);
2916 object->synchronized_set_map(*new_map);
2917 return;
2918 }
2919
2922 // This migration is a transition from a map that has run out of property 2920 // This migration is a transition from a map that has run out of property
2923 // space. Therefore it could be done by extending the backing store. 2921 // space. Extend the backing store.
2924 int grow_by = external - object->properties()->length(); 2922 int grow_by = new_map->unused_property_fields() + 1;
2925 Handle<FixedArray> old_storage = handle(object->properties(), isolate); 2923 Handle<FixedArray> old_storage = handle(object->properties(), isolate);
2926 Handle<FixedArray> new_storage = 2924 Handle<FixedArray> new_storage =
2927 isolate->factory()->CopyFixedArrayAndGrow(old_storage, grow_by); 2925 isolate->factory()->CopyFixedArrayAndGrow(old_storage, grow_by);
2928 2926
2929 // Properly initialize newly added property. 2927 // Properly initialize newly added property.
2930 Handle<Object> value; 2928 Handle<Object> value;
2931 if (details.representation().IsDouble()) { 2929 if (details.representation().IsDouble()) {
2932 value = isolate->factory()->NewHeapNumber(0, MUTABLE); 2930 value = isolate->factory()->NewHeapNumber(0, MUTABLE);
2933 } else { 2931 } else {
2934 value = isolate->factory()->uninitialized_value(); 2932 value = isolate->factory()->uninitialized_value();
2935 } 2933 }
2936 DCHECK(details.type() == DATA); 2934 DCHECK_EQ(DATA, details.type());
2937 int target_index = details.field_index() - inobject; 2935 int target_index = details.field_index() - new_map->GetInObjectProperties();
2938 DCHECK(target_index >= 0); // Must be a backing store index. 2936 DCHECK(target_index >= 0); // Must be a backing store index.
2939 new_storage->set(target_index, *value); 2937 new_storage->set(target_index, *value);
2940 2938
2941 // From here on we cannot fail and we shouldn't GC anymore. 2939 // From here on we cannot fail and we shouldn't GC anymore.
2942 DisallowHeapAllocation no_allocation; 2940 DisallowHeapAllocation no_allocation;
2943 2941
2944 // Set the new property value and do the map transition. 2942 // Set the new property value and do the map transition.
2945 object->set_properties(*new_storage); 2943 object->set_properties(*new_storage);
2946 object->synchronized_set_map(*new_map); 2944 object->synchronized_set_map(*new_map);
2947 return; 2945 return;
2948 } 2946 }
2947
2948 int old_number_of_fields;
2949 int number_of_fields = new_map->NumberOfFields();
2950 int inobject = new_map->GetInObjectProperties();
2951 int unused = new_map->unused_property_fields();
2952
2953 // Nothing to do if no functions were converted to fields and no smis were
2954 // converted to doubles.
2955 if (!old_map->InstancesNeedRewriting(*new_map, number_of_fields, inobject,
2956 unused, &old_number_of_fields)) {
2957 object->synchronized_set_map(*new_map);
2958 return;
2959 }
2960
2961 int total_size = number_of_fields + unused;
2962 int external = total_size - inobject;
2963
2949 Handle<FixedArray> array = isolate->factory()->NewFixedArray(total_size); 2964 Handle<FixedArray> array = isolate->factory()->NewFixedArray(total_size);
2950 2965
2951 Handle<DescriptorArray> old_descriptors(old_map->instance_descriptors()); 2966 Handle<DescriptorArray> old_descriptors(old_map->instance_descriptors());
2952 Handle<DescriptorArray> new_descriptors(new_map->instance_descriptors()); 2967 Handle<DescriptorArray> new_descriptors(new_map->instance_descriptors());
2953 int old_nof = old_map->NumberOfOwnDescriptors(); 2968 int old_nof = old_map->NumberOfOwnDescriptors();
2954 int new_nof = new_map->NumberOfOwnDescriptors(); 2969 int new_nof = new_map->NumberOfOwnDescriptors();
2955 2970
2956 // This method only supports generalizing instances to at least the same 2971 // This method only supports generalizing instances to at least the same
2957 // number of properties. 2972 // number of properties.
2958 DCHECK(old_nof <= new_nof); 2973 DCHECK(old_nof <= new_nof);
(...skipping 17011 matching lines...) Expand 10 before | Expand all | Expand 10 after
19970 if (cell->value() != *new_value) { 19985 if (cell->value() != *new_value) {
19971 cell->set_value(*new_value); 19986 cell->set_value(*new_value);
19972 Isolate* isolate = cell->GetIsolate(); 19987 Isolate* isolate = cell->GetIsolate();
19973 cell->dependent_code()->DeoptimizeDependentCodeGroup( 19988 cell->dependent_code()->DeoptimizeDependentCodeGroup(
19974 isolate, DependentCode::kPropertyCellChangedGroup); 19989 isolate, DependentCode::kPropertyCellChangedGroup);
19975 } 19990 }
19976 } 19991 }
19977 19992
19978 } // namespace internal 19993 } // namespace internal
19979 } // namespace v8 19994 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698