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

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