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

Unified Diff: src/objects.cc

Issue 1619803003: Revert of [runtime] Do not use the enum-cache for non-prototype objects. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 11 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/objects.h ('k') | test/mjsunit/regress/regress-705-shadowed_properties.js » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/objects.cc
diff --git a/src/objects.cc b/src/objects.cc
index c0a0c08bc74d07b4e4308368fd8b543e568561d1..326b6f169ceb29b9c6364866bb21775fcbf73d3d 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -8098,8 +8098,8 @@
PropertyFilter filter = static_cast<PropertyFilter>(
ONLY_WRITABLE | ONLY_ENUMERABLE | ONLY_CONFIGURABLE);
KeyAccumulator accumulator(isolate, filter);
- accumulator.Prepare();
- copy->CollectOwnPropertyKeys(&accumulator, filter);
+ accumulator.NextPrototype();
+ copy->CollectOwnPropertyNames(&accumulator, filter);
Handle<FixedArray> names = accumulator.GetKeys();
for (int i = 0; i < names->length(); i++) {
DCHECK(names->get(i)->IsName());
@@ -8438,9 +8438,10 @@
namespace {
-Handle<FixedArray> GetFastEnumPropertyKeys(Isolate* isolate, JSObject* object,
+Handle<FixedArray> GetFastEnumPropertyKeys(Isolate* isolate,
+ Handle<JSObject> object,
bool cache_enum_length) {
- Handle<Map> map(object->map(), isolate);
+ Handle<Map> map(object->map());
Handle<DescriptorArray> descs =
Handle<DescriptorArray>(map->instance_descriptors(), isolate);
int own_property_count = map->EnumLength();
@@ -8514,13 +8515,30 @@
} // namespace
-Handle<FixedArray> JSObject::GetOwnEnumPropertyKeys(Handle<JSObject> object,
- bool cache_enum_length) {
- PropertyFilter filter = PropertyFilter::ENUMERABLE_STRINGS;
- KeyAccumulator keys(object->GetIsolate(), filter);
- keys.Prepare();
- object->CollectOwnPropertyKeys(&keys, filter);
- return keys.GetKeys();
+Handle<FixedArray> JSObject::GetEnumPropertyKeys(Handle<JSObject> object,
+ bool cache_enum_length) {
+ Isolate* isolate = object->GetIsolate();
+ if (object->HasFastProperties()) {
+ return GetFastEnumPropertyKeys(isolate, object, cache_enum_length);
+ } else if (object->IsJSGlobalObject()) {
+ Handle<GlobalDictionary> dictionary(object->global_dictionary());
+ int length = dictionary->NumberOfEnumElements();
+ if (length == 0) {
+ return Handle<FixedArray>(isolate->heap()->empty_fixed_array());
+ }
+ Handle<FixedArray> storage = isolate->factory()->NewFixedArray(length);
+ dictionary->CopyEnumKeysTo(*storage);
+ return storage;
+ } else {
+ Handle<NameDictionary> dictionary(object->property_dictionary());
+ int length = dictionary->NumberOfEnumElements();
+ if (length == 0) {
+ return Handle<FixedArray>(isolate->heap()->empty_fixed_array());
+ }
+ Handle<FixedArray> storage = isolate->factory()->NewFixedArray(length);
+ dictionary->CopyEnumKeysTo(*storage);
+ return storage;
+ }
}
@@ -8604,7 +8622,30 @@
isolate, receiver, object, *filter, accumulator);
MAYBE_RETURN(success, Nothing<bool>());
- object->CollectOwnPropertyKeys(accumulator, *filter, type);
+ if (*filter == ENUMERABLE_STRINGS) {
+ // We can cache the computed property keys if access checks are
+ // not needed and no interceptors are involved.
+ //
+ // We do not use the cache if the object has elements and
+ // therefore it does not make sense to cache the property names
+ // for arguments objects. Arguments objects will always have
+ // elements.
+ // Wrapped strings have elements, but don't have an elements
+ // array or dictionary. So the fast inline test for whether to
+ // use the cache says yes, so we should not create a cache.
+ Handle<JSFunction> arguments_function(
+ JSFunction::cast(isolate->sloppy_arguments_map()->GetConstructor()));
+ bool cache_enum_length =
+ ((object->map()->GetConstructor() != *arguments_function) &&
+ !object->IsJSValue() && !object->IsAccessCheckNeeded() &&
+ !object->HasNamedInterceptor() && !object->HasIndexedInterceptor());
+ // Compute the property keys and cache them if possible.
+ Handle<FixedArray> enum_keys =
+ JSObject::GetEnumPropertyKeys(object, cache_enum_length);
+ accumulator->AddKeys(enum_keys);
+ } else {
+ object->CollectOwnPropertyNames(accumulator, *filter);
+ }
// Add the property keys from the interceptor.
success = GetKeysFromInterceptor<v8::GenericNamedPropertyEnumeratorCallback,
@@ -16340,74 +16381,24 @@
}
-namespace {
-
-void CollectEnumCacheTo(KeyAccumulator* keys, JSObject* object) {
- // We can cache the computed property keys if access checks are
- // not needed and no interceptors are involved.
- //
- // We do not use the cache if the object has elements and
- // therefore it does not make sense to cache the property names
- // for arguments objects. Arguments objects will always have
- // elements.
- // Wrapped strings have elements, but don't have an elements
- // array or dictionary. So the fast inline test for whether to
- // use the cache says yes, so we should not create a cache.
- Isolate* isolate = keys->isolate();
- Handle<JSFunction> arguments_function(
- JSFunction::cast(isolate->sloppy_arguments_map()->GetConstructor()));
- bool cache_enum_length =
- ((object->map()->GetConstructor() != *arguments_function) &&
- !object->IsJSValue() && !object->IsAccessCheckNeeded() &&
- !object->HasNamedInterceptor() && !object->HasIndexedInterceptor());
- // Compute the property keys and cache them if possible.
- Handle<FixedArray> enum_keys =
- GetFastEnumPropertyKeys(isolate, object, cache_enum_length);
- keys->AddKeys(enum_keys);
-}
-
-} // namespace
-
-
-void JSObject::CollectFastPropertyKeysTo(KeyAccumulator* keys,
- PropertyFilter filter,
- JSReceiver::KeyCollectionType type) {
- // Avoid using the enum cache if we have to walk the prototype chain due
- // to shadowing properties.
- if (filter == ENUMERABLE_STRINGS && type == JSReceiver::OWN_ONLY) {
- CollectEnumCacheTo(keys, this);
- return;
- }
-
- int real_size = map()->NumberOfOwnDescriptors();
- Handle<DescriptorArray> descs(map()->instance_descriptors());
- for (int i = 0; i < real_size; i++) {
- PropertyDetails details = descs->GetDetails(i);
- if ((details.attributes() & filter) != 0) {
- if (type == JSReceiver::OWN_ONLY) continue;
- if (details.attributes() & DONT_ENUM) {
- keys->HideKey(descs->GetKey(i));
+void JSObject::CollectOwnPropertyNames(KeyAccumulator* keys,
+ PropertyFilter filter) {
+ if (HasFastProperties()) {
+ int real_size = map()->NumberOfOwnDescriptors();
+ Handle<DescriptorArray> descs(map()->instance_descriptors());
+ for (int i = 0; i < real_size; i++) {
+ PropertyDetails details = descs->GetDetails(i);
+ if ((details.attributes() & filter) != 0) continue;
+ if (filter & ONLY_ALL_CAN_READ) {
+ if (details.kind() != kAccessor) continue;
+ Object* accessors = descs->GetValue(i);
+ if (!accessors->IsAccessorInfo()) continue;
+ if (!AccessorInfo::cast(accessors)->all_can_read()) continue;
}
- continue;
- }
- if (filter & ONLY_ALL_CAN_READ) {
- if (details.kind() != kAccessor) continue;
- Object* accessors = descs->GetValue(i);
- if (!accessors->IsAccessorInfo()) continue;
- if (!AccessorInfo::cast(accessors)->all_can_read()) continue;
- }
- Name* key = descs->GetKey(i);
- if (key->FilterKey(filter)) continue;
- keys->AddKey(key);
- }
-}
-
-
-void JSObject::CollectOwnPropertyKeys(KeyAccumulator* keys,
- PropertyFilter filter,
- JSReceiver::KeyCollectionType type) {
- if (HasFastProperties()) {
- CollectFastPropertyKeysTo(keys, filter, type);
+ Name* key = descs->GetKey(i);
+ if (key->FilterKey(filter)) continue;
+ keys->AddKey(key);
+ }
} else if (IsJSGlobalObject()) {
GlobalDictionary::CollectKeysTo(handle(global_dictionary()), keys, filter);
} else {
@@ -18441,27 +18432,20 @@
void Dictionary<Derived, Shape, Key>::CollectKeysTo(
Handle<Dictionary<Derived, Shape, Key> > dictionary, KeyAccumulator* keys,
PropertyFilter filter) {
- if (dictionary->NumberOfElements() == 0) return;
int capacity = dictionary->Capacity();
Handle<FixedArray> array =
keys->isolate()->factory()->NewFixedArray(dictionary->NumberOfElements());
int array_size = 0;
- std::vector<int> hidden_key_indices;
{
DisallowHeapAllocation no_gc;
Dictionary<Derived, Shape, Key>* raw_dict = *dictionary;
for (int i = 0; i < capacity; i++) {
- Object* key = raw_dict->KeyAt(i);
- if (!raw_dict->IsKey(key) || key->FilterKey(filter)) continue;
+ Object* k = raw_dict->KeyAt(i);
+ if (!raw_dict->IsKey(k) || k->FilterKey(filter)) continue;
if (raw_dict->IsDeleted(i)) continue;
PropertyDetails details = raw_dict->DetailsAt(i);
- if ((details.attributes() & filter) != 0) {
- if (details.attributes() & DONT_ENUM) {
- hidden_key_indices.push_back(i);
- }
- continue;
- }
+ if ((details.attributes() & filter) != 0) continue;
if (filter & ONLY_ALL_CAN_READ) {
if (details.kind() != kAccessor) continue;
Object* accessors = raw_dict->ValueAt(i);
@@ -18478,9 +18462,7 @@
Smi** start = reinterpret_cast<Smi**>(array->GetFirstElementAddress());
std::sort(start, start + array_size, cmp);
}
- for (uint32_t i = 0; i < hidden_key_indices.size(); i++) {
- keys->HideKey(dictionary->KeyAt(hidden_key_indices[i]));
- }
+
for (int i = 0; i < array_size; i++) {
int index = Smi::cast(array->get(i))->value();
keys->AddKey(dictionary->KeyAt(index));
« no previous file with comments | « src/objects.h ('k') | test/mjsunit/regress/regress-705-shadowed_properties.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698