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

Unified Diff: src/objects.cc

Issue 1751643003: [esnext] use map instance_descriptors() when possible in Object.values/entries() (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@ObjectValuesEntriesPerf
Patch Set: re-fix above commit to actually be able to build >:| Created 4 years, 9 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 | « no previous file | no next file » | 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 075a738d2ccf742f635d60e0cb13c49d9219d9fa..540bbb34a13748a4216ceeedfe541106cc0846d9 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -8776,10 +8776,93 @@ MaybeHandle<FixedArray> JSReceiver::GetKeys(Handle<JSReceiver> object,
return keys;
}
+MUST_USE_RESULT Maybe<bool> FastGetOwnValuesOrEntries(
+ Isolate* isolate, Handle<JSReceiver> receiver, bool get_entries,
+ Handle<FixedArray>* result) {
+ Handle<Map> map(JSReceiver::cast(*receiver)->map(), isolate);
+
+ if (!map->IsJSObjectMap()) return Just(false);
+ if (!map->OnlyHasSimpleProperties()) return Just(false);
+
+ Handle<JSObject> object(JSObject::cast(*receiver));
+ if (object->elements() != isolate->heap()->empty_fixed_array()) {
+ return Just(false);
+ }
+
+ Handle<DescriptorArray> descriptors(map->instance_descriptors(), isolate);
+ int number_of_own_descriptors = map->NumberOfOwnDescriptors();
+ Handle<FixedArray> values_or_entries =
+ isolate->factory()->NewFixedArray(number_of_own_descriptors);
+ int count = 0;
+
+ bool stable = true;
+
+ for (int index = 0; index < number_of_own_descriptors; index++) {
+ Handle<Name> next_key(descriptors->GetKey(index), isolate);
+ if (!next_key->IsString()) continue;
+ Handle<Object> prop_value;
+
+ // Directly decode from the descriptor array if |from| did not change shape.
+ if (stable) {
+ PropertyDetails details = descriptors->GetDetails(index);
+ if (!details.IsEnumerable()) continue;
+ if (details.kind() == kData) {
+ if (details.location() == kDescriptor) {
+ prop_value = handle(descriptors->GetValue(index), isolate);
+ } else {
+ Representation representation = details.representation();
+ FieldIndex field_index = FieldIndex::ForDescriptor(*map, index);
+ prop_value =
+ JSObject::FastPropertyAt(object, representation, field_index);
+ }
+ } else {
+ ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, prop_value,
+ Object::GetProperty(object, next_key),
+ Nothing<bool>());
+ stable = object->map() == *map;
+ }
+ } else {
+ // If the map did change, do a slower lookup. We are still guaranteed that
+ // the object has a simple shape, and that the key is a name.
+ LookupIterator it(object, next_key, LookupIterator::OWN_SKIP_INTERCEPTOR);
+ if (!it.IsFound()) continue;
+ DCHECK(it.state() == LookupIterator::DATA ||
+ it.state() == LookupIterator::ACCESSOR);
+ if (!it.IsEnumerable()) continue;
+ ASSIGN_RETURN_ON_EXCEPTION_VALUE(
+ isolate, prop_value, Object::GetProperty(&it), Nothing<bool>());
+ }
+
+ if (get_entries) {
+ Handle<FixedArray> entry_storage =
+ isolate->factory()->NewUninitializedFixedArray(2);
+ entry_storage->set(0, *next_key);
+ entry_storage->set(1, *prop_value);
+ prop_value = isolate->factory()->NewJSArrayWithElements(entry_storage,
+ FAST_ELEMENTS, 2);
+ }
+
+ values_or_entries->set(count, *prop_value);
+ count++;
+ }
+
+ if (count < values_or_entries->length()) values_or_entries->Shrink(count);
+ *result = values_or_entries;
+ return Just(true);
+}
+
MaybeHandle<FixedArray> GetOwnValuesOrEntries(Isolate* isolate,
Handle<JSReceiver> object,
PropertyFilter filter,
bool get_entries) {
+ Handle<FixedArray> values_or_entries;
+ if (filter == ENUMERABLE_STRINGS) {
+ Maybe<bool> fast_values_or_entries = FastGetOwnValuesOrEntries(
+ isolate, object, get_entries, &values_or_entries);
+ if (fast_values_or_entries.IsNothing()) return MaybeHandle<FixedArray>();
+ if (fast_values_or_entries.FromJust()) return values_or_entries;
+ }
+
PropertyFilter key_filter =
static_cast<PropertyFilter>(filter & ~ONLY_ENUMERABLE);
KeyAccumulator accumulator(isolate, OWN_ONLY, key_filter);
@@ -8789,8 +8872,7 @@ MaybeHandle<FixedArray> GetOwnValuesOrEntries(Isolate* isolate,
Handle<FixedArray> keys = accumulator.GetKeys(CONVERT_TO_STRING);
DCHECK(ContainsOnlyValidKeys(keys));
- Handle<FixedArray> values_or_entries =
- isolate->factory()->NewFixedArray(keys->length());
+ values_or_entries = isolate->factory()->NewFixedArray(keys->length());
int length = 0;
for (int i = 0; i < keys->length(); ++i) {
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698