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

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: Removing UnionOfKey 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
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 6462 matching lines...) Expand 10 before | Expand all | Expand 10 after
6473 if (length == 0) { 6473 if (length == 0) {
6474 return Handle<FixedArray>(isolate->heap()->empty_fixed_array()); 6474 return Handle<FixedArray>(isolate->heap()->empty_fixed_array());
6475 } 6475 }
6476 Handle<FixedArray> storage = isolate->factory()->NewFixedArray(length); 6476 Handle<FixedArray> storage = isolate->factory()->NewFixedArray(length);
6477 dictionary->CopyEnumKeysTo(*storage); 6477 dictionary->CopyEnumKeysTo(*storage);
6478 return storage; 6478 return storage;
6479 } 6479 }
6480 } 6480 }
6481 6481
6482 6482
6483 Handle<FixedArray> KeyAccumulator::GetKeys() {
6484 if (keys_.is_null()) {
6485 return isolate_->factory()->empty_fixed_array();
6486 }
6487 keys_->Shrink(GetLength());
6488 return keys_;
6489 }
6490
6491
6492 int KeyAccumulator::GetLength() { return length_; }
Igor Sheludko 2015/09/17 09:55:11 I think it's better to implement simple get/set me
6493
6494
6495 void KeyAccumulator::AddKey(Handle<Object> key) {
6496 if (!set_.is_null()) {
6497 set_ = ObjectHashTable::Put(isolate_, set_, key, key);
6498 }
6499 EnsureCapacity(length_);
6500 keys_->set(length_, *key);
6501 length_++;
6502 }
6503
6504
6505 bool KeyAccumulator::HasKey(Handle<Object> key, int limit) {
6506 if (!set_.is_null()) {
6507 return set_->HasKey(isolate_, key);
6508 }
6509 // simple fallback in case we didn't use the set_ yet
6510 limit = Min(limit, length_);
6511 for (int i = 0; i < limit; i++) {
6512 Object* current = keys_->get(i);
6513 if (current->KeyEquals(*key)) return true;
6514 }
6515 return false;
6516 }
6517
6518
6519 void KeyAccumulator::AddKeys(Handle<FixedArray> array,
6520 FixedArray::KeyFilter filter) {
6521 int add_length = array->length();
6522 if (add_length == 0) return;
6523 if (keys_.is_null() && filter == FixedArray::ALL_KEYS) {
6524 keys_ = array;
6525 length_ = keys_->length();
6526 return;
6527 }
6528 PrepareForComparisons(add_length);
6529 int previous_key_count = length_;
6530 for (int i = 0; i < add_length; i++) {
6531 Handle<Object> current(array->get(i), isolate_);
6532 if (HasKey(current, previous_key_count)) continue;
6533 AddKey(current);
6534 }
6535 }
6536
6537
6538 void KeyAccumulator::AddKeys(Handle<JSObject> array_like,
6539 FixedArray::KeyFilter filter) {
6540 DCHECK(array_like->IsJSArray() || array_like->HasSloppyArgumentsElements());
6541 ElementsAccessor* accessor = array_like->GetElementsAccessor();
6542 accessor->AddElementsToFixedArrayWithAccumulator(array_like, this, filter);
6543 #ifdef ENABLE_SLOW_DCHECKS
6544 if (FLAG_enable_slow_asserts) {
6545 DisallowHeapAllocation no_allocation;
6546 for (int i = 0; i < GetLength(); i++) {
6547 Object* current = keys_->get(i);
6548 DCHECK(current->IsNumber() || current->IsName());
6549 }
6550 }
6551 #endif
6552 }
6553
6554
6555 void KeyAccumulator::PrepareForComparisons(int count) {
6556 // Depending on how many comparisons we do we should switch to the
6557 // hash-table-based checks which have a high one-time overhead
6558 if (!set_.is_null()) return;
6559 // This is an unscientific guess for the threshold when we should
6560 // switch to the hash-table
6561 if (length_ * count < 100) return;
Camillo Bruni 2015/09/14 07:34:04 I tried a bit with different values and 100 turned
6562 set_ = ObjectHashTable::New(isolate_, length_);
Camillo Bruni 2015/09/14 07:34:04 Technically this should be a set but we only have
Igor Sheludko 2015/09/17 09:55:11 Maybe it's worth implementing an ObjectHashSet. It
6563 for (int i = 0; i < length_; i++) {
6564 Handle<Object> value(keys_->get(i), isolate_);
6565 set_ = ObjectHashTable::Put(isolate_, set_, value, value);
6566 }
6567 }
6568
6569
6570 void KeyAccumulator::EnsureCapacity(int capacity) {
6571 if (keys_.is_null() || keys_->length() <= capacity) {
6572 Grow();
6573 }
6574 }
6575
6576
6577 void KeyAccumulator::Grow() {
6578 int capacity = keys_.is_null() ? 16 : keys_->length() * 2 + 16;
6579 Handle<FixedArray> new_keys = isolate_->factory()->NewFixedArray(capacity);
6580 if (keys_.is_null()) {
6581 keys_ = new_keys;
6582 return;
6583 }
6584 int buffer_length = keys_->length();
6585 {
6586 DisallowHeapAllocation no_gc;
6587 WriteBarrierMode mode = new_keys->GetWriteBarrierMode(no_gc);
6588 for (int i = 0; i < buffer_length; i++) {
6589 new_keys->set(i, keys_->get(i), mode);
6590 }
6591 }
6592 keys_ = new_keys;
6593 }
6594
6595
6483 MaybeHandle<FixedArray> JSReceiver::GetKeys(Handle<JSReceiver> object, 6596 MaybeHandle<FixedArray> JSReceiver::GetKeys(Handle<JSReceiver> object,
6484 KeyCollectionType type) { 6597 KeyCollectionType type) {
6485 USE(ContainsOnlyValidKeys); 6598 USE(ContainsOnlyValidKeys);
6486 Isolate* isolate = object->GetIsolate(); 6599 Isolate* isolate = object->GetIsolate();
6487 Handle<FixedArray> content = isolate->factory()->empty_fixed_array(); 6600 KeyAccumulator accumulator(isolate);
6488 Handle<JSFunction> arguments_function( 6601 Handle<JSFunction> arguments_function(
6489 JSFunction::cast(isolate->sloppy_arguments_map()->GetConstructor())); 6602 JSFunction::cast(isolate->sloppy_arguments_map()->GetConstructor()));
6490 6603
6491 PrototypeIterator::WhereToEnd end = type == OWN_ONLY 6604 PrototypeIterator::WhereToEnd end = type == OWN_ONLY
6492 ? PrototypeIterator::END_AT_NON_HIDDEN 6605 ? PrototypeIterator::END_AT_NON_HIDDEN
6493 : PrototypeIterator::END_AT_NULL; 6606 : PrototypeIterator::END_AT_NULL;
6494 // Only collect keys if access is permitted. 6607 // Only collect keys if access is permitted.
6495 for (PrototypeIterator iter(isolate, object, 6608 for (PrototypeIterator iter(isolate, object,
6496 PrototypeIterator::START_AT_RECEIVER); 6609 PrototypeIterator::START_AT_RECEIVER);
6497 !iter.IsAtEnd(end); iter.Advance()) { 6610 !iter.IsAtEnd(end); iter.Advance()) {
6498 if (PrototypeIterator::GetCurrent(iter)->IsJSProxy()) { 6611 if (PrototypeIterator::GetCurrent(iter)->IsJSProxy()) {
6499 Handle<JSProxy> proxy = PrototypeIterator::GetCurrent<JSProxy>(iter); 6612 Handle<JSProxy> proxy = PrototypeIterator::GetCurrent<JSProxy>(iter);
6500 Handle<Object> args[] = { proxy }; 6613 Handle<Object> args[] = { proxy };
6501 Handle<Object> names; 6614 Handle<Object> names;
6502 ASSIGN_RETURN_ON_EXCEPTION( 6615 ASSIGN_RETURN_ON_EXCEPTION(
6503 isolate, names, 6616 isolate, names,
6504 Execution::Call(isolate, 6617 Execution::Call(isolate,
6505 isolate->proxy_enumerate(), 6618 isolate->proxy_enumerate(),
6506 object, 6619 object,
6507 arraysize(args), 6620 arraysize(args),
6508 args), 6621 args),
6509 FixedArray); 6622 FixedArray);
6510 ASSIGN_RETURN_ON_EXCEPTION( 6623 accumulator.AddKeys(Handle<JSObject>::cast(names),
6511 isolate, content, 6624 FixedArray::NON_SYMBOL_KEYS);
6512 FixedArray::AddKeysFromArrayLike(
6513 content, Handle<JSObject>::cast(names)),
6514 FixedArray);
6515 break; 6625 break;
6516 } 6626 }
6517 6627
6518 Handle<JSObject> current = PrototypeIterator::GetCurrent<JSObject>(iter); 6628 Handle<JSObject> current = PrototypeIterator::GetCurrent<JSObject>(iter);
6519 6629
6520 // Check access rights if required. 6630 // Check access rights if required.
6521 if (current->IsAccessCheckNeeded() && !isolate->MayAccess(current)) { 6631 if (current->IsAccessCheckNeeded() && !isolate->MayAccess(current)) {
6522 if (iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN)) { 6632 if (iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN)) {
6523 isolate->ReportFailedAccessCheck(current); 6633 isolate->ReportFailedAccessCheck(current);
6524 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, FixedArray); 6634 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, FixedArray);
6525 } 6635 }
6526 break; 6636 break;
6527 } 6637 }
6528 6638
6529 // Compute the element keys. 6639 // Compute the element keys.
6530 Handle<FixedArray> element_keys = 6640 Handle<FixedArray> element_keys =
6531 isolate->factory()->NewFixedArray(current->NumberOfEnumElements()); 6641 isolate->factory()->NewFixedArray(current->NumberOfEnumElements());
6532 current->GetEnumElementKeys(*element_keys); 6642 current->GetEnumElementKeys(*element_keys);
6533 ASSIGN_RETURN_ON_EXCEPTION( 6643 accumulator.AddKeys(element_keys, FixedArray::ALL_KEYS);
6534 isolate, content, 6644 DCHECK(ContainsOnlyValidKeys(accumulator.GetKeys()));
6535 FixedArray::UnionOfKeys(content, element_keys),
6536 FixedArray);
6537 DCHECK(ContainsOnlyValidKeys(content));
6538 6645
6539 // Add the element keys from the interceptor. 6646 // Add the element keys from the interceptor.
6540 if (current->HasIndexedInterceptor()) { 6647 if (current->HasIndexedInterceptor()) {
6541 Handle<JSObject> result; 6648 Handle<JSObject> result;
6542 if (JSObject::GetKeysForIndexedInterceptor( 6649 if (JSObject::GetKeysForIndexedInterceptor(
6543 current, object).ToHandle(&result)) { 6650 current, object).ToHandle(&result)) {
6544 ASSIGN_RETURN_ON_EXCEPTION( 6651 accumulator.AddKeys(result, FixedArray::ALL_KEYS);
6545 isolate, content,
6546 FixedArray::AddKeysFromArrayLike(content, result),
6547 FixedArray);
6548 } 6652 }
6549 DCHECK(ContainsOnlyValidKeys(content)); 6653 DCHECK(ContainsOnlyValidKeys(accumulator.GetKeys()));
6550 } 6654 }
6551 6655
6552 // We can cache the computed property keys if access checks are 6656 // We can cache the computed property keys if access checks are
6553 // not needed and no interceptors are involved. 6657 // not needed and no interceptors are involved.
6554 // 6658 //
6555 // We do not use the cache if the object has elements and 6659 // We do not use the cache if the object has elements and
6556 // therefore it does not make sense to cache the property names 6660 // therefore it does not make sense to cache the property names
6557 // for arguments objects. Arguments objects will always have 6661 // for arguments objects. Arguments objects will always have
6558 // elements. 6662 // elements.
6559 // Wrapped strings have elements, but don't have an elements 6663 // Wrapped strings have elements, but don't have an elements
6560 // array or dictionary. So the fast inline test for whether to 6664 // array or dictionary. So the fast inline test for whether to
6561 // use the cache says yes, so we should not create a cache. 6665 // use the cache says yes, so we should not create a cache.
6562 bool cache_enum_keys = 6666 bool cache_enum_keys =
6563 ((current->map()->GetConstructor() != *arguments_function) && 6667 ((current->map()->GetConstructor() != *arguments_function) &&
6564 !current->IsJSValue() && !current->IsAccessCheckNeeded() && 6668 !current->IsJSValue() && !current->IsAccessCheckNeeded() &&
6565 !current->HasNamedInterceptor() && !current->HasIndexedInterceptor()); 6669 !current->HasNamedInterceptor() && !current->HasIndexedInterceptor());
6566 // Compute the property keys and cache them if possible. 6670 // Compute the property keys and cache them if possible.
6567 ASSIGN_RETURN_ON_EXCEPTION( 6671
6568 isolate, content, 6672 Handle<FixedArray> enum_keys =
6569 FixedArray::UnionOfKeys( 6673 JSObject::GetEnumPropertyKeys(current, cache_enum_keys);
6570 content, JSObject::GetEnumPropertyKeys(current, cache_enum_keys)), 6674 accumulator.AddKeys(enum_keys, FixedArray::ALL_KEYS);
6571 FixedArray); 6675 DCHECK(ContainsOnlyValidKeys(accumulator.GetKeys()));
6572 DCHECK(ContainsOnlyValidKeys(content));
6573 6676
6574 // Add the non-symbol property keys from the interceptor. 6677 // Add the non-symbol property keys from the interceptor.
6575 if (current->HasNamedInterceptor()) { 6678 if (current->HasNamedInterceptor()) {
6576 Handle<JSObject> result; 6679 Handle<JSObject> result;
6577 if (JSObject::GetKeysForNamedInterceptor( 6680 if (JSObject::GetKeysForNamedInterceptor(
6578 current, object).ToHandle(&result)) { 6681 current, object).ToHandle(&result)) {
6579 ASSIGN_RETURN_ON_EXCEPTION( 6682 accumulator.AddKeys(result, FixedArray::NON_SYMBOL_KEYS);
6580 isolate, content, FixedArray::AddKeysFromArrayLike(
6581 content, result, FixedArray::NON_SYMBOL_KEYS),
6582 FixedArray);
6583 } 6683 }
6584 DCHECK(ContainsOnlyValidKeys(content)); 6684 DCHECK(ContainsOnlyValidKeys(accumulator.GetKeys()));
6585 } 6685 }
6586 } 6686 }
6587 return content; 6687
6688 Handle<FixedArray> keys = accumulator.GetKeys();
6689 DCHECK(ContainsOnlyValidKeys(keys));
6690 return keys;
6588 } 6691 }
6589 6692
6590 6693
6591 bool Map::DictionaryElementsInPrototypeChainOnly() { 6694 bool Map::DictionaryElementsInPrototypeChainOnly() {
6592 if (IsDictionaryElementsKind(elements_kind())) { 6695 if (IsDictionaryElementsKind(elements_kind())) {
6593 return false; 6696 return false;
6594 } 6697 }
6595 6698
6596 for (PrototypeIterator iter(this); !iter.IsAtEnd(); iter.Advance()) { 6699 for (PrototypeIterator iter(this); !iter.IsAtEnd(); iter.Advance()) {
6597 // Be conservative, don't walk into proxies. 6700 // Be conservative, don't walk into proxies.
(...skipping 1480 matching lines...) Expand 10 before | Expand all | Expand 10 after
8078 8181
8079 void FixedArray::Shrink(int new_length) { 8182 void FixedArray::Shrink(int new_length) {
8080 DCHECK(0 <= new_length && new_length <= length()); 8183 DCHECK(0 <= new_length && new_length <= length());
8081 if (new_length < length()) { 8184 if (new_length < length()) {
8082 GetHeap()->RightTrimFixedArray<Heap::CONCURRENT_TO_SWEEPER>( 8185 GetHeap()->RightTrimFixedArray<Heap::CONCURRENT_TO_SWEEPER>(
8083 this, length() - new_length); 8186 this, length() - new_length);
8084 } 8187 }
8085 } 8188 }
8086 8189
8087 8190
8088 MaybeHandle<FixedArray> FixedArray::AddKeysFromArrayLike(
8089 Handle<FixedArray> content, Handle<JSObject> array, KeyFilter filter) {
8090 DCHECK(array->IsJSArray() || array->HasSloppyArgumentsElements());
8091 ElementsAccessor* accessor = array->GetElementsAccessor();
8092 Handle<FixedArray> result =
8093 accessor->AddElementsToFixedArray(array, content, filter);
8094
8095 #ifdef ENABLE_SLOW_DCHECKS
8096 if (FLAG_enable_slow_asserts) {
8097 DisallowHeapAllocation no_allocation;
8098 for (int i = 0; i < result->length(); i++) {
8099 Object* current = result->get(i);
8100 DCHECK(current->IsNumber() || current->IsName());
8101 }
8102 }
8103 #endif
8104 return result;
8105 }
8106
8107
8108 MaybeHandle<FixedArray> FixedArray::UnionOfKeys(Handle<FixedArray> first,
8109 Handle<FixedArray> second) {
8110 if (second->length() == 0) return first;
8111 if (first->length() == 0) return second;
8112 Isolate* isolate = first->GetIsolate();
8113 Handle<FixedArray> result =
8114 isolate->factory()->NewFixedArray(first->length() + second->length());
8115 for (int i = 0; i < first->length(); i++) {
8116 result->set(i, first->get(i));
8117 }
8118 int pos = first->length();
8119 for (int j = 0; j < second->length(); j++) {
8120 Object* current = second->get(j);
8121 int i;
8122 for (i = 0; i < first->length(); i++) {
8123 if (current->KeyEquals(first->get(i))) break;
8124 }
8125 if (i == first->length()) {
8126 result->set(pos++, current);
8127 }
8128 }
8129
8130 result->Shrink(pos);
8131 return result;
8132 }
8133
8134
8135 void FixedArray::CopyTo(int pos, FixedArray* dest, int dest_pos, int len) { 8191 void FixedArray::CopyTo(int pos, FixedArray* dest, int dest_pos, int len) {
8136 DisallowHeapAllocation no_gc; 8192 DisallowHeapAllocation no_gc;
8137 WriteBarrierMode mode = dest->GetWriteBarrierMode(no_gc); 8193 WriteBarrierMode mode = dest->GetWriteBarrierMode(no_gc);
8138 for (int index = 0; index < len; index++) { 8194 for (int index = 0; index < len; index++) {
8139 dest->set(dest_pos+index, get(pos+index), mode); 8195 dest->set(dest_pos+index, get(pos+index), mode);
8140 } 8196 }
8141 } 8197 }
8142 8198
8143 8199
8144 #ifdef DEBUG 8200 #ifdef DEBUG
(...skipping 7075 matching lines...) Expand 10 before | Expand all | Expand 10 after
15220 e = PropertyCell::cast(e)->value(); 15276 e = PropertyCell::cast(e)->value();
15221 } 15277 }
15222 if (e == value) return k; 15278 if (e == value) return k;
15223 } 15279 }
15224 } 15280 }
15225 Heap* heap = Dictionary::GetHeap(); 15281 Heap* heap = Dictionary::GetHeap();
15226 return heap->undefined_value(); 15282 return heap->undefined_value();
15227 } 15283 }
15228 15284
15229 15285
15286 bool ObjectHashTable::HasKey(Isolate* isolate, Handle<Object> key) {
15287 DisallowHeapAllocation no_gc;
15288 DCHECK(IsKey(*key));
15289
15290 // If the object does not have an identity hash, it was never used as a key.
15291 Object* hash = key->GetHash();
15292 if (hash->IsUndefined()) return false;
15293
15294 int entry = FindEntry(isolate, key, Smi::cast(hash)->value());
15295 return entry != kNotFound;
15296 }
15297
15298
15230 Object* ObjectHashTable::Lookup(Isolate* isolate, Handle<Object> key, 15299 Object* ObjectHashTable::Lookup(Isolate* isolate, Handle<Object> key,
15231 int32_t hash) { 15300 int32_t hash) {
15232 DisallowHeapAllocation no_gc; 15301 DisallowHeapAllocation no_gc;
15233 DCHECK(IsKey(*key)); 15302 DCHECK(IsKey(*key));
15234 15303
15235 int entry = FindEntry(isolate, key, hash); 15304 int entry = FindEntry(isolate, key, hash);
15236 if (entry == kNotFound) return isolate->heap()->the_hole_value(); 15305 if (entry == kNotFound) return isolate->heap()->the_hole_value();
15237 return get(EntryToIndex(entry) + 1); 15306 return get(EntryToIndex(entry) + 1);
15238 } 15307 }
15239 15308
(...skipping 14 matching lines...) Expand all
15254 15323
15255 15324
15256 Object* ObjectHashTable::Lookup(Handle<Object> key, int32_t hash) { 15325 Object* ObjectHashTable::Lookup(Handle<Object> key, int32_t hash) {
15257 return Lookup(GetIsolate(), key, hash); 15326 return Lookup(GetIsolate(), key, hash);
15258 } 15327 }
15259 15328
15260 15329
15261 Handle<ObjectHashTable> ObjectHashTable::Put(Handle<ObjectHashTable> table, 15330 Handle<ObjectHashTable> ObjectHashTable::Put(Handle<ObjectHashTable> table,
15262 Handle<Object> key, 15331 Handle<Object> key,
15263 Handle<Object> value) { 15332 Handle<Object> value) {
15333 return Put(table->GetIsolate(), table, key, value);
15334 }
15335
15336
15337 Handle<ObjectHashTable> ObjectHashTable::Put(Isolate* isolate,
15338 Handle<ObjectHashTable> table,
15339 Handle<Object> key,
15340 Handle<Object> value) {
15264 DCHECK(table->IsKey(*key)); 15341 DCHECK(table->IsKey(*key));
15265 DCHECK(!value->IsTheHole()); 15342 DCHECK(!value->IsTheHole());
15266 15343
15267 Isolate* isolate = table->GetIsolate();
15268 // Make sure the key object has an identity hash code. 15344 // Make sure the key object has an identity hash code.
15269 int32_t hash = Object::GetOrCreateHash(isolate, key)->value(); 15345 int32_t hash = Object::GetOrCreateHash(isolate, key)->value();
15270 15346
15271 return Put(table, key, value, hash); 15347 return Put(isolate, table, key, value, hash);
15272 } 15348 }
15273 15349
15274 15350
15275 Handle<ObjectHashTable> ObjectHashTable::Put(Handle<ObjectHashTable> table, 15351 Handle<ObjectHashTable> ObjectHashTable::Put(Handle<ObjectHashTable> table,
15276 Handle<Object> key, 15352 Handle<Object> key,
15277 Handle<Object> value, 15353 Handle<Object> value,
15278 int32_t hash) { 15354 int32_t hash) {
15355 return Put(table->GetIsolate(), table, key, value, hash);
15356 }
15357
15358
15359 Handle<ObjectHashTable> ObjectHashTable::Put(Isolate* isolate,
15360 Handle<ObjectHashTable> table,
15361 Handle<Object> key,
15362 Handle<Object> value,
15363 int32_t hash) {
15279 DCHECK(table->IsKey(*key)); 15364 DCHECK(table->IsKey(*key));
15280 DCHECK(!value->IsTheHole()); 15365 DCHECK(!value->IsTheHole());
15281 15366
15282 Isolate* isolate = table->GetIsolate();
15283
15284 int entry = table->FindEntry(isolate, key, hash); 15367 int entry = table->FindEntry(isolate, key, hash);
15285 15368
15286 // Key is already in table, just overwrite value. 15369 // Key is already in table, just overwrite value.
15287 if (entry != kNotFound) { 15370 if (entry != kNotFound) {
15288 table->set(EntryToIndex(entry) + 1, *value); 15371 table->set(EntryToIndex(entry) + 1, *value);
15289 return table; 15372 return table;
15290 } 15373 }
15291 15374
15292 // Check whether the hash table should be extended. 15375 // Check whether the hash table should be extended.
15293 table = EnsureCapacity(table, 1, key); 15376 table = EnsureCapacity(table, 1, key);
(...skipping 1058 matching lines...) Expand 10 before | Expand all | Expand 10 after
16352 if (cell->value() != *new_value) { 16435 if (cell->value() != *new_value) {
16353 cell->set_value(*new_value); 16436 cell->set_value(*new_value);
16354 Isolate* isolate = cell->GetIsolate(); 16437 Isolate* isolate = cell->GetIsolate();
16355 cell->dependent_code()->DeoptimizeDependentCodeGroup( 16438 cell->dependent_code()->DeoptimizeDependentCodeGroup(
16356 isolate, DependentCode::kPropertyCellChangedGroup); 16439 isolate, DependentCode::kPropertyCellChangedGroup);
16357 } 16440 }
16358 } 16441 }
16359 16442
16360 } // namespace internal 16443 } // namespace internal
16361 } // namespace v8 16444 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698