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

Side by Side Diff: src/objects.cc

Issue 1371673004: Revert of JSObject::GetEnumProperty cleanup (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 2 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') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/objects.h" 5 #include "src/objects.h"
6 6
7 #include <cmath> 7 #include <cmath>
8 #include <iomanip> 8 #include <iomanip>
9 #include <sstream> 9 #include <sstream>
10 10
(...skipping 6550 matching lines...) Expand 10 before | Expand all | Expand 10 after
6561 DCHECK(array->length() >= length); 6561 DCHECK(array->length() >= length);
6562 if (array->length() == length) return array; 6562 if (array->length() == length) return array;
6563 6563
6564 Handle<FixedArray> new_array = 6564 Handle<FixedArray> new_array =
6565 array->GetIsolate()->factory()->NewFixedArray(length); 6565 array->GetIsolate()->factory()->NewFixedArray(length);
6566 for (int i = 0; i < length; ++i) new_array->set(i, array->get(i)); 6566 for (int i = 0; i < length; ++i) new_array->set(i, array->get(i));
6567 return new_array; 6567 return new_array;
6568 } 6568 }
6569 6569
6570 6570
6571 namespace { 6571 Handle<FixedArray> JSObject::GetEnumPropertyKeys(Handle<JSObject> object,
6572 bool cache_result) {
6573 Isolate* isolate = object->GetIsolate();
6574 if (object->HasFastProperties()) {
6575 int own_property_count = object->map()->EnumLength();
6576 // If the enum length of the given map is set to kInvalidEnumCache, this
6577 // means that the map itself has never used the present enum cache. The
6578 // first step to using the cache is to set the enum length of the map by
6579 // counting the number of own descriptors that are not DONT_ENUM or
6580 // SYMBOLIC.
6581 if (own_property_count == kInvalidEnumCacheSentinel) {
6582 own_property_count = object->map()->NumberOfDescribedProperties(
6583 OWN_DESCRIPTORS, DONT_SHOW);
6584 } else {
6585 DCHECK(own_property_count == object->map()->NumberOfDescribedProperties(
6586 OWN_DESCRIPTORS, DONT_SHOW));
6587 }
6572 6588
6573 Handle<FixedArray> GetFastEnumPropertyKeys(Isolate* isolate, 6589 if (object->map()->instance_descriptors()->HasEnumCache()) {
6574 Handle<JSObject> object, 6590 DescriptorArray* desc = object->map()->instance_descriptors();
6575 bool cache_enum_length) { 6591 Handle<FixedArray> keys(desc->GetEnumCache(), isolate);
6576 Handle<Map> map(object->map());
6577 Handle<DescriptorArray> descs =
6578 Handle<DescriptorArray>(map->instance_descriptors(), isolate);
6579 int own_property_count = map->EnumLength();
6580 // If the enum length of the given map is set to kInvalidEnumCache, this
6581 // means that the map itself has never used the present enum cache. The
6582 // first step to using the cache is to set the enum length of the map by
6583 // counting the number of own descriptors that are not DONT_ENUM or
6584 // SYMBOLIC.
6585 if (own_property_count == kInvalidEnumCacheSentinel) {
6586 own_property_count =
6587 map->NumberOfDescribedProperties(OWN_DESCRIPTORS, DONT_SHOW);
6588 } else {
6589 DCHECK(own_property_count ==
6590 map->NumberOfDescribedProperties(OWN_DESCRIPTORS, DONT_SHOW));
6591 }
6592 6592
6593 if (descs->HasEnumCache()) { 6593 // In case the number of properties required in the enum are actually
6594 Handle<FixedArray> keys(descs->GetEnumCache(), isolate); 6594 // present, we can reuse the enum cache. Otherwise, this means that the
6595 // In case the number of properties required in the enum are actually 6595 // enum cache was generated for a previous (smaller) version of the
6596 // present, we can reuse the enum cache. Otherwise, this means that the 6596 // Descriptor Array. In that case we regenerate the enum cache.
6597 // enum cache was generated for a previous (smaller) version of the 6597 if (own_property_count <= keys->length()) {
6598 // Descriptor Array. In that case we regenerate the enum cache. 6598 if (cache_result) object->map()->SetEnumLength(own_property_count);
6599 if (own_property_count <= keys->length()) { 6599 isolate->counters()->enum_cache_hits()->Increment();
6600 isolate->counters()->enum_cache_hits()->Increment(); 6600 return ReduceFixedArrayTo(keys, own_property_count);
6601 if (cache_enum_length) map->SetEnumLength(own_property_count);
6602 return ReduceFixedArrayTo(keys, own_property_count);
6603 }
6604 }
6605
6606 if (descs->IsEmpty()) {
6607 isolate->counters()->enum_cache_hits()->Increment();
6608 if (cache_enum_length) map->SetEnumLength(0);
6609 return isolate->factory()->empty_fixed_array();
6610 }
6611
6612 isolate->counters()->enum_cache_misses()->Increment();
6613
6614 Handle<FixedArray> storage =
6615 isolate->factory()->NewFixedArray(own_property_count);
6616 Handle<FixedArray> indices =
6617 isolate->factory()->NewFixedArray(own_property_count);
6618
6619 int size = map->NumberOfOwnDescriptors();
6620 int index = 0;
6621
6622 for (int i = 0; i < size; i++) {
6623 PropertyDetails details = descs->GetDetails(i);
6624 Object* key = descs->GetKey(i);
6625 if (details.IsDontEnum() || key->IsSymbol()) continue;
6626 storage->set(index, key);
6627 if (!indices.is_null()) {
6628 if (details.type() != DATA) {
6629 indices = Handle<FixedArray>();
6630 } else {
6631 FieldIndex field_index = FieldIndex::ForDescriptor(*map, i);
6632 int load_by_field_index = field_index.GetLoadByFieldIndex();
6633 indices->set(index, Smi::FromInt(load_by_field_index));
6634 } 6601 }
6635 } 6602 }
6636 index++;
6637 }
6638 DCHECK(index == storage->length());
6639 6603
6640 descs->SetEnumCache(isolate, storage, indices); 6604 Handle<Map> map(object->map());
6641 if (cache_enum_length) {
6642 map->SetEnumLength(own_property_count);
6643 }
6644 return storage;
6645 }
6646 6605
6647 } // namespace 6606 if (map->instance_descriptors()->IsEmpty()) {
6607 isolate->counters()->enum_cache_hits()->Increment();
6608 if (cache_result) map->SetEnumLength(0);
6609 return isolate->factory()->empty_fixed_array();
6610 }
6648 6611
6612 isolate->counters()->enum_cache_misses()->Increment();
6649 6613
6650 Handle<FixedArray> JSObject::GetEnumPropertyKeys(Handle<JSObject> object, 6614 Handle<FixedArray> storage = isolate->factory()->NewFixedArray(
6651 bool cache_enum_length) { 6615 own_property_count);
6652 Isolate* isolate = object->GetIsolate(); 6616 Handle<FixedArray> indices = isolate->factory()->NewFixedArray(
6653 if (object->HasFastProperties()) { 6617 own_property_count);
6654 return GetFastEnumPropertyKeys(isolate, object, cache_enum_length); 6618
6619 Handle<DescriptorArray> descs =
6620 Handle<DescriptorArray>(object->map()->instance_descriptors(), isolate);
6621
6622 int size = map->NumberOfOwnDescriptors();
6623 int index = 0;
6624
6625 for (int i = 0; i < size; i++) {
6626 PropertyDetails details = descs->GetDetails(i);
6627 Object* key = descs->GetKey(i);
6628 if (!(details.IsDontEnum() || key->IsSymbol())) {
6629 storage->set(index, key);
6630 if (!indices.is_null()) {
6631 if (details.type() != DATA) {
6632 indices = Handle<FixedArray>();
6633 } else {
6634 FieldIndex field_index = FieldIndex::ForDescriptor(*map, i);
6635 int load_by_field_index = field_index.GetLoadByFieldIndex();
6636 indices->set(index, Smi::FromInt(load_by_field_index));
6637 }
6638 }
6639 index++;
6640 }
6641 }
6642 DCHECK(index == storage->length());
6643
6644 Handle<FixedArray> bridge_storage =
6645 isolate->factory()->NewFixedArray(
6646 DescriptorArray::kEnumCacheBridgeLength);
6647 DescriptorArray* desc = object->map()->instance_descriptors();
6648 desc->SetEnumCache(*bridge_storage,
6649 *storage,
6650 indices.is_null() ? Object::cast(Smi::FromInt(0))
6651 : Object::cast(*indices));
6652 if (cache_result) {
6653 object->map()->SetEnumLength(own_property_count);
6654 }
6655 return storage;
6655 } else if (object->IsGlobalObject()) { 6656 } else if (object->IsGlobalObject()) {
6656 Handle<GlobalDictionary> dictionary(object->global_dictionary()); 6657 Handle<GlobalDictionary> dictionary(object->global_dictionary());
6657 int length = dictionary->NumberOfEnumElements(); 6658 int length = dictionary->NumberOfEnumElements();
6658 if (length == 0) { 6659 if (length == 0) {
6659 return Handle<FixedArray>(isolate->heap()->empty_fixed_array()); 6660 return Handle<FixedArray>(isolate->heap()->empty_fixed_array());
6660 } 6661 }
6661 Handle<FixedArray> storage = isolate->factory()->NewFixedArray(length); 6662 Handle<FixedArray> storage = isolate->factory()->NewFixedArray(length);
6662 dictionary->CopyEnumKeysTo(*storage); 6663 dictionary->CopyEnumKeysTo(*storage);
6663 return storage; 6664 return storage;
6664 } else { 6665 } else {
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
6848 // We can cache the computed property keys if access checks are 6849 // We can cache the computed property keys if access checks are
6849 // not needed and no interceptors are involved. 6850 // not needed and no interceptors are involved.
6850 // 6851 //
6851 // We do not use the cache if the object has elements and 6852 // We do not use the cache if the object has elements and
6852 // therefore it does not make sense to cache the property names 6853 // therefore it does not make sense to cache the property names
6853 // for arguments objects. Arguments objects will always have 6854 // for arguments objects. Arguments objects will always have
6854 // elements. 6855 // elements.
6855 // Wrapped strings have elements, but don't have an elements 6856 // Wrapped strings have elements, but don't have an elements
6856 // array or dictionary. So the fast inline test for whether to 6857 // array or dictionary. So the fast inline test for whether to
6857 // use the cache says yes, so we should not create a cache. 6858 // use the cache says yes, so we should not create a cache.
6858 bool cache_enum_length = 6859 bool cache_enum_keys =
6859 ((current->map()->GetConstructor() != *arguments_function) && 6860 ((current->map()->GetConstructor() != *arguments_function) &&
6860 !current->IsJSValue() && !current->IsAccessCheckNeeded() && 6861 !current->IsJSValue() && !current->IsAccessCheckNeeded() &&
6861 !current->HasNamedInterceptor() && !current->HasIndexedInterceptor()); 6862 !current->HasNamedInterceptor() && !current->HasIndexedInterceptor());
6862 // Compute the property keys and cache them if possible. 6863 // Compute the property keys and cache them if possible.
6863 6864
6864 Handle<FixedArray> enum_keys = 6865 Handle<FixedArray> enum_keys =
6865 JSObject::GetEnumPropertyKeys(current, cache_enum_length); 6866 JSObject::GetEnumPropertyKeys(current, cache_enum_keys);
6866 accumulator.AddKeys(enum_keys, FixedArray::ALL_KEYS); 6867 accumulator.AddKeys(enum_keys, FixedArray::ALL_KEYS);
6867 DCHECK(ContainsOnlyValidKeys(accumulator.GetKeys())); 6868 DCHECK(ContainsOnlyValidKeys(accumulator.GetKeys()));
6868 6869
6869 // Add the non-symbol property keys from the interceptor. 6870 // Add the non-symbol property keys from the interceptor.
6870 if (current->HasNamedInterceptor()) { 6871 if (current->HasNamedInterceptor()) {
6871 Handle<JSObject> result; 6872 Handle<JSObject> result;
6872 if (JSObject::GetKeysForNamedInterceptor( 6873 if (JSObject::GetKeysForNamedInterceptor(
6873 current, object).ToHandle(&result)) { 6874 current, object).ToHandle(&result)) {
6874 accumulator.AddKeys(result, FixedArray::NON_SYMBOL_KEYS); 6875 accumulator.AddKeys(result, FixedArray::NON_SYMBOL_KEYS);
6875 } 6876 }
(...skipping 1732 matching lines...) Expand 10 before | Expand all | Expand 10 after
8608 set(kEnumCacheIndex, Smi::FromInt(0)); 8609 set(kEnumCacheIndex, Smi::FromInt(0));
8609 } 8610 }
8610 8611
8611 8612
8612 void DescriptorArray::Replace(int index, Descriptor* descriptor) { 8613 void DescriptorArray::Replace(int index, Descriptor* descriptor) {
8613 descriptor->SetSortedKeyIndex(GetSortedKeyIndex(index)); 8614 descriptor->SetSortedKeyIndex(GetSortedKeyIndex(index));
8614 Set(index, descriptor); 8615 Set(index, descriptor);
8615 } 8616 }
8616 8617
8617 8618
8618 void DescriptorArray::SetEnumCache(Isolate* isolate, 8619 void DescriptorArray::SetEnumCache(FixedArray* bridge_storage,
8619 Handle<FixedArray> new_cache, 8620 FixedArray* new_cache,
8620 Handle<FixedArray> new_index_cache) { 8621 Object* new_index_cache) {
8622 DCHECK(bridge_storage->length() >= kEnumCacheBridgeLength);
8623 DCHECK(new_index_cache->IsSmi() || new_index_cache->IsFixedArray());
8621 DCHECK(!IsEmpty()); 8624 DCHECK(!IsEmpty());
8622 FixedArray* bridge_storage; 8625 DCHECK(!HasEnumCache() || new_cache->length() > GetEnumCache()->length());
8623 bool needs_new_enum_cache = !HasEnumCache(); 8626 FixedArray::cast(bridge_storage)->
8624 if (needs_new_enum_cache) { 8627 set(kEnumCacheBridgeCacheIndex, new_cache);
8625 bridge_storage = *isolate->factory()->NewFixedArray( 8628 FixedArray::cast(bridge_storage)->
8626 DescriptorArray::kEnumCacheBridgeLength); 8629 set(kEnumCacheBridgeIndicesCacheIndex, new_index_cache);
8627 } else { 8630 set(kEnumCacheIndex, bridge_storage);
8628 bridge_storage = FixedArray::cast(get(kEnumCacheIndex));
8629 }
8630 bridge_storage->set(kEnumCacheBridgeCacheIndex, *new_cache);
8631 bridge_storage->set(kEnumCacheBridgeIndicesCacheIndex,
8632 new_index_cache.is_null() ? Object::cast(Smi::FromInt(0))
8633 : *new_index_cache);
8634 if (needs_new_enum_cache) {
8635 set(kEnumCacheIndex, bridge_storage);
8636 }
8637 } 8631 }
8638 8632
8639 8633
8640 void DescriptorArray::CopyFrom(int index, DescriptorArray* src, 8634 void DescriptorArray::CopyFrom(int index, DescriptorArray* src,
8641 const WhitenessWitness& witness) { 8635 const WhitenessWitness& witness) {
8642 Object* value = src->GetValue(index); 8636 Object* value = src->GetValue(index);
8643 PropertyDetails details = src->GetDetails(index); 8637 PropertyDetails details = src->GetDetails(index);
8644 Descriptor desc(handle(src->GetKey(index)), 8638 Descriptor desc(handle(src->GetKey(index)),
8645 handle(value, src->GetIsolate()), 8639 handle(value, src->GetIsolate()),
8646 details); 8640 details);
(...skipping 8104 matching lines...) Expand 10 before | Expand all | Expand 10 after
16751 if (cell->value() != *new_value) { 16745 if (cell->value() != *new_value) {
16752 cell->set_value(*new_value); 16746 cell->set_value(*new_value);
16753 Isolate* isolate = cell->GetIsolate(); 16747 Isolate* isolate = cell->GetIsolate();
16754 cell->dependent_code()->DeoptimizeDependentCodeGroup( 16748 cell->dependent_code()->DeoptimizeDependentCodeGroup(
16755 isolate, DependentCode::kPropertyCellChangedGroup); 16749 isolate, DependentCode::kPropertyCellChangedGroup);
16756 } 16750 }
16757 } 16751 }
16758 16752
16759 } // namespace internal 16753 } // namespace internal
16760 } // namespace v8 16754 } // namespace v8
OLDNEW
« no previous file with comments | « src/objects.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698