| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #include "src/accessors.h" | 7 #include "src/accessors.h" |
| 8 #include "src/allocation-site-scopes.h" | 8 #include "src/allocation-site-scopes.h" |
| 9 #include "src/api.h" | 9 #include "src/api.h" |
| 10 #include "src/arguments.h" | 10 #include "src/arguments.h" |
| (...skipping 2105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2116 // For slow-to-fast migrations JSObject::TransformToFastProperties() | 2116 // For slow-to-fast migrations JSObject::TransformToFastProperties() |
| 2117 // must be used instead. | 2117 // must be used instead. |
| 2118 CHECK(new_map->is_dictionary_map()); | 2118 CHECK(new_map->is_dictionary_map()); |
| 2119 | 2119 |
| 2120 // Slow-to-slow migration is trivial. | 2120 // Slow-to-slow migration is trivial. |
| 2121 object->set_map(*new_map); | 2121 object->set_map(*new_map); |
| 2122 } | 2122 } |
| 2123 } | 2123 } |
| 2124 | 2124 |
| 2125 | 2125 |
| 2126 // To migrate an fast instance to a fast map: | 2126 // To migrate a fast instance to a fast map: |
| 2127 // - First check whether the instance needs to be rewritten. If not, simply | 2127 // - First check whether the instance needs to be rewritten. If not, simply |
| 2128 // change the map. | 2128 // change the map. |
| 2129 // - Otherwise, allocate a fixed array large enough to hold all fields, in | 2129 // - Otherwise, allocate a fixed array large enough to hold all fields, in |
| 2130 // addition to unused space. | 2130 // addition to unused space. |
| 2131 // - Copy all existing properties in, in the following order: backing store | 2131 // - Copy all existing properties in, in the following order: backing store |
| 2132 // properties, unused fields, inobject properties. | 2132 // properties, unused fields, inobject properties. |
| 2133 // - If all allocation succeeded, commit the state atomically: | 2133 // - If all allocation succeeded, commit the state atomically: |
| 2134 // * Copy inobject properties from the backing store back into the object. | 2134 // * Copy inobject properties from the backing store back into the object. |
| 2135 // * Trim the difference in instance size of the object. This also cleanly | 2135 // * Trim the difference in instance size of the object. This also cleanly |
| 2136 // frees inobject properties that moved to the backing store. | 2136 // frees inobject properties that moved to the backing store. |
| (...skipping 1835 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3972 // Nothing more to be done. | 3972 // Nothing more to be done. |
| 3973 if (value->IsUninitialized()) return; | 3973 if (value->IsUninitialized()) return; |
| 3974 HeapNumber* box = HeapNumber::cast(RawFastPropertyAt(index)); | 3974 HeapNumber* box = HeapNumber::cast(RawFastPropertyAt(index)); |
| 3975 box->set_value(value->Number()); | 3975 box->set_value(value->Number()); |
| 3976 } else { | 3976 } else { |
| 3977 FastPropertyAtPut(index, value); | 3977 FastPropertyAtPut(index, value); |
| 3978 } | 3978 } |
| 3979 } | 3979 } |
| 3980 | 3980 |
| 3981 | 3981 |
| 3982 static void SetPropertyToField(LookupResult* lookup, | 3982 void JSObject::SetPropertyToField(LookupResult* lookup, Handle<Object> value) { |
| 3983 Handle<Object> value) { | |
| 3984 if (lookup->type() == CONSTANT || !lookup->CanHoldValue(value)) { | 3983 if (lookup->type() == CONSTANT || !lookup->CanHoldValue(value)) { |
| 3985 Representation field_representation = value->OptimalRepresentation(); | 3984 Representation field_representation = value->OptimalRepresentation(); |
| 3986 Handle<HeapType> field_type = value->OptimalType( | 3985 Handle<HeapType> field_type = value->OptimalType( |
| 3987 lookup->isolate(), field_representation); | 3986 lookup->isolate(), field_representation); |
| 3988 JSObject::GeneralizeFieldRepresentation(handle(lookup->holder()), | 3987 JSObject::GeneralizeFieldRepresentation(handle(lookup->holder()), |
| 3989 lookup->GetDescriptorIndex(), | 3988 lookup->GetDescriptorIndex(), |
| 3990 field_representation, field_type, | 3989 field_representation, field_type, |
| 3991 FORCE_FIELD); | 3990 FORCE_FIELD); |
| 3992 } | 3991 } |
| 3993 lookup->holder()->WriteToField(lookup->GetDescriptorIndex(), *value); | 3992 lookup->holder()->WriteToField(lookup->GetDescriptorIndex(), *value); |
| 3994 } | 3993 } |
| 3995 | 3994 |
| 3996 | 3995 |
| 3997 static void ConvertAndSetOwnProperty(LookupResult* lookup, | 3996 void JSObject::ConvertAndSetOwnProperty(LookupResult* lookup, |
| 3998 Handle<Name> name, | 3997 Handle<Name> name, |
| 3999 Handle<Object> value, | 3998 Handle<Object> value, |
| 4000 PropertyAttributes attributes) { | 3999 PropertyAttributes attributes) { |
| 4001 Handle<JSObject> object(lookup->holder()); | 4000 Handle<JSObject> object(lookup->holder()); |
| 4002 if (object->TooManyFastProperties()) { | 4001 if (object->TooManyFastProperties()) { |
| 4003 JSObject::NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0); | 4002 JSObject::NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0); |
| 4004 } | 4003 } |
| 4005 | 4004 |
| 4006 if (!object->HasFastProperties()) { | 4005 if (!object->HasFastProperties()) { |
| 4007 ReplaceSlowProperty(object, name, value, attributes); | 4006 ReplaceSlowProperty(object, name, value, attributes); |
| 4008 return; | 4007 return; |
| 4009 } | 4008 } |
| 4010 | 4009 |
| 4011 int descriptor_index = lookup->GetDescriptorIndex(); | 4010 int descriptor_index = lookup->GetDescriptorIndex(); |
| 4012 if (lookup->GetAttributes() == attributes) { | 4011 if (lookup->GetAttributes() == attributes) { |
| 4013 JSObject::GeneralizeFieldRepresentation( | 4012 JSObject::GeneralizeFieldRepresentation( |
| 4014 object, descriptor_index, Representation::Tagged(), | 4013 object, descriptor_index, Representation::Tagged(), |
| 4015 HeapType::Any(lookup->isolate()), FORCE_FIELD); | 4014 HeapType::Any(lookup->isolate()), FORCE_FIELD); |
| 4016 } else { | 4015 } else { |
| 4017 Handle<Map> old_map(object->map()); | 4016 Handle<Map> old_map(object->map()); |
| 4018 Handle<Map> new_map = Map::CopyGeneralizeAllRepresentations(old_map, | 4017 Handle<Map> new_map = Map::CopyGeneralizeAllRepresentations(old_map, |
| 4019 descriptor_index, FORCE_FIELD, attributes, "attributes mismatch"); | 4018 descriptor_index, FORCE_FIELD, attributes, "attributes mismatch"); |
| 4020 JSObject::MigrateToMap(object, new_map); | 4019 JSObject::MigrateToMap(object, new_map); |
| 4021 } | 4020 } |
| 4022 | 4021 |
| 4023 object->WriteToField(descriptor_index, *value); | 4022 object->WriteToField(descriptor_index, *value); |
| 4024 } | 4023 } |
| 4025 | 4024 |
| 4026 | 4025 |
| 4027 static void SetPropertyToFieldWithAttributes(LookupResult* lookup, | 4026 void JSObject::SetPropertyToFieldWithAttributes(LookupResult* lookup, |
| 4028 Handle<Name> name, | 4027 Handle<Name> name, |
| 4029 Handle<Object> value, | 4028 Handle<Object> value, |
| 4030 PropertyAttributes attributes) { | 4029 PropertyAttributes attributes) { |
| 4031 if (lookup->GetAttributes() == attributes) { | 4030 if (lookup->GetAttributes() == attributes) { |
| 4032 if (value->IsUninitialized()) return; | 4031 if (value->IsUninitialized()) return; |
| 4033 SetPropertyToField(lookup, value); | 4032 SetPropertyToField(lookup, value); |
| 4034 } else { | 4033 } else { |
| 4035 ConvertAndSetOwnProperty(lookup, name, value, attributes); | 4034 ConvertAndSetOwnProperty(lookup, name, value, attributes); |
| 4036 } | 4035 } |
| 4037 } | 4036 } |
| 4038 | 4037 |
| 4039 | 4038 |
| 4040 MaybeHandle<Object> JSObject::SetPropertyForResult( | 4039 MaybeHandle<Object> JSObject::SetPropertyForResult( |
| (...skipping 629 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4670 | 4669 |
| 4671 #ifdef DEBUG | 4670 #ifdef DEBUG |
| 4672 if (FLAG_trace_normalization) { | 4671 if (FLAG_trace_normalization) { |
| 4673 PrintF("Object properties have been normalized:\n"); | 4672 PrintF("Object properties have been normalized:\n"); |
| 4674 object->Print(); | 4673 object->Print(); |
| 4675 } | 4674 } |
| 4676 #endif | 4675 #endif |
| 4677 } | 4676 } |
| 4678 | 4677 |
| 4679 | 4678 |
| 4680 void JSObject::TransformToFastProperties(Handle<JSObject> object, | 4679 void JSObject::MigrateSlowToFast(Handle<JSObject> object, |
| 4681 int unused_property_fields) { | 4680 int unused_property_fields) { |
| 4682 if (object->HasFastProperties()) return; | 4681 if (object->HasFastProperties()) return; |
| 4683 ASSERT(!object->IsGlobalObject()); | 4682 ASSERT(!object->IsGlobalObject()); |
| 4684 Isolate* isolate = object->GetIsolate(); | 4683 Isolate* isolate = object->GetIsolate(); |
| 4685 Factory* factory = isolate->factory(); | 4684 Factory* factory = isolate->factory(); |
| 4686 Handle<NameDictionary> dictionary(object->property_dictionary()); | 4685 Handle<NameDictionary> dictionary(object->property_dictionary()); |
| 4687 | 4686 |
| 4688 // Make sure we preserve dictionary representation if there are too many | 4687 // Make sure we preserve dictionary representation if there are too many |
| 4689 // descriptors. | 4688 // descriptors. |
| 4690 int number_of_elements = dictionary->NumberOfElements(); | 4689 int number_of_elements = dictionary->NumberOfElements(); |
| 4691 if (number_of_elements > kMaxNumberOfDescriptors) return; | 4690 if (number_of_elements > kMaxNumberOfDescriptors) return; |
| (...skipping 5214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9906 } | 9905 } |
| 9907 } | 9906 } |
| 9908 | 9907 |
| 9909 | 9908 |
| 9910 void JSObject::OptimizeAsPrototype(Handle<JSObject> object) { | 9909 void JSObject::OptimizeAsPrototype(Handle<JSObject> object) { |
| 9911 if (object->IsGlobalObject()) return; | 9910 if (object->IsGlobalObject()) return; |
| 9912 | 9911 |
| 9913 // Make sure prototypes are fast objects and their maps have the bit set | 9912 // Make sure prototypes are fast objects and their maps have the bit set |
| 9914 // so they remain fast. | 9913 // so they remain fast. |
| 9915 if (!object->HasFastProperties()) { | 9914 if (!object->HasFastProperties()) { |
| 9916 TransformToFastProperties(object, 0); | 9915 MigrateSlowToFast(object, 0); |
| 9917 } | 9916 } |
| 9918 } | 9917 } |
| 9919 | 9918 |
| 9920 | 9919 |
| 9921 Handle<Object> CacheInitialJSArrayMaps( | 9920 Handle<Object> CacheInitialJSArrayMaps( |
| 9922 Handle<Context> native_context, Handle<Map> initial_map) { | 9921 Handle<Context> native_context, Handle<Map> initial_map) { |
| 9923 // Replace all of the cached initial array maps in the native context with | 9922 // Replace all of the cached initial array maps in the native context with |
| 9924 // the appropriate transitioned elements kind maps. | 9923 // the appropriate transitioned elements kind maps. |
| 9925 Factory* factory = native_context->GetIsolate()->factory(); | 9924 Factory* factory = native_context->GetIsolate()->factory(); |
| 9926 Handle<FixedArray> maps = factory->NewFixedArrayWithHoles( | 9925 Handle<FixedArray> maps = factory->NewFixedArrayWithHoles( |
| (...skipping 7046 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 16973 #define ERROR_MESSAGES_TEXTS(C, T) T, | 16972 #define ERROR_MESSAGES_TEXTS(C, T) T, |
| 16974 static const char* error_messages_[] = { | 16973 static const char* error_messages_[] = { |
| 16975 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 16974 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
| 16976 }; | 16975 }; |
| 16977 #undef ERROR_MESSAGES_TEXTS | 16976 #undef ERROR_MESSAGES_TEXTS |
| 16978 return error_messages_[reason]; | 16977 return error_messages_[reason]; |
| 16979 } | 16978 } |
| 16980 | 16979 |
| 16981 | 16980 |
| 16982 } } // namespace v8::internal | 16981 } } // namespace v8::internal |
| OLD | NEW |