OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 1889 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1900 value->OptimalType(isolate, representation), | 1900 value->OptimalType(isolate, representation), |
1901 attributes, representation, flag); | 1901 attributes, representation, flag); |
1902 } | 1902 } |
1903 | 1903 |
1904 Handle<Map> new_map; | 1904 Handle<Map> new_map; |
1905 if (!maybe_map.ToHandle(&new_map)) { | 1905 if (!maybe_map.ToHandle(&new_map)) { |
1906 NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0); | 1906 NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0); |
1907 return; | 1907 return; |
1908 } | 1908 } |
1909 | 1909 |
1910 JSObject::MigrateToMap(object, new_map); | 1910 JSObject::MigrateToNewProperty(object, new_map, value); |
1911 | |
1912 PropertyDetails details = new_map->GetLastDescriptorDetails(); | |
1913 if (details.type() != FIELD) return; | |
1914 | |
1915 Representation representation = details.representation(); | |
1916 int index = details.field_index(); | |
1917 | |
1918 if (representation.IsDouble()) { | |
1919 // Nothing more to be done. | |
1920 if (value->IsUninitialized()) return; | |
1921 HeapNumber* box = HeapNumber::cast(object->RawFastPropertyAt(index)); | |
1922 box->set_value(value->Number()); | |
1923 } else { | |
1924 object->FastPropertyAtPut(index, *value); | |
1925 } | |
1926 } | 1911 } |
1927 | 1912 |
1928 | 1913 |
1929 void JSObject::AddSlowProperty(Handle<JSObject> object, | 1914 void JSObject::AddSlowProperty(Handle<JSObject> object, |
1930 Handle<Name> name, | 1915 Handle<Name> name, |
1931 Handle<Object> value, | 1916 Handle<Object> value, |
1932 PropertyAttributes attributes) { | 1917 PropertyAttributes attributes) { |
1933 ASSERT(!object->HasFastProperties()); | 1918 ASSERT(!object->HasFastProperties()); |
1934 Isolate* isolate = object->GetIsolate(); | 1919 Isolate* isolate = object->GetIsolate(); |
1935 Handle<NameDictionary> dict(object->property_dictionary()); | 1920 Handle<NameDictionary> dict(object->property_dictionary()); |
(...skipping 2011 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3947 // (value->IsUninitialized) as constant. | 3932 // (value->IsUninitialized) as constant. |
3948 if (!lookup->CanHoldValue(value)) { | 3933 if (!lookup->CanHoldValue(value)) { |
3949 Representation field_representation = value->OptimalRepresentation(); | 3934 Representation field_representation = value->OptimalRepresentation(); |
3950 Handle<HeapType> field_type = value->OptimalType( | 3935 Handle<HeapType> field_type = value->OptimalType( |
3951 lookup->isolate(), field_representation); | 3936 lookup->isolate(), field_representation); |
3952 transition_map = Map::GeneralizeRepresentation( | 3937 transition_map = Map::GeneralizeRepresentation( |
3953 transition_map, descriptor, | 3938 transition_map, descriptor, |
3954 field_representation, field_type, FORCE_FIELD); | 3939 field_representation, field_type, FORCE_FIELD); |
3955 } | 3940 } |
3956 | 3941 |
3957 JSObject::MigrateToMap(object, transition_map); | 3942 JSObject::MigrateToNewProperty(object, transition_map, value); |
| 3943 return value; |
| 3944 } |
3958 | 3945 |
3959 // Reload. | |
3960 descriptors = handle(transition_map->instance_descriptors()); | |
3961 details = descriptors->GetDetails(descriptor); | |
3962 | 3946 |
3963 if (details.type() != FIELD) return value; | 3947 void JSObject::MigrateToNewProperty(Handle<JSObject> object, |
| 3948 Handle<Map> map, |
| 3949 Handle<Object> value) { |
| 3950 JSObject::MigrateToMap(object, map); |
| 3951 if (map->GetLastDescriptorDetails().type() != FIELD) return; |
| 3952 object->WriteToField(map->LastAdded(), *value); |
| 3953 } |
3964 | 3954 |
3965 int field_index = descriptors->GetFieldIndex(descriptor); | 3955 |
| 3956 void JSObject::WriteToField(int descriptor, Object* value) { |
| 3957 DisallowHeapAllocation no_gc; |
| 3958 |
| 3959 DescriptorArray* desc = map()->instance_descriptors(); |
| 3960 PropertyDetails details = desc->GetDetails(descriptor); |
| 3961 |
| 3962 ASSERT(details.type() == FIELD); |
| 3963 |
| 3964 int field_index = desc->GetFieldIndex(descriptor); |
3966 if (details.representation().IsDouble()) { | 3965 if (details.representation().IsDouble()) { |
3967 // Nothing more to be done. | 3966 // Nothing more to be done. |
3968 if (value->IsUninitialized()) return value; | 3967 if (value->IsUninitialized()) return; |
3969 HeapNumber* box = HeapNumber::cast(object->RawFastPropertyAt(field_index)); | 3968 HeapNumber* box = HeapNumber::cast(RawFastPropertyAt(field_index)); |
3970 box->set_value(value->Number()); | 3969 box->set_value(value->Number()); |
3971 } else { | 3970 } else { |
3972 object->FastPropertyAtPut(field_index, *value); | 3971 FastPropertyAtPut(field_index, value); |
3973 } | 3972 } |
3974 | |
3975 return value; | |
3976 } | 3973 } |
3977 | 3974 |
3978 | 3975 |
3979 static void SetPropertyToField(LookupResult* lookup, | 3976 static void SetPropertyToField(LookupResult* lookup, |
3980 Handle<Object> value) { | 3977 Handle<Object> value) { |
3981 Representation representation = lookup->representation(); | |
3982 if (lookup->type() == CONSTANT || !lookup->CanHoldValue(value)) { | 3978 if (lookup->type() == CONSTANT || !lookup->CanHoldValue(value)) { |
3983 Representation field_representation = value->OptimalRepresentation(); | 3979 Representation field_representation = value->OptimalRepresentation(); |
3984 Handle<HeapType> field_type = value->OptimalType( | 3980 Handle<HeapType> field_type = value->OptimalType( |
3985 lookup->isolate(), field_representation); | 3981 lookup->isolate(), field_representation); |
3986 JSObject::GeneralizeFieldRepresentation(handle(lookup->holder()), | 3982 JSObject::GeneralizeFieldRepresentation(handle(lookup->holder()), |
3987 lookup->GetDescriptorIndex(), | 3983 lookup->GetDescriptorIndex(), |
3988 field_representation, field_type, | 3984 field_representation, field_type, |
3989 FORCE_FIELD); | 3985 FORCE_FIELD); |
3990 DescriptorArray* desc = lookup->holder()->map()->instance_descriptors(); | |
3991 int descriptor = lookup->GetDescriptorIndex(); | |
3992 representation = desc->GetDetails(descriptor).representation(); | |
3993 } | 3986 } |
3994 | 3987 lookup->holder()->WriteToField(lookup->GetDescriptorIndex(), *value); |
3995 if (representation.IsDouble()) { | |
3996 HeapNumber* storage = HeapNumber::cast(lookup->holder()->RawFastPropertyAt( | |
3997 lookup->GetFieldIndex().field_index())); | |
3998 storage->set_value(value->Number()); | |
3999 return; | |
4000 } | |
4001 | |
4002 lookup->holder()->FastPropertyAtPut( | |
4003 lookup->GetFieldIndex().field_index(), *value); | |
4004 } | 3988 } |
4005 | 3989 |
4006 | 3990 |
4007 static void ConvertAndSetLocalProperty(LookupResult* lookup, | 3991 static void ConvertAndSetLocalProperty(LookupResult* lookup, |
4008 Handle<Name> name, | 3992 Handle<Name> name, |
4009 Handle<Object> value, | 3993 Handle<Object> value, |
4010 PropertyAttributes attributes) { | 3994 PropertyAttributes attributes) { |
4011 Handle<JSObject> object(lookup->holder()); | 3995 Handle<JSObject> object(lookup->holder()); |
4012 if (object->TooManyFastProperties()) { | 3996 if (object->TooManyFastProperties()) { |
4013 JSObject::NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0); | 3997 JSObject::NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0); |
4014 } | 3998 } |
4015 | 3999 |
4016 if (!object->HasFastProperties()) { | 4000 if (!object->HasFastProperties()) { |
4017 ReplaceSlowProperty(object, name, value, attributes); | 4001 ReplaceSlowProperty(object, name, value, attributes); |
4018 return; | 4002 return; |
4019 } | 4003 } |
4020 | 4004 |
4021 int descriptor_index = lookup->GetDescriptorIndex(); | 4005 int descriptor_index = lookup->GetDescriptorIndex(); |
4022 if (lookup->GetAttributes() == attributes) { | 4006 if (lookup->GetAttributes() == attributes) { |
4023 JSObject::GeneralizeFieldRepresentation( | 4007 JSObject::GeneralizeFieldRepresentation( |
4024 object, descriptor_index, Representation::Tagged(), | 4008 object, descriptor_index, Representation::Tagged(), |
4025 HeapType::Any(lookup->isolate()), FORCE_FIELD); | 4009 HeapType::Any(lookup->isolate()), FORCE_FIELD); |
4026 } else { | 4010 } else { |
4027 Handle<Map> old_map(object->map()); | 4011 Handle<Map> old_map(object->map()); |
4028 Handle<Map> new_map = Map::CopyGeneralizeAllRepresentations(old_map, | 4012 Handle<Map> new_map = Map::CopyGeneralizeAllRepresentations(old_map, |
4029 descriptor_index, FORCE_FIELD, attributes, "attributes mismatch"); | 4013 descriptor_index, FORCE_FIELD, attributes, "attributes mismatch"); |
4030 JSObject::MigrateToMap(object, new_map); | 4014 JSObject::MigrateToMap(object, new_map); |
4031 } | 4015 } |
4032 | 4016 |
4033 DescriptorArray* descriptors = object->map()->instance_descriptors(); | 4017 object->WriteToField(descriptor_index, *value); |
4034 int index = descriptors->GetDetails(descriptor_index).field_index(); | |
4035 object->FastPropertyAtPut(index, *value); | |
4036 } | 4018 } |
4037 | 4019 |
4038 | 4020 |
4039 static void SetPropertyToFieldWithAttributes(LookupResult* lookup, | 4021 static void SetPropertyToFieldWithAttributes(LookupResult* lookup, |
4040 Handle<Name> name, | 4022 Handle<Name> name, |
4041 Handle<Object> value, | 4023 Handle<Object> value, |
4042 PropertyAttributes attributes) { | 4024 PropertyAttributes attributes) { |
4043 if (lookup->GetAttributes() == attributes) { | 4025 if (lookup->GetAttributes() == attributes) { |
4044 if (value->IsUninitialized()) return; | 4026 if (value->IsUninitialized()) return; |
4045 SetPropertyToField(lookup, value); | 4027 SetPropertyToField(lookup, value); |
(...skipping 1174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5220 if (object->HasFastProperties()) { | 5202 if (object->HasFastProperties()) { |
5221 // If the object has fast properties, check whether the first slot | 5203 // If the object has fast properties, check whether the first slot |
5222 // in the descriptor array matches the hidden string. Since the | 5204 // in the descriptor array matches the hidden string. Since the |
5223 // hidden strings hash code is zero (and no other name has hash | 5205 // hidden strings hash code is zero (and no other name has hash |
5224 // code zero) it will always occupy the first entry if present. | 5206 // code zero) it will always occupy the first entry if present. |
5225 DescriptorArray* descriptors = object->map()->instance_descriptors(); | 5207 DescriptorArray* descriptors = object->map()->instance_descriptors(); |
5226 if (descriptors->number_of_descriptors() > 0) { | 5208 if (descriptors->number_of_descriptors() > 0) { |
5227 int sorted_index = descriptors->GetSortedKeyIndex(0); | 5209 int sorted_index = descriptors->GetSortedKeyIndex(0); |
5228 if (descriptors->GetKey(sorted_index) == isolate->heap()->hidden_string() | 5210 if (descriptors->GetKey(sorted_index) == isolate->heap()->hidden_string() |
5229 && sorted_index < object->map()->NumberOfOwnDescriptors()) { | 5211 && sorted_index < object->map()->NumberOfOwnDescriptors()) { |
5230 ASSERT(descriptors->GetType(sorted_index) == FIELD); | 5212 object->WriteToField(sorted_index, *value); |
5231 object->FastPropertyAtPut(descriptors->GetFieldIndex(sorted_index), | |
5232 *value); | |
5233 return object; | 5213 return object; |
5234 } | 5214 } |
5235 } | 5215 } |
5236 } | 5216 } |
5237 | 5217 |
5238 SetLocalPropertyIgnoreAttributes(object, | 5218 SetLocalPropertyIgnoreAttributes(object, |
5239 isolate->factory()->hidden_string(), | 5219 isolate->factory()->hidden_string(), |
5240 value, | 5220 value, |
5241 DONT_ENUM, | 5221 DONT_ENUM, |
5242 OPTIMAL_REPRESENTATION, | 5222 OPTIMAL_REPRESENTATION, |
(...skipping 11365 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
16608 #define ERROR_MESSAGES_TEXTS(C, T) T, | 16588 #define ERROR_MESSAGES_TEXTS(C, T) T, |
16609 static const char* error_messages_[] = { | 16589 static const char* error_messages_[] = { |
16610 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 16590 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
16611 }; | 16591 }; |
16612 #undef ERROR_MESSAGES_TEXTS | 16592 #undef ERROR_MESSAGES_TEXTS |
16613 return error_messages_[reason]; | 16593 return error_messages_[reason]; |
16614 } | 16594 } |
16615 | 16595 |
16616 | 16596 |
16617 } } // namespace v8::internal | 16597 } } // namespace v8::internal |
OLD | NEW |