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

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: undo change 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 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 !IsStringWrapperElementsKind(map->elements_kind()) &&
Toon Verwaest 2016/03/30 06:51:17 You can just check for LAST_CUSTOM_ELEMENTS_TYPE,
410 map->instance_type() > LAST_SPECIAL_RECEIVER_TYPE &&
411 !map->has_hidden_prototype();
412 }
413
400 } // namespace 414 } // namespace
401 415
402 MaybeHandle<FixedArray> FastKeyAccumulator::GetKeys(GetKeysConversion convert) { 416 MaybeHandle<FixedArray> FastKeyAccumulator::GetKeys(GetKeysConversion convert) {
403 Handle<FixedArray> keys; 417 Handle<FixedArray> keys;
404 if (GetKeysFast(convert).ToHandle(&keys)) { 418 if (GetKeysFast(convert).ToHandle(&keys)) {
405 return keys; 419 return keys;
406 } 420 }
407 return GetKeysSlow(convert); 421 return GetKeysSlow(convert);
408 } 422 }
409 423
410 MaybeHandle<FixedArray> FastKeyAccumulator::GetKeysFast( 424 MaybeHandle<FixedArray> FastKeyAccumulator::GetKeysFast(
411 GetKeysConversion convert) { 425 GetKeysConversion convert) {
412 bool own_only = has_empty_prototype_ || type_ == OWN_ONLY; 426 bool own_only = has_empty_prototype_ || type_ == OWN_ONLY;
413 if (!own_only || !receiver_->map()->OnlyHasSimpleProperties()) { 427 Map* map = receiver_->map();
428 if (!own_only || !OnlyHasSimpleProperties(map)) {
414 return MaybeHandle<FixedArray>(); 429 return MaybeHandle<FixedArray>();
415 } 430 }
416 431
417 Handle<FixedArray> keys; 432 // From this point on we are certiain to only collect own keys.
418 DCHECK(receiver_->IsJSObject()); 433 DCHECK(receiver_->IsJSObject());
419 Handle<JSObject> object = Handle<JSObject>::cast(receiver_); 434 Handle<JSObject> object = Handle<JSObject>::cast(receiver_);
420 435
436 // Do not try to use the enum-cache for dict-mode objects.
437 if (map->is_dictionary_map()) {
438 return GetOwnKeysWithElements<false>(isolate_, object, convert);
439 }
421 int enum_length = receiver_->map()->EnumLength(); 440 int enum_length = receiver_->map()->EnumLength();
422 if (enum_length == kInvalidEnumCacheSentinel) { 441 if (enum_length == kInvalidEnumCacheSentinel) {
442 Handle<FixedArray> keys;
423 // Try initializing the enum cache and return own properties. 443 // Try initializing the enum cache and return own properties.
424 if (GetOwnKeysWithUninitializedEnumCache(isolate_, object) 444 if (GetOwnKeysWithUninitializedEnumCache(isolate_, object)
425 .ToHandle(&keys)) { 445 .ToHandle(&keys)) {
426 if (FLAG_trace_for_in_enumerate) { 446 if (FLAG_trace_for_in_enumerate) {
427 PrintF("| strings=%d symbols=0 elements=0 || prototypes>=1 ||\n", 447 PrintF("| strings=%d symbols=0 elements=0 || prototypes>=1 ||\n",
428 keys->length()); 448 keys->length());
429 } 449 }
430
431 is_receiver_simple_enum_ = 450 is_receiver_simple_enum_ =
432 object->map()->EnumLength() != kInvalidEnumCacheSentinel; 451 object->map()->EnumLength() != kInvalidEnumCacheSentinel;
433 return keys; 452 return keys;
434 } 453 }
435 } 454 }
436 // The properties-only case failed because there were probably elements on the 455 // The properties-only case failed because there were probably elements on the
437 // receiver. 456 // receiver.
438 return GetOwnKeysWithElements(isolate_, object, convert); 457 return GetOwnKeysWithElements<true>(isolate_, object, convert);
439 } 458 }
440 459
441 MaybeHandle<FixedArray> FastKeyAccumulator::GetKeysSlow( 460 MaybeHandle<FixedArray> FastKeyAccumulator::GetKeysSlow(
442 GetKeysConversion convert) { 461 GetKeysConversion convert) {
443 return JSReceiver::GetKeys(receiver_, type_, ENUMERABLE_STRINGS, KEEP_NUMBERS, 462 return JSReceiver::GetKeys(receiver_, type_, ENUMERABLE_STRINGS, KEEP_NUMBERS,
444 filter_proxy_keys_); 463 filter_proxy_keys_);
445 } 464 }
446 465
447 } // namespace internal 466 } // namespace internal
448 } // namespace v8 467 } // 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