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 1886 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1897 handle(object->map(), isolate), name, | 1897 handle(object->map(), isolate), name, |
1898 value->OptimalType(isolate, representation), | 1898 value->OptimalType(isolate, representation), |
1899 attributes, representation, flag); | 1899 attributes, representation, flag); |
1900 | 1900 |
1901 if (new_map.is_null()) { | 1901 if (new_map.is_null()) { |
1902 NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0); | 1902 NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0); |
1903 return; | 1903 return; |
1904 } | 1904 } |
1905 } | 1905 } |
1906 | 1906 |
1907 JSObject::MigrateToMap(object, new_map); | 1907 JSObject::MigrateToNewProperty(object, new_map, value); |
1908 | |
1909 PropertyDetails details = new_map->GetLastDescriptorDetails(); | |
1910 if (details.type() != FIELD) return; | |
1911 | |
1912 Representation representation = details.representation(); | |
1913 int index = details.field_index(); | |
1914 | |
1915 if (representation.IsDouble()) { | |
1916 // Nothing more to be done. | |
1917 if (value->IsUninitialized()) return; | |
1918 HeapNumber* box = HeapNumber::cast(object->RawFastPropertyAt(index)); | |
1919 box->set_value(value->Number()); | |
1920 } else { | |
1921 object->FastPropertyAtPut(index, *value); | |
1922 } | |
1923 } | 1908 } |
1924 | 1909 |
1925 | 1910 |
1926 void JSObject::AddSlowProperty(Handle<JSObject> object, | 1911 void JSObject::AddSlowProperty(Handle<JSObject> object, |
1927 Handle<Name> name, | 1912 Handle<Name> name, |
1928 Handle<Object> value, | 1913 Handle<Object> value, |
1929 PropertyAttributes attributes) { | 1914 PropertyAttributes attributes) { |
1930 ASSERT(!object->HasFastProperties()); | 1915 ASSERT(!object->HasFastProperties()); |
1931 Isolate* isolate = object->GetIsolate(); | 1916 Isolate* isolate = object->GetIsolate(); |
1932 Handle<NameDictionary> dict(object->property_dictionary()); | 1917 Handle<NameDictionary> dict(object->property_dictionary()); |
(...skipping 2012 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3945 // (value->IsUninitialized) as constant. | 3930 // (value->IsUninitialized) as constant. |
3946 if (!lookup->CanHoldValue(value)) { | 3931 if (!lookup->CanHoldValue(value)) { |
3947 Representation field_representation = value->OptimalRepresentation(); | 3932 Representation field_representation = value->OptimalRepresentation(); |
3948 Handle<HeapType> field_type = value->OptimalType( | 3933 Handle<HeapType> field_type = value->OptimalType( |
3949 lookup->isolate(), field_representation); | 3934 lookup->isolate(), field_representation); |
3950 transition_map = Map::GeneralizeRepresentation( | 3935 transition_map = Map::GeneralizeRepresentation( |
3951 transition_map, descriptor, | 3936 transition_map, descriptor, |
3952 field_representation, field_type, FORCE_FIELD); | 3937 field_representation, field_type, FORCE_FIELD); |
3953 } | 3938 } |
3954 | 3939 |
3955 JSObject::MigrateToMap(object, transition_map); | 3940 JSObject::MigrateToNewProperty(object, transition_map, value); |
3941 return value; | |
3942 } | |
3956 | 3943 |
3957 // Reload. | |
3958 descriptors = handle(transition_map->instance_descriptors()); | |
3959 details = descriptors->GetDetails(descriptor); | |
3960 | 3944 |
3961 if (details.type() != FIELD) return value; | 3945 void JSObject::MigrateToNewProperty(Handle<JSObject> object, |
3946 Handle<Map> map, | |
3947 Handle<Object> value) { | |
3948 JSObject::MigrateToMap(object, map); | |
3949 if (map->GetLastDescriptorDetails().type() != FIELD) return; | |
3950 object->WriteToField(map->LastAdded(), *value); | |
3951 } | |
3962 | 3952 |
3963 int field_index = descriptors->GetFieldIndex(descriptor); | 3953 |
3954 void JSObject::WriteToField(int descriptor, Object* value) { | |
Igor Sheludko
2014/04/16 09:50:03
Suggestion: you are not using handles here, what a
| |
3955 DescriptorArray* desc = map()->instance_descriptors(); | |
3956 PropertyDetails details = desc->GetDetails(descriptor); | |
3957 int field_index = desc->GetFieldIndex(descriptor); | |
3964 if (details.representation().IsDouble()) { | 3958 if (details.representation().IsDouble()) { |
3965 // Nothing more to be done. | 3959 // Nothing more to be done. |
3966 if (value->IsUninitialized()) return value; | 3960 if (value->IsUninitialized()) return; |
3967 HeapNumber* box = HeapNumber::cast(object->RawFastPropertyAt(field_index)); | 3961 HeapNumber* box = HeapNumber::cast(RawFastPropertyAt(field_index)); |
3968 box->set_value(value->Number()); | 3962 box->set_value(value->Number()); |
3969 } else { | 3963 } else { |
3970 object->FastPropertyAtPut(field_index, *value); | 3964 FastPropertyAtPut(field_index, value); |
3971 } | 3965 } |
3972 | |
3973 return value; | |
3974 } | 3966 } |
3975 | 3967 |
3976 | 3968 |
3977 static void SetPropertyToField(LookupResult* lookup, | 3969 static void SetPropertyToField(LookupResult* lookup, |
3978 Handle<Object> value) { | 3970 Handle<Object> value) { |
3979 Representation representation = lookup->representation(); | |
3980 if (lookup->type() == CONSTANT || !lookup->CanHoldValue(value)) { | 3971 if (lookup->type() == CONSTANT || !lookup->CanHoldValue(value)) { |
3981 Representation field_representation = value->OptimalRepresentation(); | 3972 Representation field_representation = value->OptimalRepresentation(); |
3982 Handle<HeapType> field_type = value->OptimalType( | 3973 Handle<HeapType> field_type = value->OptimalType( |
3983 lookup->isolate(), field_representation); | 3974 lookup->isolate(), field_representation); |
3984 JSObject::GeneralizeFieldRepresentation(handle(lookup->holder()), | 3975 JSObject::GeneralizeFieldRepresentation(handle(lookup->holder()), |
3985 lookup->GetDescriptorIndex(), | 3976 lookup->GetDescriptorIndex(), |
3986 field_representation, field_type, | 3977 field_representation, field_type, |
3987 FORCE_FIELD); | 3978 FORCE_FIELD); |
3988 DescriptorArray* desc = lookup->holder()->map()->instance_descriptors(); | |
3989 int descriptor = lookup->GetDescriptorIndex(); | |
3990 representation = desc->GetDetails(descriptor).representation(); | |
3991 } | 3979 } |
3992 | 3980 lookup->holder()->WriteToField(lookup->GetDescriptorIndex(), *value); |
3993 if (representation.IsDouble()) { | |
3994 HeapNumber* storage = HeapNumber::cast(lookup->holder()->RawFastPropertyAt( | |
3995 lookup->GetFieldIndex().field_index())); | |
3996 storage->set_value(value->Number()); | |
3997 return; | |
3998 } | |
3999 | |
4000 lookup->holder()->FastPropertyAtPut( | |
4001 lookup->GetFieldIndex().field_index(), *value); | |
4002 } | 3981 } |
4003 | 3982 |
4004 | 3983 |
4005 static void ConvertAndSetLocalProperty(LookupResult* lookup, | 3984 static void ConvertAndSetLocalProperty(LookupResult* lookup, |
4006 Handle<Name> name, | 3985 Handle<Name> name, |
4007 Handle<Object> value, | 3986 Handle<Object> value, |
4008 PropertyAttributes attributes) { | 3987 PropertyAttributes attributes) { |
4009 Handle<JSObject> object(lookup->holder()); | 3988 Handle<JSObject> object(lookup->holder()); |
4010 if (object->TooManyFastProperties()) { | 3989 if (object->TooManyFastProperties()) { |
4011 JSObject::NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0); | 3990 JSObject::NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0); |
4012 } | 3991 } |
4013 | 3992 |
4014 if (!object->HasFastProperties()) { | 3993 if (!object->HasFastProperties()) { |
4015 ReplaceSlowProperty(object, name, value, attributes); | 3994 ReplaceSlowProperty(object, name, value, attributes); |
4016 return; | 3995 return; |
4017 } | 3996 } |
4018 | 3997 |
4019 int descriptor_index = lookup->GetDescriptorIndex(); | 3998 int descriptor_index = lookup->GetDescriptorIndex(); |
4020 if (lookup->GetAttributes() == attributes) { | 3999 if (lookup->GetAttributes() == attributes) { |
4021 JSObject::GeneralizeFieldRepresentation( | 4000 JSObject::GeneralizeFieldRepresentation( |
4022 object, descriptor_index, Representation::Tagged(), | 4001 object, descriptor_index, Representation::Tagged(), |
4023 HeapType::Any(lookup->isolate()), FORCE_FIELD); | 4002 HeapType::Any(lookup->isolate()), FORCE_FIELD); |
4024 } else { | 4003 } else { |
4025 Handle<Map> old_map(object->map()); | 4004 Handle<Map> old_map(object->map()); |
4026 Handle<Map> new_map = Map::CopyGeneralizeAllRepresentations(old_map, | 4005 Handle<Map> new_map = Map::CopyGeneralizeAllRepresentations(old_map, |
4027 descriptor_index, FORCE_FIELD, attributes, "attributes mismatch"); | 4006 descriptor_index, FORCE_FIELD, attributes, "attributes mismatch"); |
4028 JSObject::MigrateToMap(object, new_map); | 4007 JSObject::MigrateToMap(object, new_map); |
4029 } | 4008 } |
4030 | 4009 |
4031 DescriptorArray* descriptors = object->map()->instance_descriptors(); | 4010 object->WriteToField(descriptor_index, *value); |
4032 int index = descriptors->GetDetails(descriptor_index).field_index(); | |
4033 object->FastPropertyAtPut(index, *value); | |
4034 } | 4011 } |
4035 | 4012 |
4036 | 4013 |
4037 static void SetPropertyToFieldWithAttributes(LookupResult* lookup, | 4014 static void SetPropertyToFieldWithAttributes(LookupResult* lookup, |
4038 Handle<Name> name, | 4015 Handle<Name> name, |
4039 Handle<Object> value, | 4016 Handle<Object> value, |
4040 PropertyAttributes attributes) { | 4017 PropertyAttributes attributes) { |
4041 if (lookup->GetAttributes() == attributes) { | 4018 if (lookup->GetAttributes() == attributes) { |
4042 if (value->IsUninitialized()) return; | 4019 if (value->IsUninitialized()) return; |
4043 SetPropertyToField(lookup, value); | 4020 SetPropertyToField(lookup, value); |
(...skipping 1174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5218 if (object->HasFastProperties()) { | 5195 if (object->HasFastProperties()) { |
5219 // If the object has fast properties, check whether the first slot | 5196 // If the object has fast properties, check whether the first slot |
5220 // in the descriptor array matches the hidden string. Since the | 5197 // in the descriptor array matches the hidden string. Since the |
5221 // hidden strings hash code is zero (and no other name has hash | 5198 // hidden strings hash code is zero (and no other name has hash |
5222 // code zero) it will always occupy the first entry if present. | 5199 // code zero) it will always occupy the first entry if present. |
5223 DescriptorArray* descriptors = object->map()->instance_descriptors(); | 5200 DescriptorArray* descriptors = object->map()->instance_descriptors(); |
5224 if (descriptors->number_of_descriptors() > 0) { | 5201 if (descriptors->number_of_descriptors() > 0) { |
5225 int sorted_index = descriptors->GetSortedKeyIndex(0); | 5202 int sorted_index = descriptors->GetSortedKeyIndex(0); |
5226 if (descriptors->GetKey(sorted_index) == isolate->heap()->hidden_string() | 5203 if (descriptors->GetKey(sorted_index) == isolate->heap()->hidden_string() |
5227 && sorted_index < object->map()->NumberOfOwnDescriptors()) { | 5204 && sorted_index < object->map()->NumberOfOwnDescriptors()) { |
5228 ASSERT(descriptors->GetType(sorted_index) == FIELD); | 5205 ASSERT(descriptors->GetType(sorted_index) == FIELD); |
Igor Sheludko
2014/04/16 09:50:03
Does it make sense to move this assert to WriteToF
| |
5229 object->FastPropertyAtPut(descriptors->GetFieldIndex(sorted_index), | 5206 object->WriteToField(sorted_index, *value); |
5230 *value); | |
5231 return object; | 5207 return object; |
5232 } | 5208 } |
5233 } | 5209 } |
5234 } | 5210 } |
5235 | 5211 |
5236 SetLocalPropertyIgnoreAttributes(object, | 5212 SetLocalPropertyIgnoreAttributes(object, |
5237 isolate->factory()->hidden_string(), | 5213 isolate->factory()->hidden_string(), |
5238 value, | 5214 value, |
5239 DONT_ENUM, | 5215 DONT_ENUM, |
5240 OPTIMAL_REPRESENTATION, | 5216 OPTIMAL_REPRESENTATION, |
(...skipping 11361 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
16602 #define ERROR_MESSAGES_TEXTS(C, T) T, | 16578 #define ERROR_MESSAGES_TEXTS(C, T) T, |
16603 static const char* error_messages_[] = { | 16579 static const char* error_messages_[] = { |
16604 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 16580 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
16605 }; | 16581 }; |
16606 #undef ERROR_MESSAGES_TEXTS | 16582 #undef ERROR_MESSAGES_TEXTS |
16607 return error_messages_[reason]; | 16583 return error_messages_[reason]; |
16608 } | 16584 } |
16609 | 16585 |
16610 | 16586 |
16611 } } // namespace v8::internal | 16587 } } // namespace v8::internal |
OLD | NEW |