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/keys.cc

Issue 1831783002: [keys] adding fast-path for dict-mode objects with own keys only (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: simplifying simple property test Created 4 years, 8 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 | « no previous file | src/objects.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/keys.h" 5 #include "src/keys.h"
6 6
7 #include "src/elements.h" 7 #include "src/elements.h"
8 #include "src/factory.h" 8 #include "src/factory.h"
9 #include "src/isolate-inl.h" 9 #include "src/isolate-inl.h"
10 #include "src/objects-inl.h" 10 #include "src/objects-inl.h"
(...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after
356 USE(first_non_empty_prototype); 356 USE(first_non_empty_prototype);
357 return; 357 return;
358 } 358 }
359 DCHECK(has_empty_prototype_); 359 DCHECK(has_empty_prototype_);
360 is_receiver_simple_enum_ = 360 is_receiver_simple_enum_ =
361 receiver_->map()->EnumLength() != kInvalidEnumCacheSentinel && 361 receiver_->map()->EnumLength() != kInvalidEnumCacheSentinel &&
362 !JSObject::cast(*receiver_)->HasEnumerableElements(); 362 !JSObject::cast(*receiver_)->HasEnumerableElements();
363 } 363 }
364 364
365 namespace { 365 namespace {
366
367 template <bool fast_properties>
366 Handle<FixedArray> GetOwnKeysWithElements(Isolate* isolate, 368 Handle<FixedArray> GetOwnKeysWithElements(Isolate* isolate,
367 Handle<JSObject> object, 369 Handle<JSObject> object,
368 GetKeysConversion convert) { 370 GetKeysConversion convert) {
369 Handle<FixedArray> keys = JSObject::GetFastEnumPropertyKeys(isolate, object); 371 Handle<FixedArray> keys;
370 ElementsAccessor* accessor = object->GetElementsAccessor(); 372 ElementsAccessor* accessor = object->GetElementsAccessor();
373 if (fast_properties) {
374 keys = JSObject::GetFastEnumPropertyKeys(isolate, object);
375 } else {
376 // TODO(cbruni): preallocate big enough array to also hold elements.
377 keys = JSObject::GetEnumPropertyKeys(object);
378 }
371 Handle<FixedArray> result = 379 Handle<FixedArray> result =
372 accessor->PrependElementIndices(object, keys, convert, ONLY_ENUMERABLE); 380 accessor->PrependElementIndices(object, keys, convert, ONLY_ENUMERABLE);
373 381
374 if (FLAG_trace_for_in_enumerate) { 382 if (FLAG_trace_for_in_enumerate) {
375 PrintF("| strings=%d symbols=0 elements=%u || prototypes>=1 ||\n", 383 PrintF("| strings=%d symbols=0 elements=%u || prototypes>=1 ||\n",
376 keys->length(), result->length() - keys->length()); 384 keys->length(), result->length() - keys->length());
377 } 385 }
378 return result; 386 return result;
379 } 387 }
380 388
381 MaybeHandle<FixedArray> GetOwnKeysWithUninitializedEnumCache( 389 MaybeHandle<FixedArray> GetOwnKeysWithUninitializedEnumCache(
382 Isolate* isolate, Handle<JSObject> object) { 390 Isolate* isolate, Handle<JSObject> object) {
383 // Uninitalized enum cache 391 // Uninitalized enum cache
384 Map* map = object->map(); 392 Map* map = object->map();
385 if (object->elements() != isolate->heap()->empty_fixed_array() || 393 if (object->elements() != isolate->heap()->empty_fixed_array() ||
386 object->elements() != isolate->heap()->empty_slow_element_dictionary()) { 394 object->elements() != isolate->heap()->empty_slow_element_dictionary()) {
387 // Assume that there are elements. 395 // Assume that there are elements.
388 return MaybeHandle<FixedArray>(); 396 return MaybeHandle<FixedArray>();
389 } 397 }
390 int number_of_own_descriptors = map->NumberOfOwnDescriptors(); 398 int number_of_own_descriptors = map->NumberOfOwnDescriptors();
391 if (number_of_own_descriptors == 0) { 399 if (number_of_own_descriptors == 0) {
392 map->SetEnumLength(0); 400 map->SetEnumLength(0);
393 return isolate->factory()->empty_fixed_array(); 401 return isolate->factory()->empty_fixed_array();
394 } 402 }
395 // We have no elements but possibly enumerable property keys, hence we can 403 // We have no elements but possibly enumerable property keys, hence we can
396 // directly initialize the enum cache. 404 // directly initialize the enum cache.
397 return JSObject::GetFastEnumPropertyKeys(isolate, object); 405 return JSObject::GetFastEnumPropertyKeys(isolate, object);
398 } 406 }
399 407
408 bool OnlyHasSimpleProperties(Map* map) {
409 return map->instance_type() > LAST_CUSTOM_ELEMENTS_RECEIVER;
410 }
411
400 } // namespace 412 } // namespace
401 413
402 MaybeHandle<FixedArray> FastKeyAccumulator::GetKeys(GetKeysConversion convert) { 414 MaybeHandle<FixedArray> FastKeyAccumulator::GetKeys(GetKeysConversion convert) {
403 Handle<FixedArray> keys; 415 Handle<FixedArray> keys;
404 if (GetKeysFast(convert).ToHandle(&keys)) { 416 if (GetKeysFast(convert).ToHandle(&keys)) {
405 return keys; 417 return keys;
406 } 418 }
407 return GetKeysSlow(convert); 419 return GetKeysSlow(convert);
408 } 420 }
409 421
410 MaybeHandle<FixedArray> FastKeyAccumulator::GetKeysFast( 422 MaybeHandle<FixedArray> FastKeyAccumulator::GetKeysFast(
411 GetKeysConversion convert) { 423 GetKeysConversion convert) {
412 bool own_only = has_empty_prototype_ || type_ == OWN_ONLY; 424 bool own_only = has_empty_prototype_ || type_ == OWN_ONLY;
413 if (!own_only || !receiver_->map()->OnlyHasSimpleProperties()) { 425 Map* map = receiver_->map();
426 if (!own_only || !OnlyHasSimpleProperties(map)) {
414 return MaybeHandle<FixedArray>(); 427 return MaybeHandle<FixedArray>();
415 } 428 }
416 429
417 Handle<FixedArray> keys; 430 // From this point on we are certiain to only collect own keys.
418 DCHECK(receiver_->IsJSObject()); 431 DCHECK(receiver_->IsJSObject());
419 Handle<JSObject> object = Handle<JSObject>::cast(receiver_); 432 Handle<JSObject> object = Handle<JSObject>::cast(receiver_);
420 433
434 // Do not try to use the enum-cache for dict-mode objects.
435 if (map->is_dictionary_map()) {
436 return GetOwnKeysWithElements<false>(isolate_, object, convert);
437 }
421 int enum_length = receiver_->map()->EnumLength(); 438 int enum_length = receiver_->map()->EnumLength();
422 if (enum_length == kInvalidEnumCacheSentinel) { 439 if (enum_length == kInvalidEnumCacheSentinel) {
440 Handle<FixedArray> keys;
423 // Try initializing the enum cache and return own properties. 441 // Try initializing the enum cache and return own properties.
424 if (GetOwnKeysWithUninitializedEnumCache(isolate_, object) 442 if (GetOwnKeysWithUninitializedEnumCache(isolate_, object)
425 .ToHandle(&keys)) { 443 .ToHandle(&keys)) {
426 if (FLAG_trace_for_in_enumerate) { 444 if (FLAG_trace_for_in_enumerate) {
427 PrintF("| strings=%d symbols=0 elements=0 || prototypes>=1 ||\n", 445 PrintF("| strings=%d symbols=0 elements=0 || prototypes>=1 ||\n",
428 keys->length()); 446 keys->length());
429 } 447 }
430
431 is_receiver_simple_enum_ = 448 is_receiver_simple_enum_ =
432 object->map()->EnumLength() != kInvalidEnumCacheSentinel; 449 object->map()->EnumLength() != kInvalidEnumCacheSentinel;
433 return keys; 450 return keys;
434 } 451 }
435 } 452 }
436 // The properties-only case failed because there were probably elements on the 453 // The properties-only case failed because there were probably elements on the
437 // receiver. 454 // receiver.
438 return GetOwnKeysWithElements(isolate_, object, convert); 455 return GetOwnKeysWithElements<true>(isolate_, object, convert);
439 } 456 }
440 457
441 MaybeHandle<FixedArray> FastKeyAccumulator::GetKeysSlow( 458 MaybeHandle<FixedArray> FastKeyAccumulator::GetKeysSlow(
442 GetKeysConversion convert) { 459 GetKeysConversion convert) {
443 return JSReceiver::GetKeys(receiver_, type_, ENUMERABLE_STRINGS, KEEP_NUMBERS, 460 return JSReceiver::GetKeys(receiver_, type_, ENUMERABLE_STRINGS, KEEP_NUMBERS,
444 filter_proxy_keys_); 461 filter_proxy_keys_);
445 } 462 }
446 463
447 } // namespace internal 464 } // namespace internal
448 } // namespace v8 465 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | src/objects.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698