| 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 12 matching lines...) Expand all Loading... |
| 23 #include "src/debug/debug.h" | 23 #include "src/debug/debug.h" |
| 24 #include "src/deoptimizer.h" | 24 #include "src/deoptimizer.h" |
| 25 #include "src/elements.h" | 25 #include "src/elements.h" |
| 26 #include "src/execution.h" | 26 #include "src/execution.h" |
| 27 #include "src/field-index.h" | 27 #include "src/field-index.h" |
| 28 #include "src/field-index-inl.h" | 28 #include "src/field-index-inl.h" |
| 29 #include "src/full-codegen/full-codegen.h" | 29 #include "src/full-codegen/full-codegen.h" |
| 30 #include "src/ic/ic.h" | 30 #include "src/ic/ic.h" |
| 31 #include "src/interpreter/bytecodes.h" | 31 #include "src/interpreter/bytecodes.h" |
| 32 #include "src/isolate-inl.h" | 32 #include "src/isolate-inl.h" |
| 33 #include "src/key-accumulator.h" |
| 33 #include "src/list.h" | 34 #include "src/list.h" |
| 34 #include "src/log.h" | 35 #include "src/log.h" |
| 35 #include "src/lookup.h" | 36 #include "src/lookup.h" |
| 36 #include "src/macro-assembler.h" | 37 #include "src/macro-assembler.h" |
| 37 #include "src/messages.h" | 38 #include "src/messages.h" |
| 38 #include "src/objects-inl.h" | 39 #include "src/objects-inl.h" |
| 39 #include "src/profiler/cpu-profiler.h" | 40 #include "src/profiler/cpu-profiler.h" |
| 40 #include "src/property-descriptor.h" | 41 #include "src/property-descriptor.h" |
| 41 #include "src/prototype.h" | 42 #include "src/prototype.h" |
| 42 #include "src/safepoint-table.h" | 43 #include "src/safepoint-table.h" |
| (...skipping 7496 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7539 if (length == 0) { | 7540 if (length == 0) { |
| 7540 return Handle<FixedArray>(isolate->heap()->empty_fixed_array()); | 7541 return Handle<FixedArray>(isolate->heap()->empty_fixed_array()); |
| 7541 } | 7542 } |
| 7542 Handle<FixedArray> storage = isolate->factory()->NewFixedArray(length); | 7543 Handle<FixedArray> storage = isolate->factory()->NewFixedArray(length); |
| 7543 dictionary->CopyEnumKeysTo(*storage); | 7544 dictionary->CopyEnumKeysTo(*storage); |
| 7544 return storage; | 7545 return storage; |
| 7545 } | 7546 } |
| 7546 } | 7547 } |
| 7547 | 7548 |
| 7548 | 7549 |
| 7549 KeyAccumulator::~KeyAccumulator() { | |
| 7550 for (size_t i = 0; i < elements_.size(); i++) { | |
| 7551 delete elements_[i]; | |
| 7552 } | |
| 7553 } | |
| 7554 | |
| 7555 | |
| 7556 Handle<FixedArray> KeyAccumulator::GetKeys(GetKeysConversion convert) { | |
| 7557 if (length_ == 0) { | |
| 7558 return isolate_->factory()->empty_fixed_array(); | |
| 7559 } | |
| 7560 // Make sure we have all the lengths collected. | |
| 7561 NextPrototype(); | |
| 7562 | |
| 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 | |
| 7565 // |protoLengths_| and the available element keys in the corresponding bucket | |
| 7566 // in |elements_| to deduce the number of keys to take from the |properties_| | |
| 7567 // set. | |
| 7568 Handle<FixedArray> result = isolate_->factory()->NewFixedArray(length_); | |
| 7569 int index = 0; | |
| 7570 int properties_index = 0; | |
| 7571 for (size_t level = 0; level < levelLengths_.size(); level++) { | |
| 7572 int num_total = levelLengths_[level]; | |
| 7573 int num_elements = 0; | |
| 7574 if (num_total < 0) { | |
| 7575 // If the total is negative, the current level contains properties from a | |
| 7576 // proxy, hence we skip the integer keys in |elements_| since proxies | |
| 7577 // define the complete ordering. | |
| 7578 num_total = -num_total; | |
| 7579 } else if (level < elements_.size()) { | |
| 7580 std::vector<uint32_t>* elements = elements_[level]; | |
| 7581 num_elements = static_cast<int>(elements->size()); | |
| 7582 for (int i = 0; i < num_elements; i++) { | |
| 7583 Handle<Object> key; | |
| 7584 if (convert == KEEP_NUMBERS) { | |
| 7585 key = isolate_->factory()->NewNumberFromUint(elements->at(i)); | |
| 7586 } else { | |
| 7587 key = isolate_->factory()->Uint32ToString(elements->at(i)); | |
| 7588 } | |
| 7589 result->set(index, *key); | |
| 7590 index++; | |
| 7591 } | |
| 7592 } | |
| 7593 // Add the property keys for this prototype level. | |
| 7594 int num_properties = num_total - num_elements; | |
| 7595 for (int i = 0; i < num_properties; i++) { | |
| 7596 Object* key = properties_->KeyAt(properties_index); | |
| 7597 result->set(index, key); | |
| 7598 index++; | |
| 7599 properties_index++; | |
| 7600 } | |
| 7601 } | |
| 7602 | |
| 7603 DCHECK_EQ(index, length_); | |
| 7604 return result; | |
| 7605 } | |
| 7606 | |
| 7607 | |
| 7608 namespace { | |
| 7609 | |
| 7610 bool AccumulatorHasKey(std::vector<uint32_t>* sub_elements, uint32_t key) { | |
| 7611 return std::binary_search(sub_elements->begin(), sub_elements->end(), key); | |
| 7612 } | |
| 7613 | |
| 7614 } // namespace | |
| 7615 | |
| 7616 | |
| 7617 bool KeyAccumulator::AddKey(uint32_t key) { | |
| 7618 // Make sure we do not add keys to a proxy-level (see AddKeysFromProxy). | |
| 7619 // We mark proxy-levels with a negative length | |
| 7620 DCHECK_LE(0, levelLength_); | |
| 7621 // Binary search over all but the last level. The last one might not be | |
| 7622 // sorted yet. | |
| 7623 for (size_t i = 1; i < elements_.size(); i++) { | |
| 7624 if (AccumulatorHasKey(elements_[i - 1], key)) return false; | |
| 7625 } | |
| 7626 elements_.back()->push_back(key); | |
| 7627 length_++; | |
| 7628 levelLength_++; | |
| 7629 return true; | |
| 7630 } | |
| 7631 | |
| 7632 | |
| 7633 bool KeyAccumulator::AddKey(Object* key, AddKeyConversion convert) { | |
| 7634 return AddKey(handle(key, isolate_), convert); | |
| 7635 } | |
| 7636 | |
| 7637 | |
| 7638 bool KeyAccumulator::AddKey(Handle<Object> key, AddKeyConversion convert) { | |
| 7639 if (filter_ == SKIP_SYMBOLS && key->IsSymbol()) { | |
| 7640 return false; | |
| 7641 } | |
| 7642 // Make sure we do not add keys to a proxy-level (see AddKeysFromProxy). | |
| 7643 DCHECK_LE(0, levelLength_); | |
| 7644 // 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 | |
| 7646 // proxies we have to convert as well but also respect the original order. | |
| 7647 // Therefore we add a converted key to both sides | |
| 7648 if (convert == CONVERT_TO_ARRAY_INDEX || convert == PROXY_MAGIC) { | |
| 7649 uint32_t index = 0; | |
| 7650 int prev_length = length_; | |
| 7651 int prev_proto = levelLength_; | |
| 7652 bool was_array_index = false; | |
| 7653 bool key_was_added = false; | |
| 7654 if ((key->IsString() && Handle<String>::cast(key)->AsArrayIndex(&index)) || | |
| 7655 key->ToArrayIndex(&index)) { | |
| 7656 key_was_added = AddKey(index); | |
| 7657 was_array_index = true; | |
| 7658 if (convert == CONVERT_TO_ARRAY_INDEX) return key_was_added; | |
| 7659 } | |
| 7660 if (was_array_index && convert == PROXY_MAGIC) { | |
| 7661 // 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 | |
| 7663 // keys as it would lead to duplicate entries. | |
| 7664 if (!key_was_added) { | |
| 7665 return false; | |
| 7666 } | |
| 7667 length_ = prev_length; | |
| 7668 levelLength_ = prev_proto; | |
| 7669 } | |
| 7670 } | |
| 7671 if (properties_.is_null()) { | |
| 7672 properties_ = OrderedHashSet::Allocate(isolate_, 16); | |
| 7673 } | |
| 7674 // TODO(cbruni): remove this conversion once we throw the correct TypeError | |
| 7675 // for non-string/symbol elements returned by proxies | |
| 7676 if (convert == PROXY_MAGIC && key->IsNumber()) { | |
| 7677 key = isolate_->factory()->NumberToString(key); | |
| 7678 } | |
| 7679 int prev_size = properties_->NumberOfElements(); | |
| 7680 properties_ = OrderedHashSet::Add(properties_, key); | |
| 7681 if (prev_size < properties_->NumberOfElements()) { | |
| 7682 length_++; | |
| 7683 levelLength_++; | |
| 7684 } | |
| 7685 return true; | |
| 7686 } | |
| 7687 | |
| 7688 | |
| 7689 void KeyAccumulator::AddKeys(Handle<FixedArray> array, | |
| 7690 AddKeyConversion convert) { | |
| 7691 int add_length = array->length(); | |
| 7692 if (add_length == 0) return; | |
| 7693 for (int i = 0; i < add_length; i++) { | |
| 7694 Handle<Object> current(array->get(i), isolate_); | |
| 7695 AddKey(current); | |
| 7696 } | |
| 7697 } | |
| 7698 | |
| 7699 | |
| 7700 void KeyAccumulator::AddKeys(Handle<JSObject> array_like, | |
| 7701 AddKeyConversion convert) { | |
| 7702 DCHECK(array_like->IsJSArray() || array_like->HasSloppyArgumentsElements()); | |
| 7703 ElementsAccessor* accessor = array_like->GetElementsAccessor(); | |
| 7704 accessor->AddElementsToKeyAccumulator(array_like, this, convert); | |
| 7705 } | |
| 7706 | |
| 7707 | |
| 7708 void KeyAccumulator::AddKeysFromProxy(Handle<JSObject> array_like) { | |
| 7709 // Proxies define a complete list of keys with no distinction of | |
| 7710 // elements and properties, which breaks the normal assumption for the | |
| 7711 // KeyAccumulator. | |
| 7712 AddKeys(array_like, PROXY_MAGIC); | |
| 7713 // 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 | |
| 7715 // given by the proxy. | |
| 7716 levelLength_ = -levelLength_; | |
| 7717 } | |
| 7718 | |
| 7719 | |
| 7720 void KeyAccumulator::AddElementKeysFromInterceptor( | |
| 7721 Handle<JSObject> array_like) { | |
| 7722 AddKeys(array_like, CONVERT_TO_ARRAY_INDEX); | |
| 7723 // The interceptor might introduce duplicates for the current level, since | |
| 7724 // these keys get added after the objects's normal element keys. | |
| 7725 SortCurrentElementsListRemoveDuplicates(); | |
| 7726 } | |
| 7727 | |
| 7728 | |
| 7729 void KeyAccumulator::SortCurrentElementsListRemoveDuplicates() { | |
| 7730 // Sort and remove duplciated from the current elements level and adjust | |
| 7731 // the lengths accordingly. | |
| 7732 auto last_level = elements_.back(); | |
| 7733 size_t nof_removed_keys = last_level->size(); | |
| 7734 std::sort(last_level->begin(), last_level->end()); | |
| 7735 last_level->erase(std::unique(last_level->begin(), last_level->end()), | |
| 7736 last_level->end()); | |
| 7737 // Adjust total length / level length by the number of removed duplicates | |
| 7738 nof_removed_keys -= last_level->size(); | |
| 7739 levelLength_ -= static_cast<int>(nof_removed_keys); | |
| 7740 length_ -= static_cast<int>(nof_removed_keys); | |
| 7741 } | |
| 7742 | |
| 7743 | |
| 7744 void KeyAccumulator::SortCurrentElementsList() { | |
| 7745 if (elements_.empty()) return; | |
| 7746 auto element_keys = elements_.back(); | |
| 7747 std::sort(element_keys->begin(), element_keys->end()); | |
| 7748 } | |
| 7749 | |
| 7750 | |
| 7751 void KeyAccumulator::NextPrototype() { | |
| 7752 // Store the protoLength on the first call of this method. | |
| 7753 if (!elements_.empty()) { | |
| 7754 levelLengths_.push_back(levelLength_); | |
| 7755 } | |
| 7756 elements_.push_back(new std::vector<uint32_t>()); | |
| 7757 levelLength_ = 0; | |
| 7758 } | |
| 7759 | |
| 7760 | |
| 7761 MaybeHandle<FixedArray> JSReceiver::GetKeys(Handle<JSReceiver> object, | 7550 MaybeHandle<FixedArray> JSReceiver::GetKeys(Handle<JSReceiver> object, |
| 7762 KeyCollectionType type, | 7551 KeyCollectionType type, |
| 7763 KeyFilter filter, | 7552 KeyFilter filter, |
| 7764 GetKeysConversion getConversion) { | 7553 GetKeysConversion getConversion) { |
| 7765 USE(ContainsOnlyValidKeys); | 7554 USE(ContainsOnlyValidKeys); |
| 7766 Isolate* isolate = object->GetIsolate(); | 7555 Isolate* isolate = object->GetIsolate(); |
| 7767 KeyAccumulator accumulator(isolate, filter); | 7556 KeyAccumulator accumulator(isolate, filter); |
| 7768 Handle<JSFunction> arguments_function( | 7557 Handle<JSFunction> arguments_function( |
| 7769 JSFunction::cast(isolate->sloppy_arguments_map()->GetConstructor())); | 7558 JSFunction::cast(isolate->sloppy_arguments_map()->GetConstructor())); |
| 7770 PrototypeIterator::WhereToEnd end = type == OWN_ONLY | 7559 PrototypeIterator::WhereToEnd end = type == OWN_ONLY |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7833 !current->HasNamedInterceptor() && | 7622 !current->HasNamedInterceptor() && |
| 7834 !current->HasIndexedInterceptor()); | 7623 !current->HasIndexedInterceptor()); |
| 7835 // Compute the property keys and cache them if possible. | 7624 // Compute the property keys and cache them if possible. |
| 7836 Handle<FixedArray> enum_keys = | 7625 Handle<FixedArray> enum_keys = |
| 7837 JSObject::GetEnumPropertyKeys(current, cache_enum_length); | 7626 JSObject::GetEnumPropertyKeys(current, cache_enum_length); |
| 7838 accumulator.AddKeys(enum_keys); | 7627 accumulator.AddKeys(enum_keys); |
| 7839 } else { | 7628 } else { |
| 7840 DCHECK(filter == INCLUDE_SYMBOLS); | 7629 DCHECK(filter == INCLUDE_SYMBOLS); |
| 7841 PropertyAttributes attr_filter = | 7630 PropertyAttributes attr_filter = |
| 7842 static_cast<PropertyAttributes>(DONT_ENUM | PRIVATE_SYMBOL); | 7631 static_cast<PropertyAttributes>(DONT_ENUM | PRIVATE_SYMBOL); |
| 7843 Handle<FixedArray> property_keys = isolate->factory()->NewFixedArray( | 7632 current->CollectOwnPropertyNames(&accumulator, attr_filter); |
| 7844 current->NumberOfOwnProperties(attr_filter)); | |
| 7845 current->GetOwnPropertyNames(*property_keys, 0, attr_filter); | |
| 7846 accumulator.AddKeys(property_keys); | |
| 7847 } | 7633 } |
| 7848 | 7634 |
| 7849 // Add the property keys from the interceptor. | 7635 // Add the property keys from the interceptor. |
| 7850 if (current->HasNamedInterceptor()) { | 7636 if (current->HasNamedInterceptor()) { |
| 7851 Handle<JSObject> result; | 7637 Handle<JSObject> result; |
| 7852 if (JSObject::GetKeysForNamedInterceptor(current, object) | 7638 if (JSObject::GetKeysForNamedInterceptor(current, object) |
| 7853 .ToHandle(&result)) { | 7639 .ToHandle(&result)) { |
| 7854 accumulator.AddKeys(result); | 7640 accumulator.AddKeys(result); |
| 7855 } | 7641 } |
| 7856 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, FixedArray); | 7642 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, FixedArray); |
| (...skipping 7156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 15013 } else if (IsJSGlobalObject()) { | 14799 } else if (IsJSGlobalObject()) { |
| 15014 return global_dictionary()->CopyKeysTo(storage, index, filter, | 14800 return global_dictionary()->CopyKeysTo(storage, index, filter, |
| 15015 GlobalDictionary::UNSORTED); | 14801 GlobalDictionary::UNSORTED); |
| 15016 } else { | 14802 } else { |
| 15017 return property_dictionary()->CopyKeysTo(storage, index, filter, | 14803 return property_dictionary()->CopyKeysTo(storage, index, filter, |
| 15018 NameDictionary::UNSORTED); | 14804 NameDictionary::UNSORTED); |
| 15019 } | 14805 } |
| 15020 } | 14806 } |
| 15021 | 14807 |
| 15022 | 14808 |
| 14809 int JSObject::CollectOwnPropertyNames(KeyAccumulator* keys, |
| 14810 PropertyAttributes filter) { |
| 14811 if (HasFastProperties()) { |
| 14812 int nof_keys = keys->length(); |
| 14813 int real_size = map()->NumberOfOwnDescriptors(); |
| 14814 Handle<DescriptorArray> descs(map()->instance_descriptors()); |
| 14815 for (int i = 0; i < real_size; i++) { |
| 14816 if ((descs->GetDetails(i).attributes() & filter) != 0) continue; |
| 14817 Name* key = descs->GetKey(i); |
| 14818 if (key->FilterKey(filter)) continue; |
| 14819 keys->AddKey(key); |
| 14820 } |
| 14821 return nof_keys - keys->length(); |
| 14822 } else if (IsJSGlobalObject()) { |
| 14823 return global_dictionary()->CollectKeysTo(keys, filter); |
| 14824 } else { |
| 14825 return property_dictionary()->CollectKeysTo(keys, filter); |
| 14826 } |
| 14827 } |
| 14828 |
| 14829 |
| 15023 int JSObject::NumberOfOwnElements(PropertyAttributes filter) { | 14830 int JSObject::NumberOfOwnElements(PropertyAttributes filter) { |
| 15024 // Fast case for objects with no elements. | 14831 // Fast case for objects with no elements. |
| 15025 if (!IsJSValue() && HasFastElements()) { | 14832 if (!IsJSValue() && HasFastElements()) { |
| 15026 uint32_t length = | 14833 uint32_t length = |
| 15027 IsJSArray() | 14834 IsJSArray() |
| 15028 ? static_cast<uint32_t>( | 14835 ? static_cast<uint32_t>( |
| 15029 Smi::cast(JSArray::cast(this)->length())->value()) | 14836 Smi::cast(JSArray::cast(this)->length())->value()) |
| 15030 : static_cast<uint32_t>(FixedArrayBase::cast(elements())->length()); | 14837 : static_cast<uint32_t>(FixedArrayBase::cast(elements())->length()); |
| 15031 if (length == 0) return 0; | 14838 if (length == 0) return 0; |
| 15032 } | 14839 } |
| (...skipping 1751 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 16784 | 16591 |
| 16785 template <typename Derived, typename Shape, typename Key> | 16592 template <typename Derived, typename Shape, typename Key> |
| 16786 int Dictionary<Derived, Shape, Key>::CopyKeysTo( | 16593 int Dictionary<Derived, Shape, Key>::CopyKeysTo( |
| 16787 FixedArray* storage, int index, PropertyAttributes filter, | 16594 FixedArray* storage, int index, PropertyAttributes filter, |
| 16788 typename Dictionary<Derived, Shape, Key>::SortMode sort_mode) { | 16595 typename Dictionary<Derived, Shape, Key>::SortMode sort_mode) { |
| 16789 DCHECK(storage->length() >= NumberOfElementsFilterAttributes(filter)); | 16596 DCHECK(storage->length() >= NumberOfElementsFilterAttributes(filter)); |
| 16790 int start_index = index; | 16597 int start_index = index; |
| 16791 int capacity = this->Capacity(); | 16598 int capacity = this->Capacity(); |
| 16792 for (int i = 0; i < capacity; i++) { | 16599 for (int i = 0; i < capacity; i++) { |
| 16793 Object* k = this->KeyAt(i); | 16600 Object* k = this->KeyAt(i); |
| 16794 if (this->IsKey(k) && !k->FilterKey(filter)) { | 16601 if (!this->IsKey(k) || k->FilterKey(filter)) continue; |
| 16795 if (this->IsDeleted(i)) continue; | 16602 if (this->IsDeleted(i)) continue; |
| 16796 PropertyDetails details = this->DetailsAt(i); | 16603 PropertyDetails details = this->DetailsAt(i); |
| 16797 PropertyAttributes attr = details.attributes(); | 16604 PropertyAttributes attr = details.attributes(); |
| 16798 if ((attr & filter) == 0) storage->set(index++, k); | 16605 if ((attr & filter) != 0) continue; |
| 16799 } | 16606 storage->set(index++, k); |
| 16800 } | 16607 } |
| 16801 if (sort_mode == Dictionary::SORTED) { | 16608 if (sort_mode == Dictionary::SORTED) { |
| 16802 storage->SortPairs(storage, index); | 16609 storage->SortPairs(storage, index); |
| 16803 } | 16610 } |
| 16804 DCHECK(storage->length() >= index); | 16611 DCHECK(storage->length() >= index); |
| 16805 return index - start_index; | 16612 return index - start_index; |
| 16806 } | 16613 } |
| 16807 | 16614 |
| 16808 | 16615 |
| 16616 template <typename Derived, typename Shape, typename Key> |
| 16617 int Dictionary<Derived, Shape, Key>::CollectKeysTo(KeyAccumulator* keys, |
| 16618 PropertyAttributes filter) { |
| 16619 int capacity = this->Capacity(); |
| 16620 int keyLength = keys->length(); |
| 16621 for (int i = 0; i < capacity; i++) { |
| 16622 Object* k = this->KeyAt(i); |
| 16623 if (!this->IsKey(k) || k->FilterKey(filter)) continue; |
| 16624 if (this->IsDeleted(i)) continue; |
| 16625 PropertyDetails details = this->DetailsAt(i); |
| 16626 PropertyAttributes attr = details.attributes(); |
| 16627 if ((attr & filter) != 0) continue; |
| 16628 keys->AddKey(k); |
| 16629 } |
| 16630 return keyLength - keys->length(); |
| 16631 } |
| 16632 |
| 16633 |
| 16809 // Backwards lookup (slow). | 16634 // Backwards lookup (slow). |
| 16810 template<typename Derived, typename Shape, typename Key> | 16635 template<typename Derived, typename Shape, typename Key> |
| 16811 Object* Dictionary<Derived, Shape, Key>::SlowReverseLookup(Object* value) { | 16636 Object* Dictionary<Derived, Shape, Key>::SlowReverseLookup(Object* value) { |
| 16812 int capacity = this->Capacity(); | 16637 int capacity = this->Capacity(); |
| 16813 for (int i = 0; i < capacity; i++) { | 16638 for (int i = 0; i < capacity; i++) { |
| 16814 Object* k = this->KeyAt(i); | 16639 Object* k = this->KeyAt(i); |
| 16815 if (this->IsKey(k)) { | 16640 if (this->IsKey(k)) { |
| 16816 Object* e = this->ValueAt(i); | 16641 Object* e = this->ValueAt(i); |
| 16817 // TODO(dcarney): this should be templatized. | 16642 // TODO(dcarney): this should be templatized. |
| 16818 if (e->IsPropertyCell()) { | 16643 if (e->IsPropertyCell()) { |
| (...skipping 1190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 18009 if (cell->value() != *new_value) { | 17834 if (cell->value() != *new_value) { |
| 18010 cell->set_value(*new_value); | 17835 cell->set_value(*new_value); |
| 18011 Isolate* isolate = cell->GetIsolate(); | 17836 Isolate* isolate = cell->GetIsolate(); |
| 18012 cell->dependent_code()->DeoptimizeDependentCodeGroup( | 17837 cell->dependent_code()->DeoptimizeDependentCodeGroup( |
| 18013 isolate, DependentCode::kPropertyCellChangedGroup); | 17838 isolate, DependentCode::kPropertyCellChangedGroup); |
| 18014 } | 17839 } |
| 18015 } | 17840 } |
| 18016 | 17841 |
| 18017 } // namespace internal | 17842 } // namespace internal |
| 18018 } // namespace v8 | 17843 } // namespace v8 |
| OLD | NEW |