Chromium Code Reviews| 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/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 6813 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6824 DisallowHeapAllocation no_gc; | 6824 DisallowHeapAllocation no_gc; |
| 6825 WriteBarrierMode mode = new_keys->GetWriteBarrierMode(no_gc); | 6825 WriteBarrierMode mode = new_keys->GetWriteBarrierMode(no_gc); |
| 6826 for (int i = 0; i < buffer_length; i++) { | 6826 for (int i = 0; i < buffer_length; i++) { |
| 6827 new_keys->set(i, keys_->get(i), mode); | 6827 new_keys->set(i, keys_->get(i), mode); |
| 6828 } | 6828 } |
| 6829 } | 6829 } |
| 6830 keys_ = new_keys; | 6830 keys_ = new_keys; |
| 6831 } | 6831 } |
| 6832 | 6832 |
| 6833 | 6833 |
| 6834 MaybeHandle<FixedArray> JSReceiver::GetKeys(Handle<JSReceiver> object, | 6834 MaybeHandle<FixedArray> JSReceiver::GetKeys( |
| 6835 KeyCollectionType type) { | 6835 Handle<JSReceiver> object, KeyCollectionType type, |
| 6836 IncludeSymbolNamedProperties include_symbols) { | |
| 6836 USE(ContainsOnlyValidKeys); | 6837 USE(ContainsOnlyValidKeys); |
| 6837 Isolate* isolate = object->GetIsolate(); | 6838 Isolate* isolate = object->GetIsolate(); |
| 6838 KeyAccumulator accumulator(isolate); | 6839 KeyAccumulator accumulator(isolate); |
| 6839 Handle<JSFunction> arguments_function( | 6840 Handle<JSFunction> arguments_function( |
| 6840 JSFunction::cast(isolate->sloppy_arguments_map()->GetConstructor())); | 6841 JSFunction::cast(isolate->sloppy_arguments_map()->GetConstructor())); |
| 6841 | 6842 |
| 6842 PrototypeIterator::WhereToEnd end = type == OWN_ONLY | 6843 PrototypeIterator::WhereToEnd end = type == OWN_ONLY |
| 6843 ? PrototypeIterator::END_AT_NON_HIDDEN | 6844 ? PrototypeIterator::END_AT_NON_HIDDEN |
| 6844 : PrototypeIterator::END_AT_NULL; | 6845 : PrototypeIterator::END_AT_NULL; |
| 6845 // Only collect keys if access is permitted. | 6846 // Only collect keys if access is permitted. |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6883 // Add the element keys from the interceptor. | 6884 // Add the element keys from the interceptor. |
| 6884 if (current->HasIndexedInterceptor()) { | 6885 if (current->HasIndexedInterceptor()) { |
| 6885 Handle<JSObject> result; | 6886 Handle<JSObject> result; |
| 6886 if (JSObject::GetKeysForIndexedInterceptor( | 6887 if (JSObject::GetKeysForIndexedInterceptor( |
| 6887 current, object).ToHandle(&result)) { | 6888 current, object).ToHandle(&result)) { |
| 6888 accumulator.AddKeys(result, FixedArray::ALL_KEYS); | 6889 accumulator.AddKeys(result, FixedArray::ALL_KEYS); |
| 6889 } | 6890 } |
| 6890 DCHECK(ContainsOnlyValidKeys(accumulator.GetKeys())); | 6891 DCHECK(ContainsOnlyValidKeys(accumulator.GetKeys())); |
| 6891 } | 6892 } |
| 6892 | 6893 |
| 6893 // We can cache the computed property keys if access checks are | 6894 if (include_symbols == SKIP_SYMBOLS) { |
| 6894 // not needed and no interceptors are involved. | 6895 // We can cache the computed property keys if access checks are |
| 6895 // | 6896 // not needed and no interceptors are involved. |
| 6896 // We do not use the cache if the object has elements and | 6897 // |
| 6897 // therefore it does not make sense to cache the property names | 6898 // We do not use the cache if the object has elements and |
| 6898 // for arguments objects. Arguments objects will always have | 6899 // therefore it does not make sense to cache the property names |
| 6899 // elements. | 6900 // for arguments objects. Arguments objects will always have |
| 6900 // Wrapped strings have elements, but don't have an elements | 6901 // elements. |
| 6901 // array or dictionary. So the fast inline test for whether to | 6902 // Wrapped strings have elements, but don't have an elements |
| 6902 // use the cache says yes, so we should not create a cache. | 6903 // array or dictionary. So the fast inline test for whether to |
| 6903 bool cache_enum_keys = | 6904 // use the cache says yes, so we should not create a cache. |
| 6904 ((current->map()->GetConstructor() != *arguments_function) && | 6905 bool cache_enum_keys = |
| 6905 !current->IsJSValue() && !current->IsAccessCheckNeeded() && | 6906 ((current->map()->GetConstructor() != *arguments_function) && |
| 6906 !current->HasNamedInterceptor() && !current->HasIndexedInterceptor()); | 6907 !current->IsJSValue() && !current->IsAccessCheckNeeded() && |
| 6907 // Compute the property keys and cache them if possible. | 6908 !current->HasNamedInterceptor() && |
| 6908 | 6909 !current->HasIndexedInterceptor()); |
| 6909 Handle<FixedArray> enum_keys = | 6910 // Compute the property keys and cache them if possible. |
| 6910 JSObject::GetEnumPropertyKeys(current, cache_enum_keys); | 6911 Handle<FixedArray> enum_keys = |
| 6911 accumulator.AddKeys(enum_keys, FixedArray::ALL_KEYS); | 6912 JSObject::GetEnumPropertyKeys(current, cache_enum_keys); |
| 6913 accumulator.AddKeys(enum_keys, FixedArray::ALL_KEYS); | |
| 6914 } else { | |
| 6915 DCHECK(include_symbols == INCLUDE_SYMBOLS); | |
| 6916 PropertyAttributes filter = | |
| 6917 static_cast<PropertyAttributes>(DONT_ENUM | PRIVATE_SYMBOL); | |
| 6918 Handle<FixedArray> property_keys = isolate->factory()->NewFixedArray( | |
| 6919 current->NumberOfOwnProperties(filter)); | |
| 6920 current->GetOwnPropertyNames(*property_keys, 0, filter); | |
|
Camillo Bruni
2015/09/29 16:27:20
Not sure how much work this would be, but essentia
Jakob Kummerow
2015/09/30 13:59:30
I'm leaving that to you :-)
| |
| 6921 accumulator.AddKeys(property_keys, FixedArray::ALL_KEYS); | |
| 6922 } | |
| 6912 DCHECK(ContainsOnlyValidKeys(accumulator.GetKeys())); | 6923 DCHECK(ContainsOnlyValidKeys(accumulator.GetKeys())); |
| 6913 | 6924 |
| 6914 // Add the non-symbol property keys from the interceptor. | 6925 // Add the property keys from the interceptor. |
| 6915 if (current->HasNamedInterceptor()) { | 6926 if (current->HasNamedInterceptor()) { |
| 6916 Handle<JSObject> result; | 6927 Handle<JSObject> result; |
| 6917 if (JSObject::GetKeysForNamedInterceptor( | 6928 if (JSObject::GetKeysForNamedInterceptor( |
| 6918 current, object).ToHandle(&result)) { | 6929 current, object).ToHandle(&result)) { |
| 6919 accumulator.AddKeys(result, FixedArray::NON_SYMBOL_KEYS); | 6930 FixedArray::KeyFilter filter = include_symbols == SKIP_SYMBOLS |
| 6931 ? FixedArray::NON_SYMBOL_KEYS | |
| 6932 : FixedArray::ALL_KEYS; | |
| 6933 accumulator.AddKeys(result, filter); | |
| 6920 } | 6934 } |
| 6921 DCHECK(ContainsOnlyValidKeys(accumulator.GetKeys())); | 6935 DCHECK(ContainsOnlyValidKeys(accumulator.GetKeys())); |
| 6922 } | 6936 } |
| 6923 } | 6937 } |
| 6924 | 6938 |
| 6925 Handle<FixedArray> keys = accumulator.GetKeys(); | 6939 Handle<FixedArray> keys = accumulator.GetKeys(); |
| 6926 DCHECK(ContainsOnlyValidKeys(keys)); | 6940 DCHECK(ContainsOnlyValidKeys(keys)); |
| 6927 return keys; | 6941 return keys; |
| 6928 } | 6942 } |
| 6929 | 6943 |
| (...skipping 6895 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 13825 return global_dictionary()->CopyKeysTo(storage, index, filter, | 13839 return global_dictionary()->CopyKeysTo(storage, index, filter, |
| 13826 GlobalDictionary::UNSORTED); | 13840 GlobalDictionary::UNSORTED); |
| 13827 } else { | 13841 } else { |
| 13828 return property_dictionary()->CopyKeysTo(storage, index, filter, | 13842 return property_dictionary()->CopyKeysTo(storage, index, filter, |
| 13829 NameDictionary::UNSORTED); | 13843 NameDictionary::UNSORTED); |
| 13830 } | 13844 } |
| 13831 } | 13845 } |
| 13832 | 13846 |
| 13833 | 13847 |
| 13834 int JSObject::NumberOfOwnElements(PropertyAttributes filter) { | 13848 int JSObject::NumberOfOwnElements(PropertyAttributes filter) { |
| 13835 return GetOwnElementKeys(NULL, filter); | |
| 13836 } | |
| 13837 | |
| 13838 | |
| 13839 int JSObject::NumberOfEnumElements() { | |
| 13840 // Fast case for objects with no elements. | 13849 // Fast case for objects with no elements. |
| 13841 if (!IsJSValue() && HasFastObjectElements()) { | 13850 if (!IsJSValue() && HasFastElements()) { |
| 13842 uint32_t length = IsJSArray() ? | 13851 uint32_t length = IsJSArray() ? |
| 13843 static_cast<uint32_t>( | 13852 static_cast<uint32_t>( |
| 13844 Smi::cast(JSArray::cast(this)->length())->value()) : | 13853 Smi::cast(JSArray::cast(this)->length())->value()) : |
| 13845 static_cast<uint32_t>(FixedArray::cast(elements())->length()); | 13854 static_cast<uint32_t>(FixedArray::cast(elements())->length()); |
| 13846 if (length == 0) return 0; | 13855 if (length == 0) return 0; |
| 13847 } | 13856 } |
| 13848 // Compute the number of enumerable elements. | 13857 // Compute the number of enumerable elements. |
| 13858 return GetOwnElementKeys(NULL, filter); | |
| 13859 } | |
| 13860 | |
| 13861 | |
| 13862 int JSObject::NumberOfEnumElements() { | |
| 13849 return NumberOfOwnElements(static_cast<PropertyAttributes>(DONT_ENUM)); | 13863 return NumberOfOwnElements(static_cast<PropertyAttributes>(DONT_ENUM)); |
| 13850 } | 13864 } |
| 13851 | 13865 |
| 13852 | 13866 |
| 13853 int JSObject::GetOwnElementKeys(FixedArray* storage, | 13867 int JSObject::GetOwnElementKeys(FixedArray* storage, |
| 13854 PropertyAttributes filter) { | 13868 PropertyAttributes filter) { |
| 13855 int counter = 0; | 13869 int counter = 0; |
| 13856 | 13870 |
| 13857 // If this is a String wrapper, add the string indices first, | 13871 // If this is a String wrapper, add the string indices first, |
| 13858 // as they're guaranteed to preced the elements in numerical order | 13872 // as they're guaranteed to preced the elements in numerical order |
| (...skipping 2942 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 16801 if (cell->value() != *new_value) { | 16815 if (cell->value() != *new_value) { |
| 16802 cell->set_value(*new_value); | 16816 cell->set_value(*new_value); |
| 16803 Isolate* isolate = cell->GetIsolate(); | 16817 Isolate* isolate = cell->GetIsolate(); |
| 16804 cell->dependent_code()->DeoptimizeDependentCodeGroup( | 16818 cell->dependent_code()->DeoptimizeDependentCodeGroup( |
| 16805 isolate, DependentCode::kPropertyCellChangedGroup); | 16819 isolate, DependentCode::kPropertyCellChangedGroup); |
| 16806 } | 16820 } |
| 16807 } | 16821 } |
| 16808 | 16822 |
| 16809 } // namespace internal | 16823 } // namespace internal |
| 16810 } // namespace v8 | 16824 } // namespace v8 |
| OLD | NEW |