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

Side by Side Diff: src/builtins.cc

Issue 1894953004: Add HasProperty code stub that tries simple lookups or jumps to runtime otherwise. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: 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
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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/builtins.h" 5 #include "src/builtins.h"
6 6
7 #include "src/api-arguments.h" 7 #include "src/api-arguments.h"
8 #include "src/api-natives.h" 8 #include "src/api-natives.h"
9 #include "src/api.h" 9 #include "src/api.h"
10 #include "src/base/once.h" 10 #include "src/base/once.h"
(...skipping 357 matching lines...) Expand 10 before | Expand all | Expand 10 after
368 Label if_objectisnotsmi(assembler); 368 Label if_objectisnotsmi(assembler);
369 assembler->Branch(assembler->WordIsSmi(object), &return_false, 369 assembler->Branch(assembler->WordIsSmi(object), &return_false,
370 &if_objectisnotsmi); 370 &if_objectisnotsmi);
371 assembler->Bind(&if_objectisnotsmi); 371 assembler->Bind(&if_objectisnotsmi);
372 372
373 Node* map = assembler->LoadMap(object); 373 Node* map = assembler->LoadMap(object);
374 Node* instance_type = assembler->LoadMapInstanceType(map); 374 Node* instance_type = assembler->LoadMapInstanceType(map);
375 375
376 Variable var_index(assembler, MachineRepresentation::kWord32); 376 Variable var_index(assembler, MachineRepresentation::kWord32);
377 377
378 Label if_keyissmi(assembler), if_keyisnotsmi(assembler), 378 Label keyisindex(assembler), if_iskeyunique(assembler);
379 keyisindex(assembler); 379 assembler->TryToName(key, &keyisindex, &var_index, &if_iskeyunique,
380 assembler->Branch(assembler->WordIsSmi(key), &if_keyissmi, &if_keyisnotsmi); 380 &call_runtime);
381 assembler->Bind(&if_keyissmi);
382 {
383 // Negative smi keys are named properties. Handle in the runtime.
384 Label if_keyispositive(assembler);
385 assembler->Branch(assembler->WordIsPositiveSmi(key), &if_keyispositive,
386 &call_runtime);
387 assembler->Bind(&if_keyispositive);
388 381
389 var_index.Bind(assembler->SmiUntag(key));
390 assembler->Goto(&keyisindex);
391 }
392
393 assembler->Bind(&if_keyisnotsmi);
394
395 Node* key_instance_type = assembler->LoadInstanceType(key);
396 Label if_iskeyunique(assembler), if_iskeynotsymbol(assembler);
397 assembler->Branch(
398 assembler->Word32Equal(key_instance_type,
399 assembler->Int32Constant(SYMBOL_TYPE)),
400 &if_iskeyunique, &if_iskeynotsymbol);
401 assembler->Bind(&if_iskeynotsymbol);
402 {
403 Label if_iskeyinternalized(assembler);
404 Node* bits = assembler->WordAnd(
405 key_instance_type,
406 assembler->Int32Constant(kIsNotStringMask | kIsNotInternalizedMask));
407 assembler->Branch(
408 assembler->Word32Equal(
409 bits, assembler->Int32Constant(kStringTag | kInternalizedTag)),
410 &if_iskeyinternalized, &call_runtime);
411 assembler->Bind(&if_iskeyinternalized);
412
413 // Check whether the key is an array index passed in as string. Handle
414 // uniform with smi keys if so.
415 // TODO(verwaest): Also support non-internalized strings.
416 Node* hash = assembler->LoadNameHash(key);
417 Node* bit = assembler->Word32And(
418 hash, assembler->Int32Constant(internal::Name::kIsNotArrayIndexMask));
419 Label if_isarrayindex(assembler);
420 assembler->Branch(assembler->Word32Equal(bit, assembler->Int32Constant(0)),
421 &if_isarrayindex, &if_iskeyunique);
422 assembler->Bind(&if_isarrayindex);
423 var_index.Bind(
424 assembler->BitFieldDecode<internal::Name::ArrayIndexValueBits>(hash));
425 assembler->Goto(&keyisindex);
426 }
427 assembler->Bind(&if_iskeyunique); 382 assembler->Bind(&if_iskeyunique);
428 383 assembler->TryLookupProperty(object, map, instance_type, key, &return_true,
429 { 384 &return_false, &call_runtime);
430 Label if_objectissimple(assembler);
431 assembler->Branch(assembler->Int32LessThanOrEqual(
432 instance_type,
433 assembler->Int32Constant(LAST_SPECIAL_RECEIVER_TYPE)),
434 &call_runtime, &if_objectissimple);
435 assembler->Bind(&if_objectissimple);
436 }
437
438 // TODO(verwaest): Perform a dictonary lookup on slow-mode receivers.
439 Node* bit_field3 = assembler->LoadMapBitField3(map);
440 Node* bit = assembler->BitFieldDecode<Map::DictionaryMap>(bit_field3);
441 Label if_isfastmap(assembler);
442 assembler->Branch(assembler->Word32Equal(bit, assembler->Int32Constant(0)),
443 &if_isfastmap, &call_runtime);
444 assembler->Bind(&if_isfastmap);
445 Node* nof =
446 assembler->BitFieldDecode<Map::NumberOfOwnDescriptorsBits>(bit_field3);
447 // Bail out to the runtime for large numbers of own descriptors. The stub only
448 // does linear search, which becomes too expensive in that case.
449 {
450 static const int32_t kMaxLinear = 256;
451 Label above_max(assembler), below_max(assembler);
452 assembler->Branch(assembler->Int32LessThanOrEqual(
453 nof, assembler->Int32Constant(kMaxLinear)),
454 &below_max, &call_runtime);
455 assembler->Bind(&below_max);
456 }
457 Node* descriptors = assembler->LoadMapDescriptors(map);
458
459 Variable var_descriptor(assembler, MachineRepresentation::kWord32);
460 Label loop(assembler, &var_descriptor);
461 var_descriptor.Bind(assembler->Int32Constant(0));
462 assembler->Goto(&loop);
463 assembler->Bind(&loop);
464 {
465 Node* index = var_descriptor.value();
466 Node* offset = assembler->Int32Constant(DescriptorArray::ToKeyIndex(0));
467 Node* factor = assembler->Int32Constant(DescriptorArray::kDescriptorSize);
468 Label if_notdone(assembler);
469 assembler->Branch(assembler->Word32Equal(index, nof), &return_false,
470 &if_notdone);
471 assembler->Bind(&if_notdone);
472 {
473 Node* array_index =
474 assembler->Int32Add(offset, assembler->Int32Mul(index, factor));
475 Node* current =
476 assembler->LoadFixedArrayElementInt32Index(descriptors, array_index);
477 Label if_unequal(assembler);
478 assembler->Branch(assembler->WordEqual(current, key), &return_true,
479 &if_unequal);
480 assembler->Bind(&if_unequal);
481
482 var_descriptor.Bind(
483 assembler->Int32Add(index, assembler->Int32Constant(1)));
484 assembler->Goto(&loop);
485 }
486 }
487 385
488 assembler->Bind(&keyisindex); 386 assembler->Bind(&keyisindex);
489 { 387 assembler->TryLookupElement(object, map, instance_type, var_index.value(),
490 Label if_objectissimple(assembler); 388 &return_true, &return_false, &call_runtime);
491 assembler->Branch(assembler->Int32LessThanOrEqual(
492 instance_type, assembler->Int32Constant(
493 LAST_CUSTOM_ELEMENTS_RECEIVER)),
494 &call_runtime, &if_objectissimple);
495 assembler->Bind(&if_objectissimple);
496 }
497
498 Node* index = var_index.value();
499 Node* bit_field2 = assembler->LoadMapBitField2(map);
500 Node* elements_kind =
501 assembler->BitFieldDecode<Map::ElementsKindBits>(bit_field2);
502
503 // TODO(verwaest): Support other elements kinds as well.
504 Label if_isobjectorsmi(assembler);
505 assembler->Branch(
506 assembler->Int32LessThanOrEqual(
507 elements_kind, assembler->Int32Constant(FAST_HOLEY_ELEMENTS)),
508 &if_isobjectorsmi, &call_runtime);
509 assembler->Bind(&if_isobjectorsmi);
510 {
511 Node* elements = assembler->LoadElements(object);
512 Node* length = assembler->LoadFixedArrayBaseLength(elements);
513
514 Label if_iskeyinrange(assembler);
515 assembler->Branch(
516 assembler->Int32LessThan(index, assembler->SmiToWord32(length)),
517 &if_iskeyinrange, &return_false);
518
519 assembler->Bind(&if_iskeyinrange);
520 Node* element = assembler->LoadFixedArrayElementInt32Index(elements, index);
521 Node* the_hole = assembler->LoadRoot(Heap::kTheHoleValueRootIndex);
522 assembler->Branch(assembler->WordEqual(element, the_hole), &return_false,
523 &return_true);
524 }
525 389
526 assembler->Bind(&return_true); 390 assembler->Bind(&return_true);
527 assembler->Return(assembler->BooleanConstant(true)); 391 assembler->Return(assembler->BooleanConstant(true));
528 392
529 assembler->Bind(&return_false); 393 assembler->Bind(&return_false);
530 assembler->Return(assembler->BooleanConstant(false)); 394 assembler->Return(assembler->BooleanConstant(false));
531 395
532 assembler->Bind(&call_runtime); 396 assembler->Bind(&call_runtime);
533 assembler->Return(assembler->CallRuntime(Runtime::kObjectHasOwnProperty, 397 assembler->Return(assembler->CallRuntime(Runtime::kObjectHasOwnProperty,
534 context, object, key)); 398 context, object, key));
(...skipping 4764 matching lines...) Expand 10 before | Expand all | Expand 10 after
5299 BUILTIN_LIST_T(DEFINE_BUILTIN_ACCESSOR_T) 5163 BUILTIN_LIST_T(DEFINE_BUILTIN_ACCESSOR_T)
5300 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H) 5164 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H)
5301 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A) 5165 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A)
5302 #undef DEFINE_BUILTIN_ACCESSOR_C 5166 #undef DEFINE_BUILTIN_ACCESSOR_C
5303 #undef DEFINE_BUILTIN_ACCESSOR_A 5167 #undef DEFINE_BUILTIN_ACCESSOR_A
5304 #undef DEFINE_BUILTIN_ACCESSOR_T 5168 #undef DEFINE_BUILTIN_ACCESSOR_T
5305 #undef DEFINE_BUILTIN_ACCESSOR_H 5169 #undef DEFINE_BUILTIN_ACCESSOR_H
5306 5170
5307 } // namespace internal 5171 } // namespace internal
5308 } // namespace v8 5172 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698