OLD | NEW |
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 8758 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8769 Isolate* isolate = object->GetIsolate(); | 8769 Isolate* isolate = object->GetIsolate(); |
8770 KeyAccumulator accumulator(isolate, type, filter); | 8770 KeyAccumulator accumulator(isolate, type, filter); |
8771 MAYBE_RETURN( | 8771 MAYBE_RETURN( |
8772 GetKeys_Internal(isolate, object, object, type, filter, &accumulator), | 8772 GetKeys_Internal(isolate, object, object, type, filter, &accumulator), |
8773 MaybeHandle<FixedArray>()); | 8773 MaybeHandle<FixedArray>()); |
8774 Handle<FixedArray> keys = accumulator.GetKeys(keys_conversion); | 8774 Handle<FixedArray> keys = accumulator.GetKeys(keys_conversion); |
8775 DCHECK(ContainsOnlyValidKeys(keys)); | 8775 DCHECK(ContainsOnlyValidKeys(keys)); |
8776 return keys; | 8776 return keys; |
8777 } | 8777 } |
8778 | 8778 |
| 8779 MUST_USE_RESULT Maybe<bool> FastGetOwnValuesOrEntries( |
| 8780 Isolate* isolate, Handle<JSReceiver> receiver, bool get_entries, |
| 8781 Handle<FixedArray>* result) { |
| 8782 Handle<Map> map(JSReceiver::cast(*receiver)->map(), isolate); |
| 8783 |
| 8784 if (!map->IsJSObjectMap()) return Just(false); |
| 8785 if (!map->OnlyHasSimpleProperties()) return Just(false); |
| 8786 |
| 8787 Handle<JSObject> object(JSObject::cast(*receiver)); |
| 8788 if (object->elements() != isolate->heap()->empty_fixed_array()) { |
| 8789 return Just(false); |
| 8790 } |
| 8791 |
| 8792 Handle<DescriptorArray> descriptors(map->instance_descriptors(), isolate); |
| 8793 int number_of_own_descriptors = map->NumberOfOwnDescriptors(); |
| 8794 Handle<FixedArray> values_or_entries = |
| 8795 isolate->factory()->NewFixedArray(number_of_own_descriptors); |
| 8796 int count = 0; |
| 8797 |
| 8798 bool stable = true; |
| 8799 |
| 8800 for (int index = 0; index < number_of_own_descriptors; index++) { |
| 8801 Handle<Name> next_key(descriptors->GetKey(index), isolate); |
| 8802 if (!next_key->IsString()) continue; |
| 8803 Handle<Object> prop_value; |
| 8804 |
| 8805 // Directly decode from the descriptor array if |from| did not change shape. |
| 8806 if (stable) { |
| 8807 PropertyDetails details = descriptors->GetDetails(index); |
| 8808 if (!details.IsEnumerable()) continue; |
| 8809 if (details.kind() == kData) { |
| 8810 if (details.location() == kDescriptor) { |
| 8811 prop_value = handle(descriptors->GetValue(index), isolate); |
| 8812 } else { |
| 8813 Representation representation = details.representation(); |
| 8814 FieldIndex field_index = FieldIndex::ForDescriptor(*map, index); |
| 8815 prop_value = |
| 8816 JSObject::FastPropertyAt(object, representation, field_index); |
| 8817 } |
| 8818 } else { |
| 8819 ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, prop_value, |
| 8820 Object::GetProperty(object, next_key), |
| 8821 Nothing<bool>()); |
| 8822 stable = object->map() == *map; |
| 8823 } |
| 8824 } else { |
| 8825 // If the map did change, do a slower lookup. We are still guaranteed that |
| 8826 // the object has a simple shape, and that the key is a name. |
| 8827 LookupIterator it(object, next_key, LookupIterator::OWN_SKIP_INTERCEPTOR); |
| 8828 if (!it.IsFound()) continue; |
| 8829 DCHECK(it.state() == LookupIterator::DATA || |
| 8830 it.state() == LookupIterator::ACCESSOR); |
| 8831 if (!it.IsEnumerable()) continue; |
| 8832 ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
| 8833 isolate, prop_value, Object::GetProperty(&it), Nothing<bool>()); |
| 8834 } |
| 8835 |
| 8836 if (get_entries) { |
| 8837 Handle<FixedArray> entry_storage = |
| 8838 isolate->factory()->NewUninitializedFixedArray(2); |
| 8839 entry_storage->set(0, *next_key); |
| 8840 entry_storage->set(1, *prop_value); |
| 8841 prop_value = isolate->factory()->NewJSArrayWithElements(entry_storage, |
| 8842 FAST_ELEMENTS, 2); |
| 8843 } |
| 8844 |
| 8845 values_or_entries->set(count, *prop_value); |
| 8846 count++; |
| 8847 } |
| 8848 |
| 8849 if (count < values_or_entries->length()) values_or_entries->Shrink(count); |
| 8850 *result = values_or_entries; |
| 8851 return Just(true); |
| 8852 } |
| 8853 |
8779 MaybeHandle<FixedArray> GetOwnValuesOrEntries(Isolate* isolate, | 8854 MaybeHandle<FixedArray> GetOwnValuesOrEntries(Isolate* isolate, |
8780 Handle<JSReceiver> object, | 8855 Handle<JSReceiver> object, |
8781 PropertyFilter filter, | 8856 PropertyFilter filter, |
8782 bool get_entries) { | 8857 bool get_entries) { |
| 8858 Handle<FixedArray> values_or_entries; |
| 8859 if (filter == ENUMERABLE_STRINGS) { |
| 8860 Maybe<bool> fast_values_or_entries = FastGetOwnValuesOrEntries( |
| 8861 isolate, object, get_entries, &values_or_entries); |
| 8862 if (fast_values_or_entries.IsNothing()) return MaybeHandle<FixedArray>(); |
| 8863 if (fast_values_or_entries.FromJust()) return values_or_entries; |
| 8864 } |
| 8865 |
8783 PropertyFilter key_filter = | 8866 PropertyFilter key_filter = |
8784 static_cast<PropertyFilter>(filter & ~ONLY_ENUMERABLE); | 8867 static_cast<PropertyFilter>(filter & ~ONLY_ENUMERABLE); |
8785 KeyAccumulator accumulator(isolate, OWN_ONLY, key_filter); | 8868 KeyAccumulator accumulator(isolate, OWN_ONLY, key_filter); |
8786 MAYBE_RETURN(GetKeys_Internal(isolate, object, object, OWN_ONLY, key_filter, | 8869 MAYBE_RETURN(GetKeys_Internal(isolate, object, object, OWN_ONLY, key_filter, |
8787 &accumulator), | 8870 &accumulator), |
8788 MaybeHandle<FixedArray>()); | 8871 MaybeHandle<FixedArray>()); |
8789 Handle<FixedArray> keys = accumulator.GetKeys(CONVERT_TO_STRING); | 8872 Handle<FixedArray> keys = accumulator.GetKeys(CONVERT_TO_STRING); |
8790 DCHECK(ContainsOnlyValidKeys(keys)); | 8873 DCHECK(ContainsOnlyValidKeys(keys)); |
8791 | 8874 |
8792 Handle<FixedArray> values_or_entries = | 8875 values_or_entries = isolate->factory()->NewFixedArray(keys->length()); |
8793 isolate->factory()->NewFixedArray(keys->length()); | |
8794 int length = 0; | 8876 int length = 0; |
8795 | 8877 |
8796 for (int i = 0; i < keys->length(); ++i) { | 8878 for (int i = 0; i < keys->length(); ++i) { |
8797 Handle<Name> key = Handle<Name>::cast(handle(keys->get(i), isolate)); | 8879 Handle<Name> key = Handle<Name>::cast(handle(keys->get(i), isolate)); |
8798 | 8880 |
8799 if (filter & ONLY_ENUMERABLE) { | 8881 if (filter & ONLY_ENUMERABLE) { |
8800 PropertyDescriptor descriptor; | 8882 PropertyDescriptor descriptor; |
8801 Maybe<bool> did_get_descriptor = JSReceiver::GetOwnPropertyDescriptor( | 8883 Maybe<bool> did_get_descriptor = JSReceiver::GetOwnPropertyDescriptor( |
8802 isolate, object, key, &descriptor); | 8884 isolate, object, key, &descriptor); |
8803 MAYBE_RETURN(did_get_descriptor, MaybeHandle<FixedArray>()); | 8885 MAYBE_RETURN(did_get_descriptor, MaybeHandle<FixedArray>()); |
(...skipping 10952 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
19756 if (cell->value() != *new_value) { | 19838 if (cell->value() != *new_value) { |
19757 cell->set_value(*new_value); | 19839 cell->set_value(*new_value); |
19758 Isolate* isolate = cell->GetIsolate(); | 19840 Isolate* isolate = cell->GetIsolate(); |
19759 cell->dependent_code()->DeoptimizeDependentCodeGroup( | 19841 cell->dependent_code()->DeoptimizeDependentCodeGroup( |
19760 isolate, DependentCode::kPropertyCellChangedGroup); | 19842 isolate, DependentCode::kPropertyCellChangedGroup); |
19761 } | 19843 } |
19762 } | 19844 } |
19763 | 19845 |
19764 } // namespace internal | 19846 } // namespace internal |
19765 } // namespace v8 | 19847 } // namespace v8 |
OLD | NEW |