Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(373)

Side by Side Diff: src/objects.cc

Issue 1425403002: [runtime] Support Symbols in KeyAccumulator (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: fixing raw pointer issue Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« src/objects.h ('K') | « src/objects.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 7544 matching lines...) Expand 10 before | Expand all | Expand 10 after
7555 7555
7556 Handle<FixedArray> KeyAccumulator::GetKeys(GetKeysConversion convert) { 7556 Handle<FixedArray> KeyAccumulator::GetKeys(GetKeysConversion convert) {
7557 if (length_ == 0) { 7557 if (length_ == 0) {
7558 return isolate_->factory()->empty_fixed_array(); 7558 return isolate_->factory()->empty_fixed_array();
7559 } 7559 }
7560 // Make sure we have all the lengths collected. 7560 // Make sure we have all the lengths collected.
7561 NextPrototype(); 7561 NextPrototype();
7562 7562
7563 // Assemble the result array by first adding the element keys and then 7563 // Assemble the result array by first adding the element keys and then
7564 // the property keys. We use the total number of keys per level in 7564 // the property keys. We use the total number of keys per level in
7565 // |protoLengths_| and the available element keys in the corresponding bucket 7565 // |protoLengths_| and the available element keys in the corresponding bucket
Jakob Kummerow 2015/11/03 15:33:37 nit: outdated comment
7566 // in |elements_| to deduce the number of keys to take from the |properties_| 7566 // in |elements_| to deduce the number of keys to take from the |properties_|
7567 // set. 7567 // set.
7568 Handle<FixedArray> result = isolate_->factory()->NewFixedArray(length_); 7568 Handle<FixedArray> result = isolate_->factory()->NewFixedArray(length_);
7569 int index = 0; 7569 int insertion_index = 0;
7570 int properties_index = 0; 7570 int string_properties_index = 0;
7571 for (size_t level = 0; level < levelLengths_.size(); level++) { 7571 int symbol_properties_index = 0;
7572 int num_total = levelLengths_[level]; 7572 // String and Symbol lengths always come in pairs:
7573 int num_elements = 0; 7573 size_t max_level = level_lengths_.size() / 2;
7574 if (num_total < 0) { 7574 for (size_t level = 0; level < max_level; level++) {
7575 // If the total is negative, the current level contains properties from a 7575 int num_string_properties = level_lengths_[level * 2];
7576 // proxy, hence we skip the integer keys in |elements_| since proxies 7576 int num_symbol_properties = level_lengths_[level * 2 + 1];
7577 // define the complete ordering. 7577 if (num_string_properties < 0) {
7578 num_total = -num_total; 7578 // If the num_string_properties is negative, the current level contains
7579 // properties from a proxy, hence we skip the integer keys in |elements_|
7580 // since proxies define the complete ordering.
7581 num_string_properties = -num_string_properties;
7579 } else if (level < elements_.size()) { 7582 } else if (level < elements_.size()) {
7583 // Add the element indices for this prototype level.
7580 std::vector<uint32_t>* elements = elements_[level]; 7584 std::vector<uint32_t>* elements = elements_[level];
7581 num_elements = static_cast<int>(elements->size()); 7585 int num_elements = static_cast<int>(elements->size());
7582 for (int i = 0; i < num_elements; i++) { 7586 for (int i = 0; i < num_elements; i++) {
7583 Handle<Object> key; 7587 Handle<Object> key;
7584 if (convert == KEEP_NUMBERS) { 7588 if (convert == KEEP_NUMBERS) {
7585 key = isolate_->factory()->NewNumberFromUint(elements->at(i)); 7589 key = isolate_->factory()->NewNumberFromUint(elements->at(i));
7586 } else { 7590 } else {
7587 key = isolate_->factory()->Uint32ToString(elements->at(i)); 7591 key = isolate_->factory()->Uint32ToString(elements->at(i));
7588 } 7592 }
7589 result->set(index, *key); 7593 result->set(insertion_index, *key);
7590 index++; 7594 insertion_index++;
7591 } 7595 }
7592 } 7596 }
7593 // Add the property keys for this prototype level. 7597 // Add the string property keys for this prototype level.
7594 int num_properties = num_total - num_elements; 7598 for (int i = 0; i < num_string_properties; i++) {
7595 for (int i = 0; i < num_properties; i++) { 7599 Object* key = string_properties_->KeyAt(string_properties_index);
7596 Object* key = properties_->KeyAt(properties_index); 7600 result->set(insertion_index, key);
7597 result->set(index, key); 7601 insertion_index++;
7598 index++; 7602 string_properties_index++;
7599 properties_index++; 7603 }
7604 // Add the symbol property keys for this prototype level.
7605 for (int i = 0; i < num_symbol_properties; i++) {
7606 Object* key = symbol_properties_->KeyAt(symbol_properties_index);
7607 result->set(insertion_index, key);
7608 insertion_index++;
7609 symbol_properties_index++;
7600 } 7610 }
7601 } 7611 }
7602 7612
7603 DCHECK_EQ(index, length_); 7613 DCHECK_EQ(insertion_index, length_);
7604 return result; 7614 return result;
7605 } 7615 }
7606 7616
7607 7617
7618 int KeyAccumulator::GetLength() { return length_; }
Jakob Kummerow 2015/11/03 15:33:37 nit: a simple getter like this should be called ju
7619
7620
7608 namespace { 7621 namespace {
7609 7622
7610 bool AccumulatorHasKey(std::vector<uint32_t>* sub_elements, uint32_t key) { 7623 bool AccumulatorHasKey(std::vector<uint32_t>* sub_elements, uint32_t key) {
7611 return std::binary_search(sub_elements->begin(), sub_elements->end(), key); 7624 return std::binary_search(sub_elements->begin(), sub_elements->end(), key);
7612 } 7625 }
7613 7626
7614 } // namespace 7627 } // namespace
7615 7628
7616 7629
7617 bool KeyAccumulator::AddKey(uint32_t key) { 7630 bool KeyAccumulator::AddKey(uint32_t key) {
7618 // Make sure we do not add keys to a proxy-level (see AddKeysFromProxy). 7631 // Make sure we do not add keys to a proxy-level (see AddKeysFromProxy).
7619 // We mark proxy-levels with a negative length 7632 // We mark proxy-levels with a negative length
7620 DCHECK_LE(0, levelLength_); 7633 DCHECK_LE(0, level_string_length_);
7621 // Binary search over all but the last level. The last one might not be 7634 // Binary search over all but the last level. The last one might not be
7622 // sorted yet. 7635 // sorted yet.
7623 for (size_t i = 1; i < elements_.size(); i++) { 7636 for (size_t i = 1; i < elements_.size(); i++) {
7624 if (AccumulatorHasKey(elements_[i - 1], key)) return false; 7637 if (AccumulatorHasKey(elements_[i - 1], key)) return false;
7625 } 7638 }
7626 elements_.back()->push_back(key); 7639 elements_.back()->push_back(key);
7627 length_++; 7640 length_++;
7628 levelLength_++;
7629 return true; 7641 return true;
7630 } 7642 }
7631 7643
7632 7644
7633 bool KeyAccumulator::AddKey(Object* key, AddKeyConversion convert) { 7645 bool KeyAccumulator::AddKey(Object* key, AddKeyConversion convert) {
7634 return AddKey(handle(key, isolate_), convert); 7646 return AddKey(handle(key, isolate_), convert);
7635 } 7647 }
7636 7648
7637 7649
7638 bool KeyAccumulator::AddKey(Handle<Object> key, AddKeyConversion convert) { 7650 bool KeyAccumulator::AddKey(Handle<Object> key, AddKeyConversion convert) {
7639 if (filter_ == SKIP_SYMBOLS && key->IsSymbol()) { 7651 if (key->IsSymbol()) {
7640 return false; 7652 if (filter_ == SKIP_SYMBOLS) return false;
7653 return AddSymbolKey(key);
7641 } 7654 }
7642 // Make sure we do not add keys to a proxy-level (see AddKeysFromProxy). 7655 // Make sure we do not add keys to a proxy-level (see AddKeysFromProxy).
7643 DCHECK_LE(0, levelLength_); 7656 DCHECK_LE(0, level_string_length_);
7644 // In some cases (e.g. proxies) we might get in String-converted ints which 7657 // In some cases (e.g. proxies) we might get in String-converted ints which
7645 // should be added to the elements list instead of the properties. For 7658 // should be added to the elements list instead of the properties. For
7646 // proxies we have to convert as well but also respect the original order. 7659 // proxies we have to convert as well but also respect the original order.
7647 // Therefore we add a converted key to both sides 7660 // Therefore we add a converted key to both sides
7648 if (convert == CONVERT_TO_ARRAY_INDEX || convert == PROXY_MAGIC) { 7661 if (convert == CONVERT_TO_ARRAY_INDEX || convert == PROXY_MAGIC) {
7649 uint32_t index = 0; 7662 uint32_t index = 0;
7650 int prev_length = length_; 7663 int prev_length = length_;
7651 int prev_proto = levelLength_; 7664 int prev_proto = level_string_length_;
7652 bool was_array_index = false; 7665 bool was_array_index = false;
7653 bool key_was_added = false; 7666 bool key_was_added = false;
7654 if ((key->IsString() && Handle<String>::cast(key)->AsArrayIndex(&index)) || 7667 if ((key->IsString() && Handle<String>::cast(key)->AsArrayIndex(&index)) ||
7655 key->ToArrayIndex(&index)) { 7668 key->ToArrayIndex(&index)) {
7656 key_was_added = AddKey(index); 7669 key_was_added = AddKey(index);
7657 was_array_index = true; 7670 was_array_index = true;
7658 if (convert == CONVERT_TO_ARRAY_INDEX) return key_was_added; 7671 if (convert == CONVERT_TO_ARRAY_INDEX) return key_was_added;
7659 } 7672 }
7660 if (was_array_index && convert == PROXY_MAGIC) { 7673 if (was_array_index && convert == PROXY_MAGIC) {
7661 // If we had an array index (number) and it wasn't added, the key 7674 // If we had an array index (number) and it wasn't added, the key
7662 // already existed before, hence we cannot add it to the properties 7675 // already existed before, hence we cannot add it to the properties
7663 // keys as it would lead to duplicate entries. 7676 // keys as it would lead to duplicate entries.
7664 if (!key_was_added) { 7677 if (!key_was_added) {
7665 return false; 7678 return false;
7666 } 7679 }
7667 length_ = prev_length; 7680 length_ = prev_length;
7668 levelLength_ = prev_proto; 7681 level_string_length_ = prev_proto;
7669 } 7682 }
7670 } 7683 }
7671 if (properties_.is_null()) { 7684 return AddStringKey(key, convert);
7672 properties_ = OrderedHashSet::Allocate(isolate_, 16); 7685 }
7686
7687
7688 bool KeyAccumulator::AddStringKey(Handle<Object> key,
7689 AddKeyConversion convert) {
7690 if (string_properties_.is_null()) {
7691 string_properties_ = OrderedHashSet::Allocate(isolate_, 16);
7673 } 7692 }
7674 // TODO(cbruni): remove this conversion once we throw the correct TypeError 7693 // TODO(cbruni): remove this conversion once we throw the correct TypeError
7675 // for non-string/symbol elements returned by proxies 7694 // for non-string/symbol elements returned by proxies
7676 if (convert == PROXY_MAGIC && key->IsNumber()) { 7695 if (convert == PROXY_MAGIC && key->IsNumber()) {
7677 key = isolate_->factory()->NumberToString(key); 7696 key = isolate_->factory()->NumberToString(key);
7678 } 7697 }
7679 int prev_size = properties_->NumberOfElements(); 7698 int prev_size = string_properties_->NumberOfElements();
7680 properties_ = OrderedHashSet::Add(properties_, key); 7699 string_properties_ = OrderedHashSet::Add(string_properties_, key);
7681 if (prev_size < properties_->NumberOfElements()) { 7700 if (prev_size < string_properties_->NumberOfElements()) {
7682 length_++; 7701 length_++;
7683 levelLength_++; 7702 level_string_length_++;
7703 return true;
7704 } else {
7705 return false;
7684 } 7706 }
7685 return true;
7686 } 7707 }
7687 7708
7688 7709
7710 bool KeyAccumulator::AddSymbolKey(Handle<Object> key) {
7711 if (symbol_properties_.is_null()) {
7712 symbol_properties_ = OrderedHashSet::Allocate(isolate_, 16);
7713 }
7714 int prev_size = symbol_properties_->NumberOfElements();
7715 symbol_properties_ = OrderedHashSet::Add(symbol_properties_, key);
7716 if (prev_size < symbol_properties_->NumberOfElements()) {
7717 length_++;
7718 level_symbol_length_++;
7719 return true;
7720 } else {
7721 return false;
7722 }
7723 }
7724
7725
7689 void KeyAccumulator::AddKeys(Handle<FixedArray> array, 7726 void KeyAccumulator::AddKeys(Handle<FixedArray> array,
7690 AddKeyConversion convert) { 7727 AddKeyConversion convert) {
7691 int add_length = array->length(); 7728 int add_length = array->length();
7692 if (add_length == 0) return; 7729 if (add_length == 0) return;
7693 for (int i = 0; i < add_length; i++) { 7730 for (int i = 0; i < add_length; i++) {
7694 Handle<Object> current(array->get(i), isolate_); 7731 Handle<Object> current(array->get(i), isolate_);
7695 AddKey(current); 7732 AddKey(current, convert);
7696 } 7733 }
7697 } 7734 }
7698 7735
7699 7736
7700 void KeyAccumulator::AddKeys(Handle<JSObject> array_like, 7737 void KeyAccumulator::AddKeys(Handle<JSObject> array_like,
7701 AddKeyConversion convert) { 7738 AddKeyConversion convert) {
7702 DCHECK(array_like->IsJSArray() || array_like->HasSloppyArgumentsElements()); 7739 DCHECK(array_like->IsJSArray() || array_like->HasSloppyArgumentsElements());
7703 ElementsAccessor* accessor = array_like->GetElementsAccessor(); 7740 ElementsAccessor* accessor = array_like->GetElementsAccessor();
7704 accessor->AddElementsToKeyAccumulator(array_like, this, convert); 7741 accessor->AddElementsToKeyAccumulator(array_like, this, convert);
7705 } 7742 }
7706 7743
7707 7744
7708 void KeyAccumulator::AddKeysFromProxy(Handle<JSObject> array_like) { 7745 void KeyAccumulator::AddKeysFromProxy(Handle<JSObject> array_like) {
7709 // Proxies define a complete list of keys with no distinction of 7746 // Proxies define a complete list of keys with no distinction of
7710 // elements and properties, which breaks the normal assumption for the 7747 // elements and properties, which breaks the normal assumption for the
7711 // KeyAccumulator. 7748 // KeyAccumulator.
7712 AddKeys(array_like, PROXY_MAGIC); 7749 AddKeys(array_like, PROXY_MAGIC);
7713 // Invert the current length to indicate a present proxy, so we can ignore 7750 // Invert the current length to indicate a present proxy, so we can ignore
7714 // element keys for this level. Otherwise we would not fully respect the order 7751 // element keys for this level. Otherwise we would not fully respect the order
7715 // given by the proxy. 7752 // given by the proxy.
7716 levelLength_ = -levelLength_; 7753 level_string_length_ = -level_string_length_;
7717 } 7754 }
7718 7755
7719 7756
7720 void KeyAccumulator::AddElementKeysFromInterceptor( 7757 void KeyAccumulator::AddElementKeysFromInterceptor(
7721 Handle<JSObject> array_like) { 7758 Handle<JSObject> array_like) {
7722 AddKeys(array_like, CONVERT_TO_ARRAY_INDEX); 7759 AddKeys(array_like, CONVERT_TO_ARRAY_INDEX);
7723 // The interceptor might introduce duplicates for the current level, since 7760 // The interceptor might introduce duplicates for the current level, since
7724 // these keys get added after the objects's normal element keys. 7761 // these keys get added after the objects's normal element keys.
7725 SortCurrentElementsListRemoveDuplicates(); 7762 SortCurrentElementsListRemoveDuplicates();
7726 } 7763 }
7727 7764
7728 7765
7729 void KeyAccumulator::SortCurrentElementsListRemoveDuplicates() { 7766 void KeyAccumulator::SortCurrentElementsListRemoveDuplicates() {
7730 // Sort and remove duplciated from the current elements level and adjust 7767 // Sort and remove duplicated from the current elements level and adjust.
Jakob Kummerow 2015/11/03 15:33:37 nit: s/.//, also s/duplicated/duplicate entries/?
7731 // the lengths accordingly. 7768 // the lengths accordingly.
7732 auto last_level = elements_.back(); 7769 auto last_level = elements_.back();
7733 size_t nof_removed_keys = last_level->size(); 7770 size_t nof_removed_keys = last_level->size();
7734 std::sort(last_level->begin(), last_level->end()); 7771 std::sort(last_level->begin(), last_level->end());
7735 last_level->erase(std::unique(last_level->begin(), last_level->end()), 7772 last_level->erase(std::unique(last_level->begin(), last_level->end()),
7736 last_level->end()); 7773 last_level->end());
7737 // Adjust total length / level length by the number of removed duplicates 7774 // Adjust total length by the number of removed duplicates.
7738 nof_removed_keys -= last_level->size(); 7775 nof_removed_keys -= last_level->size();
7739 levelLength_ -= static_cast<int>(nof_removed_keys);
7740 length_ -= static_cast<int>(nof_removed_keys); 7776 length_ -= static_cast<int>(nof_removed_keys);
7741 } 7777 }
7742 7778
7743 7779
7744 void KeyAccumulator::SortCurrentElementsList() { 7780 void KeyAccumulator::SortCurrentElementsList() {
7745 if (elements_.empty()) return; 7781 if (elements_.empty()) return;
7746 auto element_keys = elements_.back(); 7782 auto element_keys = elements_.back();
7747 std::sort(element_keys->begin(), element_keys->end()); 7783 std::sort(element_keys->begin(), element_keys->end());
7748 } 7784 }
7749 7785
7750 7786
7751 void KeyAccumulator::NextPrototype() { 7787 void KeyAccumulator::NextPrototype() {
7752 // Store the protoLength on the first call of this method. 7788 // Store the protoLength on the first call of this method.
7753 if (!elements_.empty()) { 7789 if (!elements_.empty()) {
7754 levelLengths_.push_back(levelLength_); 7790 level_lengths_.push_back(level_string_length_);
7791 level_lengths_.push_back(level_symbol_length_);
7755 } 7792 }
7756 elements_.push_back(new std::vector<uint32_t>()); 7793 elements_.push_back(new std::vector<uint32_t>());
7757 levelLength_ = 0; 7794 level_string_length_ = 0;
7795 level_symbol_length_ = 0;
7758 } 7796 }
7759 7797
7760 7798
7761 MaybeHandle<FixedArray> JSReceiver::GetKeys(Handle<JSReceiver> object, 7799 MaybeHandle<FixedArray> JSReceiver::GetKeys(Handle<JSReceiver> object,
7762 KeyCollectionType type, 7800 KeyCollectionType type,
7763 KeyFilter filter, 7801 KeyFilter filter,
7764 GetKeysConversion getConversion) { 7802 GetKeysConversion getConversion) {
7765 USE(ContainsOnlyValidKeys); 7803 USE(ContainsOnlyValidKeys);
7766 Isolate* isolate = object->GetIsolate(); 7804 Isolate* isolate = object->GetIsolate();
7767 KeyAccumulator accumulator(isolate, filter); 7805 KeyAccumulator accumulator(isolate, filter);
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
7833 !current->HasNamedInterceptor() && 7871 !current->HasNamedInterceptor() &&
7834 !current->HasIndexedInterceptor()); 7872 !current->HasIndexedInterceptor());
7835 // Compute the property keys and cache them if possible. 7873 // Compute the property keys and cache them if possible.
7836 Handle<FixedArray> enum_keys = 7874 Handle<FixedArray> enum_keys =
7837 JSObject::GetEnumPropertyKeys(current, cache_enum_length); 7875 JSObject::GetEnumPropertyKeys(current, cache_enum_length);
7838 accumulator.AddKeys(enum_keys); 7876 accumulator.AddKeys(enum_keys);
7839 } else { 7877 } else {
7840 DCHECK(filter == INCLUDE_SYMBOLS); 7878 DCHECK(filter == INCLUDE_SYMBOLS);
7841 PropertyAttributes attr_filter = 7879 PropertyAttributes attr_filter =
7842 static_cast<PropertyAttributes>(DONT_ENUM | PRIVATE_SYMBOL); 7880 static_cast<PropertyAttributes>(DONT_ENUM | PRIVATE_SYMBOL);
7843 Handle<FixedArray> property_keys = isolate->factory()->NewFixedArray( 7881 current->CollectOwnPropertyNames(&accumulator, attr_filter);
7844 current->NumberOfOwnProperties(attr_filter));
7845 current->GetOwnPropertyNames(*property_keys, 0, attr_filter);
7846 accumulator.AddKeys(property_keys);
7847 } 7882 }
7848 7883
7849 // Add the property keys from the interceptor. 7884 // Add the property keys from the interceptor.
7850 if (current->HasNamedInterceptor()) { 7885 if (current->HasNamedInterceptor()) {
7851 Handle<JSObject> result; 7886 Handle<JSObject> result;
7852 if (JSObject::GetKeysForNamedInterceptor(current, object) 7887 if (JSObject::GetKeysForNamedInterceptor(current, object)
7853 .ToHandle(&result)) { 7888 .ToHandle(&result)) {
7854 accumulator.AddKeys(result); 7889 accumulator.AddKeys(result);
7855 } 7890 }
7856 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, FixedArray); 7891 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, FixedArray);
(...skipping 7156 matching lines...) Expand 10 before | Expand all | Expand 10 after
15013 } else if (IsJSGlobalObject()) { 15048 } else if (IsJSGlobalObject()) {
15014 return global_dictionary()->CopyKeysTo(storage, index, filter, 15049 return global_dictionary()->CopyKeysTo(storage, index, filter,
15015 GlobalDictionary::UNSORTED); 15050 GlobalDictionary::UNSORTED);
15016 } else { 15051 } else {
15017 return property_dictionary()->CopyKeysTo(storage, index, filter, 15052 return property_dictionary()->CopyKeysTo(storage, index, filter,
15018 NameDictionary::UNSORTED); 15053 NameDictionary::UNSORTED);
15019 } 15054 }
15020 } 15055 }
15021 15056
15022 15057
15058 int JSObject::CollectOwnPropertyNames(KeyAccumulator* keys,
15059 PropertyAttributes filter) {
15060 if (HasFastProperties()) {
15061 int nof_keys = keys->GetLength();
15062 int real_size = map()->NumberOfOwnDescriptors();
15063 Handle<DescriptorArray> descs(map()->instance_descriptors());
15064 for (int i = 0; i < real_size; i++) {
15065 if ((descs->GetDetails(i).attributes() & filter) != 0) continue;
15066 Name* key = descs->GetKey(i);
15067 if (key->FilterKey(filter)) continue;
15068 keys->AddKey(key);
15069 }
15070 return nof_keys - keys->GetLength();
15071 } else if (IsJSGlobalObject()) {
15072 return global_dictionary()->CollectKeysTo(keys, filter);
15073 } else {
15074 return property_dictionary()->CollectKeysTo(keys, filter);
15075 }
15076 }
15077
15078
15023 int JSObject::NumberOfOwnElements(PropertyAttributes filter) { 15079 int JSObject::NumberOfOwnElements(PropertyAttributes filter) {
15024 // Fast case for objects with no elements. 15080 // Fast case for objects with no elements.
15025 if (!IsJSValue() && HasFastElements()) { 15081 if (!IsJSValue() && HasFastElements()) {
15026 uint32_t length = 15082 uint32_t length =
15027 IsJSArray() 15083 IsJSArray()
15028 ? static_cast<uint32_t>( 15084 ? static_cast<uint32_t>(
15029 Smi::cast(JSArray::cast(this)->length())->value()) 15085 Smi::cast(JSArray::cast(this)->length())->value())
15030 : static_cast<uint32_t>(FixedArrayBase::cast(elements())->length()); 15086 : static_cast<uint32_t>(FixedArrayBase::cast(elements())->length());
15031 if (length == 0) return 0; 15087 if (length == 0) return 0;
15032 } 15088 }
(...skipping 1751 matching lines...) Expand 10 before | Expand all | Expand 10 after
16784 16840
16785 template <typename Derived, typename Shape, typename Key> 16841 template <typename Derived, typename Shape, typename Key>
16786 int Dictionary<Derived, Shape, Key>::CopyKeysTo( 16842 int Dictionary<Derived, Shape, Key>::CopyKeysTo(
16787 FixedArray* storage, int index, PropertyAttributes filter, 16843 FixedArray* storage, int index, PropertyAttributes filter,
16788 typename Dictionary<Derived, Shape, Key>::SortMode sort_mode) { 16844 typename Dictionary<Derived, Shape, Key>::SortMode sort_mode) {
16789 DCHECK(storage->length() >= NumberOfElementsFilterAttributes(filter)); 16845 DCHECK(storage->length() >= NumberOfElementsFilterAttributes(filter));
16790 int start_index = index; 16846 int start_index = index;
16791 int capacity = this->Capacity(); 16847 int capacity = this->Capacity();
16792 for (int i = 0; i < capacity; i++) { 16848 for (int i = 0; i < capacity; i++) {
16793 Object* k = this->KeyAt(i); 16849 Object* k = this->KeyAt(i);
16794 if (this->IsKey(k) && !k->FilterKey(filter)) { 16850 if (!this->IsKey(k) || k->FilterKey(filter)) continue;
16795 if (this->IsDeleted(i)) continue; 16851 if (this->IsDeleted(i)) continue;
16796 PropertyDetails details = this->DetailsAt(i); 16852 PropertyDetails details = this->DetailsAt(i);
16797 PropertyAttributes attr = details.attributes(); 16853 PropertyAttributes attr = details.attributes();
16798 if ((attr & filter) == 0) storage->set(index++, k); 16854 if ((attr & filter) != 0) continue;
16799 } 16855 storage->set(index++, k);
16800 } 16856 }
16801 if (sort_mode == Dictionary::SORTED) { 16857 if (sort_mode == Dictionary::SORTED) {
16802 storage->SortPairs(storage, index); 16858 storage->SortPairs(storage, index);
16803 } 16859 }
16804 DCHECK(storage->length() >= index); 16860 DCHECK(storage->length() >= index);
16805 return index - start_index; 16861 return index - start_index;
16806 } 16862 }
16807 16863
16808 16864
16865 template <typename Derived, typename Shape, typename Key>
16866 int Dictionary<Derived, Shape, Key>::CollectKeysTo(KeyAccumulator* keys,
16867 PropertyAttributes filter) {
16868 int capacity = this->Capacity();
16869 int keyLength = keys->GetLength();
16870 for (int i = 0; i < capacity; i++) {
16871 Object* k = this->KeyAt(i);
16872 if (!this->IsKey(k) || k->FilterKey(filter)) continue;
16873 if (this->IsDeleted(i)) continue;
16874 PropertyDetails details = this->DetailsAt(i);
16875 PropertyAttributes attr = details.attributes();
16876 if ((attr & filter) != 0) continue;
16877 keys->AddKey(k);
16878 }
16879 return keyLength - keys->GetLength();
16880 }
16881
16882
16809 // Backwards lookup (slow). 16883 // Backwards lookup (slow).
16810 template<typename Derived, typename Shape, typename Key> 16884 template<typename Derived, typename Shape, typename Key>
16811 Object* Dictionary<Derived, Shape, Key>::SlowReverseLookup(Object* value) { 16885 Object* Dictionary<Derived, Shape, Key>::SlowReverseLookup(Object* value) {
16812 int capacity = this->Capacity(); 16886 int capacity = this->Capacity();
16813 for (int i = 0; i < capacity; i++) { 16887 for (int i = 0; i < capacity; i++) {
16814 Object* k = this->KeyAt(i); 16888 Object* k = this->KeyAt(i);
16815 if (this->IsKey(k)) { 16889 if (this->IsKey(k)) {
16816 Object* e = this->ValueAt(i); 16890 Object* e = this->ValueAt(i);
16817 // TODO(dcarney): this should be templatized. 16891 // TODO(dcarney): this should be templatized.
16818 if (e->IsPropertyCell()) { 16892 if (e->IsPropertyCell()) {
(...skipping 1190 matching lines...) Expand 10 before | Expand all | Expand 10 after
18009 if (cell->value() != *new_value) { 18083 if (cell->value() != *new_value) {
18010 cell->set_value(*new_value); 18084 cell->set_value(*new_value);
18011 Isolate* isolate = cell->GetIsolate(); 18085 Isolate* isolate = cell->GetIsolate();
18012 cell->dependent_code()->DeoptimizeDependentCodeGroup( 18086 cell->dependent_code()->DeoptimizeDependentCodeGroup(
18013 isolate, DependentCode::kPropertyCellChangedGroup); 18087 isolate, DependentCode::kPropertyCellChangedGroup);
18014 } 18088 }
18015 } 18089 }
18016 18090
18017 } // namespace internal 18091 } // namespace internal
18018 } // namespace v8 18092 } // namespace v8
OLDNEW
« src/objects.h ('K') | « src/objects.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698