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

Side by Side Diff: src/objects.cc

Issue 1316213008: Speedup JSReceiver::GetKeys (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Compilation Fix Created 5 years, 3 months 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
« no previous file with comments | « src/objects.h ('k') | src/runtime/runtime-array.cc » ('j') | 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 <iomanip> 7 #include <iomanip>
8 #include <sstream> 8 #include <sstream>
9 9
10 #include "src/accessors.h" 10 #include "src/accessors.h"
(...skipping 6572 matching lines...) Expand 10 before | Expand all | Expand 10 after
6583 if (length == 0) { 6583 if (length == 0) {
6584 return Handle<FixedArray>(isolate->heap()->empty_fixed_array()); 6584 return Handle<FixedArray>(isolate->heap()->empty_fixed_array());
6585 } 6585 }
6586 Handle<FixedArray> storage = isolate->factory()->NewFixedArray(length); 6586 Handle<FixedArray> storage = isolate->factory()->NewFixedArray(length);
6587 dictionary->CopyEnumKeysTo(*storage); 6587 dictionary->CopyEnumKeysTo(*storage);
6588 return storage; 6588 return storage;
6589 } 6589 }
6590 } 6590 }
6591 6591
6592 6592
6593 Handle<FixedArray> KeyAccumulator::GetKeys() {
6594 if (length_ == 0) {
6595 return isolate_->factory()->empty_fixed_array();
6596 }
6597 if (set_.is_null()) {
6598 keys_->Shrink(length_);
6599 return keys_;
6600 }
6601 // copy over results from set_
6602 Handle<FixedArray> result = isolate_->factory()->NewFixedArray(length_);
6603 for (int i = 0; i < length_; i++) {
6604 result->set(i, set_->KeyAt(i));
6605 }
6606 return result;
6607 }
6608
6609
6610 void KeyAccumulator::AddKey(Handle<Object> key, int check_limit) {
6611 #ifdef ENABLE_SLOW_DCHECKS
6612 if (FLAG_enable_slow_asserts) {
6613 DCHECK(key->IsNumber() || key->IsName());
6614 }
6615 #endif
6616 if (!set_.is_null()) {
6617 set_ = OrderedHashSet::Add(set_, key);
6618 length_ = set_->NumberOfElements();
6619 return;
6620 }
6621 // check if we already have the key in the case we are still using
6622 // the keys_ FixedArray
6623 check_limit = Min(check_limit, length_);
6624 for (int i = 0; i < check_limit; i++) {
6625 Object* current = keys_->get(i);
6626 if (current->KeyEquals(*key)) return;
6627 }
6628 EnsureCapacity(length_);
6629 keys_->set(length_, *key);
6630 length_++;
6631 }
6632
6633
6634 void KeyAccumulator::AddKeys(Handle<FixedArray> array,
6635 FixedArray::KeyFilter filter) {
6636 int add_length = array->length();
6637 if (add_length == 0) return;
6638 if (keys_.is_null() && filter == FixedArray::ALL_KEYS) {
6639 keys_ = array;
6640 length_ = keys_->length();
6641 return;
6642 }
6643 PrepareForComparisons(add_length);
6644 int previous_key_count = length_;
6645 for (int i = 0; i < add_length; i++) {
6646 Handle<Object> current(array->get(i), isolate_);
6647 if (filter == FixedArray::NON_SYMBOL_KEYS && current->IsSymbol()) continue;
6648 AddKey(current, previous_key_count);
6649 }
6650 }
6651
6652
6653 void KeyAccumulator::AddKeys(Handle<JSObject> array_like,
6654 FixedArray::KeyFilter filter) {
6655 DCHECK(array_like->IsJSArray() || array_like->HasSloppyArgumentsElements());
6656 ElementsAccessor* accessor = array_like->GetElementsAccessor();
6657 accessor->AddElementsToKeyAccumulator(array_like, this, filter);
6658 }
6659
6660
6661 void KeyAccumulator::PrepareForComparisons(int count) {
6662 // Depending on how many comparisons we do we should switch to the
6663 // hash-table-based checks which have a one-time overhead for
6664 // initializing but O(1) for HasKey checks.
6665 if (!set_.is_null()) return;
6666 // This limit was obtained through evaluation of a microbench.
6667 if (length_ * count < 50) return;
6668 set_ = OrderedHashSet::Allocate(isolate_, length_);
6669 for (int i = 0; i < length_; i++) {
6670 Handle<Object> value(keys_->get(i), isolate_);
6671 set_ = OrderedHashSet::Add(set_, value);
6672 }
6673 }
6674
6675
6676 void KeyAccumulator::EnsureCapacity(int capacity) {
6677 if (keys_.is_null() || keys_->length() <= capacity) {
6678 Grow();
6679 }
6680 }
6681
6682
6683 void KeyAccumulator::Grow() {
6684 // The OrderedHashSet handles growing by itself.
6685 if (!set_.is_null()) return;
6686 // Otherwise, grow the internal keys_ FixedArray
6687 int capacity = keys_.is_null() ? 16 : keys_->length() * 2 + 16;
6688 Handle<FixedArray> new_keys = isolate_->factory()->NewFixedArray(capacity);
6689 if (keys_.is_null()) {
6690 keys_ = new_keys;
6691 return;
6692 }
6693 int buffer_length = keys_->length();
6694 {
6695 DisallowHeapAllocation no_gc;
6696 WriteBarrierMode mode = new_keys->GetWriteBarrierMode(no_gc);
6697 for (int i = 0; i < buffer_length; i++) {
6698 new_keys->set(i, keys_->get(i), mode);
6699 }
6700 }
6701 keys_ = new_keys;
6702 }
6703
6704
6593 MaybeHandle<FixedArray> JSReceiver::GetKeys(Handle<JSReceiver> object, 6705 MaybeHandle<FixedArray> JSReceiver::GetKeys(Handle<JSReceiver> object,
6594 KeyCollectionType type) { 6706 KeyCollectionType type) {
6595 USE(ContainsOnlyValidKeys); 6707 USE(ContainsOnlyValidKeys);
6596 Isolate* isolate = object->GetIsolate(); 6708 Isolate* isolate = object->GetIsolate();
6597 Handle<FixedArray> content = isolate->factory()->empty_fixed_array(); 6709 KeyAccumulator accumulator(isolate);
6598 Handle<JSFunction> arguments_function( 6710 Handle<JSFunction> arguments_function(
6599 JSFunction::cast(isolate->sloppy_arguments_map()->GetConstructor())); 6711 JSFunction::cast(isolate->sloppy_arguments_map()->GetConstructor()));
6600 6712
6601 PrototypeIterator::WhereToEnd end = type == OWN_ONLY 6713 PrototypeIterator::WhereToEnd end = type == OWN_ONLY
6602 ? PrototypeIterator::END_AT_NON_HIDDEN 6714 ? PrototypeIterator::END_AT_NON_HIDDEN
6603 : PrototypeIterator::END_AT_NULL; 6715 : PrototypeIterator::END_AT_NULL;
6604 // Only collect keys if access is permitted. 6716 // Only collect keys if access is permitted.
6605 for (PrototypeIterator iter(isolate, object, 6717 for (PrototypeIterator iter(isolate, object,
6606 PrototypeIterator::START_AT_RECEIVER); 6718 PrototypeIterator::START_AT_RECEIVER);
6607 !iter.IsAtEnd(end); iter.Advance()) { 6719 !iter.IsAtEnd(end); iter.Advance()) {
6608 if (PrototypeIterator::GetCurrent(iter)->IsJSProxy()) { 6720 if (PrototypeIterator::GetCurrent(iter)->IsJSProxy()) {
6609 Handle<JSProxy> proxy = PrototypeIterator::GetCurrent<JSProxy>(iter); 6721 Handle<JSProxy> proxy = PrototypeIterator::GetCurrent<JSProxy>(iter);
6610 Handle<Object> args[] = { proxy }; 6722 Handle<Object> args[] = { proxy };
6611 Handle<Object> names; 6723 Handle<Object> names;
6612 ASSIGN_RETURN_ON_EXCEPTION( 6724 ASSIGN_RETURN_ON_EXCEPTION(
6613 isolate, names, 6725 isolate, names,
6614 Execution::Call(isolate, 6726 Execution::Call(isolate,
6615 isolate->proxy_enumerate(), 6727 isolate->proxy_enumerate(),
6616 object, 6728 object,
6617 arraysize(args), 6729 arraysize(args),
6618 args), 6730 args),
6619 FixedArray); 6731 FixedArray);
6620 ASSIGN_RETURN_ON_EXCEPTION( 6732 accumulator.AddKeys(Handle<JSObject>::cast(names), FixedArray::ALL_KEYS);
6621 isolate, content,
6622 FixedArray::AddKeysFromArrayLike(
6623 content, Handle<JSObject>::cast(names)),
6624 FixedArray);
6625 break; 6733 break;
6626 } 6734 }
6627 6735
6628 Handle<JSObject> current = PrototypeIterator::GetCurrent<JSObject>(iter); 6736 Handle<JSObject> current = PrototypeIterator::GetCurrent<JSObject>(iter);
6629 6737
6630 // Check access rights if required. 6738 // Check access rights if required.
6631 if (current->IsAccessCheckNeeded() && !isolate->MayAccess(current)) { 6739 if (current->IsAccessCheckNeeded() && !isolate->MayAccess(current)) {
6632 if (iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN)) { 6740 if (iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN)) {
6633 isolate->ReportFailedAccessCheck(current); 6741 isolate->ReportFailedAccessCheck(current);
6634 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, FixedArray); 6742 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, FixedArray);
6635 } 6743 }
6636 break; 6744 break;
6637 } 6745 }
6638 6746
6639 // Compute the element keys. 6747 // Compute the element keys.
6640 Handle<FixedArray> element_keys = 6748 Handle<FixedArray> element_keys =
6641 isolate->factory()->NewFixedArray(current->NumberOfEnumElements()); 6749 isolate->factory()->NewFixedArray(current->NumberOfEnumElements());
6642 current->GetEnumElementKeys(*element_keys); 6750 current->GetEnumElementKeys(*element_keys);
6643 ASSIGN_RETURN_ON_EXCEPTION( 6751 accumulator.AddKeys(element_keys, FixedArray::ALL_KEYS);
6644 isolate, content, 6752 DCHECK(ContainsOnlyValidKeys(accumulator.GetKeys()));
6645 FixedArray::UnionOfKeys(content, element_keys),
6646 FixedArray);
6647 DCHECK(ContainsOnlyValidKeys(content));
6648 6753
6649 // Add the element keys from the interceptor. 6754 // Add the element keys from the interceptor.
6650 if (current->HasIndexedInterceptor()) { 6755 if (current->HasIndexedInterceptor()) {
6651 Handle<JSObject> result; 6756 Handle<JSObject> result;
6652 if (JSObject::GetKeysForIndexedInterceptor( 6757 if (JSObject::GetKeysForIndexedInterceptor(
6653 current, object).ToHandle(&result)) { 6758 current, object).ToHandle(&result)) {
6654 ASSIGN_RETURN_ON_EXCEPTION( 6759 accumulator.AddKeys(result, FixedArray::ALL_KEYS);
6655 isolate, content,
6656 FixedArray::AddKeysFromArrayLike(content, result),
6657 FixedArray);
6658 } 6760 }
6659 DCHECK(ContainsOnlyValidKeys(content)); 6761 DCHECK(ContainsOnlyValidKeys(accumulator.GetKeys()));
6660 } 6762 }
6661 6763
6662 // We can cache the computed property keys if access checks are 6764 // We can cache the computed property keys if access checks are
6663 // not needed and no interceptors are involved. 6765 // not needed and no interceptors are involved.
6664 // 6766 //
6665 // We do not use the cache if the object has elements and 6767 // We do not use the cache if the object has elements and
6666 // therefore it does not make sense to cache the property names 6768 // therefore it does not make sense to cache the property names
6667 // for arguments objects. Arguments objects will always have 6769 // for arguments objects. Arguments objects will always have
6668 // elements. 6770 // elements.
6669 // Wrapped strings have elements, but don't have an elements 6771 // Wrapped strings have elements, but don't have an elements
6670 // array or dictionary. So the fast inline test for whether to 6772 // array or dictionary. So the fast inline test for whether to
6671 // use the cache says yes, so we should not create a cache. 6773 // use the cache says yes, so we should not create a cache.
6672 bool cache_enum_keys = 6774 bool cache_enum_keys =
6673 ((current->map()->GetConstructor() != *arguments_function) && 6775 ((current->map()->GetConstructor() != *arguments_function) &&
6674 !current->IsJSValue() && !current->IsAccessCheckNeeded() && 6776 !current->IsJSValue() && !current->IsAccessCheckNeeded() &&
6675 !current->HasNamedInterceptor() && !current->HasIndexedInterceptor()); 6777 !current->HasNamedInterceptor() && !current->HasIndexedInterceptor());
6676 // Compute the property keys and cache them if possible. 6778 // Compute the property keys and cache them if possible.
6677 ASSIGN_RETURN_ON_EXCEPTION( 6779
6678 isolate, content, 6780 Handle<FixedArray> enum_keys =
6679 FixedArray::UnionOfKeys( 6781 JSObject::GetEnumPropertyKeys(current, cache_enum_keys);
6680 content, JSObject::GetEnumPropertyKeys(current, cache_enum_keys)), 6782 accumulator.AddKeys(enum_keys, FixedArray::ALL_KEYS);
6681 FixedArray); 6783 DCHECK(ContainsOnlyValidKeys(accumulator.GetKeys()));
6682 DCHECK(ContainsOnlyValidKeys(content));
6683 6784
6684 // Add the non-symbol property keys from the interceptor. 6785 // Add the non-symbol property keys from the interceptor.
6685 if (current->HasNamedInterceptor()) { 6786 if (current->HasNamedInterceptor()) {
6686 Handle<JSObject> result; 6787 Handle<JSObject> result;
6687 if (JSObject::GetKeysForNamedInterceptor( 6788 if (JSObject::GetKeysForNamedInterceptor(
6688 current, object).ToHandle(&result)) { 6789 current, object).ToHandle(&result)) {
6689 ASSIGN_RETURN_ON_EXCEPTION( 6790 accumulator.AddKeys(result, FixedArray::NON_SYMBOL_KEYS);
6690 isolate, content, FixedArray::AddKeysFromArrayLike(
6691 content, result, FixedArray::NON_SYMBOL_KEYS),
6692 FixedArray);
6693 } 6791 }
6694 DCHECK(ContainsOnlyValidKeys(content)); 6792 DCHECK(ContainsOnlyValidKeys(accumulator.GetKeys()));
6695 } 6793 }
6696 } 6794 }
6697 return content; 6795
6796 Handle<FixedArray> keys = accumulator.GetKeys();
6797 DCHECK(ContainsOnlyValidKeys(keys));
6798 return keys;
6698 } 6799 }
6699 6800
6700 6801
6701 bool Map::DictionaryElementsInPrototypeChainOnly() { 6802 bool Map::DictionaryElementsInPrototypeChainOnly() {
6702 if (IsDictionaryElementsKind(elements_kind())) { 6803 if (IsDictionaryElementsKind(elements_kind())) {
6703 return false; 6804 return false;
6704 } 6805 }
6705 6806
6706 for (PrototypeIterator iter(this); !iter.IsAtEnd(); iter.Advance()) { 6807 for (PrototypeIterator iter(this); !iter.IsAtEnd(); iter.Advance()) {
6707 // Be conservative, don't walk into proxies. 6808 // Be conservative, don't walk into proxies.
(...skipping 1480 matching lines...) Expand 10 before | Expand all | Expand 10 after
8188 8289
8189 void FixedArray::Shrink(int new_length) { 8290 void FixedArray::Shrink(int new_length) {
8190 DCHECK(0 <= new_length && new_length <= length()); 8291 DCHECK(0 <= new_length && new_length <= length());
8191 if (new_length < length()) { 8292 if (new_length < length()) {
8192 GetHeap()->RightTrimFixedArray<Heap::CONCURRENT_TO_SWEEPER>( 8293 GetHeap()->RightTrimFixedArray<Heap::CONCURRENT_TO_SWEEPER>(
8193 this, length() - new_length); 8294 this, length() - new_length);
8194 } 8295 }
8195 } 8296 }
8196 8297
8197 8298
8198 MaybeHandle<FixedArray> FixedArray::AddKeysFromArrayLike(
8199 Handle<FixedArray> content, Handle<JSObject> array, KeyFilter filter) {
8200 DCHECK(array->IsJSArray() || array->HasSloppyArgumentsElements());
8201 ElementsAccessor* accessor = array->GetElementsAccessor();
8202 Handle<FixedArray> result =
8203 accessor->AddElementsToFixedArray(array, content, filter);
8204
8205 #ifdef ENABLE_SLOW_DCHECKS
8206 if (FLAG_enable_slow_asserts) {
8207 DisallowHeapAllocation no_allocation;
8208 for (int i = 0; i < result->length(); i++) {
8209 Object* current = result->get(i);
8210 DCHECK(current->IsNumber() || current->IsName());
8211 }
8212 }
8213 #endif
8214 return result;
8215 }
8216
8217
8218 MaybeHandle<FixedArray> FixedArray::UnionOfKeys(Handle<FixedArray> first,
8219 Handle<FixedArray> second) {
8220 if (second->length() == 0) return first;
8221 if (first->length() == 0) return second;
8222 Isolate* isolate = first->GetIsolate();
8223 Handle<FixedArray> result =
8224 isolate->factory()->NewFixedArray(first->length() + second->length());
8225 for (int i = 0; i < first->length(); i++) {
8226 result->set(i, first->get(i));
8227 }
8228 int pos = first->length();
8229 for (int j = 0; j < second->length(); j++) {
8230 Object* current = second->get(j);
8231 int i;
8232 for (i = 0; i < first->length(); i++) {
8233 if (current->KeyEquals(first->get(i))) break;
8234 }
8235 if (i == first->length()) {
8236 result->set(pos++, current);
8237 }
8238 }
8239
8240 result->Shrink(pos);
8241 return result;
8242 }
8243
8244
8245 void FixedArray::CopyTo(int pos, FixedArray* dest, int dest_pos, int len) { 8299 void FixedArray::CopyTo(int pos, FixedArray* dest, int dest_pos, int len) {
8246 DisallowHeapAllocation no_gc; 8300 DisallowHeapAllocation no_gc;
8247 WriteBarrierMode mode = dest->GetWriteBarrierMode(no_gc); 8301 WriteBarrierMode mode = dest->GetWriteBarrierMode(no_gc);
8248 for (int index = 0; index < len; index++) { 8302 for (int index = 0; index < len; index++) {
8249 dest->set(dest_pos+index, get(pos+index), mode); 8303 dest->set(dest_pos+index, get(pos+index), mode);
8250 } 8304 }
8251 } 8305 }
8252 8306
8253 8307
8254 #ifdef DEBUG 8308 #ifdef DEBUG
(...skipping 7302 matching lines...) Expand 10 before | Expand all | Expand 10 after
15557 Allocate(table->GetIsolate(), 15611 Allocate(table->GetIsolate(),
15558 kMinCapacity, 15612 kMinCapacity,
15559 table->GetHeap()->InNewSpace(*table) ? NOT_TENURED : TENURED); 15613 table->GetHeap()->InNewSpace(*table) ? NOT_TENURED : TENURED);
15560 15614
15561 table->SetNextTable(*new_table); 15615 table->SetNextTable(*new_table);
15562 table->SetNumberOfDeletedElements(kClearedTableSentinel); 15616 table->SetNumberOfDeletedElements(kClearedTableSentinel);
15563 15617
15564 return new_table; 15618 return new_table;
15565 } 15619 }
15566 15620
15621 template <class Derived, class Iterator, int entrysize>
15622 bool OrderedHashTable<Derived, Iterator, entrysize>::HasKey(
15623 Handle<Derived> table, Handle<Object> key) {
15624 int entry = table->KeyToFirstEntry(*key);
15625 // Walk the chain in the bucket to find the key.
15626 while (entry != kNotFound) {
15627 Object* candidate_key = table->KeyAt(entry);
15628 if (candidate_key->SameValueZero(*key)) return true;
15629 entry = table->NextChainEntry(entry);
15630 }
15631 return false;
15632 }
15633
15634
15635 Handle<OrderedHashSet> OrderedHashSet::Add(Handle<OrderedHashSet> table,
15636 Handle<Object> key) {
15637 int hash = Object::GetOrCreateHash(table->GetIsolate(), key)->value();
15638 int entry = table->HashToEntry(hash);
15639 // Walk the chain of the bucket and try finding the key.
15640 while (entry != kNotFound) {
15641 Object* candidate_key = table->KeyAt(entry);
15642 // Do not add if we have the key already
15643 if (candidate_key->SameValueZero(*key)) return table;
15644 entry = table->NextChainEntry(entry);
15645 }
15646
15647 table = OrderedHashSet::EnsureGrowable(table);
15648 // Read the existing bucket values.
15649 int bucket = table->HashToBucket(hash);
15650 int previous_entry = table->HashToEntry(hash);
15651 int nof = table->NumberOfElements();
15652 // Insert a new entry at the end,
15653 int new_entry = nof + table->NumberOfDeletedElements();
15654 int new_index = table->EntryToIndex(new_entry);
15655 table->set(new_index, *key);
15656 table->set(new_index + kChainOffset, Smi::FromInt(previous_entry));
15657 // and point the bucket to the new entry.
15658 table->set(kHashTableStartIndex + bucket, Smi::FromInt(new_entry));
15659 table->SetNumberOfElements(nof + 1);
15660 return table;
15661 }
15662
15567 15663
15568 template<class Derived, class Iterator, int entrysize> 15664 template<class Derived, class Iterator, int entrysize>
15569 Handle<Derived> OrderedHashTable<Derived, Iterator, entrysize>::Rehash( 15665 Handle<Derived> OrderedHashTable<Derived, Iterator, entrysize>::Rehash(
15570 Handle<Derived> table, int new_capacity) { 15666 Handle<Derived> table, int new_capacity) {
15571 DCHECK(!table->IsObsolete()); 15667 DCHECK(!table->IsObsolete());
15572 15668
15573 Handle<Derived> new_table = 15669 Handle<Derived> new_table =
15574 Allocate(table->GetIsolate(), 15670 Allocate(table->GetIsolate(),
15575 new_capacity, 15671 new_capacity,
15576 table->GetHeap()->InNewSpace(*table) ? NOT_TENURED : TENURED); 15672 table->GetHeap()->InNewSpace(*table) ? NOT_TENURED : TENURED);
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
15619 Handle<OrderedHashSet> table); 15715 Handle<OrderedHashSet> table);
15620 15716
15621 template Handle<OrderedHashSet> 15717 template Handle<OrderedHashSet>
15622 OrderedHashTable<OrderedHashSet, JSSetIterator, 1>::Shrink( 15718 OrderedHashTable<OrderedHashSet, JSSetIterator, 1>::Shrink(
15623 Handle<OrderedHashSet> table); 15719 Handle<OrderedHashSet> table);
15624 15720
15625 template Handle<OrderedHashSet> 15721 template Handle<OrderedHashSet>
15626 OrderedHashTable<OrderedHashSet, JSSetIterator, 1>::Clear( 15722 OrderedHashTable<OrderedHashSet, JSSetIterator, 1>::Clear(
15627 Handle<OrderedHashSet> table); 15723 Handle<OrderedHashSet> table);
15628 15724
15725 template bool OrderedHashTable<OrderedHashSet, JSSetIterator, 1>::HasKey(
15726 Handle<OrderedHashSet> table, Handle<Object> key);
15727
15629 15728
15630 template Handle<OrderedHashMap> 15729 template Handle<OrderedHashMap>
15631 OrderedHashTable<OrderedHashMap, JSMapIterator, 2>::Allocate( 15730 OrderedHashTable<OrderedHashMap, JSMapIterator, 2>::Allocate(
15632 Isolate* isolate, int capacity, PretenureFlag pretenure); 15731 Isolate* isolate, int capacity, PretenureFlag pretenure);
15633 15732
15634 template Handle<OrderedHashMap> 15733 template Handle<OrderedHashMap>
15635 OrderedHashTable<OrderedHashMap, JSMapIterator, 2>::EnsureGrowable( 15734 OrderedHashTable<OrderedHashMap, JSMapIterator, 2>::EnsureGrowable(
15636 Handle<OrderedHashMap> table); 15735 Handle<OrderedHashMap> table);
15637 15736
15638 template Handle<OrderedHashMap> 15737 template Handle<OrderedHashMap>
15639 OrderedHashTable<OrderedHashMap, JSMapIterator, 2>::Shrink( 15738 OrderedHashTable<OrderedHashMap, JSMapIterator, 2>::Shrink(
15640 Handle<OrderedHashMap> table); 15739 Handle<OrderedHashMap> table);
15641 15740
15642 template Handle<OrderedHashMap> 15741 template Handle<OrderedHashMap>
15643 OrderedHashTable<OrderedHashMap, JSMapIterator, 2>::Clear( 15742 OrderedHashTable<OrderedHashMap, JSMapIterator, 2>::Clear(
15644 Handle<OrderedHashMap> table); 15743 Handle<OrderedHashMap> table);
15645 15744
15745 template bool OrderedHashTable<OrderedHashMap, JSMapIterator, 2>::HasKey(
15746 Handle<OrderedHashMap> table, Handle<Object> key);
15747
15646 15748
15647 template<class Derived, class TableType> 15749 template<class Derived, class TableType>
15648 void OrderedHashTableIterator<Derived, TableType>::Transition() { 15750 void OrderedHashTableIterator<Derived, TableType>::Transition() {
15649 DisallowHeapAllocation no_allocation; 15751 DisallowHeapAllocation no_allocation;
15650 TableType* table = TableType::cast(this->table()); 15752 TableType* table = TableType::cast(this->table());
15651 if (!table->IsObsolete()) return; 15753 if (!table->IsObsolete()) return;
15652 15754
15653 int index = Smi::cast(this->index())->value(); 15755 int index = Smi::cast(this->index())->value();
15654 while (table->IsObsolete()) { 15756 while (table->IsObsolete()) {
15655 TableType* next_table = table->NextTable(); 15757 TableType* next_table = table->NextTable();
(...skipping 817 matching lines...) Expand 10 before | Expand all | Expand 10 after
16473 if (cell->value() != *new_value) { 16575 if (cell->value() != *new_value) {
16474 cell->set_value(*new_value); 16576 cell->set_value(*new_value);
16475 Isolate* isolate = cell->GetIsolate(); 16577 Isolate* isolate = cell->GetIsolate();
16476 cell->dependent_code()->DeoptimizeDependentCodeGroup( 16578 cell->dependent_code()->DeoptimizeDependentCodeGroup(
16477 isolate, DependentCode::kPropertyCellChangedGroup); 16579 isolate, DependentCode::kPropertyCellChangedGroup);
16478 } 16580 }
16479 } 16581 }
16480 16582
16481 } // namespace internal 16583 } // namespace internal
16482 } // namespace v8 16584 } // namespace v8
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/runtime/runtime-array.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698