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

Side by Side Diff: src/code-stubs.cc

Issue 1753173003: [compiler] Introduce initial StrictEqualStub. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Add pseudo-code. 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 | « src/code-stubs.h ('k') | src/compiler/code-stub-assembler.h » ('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 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/code-stubs.h" 5 #include "src/code-stubs.h"
6 6
7 #include <sstream> 7 #include <sstream>
8 8
9 #include "src/bootstrapper.h" 9 #include "src/bootstrapper.h"
10 #include "src/compiler/code-stub-assembler.h" 10 #include "src/compiler/code-stub-assembler.h"
(...skipping 455 matching lines...) Expand 10 before | Expand all | Expand 10 after
466 void StringLengthStub::GenerateAssembly( 466 void StringLengthStub::GenerateAssembly(
467 compiler::CodeStubAssembler* assembler) const { 467 compiler::CodeStubAssembler* assembler) const {
468 compiler::Node* value = assembler->Parameter(0); 468 compiler::Node* value = assembler->Parameter(0);
469 compiler::Node* string = 469 compiler::Node* string =
470 assembler->LoadObjectField(value, JSValue::kValueOffset); 470 assembler->LoadObjectField(value, JSValue::kValueOffset);
471 compiler::Node* result = 471 compiler::Node* result =
472 assembler->LoadObjectField(string, String::kLengthOffset); 472 assembler->LoadObjectField(string, String::kLengthOffset);
473 assembler->Return(result); 473 assembler->Return(result);
474 } 474 }
475 475
476 void StrictEqualStub::GenerateAssembly(
477 compiler::CodeStubAssembler* assembler) const {
478 // Here's pseudo-code for the algorithm below:
479 //
480 // if (lhs == rhs) {
481 // if (lhs->IsHeapNumber()) return HeapNumber::cast(lhs)->value() != NaN;
482 // return true;
483 // }
484 // if (!lhs->IsSmi()) {
485 // if (lhs->IsHeapNumber()) {
486 // if (rhs->IsSmi()) {
487 // return Smi::cast(rhs)->value() == HeapNumber::cast(lhs)->value();
488 // } else if (rhs->IsHeapNumber()) {
489 // return HeapNumber::cast(rhs)->value() ==
490 // HeapNumber::cast(lhs)->value();
491 // } else {
492 // return false;
493 // }
494 // } else {
495 // if (rhs->IsSmi()) {
496 // return false;
497 // } else {
498 // if (lhs->IsString()) {
499 // if (rhs->IsString()) {
500 // return %StringEqual(lhs, rhs);
501 // } else {
502 // return false;
503 // }
504 // } else if (lhs->IsSimd128()) {
505 // if (rhs->IsSimd128()) {
506 // return %StrictEqual(lhs, rhs);
507 // }
508 // } else {
509 // return false;
510 // }
511 // }
512 // }
513 // } else {
514 // if (rhs->IsSmi()) {
515 // return false;
516 // } else {
517 // if (rhs->IsHeapNumber()) {
518 // return Smi::cast(lhs)->value() == HeapNumber::cast(rhs)->value();
519 // } else {
520 // return false;
521 // }
522 // }
523 // }
524
525 typedef compiler::CodeStubAssembler::Label Label;
526 typedef compiler::Node Node;
527
528 Node* lhs = assembler->Parameter(0);
529 Node* rhs = assembler->Parameter(1);
530 Node* context = assembler->Parameter(2);
531
532 Label if_true(assembler), if_false(assembler);
533
534 // Check if {lhs} and {rhs} refer to the same object.
535 Label if_same(assembler), if_notsame(assembler);
536 assembler->Branch(assembler->WordEqual(lhs, rhs), &if_same, &if_notsame);
537
538 assembler->Bind(&if_same);
539 {
540 // The {lhs} and {rhs} reference the exact same value, yet we need special
541 // treatment for HeapNumber, as NaN is not equal to NaN.
542 // TODO(bmeurer): This seems to violate the SIMD.js specification, but it
543 // seems to be what is tested in the current SIMD.js testsuite.
544
545 // Check if {lhs} (and therefore {rhs}) is a Smi or a HeapObject.
546 Label if_lhsissmi(assembler), if_lhsisnotsmi(assembler);
547 assembler->Branch(assembler->WordIsSmi(lhs), &if_lhsissmi, &if_lhsisnotsmi);
548
549 assembler->Bind(&if_lhsisnotsmi);
550 {
551 // Load the map of {lhs}.
552 Node* lhs_map = assembler->LoadObjectField(lhs, HeapObject::kMapOffset);
553
554 // Check if {lhs} (and therefore {rhs}) is a HeapNumber.
555 Node* number_map = assembler->HeapNumberMapConstant();
556 Label if_lhsisnumber(assembler), if_lhsisnotnumber(assembler);
557 assembler->Branch(assembler->WordEqual(lhs_map, number_map),
558 &if_lhsisnumber, &if_lhsisnotnumber);
559
560 assembler->Bind(&if_lhsisnumber);
561 {
562 // Convert {lhs} (and therefore {rhs}) to floating point value.
563 Node* lhs_value = assembler->LoadHeapNumberValue(lhs);
564
565 // Check if the HeapNumber value is a NaN.
566 assembler->BranchIfFloat64IsNaN(lhs_value, &if_false, &if_true);
567 }
568
569 assembler->Bind(&if_lhsisnotnumber);
570 assembler->Goto(&if_true);
571 }
572
573 assembler->Bind(&if_lhsissmi);
574 assembler->Goto(&if_true);
575 }
576
577 assembler->Bind(&if_notsame);
578 {
579 // The {lhs} and {rhs} reference different objects, yet for Smi, HeapNumber,
580 // String and Simd128Value they can still be considered equal.
581 Node* number_map = assembler->HeapNumberMapConstant();
582
583 // Check if {lhs} is a Smi or a HeapObject.
584 Label if_lhsissmi(assembler), if_lhsisnotsmi(assembler);
585 assembler->Branch(assembler->WordIsSmi(lhs), &if_lhsissmi, &if_lhsisnotsmi);
586
587 assembler->Bind(&if_lhsisnotsmi);
588 {
589 // Load the map of {lhs}.
590 Node* lhs_map = assembler->LoadObjectField(lhs, HeapObject::kMapOffset);
591
592 // Check if {lhs} is a HeapNumber.
593 Label if_lhsisnumber(assembler), if_lhsisnotnumber(assembler);
594 assembler->Branch(assembler->WordEqual(lhs_map, number_map),
595 &if_lhsisnumber, &if_lhsisnotnumber);
596
597 assembler->Bind(&if_lhsisnumber);
598 {
599 // Check if {rhs} is a Smi or a HeapObject.
600 Label if_rhsissmi(assembler), if_rhsisnotsmi(assembler);
601 assembler->Branch(assembler->WordIsSmi(rhs), &if_rhsissmi,
602 &if_rhsisnotsmi);
603
604 assembler->Bind(&if_rhsissmi);
605 {
606 // Convert {lhs} and {rhs} to floating point values.
607 Node* lhs_value = assembler->LoadHeapNumberValue(lhs);
608 Node* rhs_value = assembler->SmiToFloat64(rhs);
609
610 // Perform a floating point comparison of {lhs} and {rhs}.
611 assembler->BranchIfFloat64Equal(lhs_value, rhs_value, &if_true,
612 &if_false);
613 }
614
615 assembler->Bind(&if_rhsisnotsmi);
616 {
617 // Load the map of {rhs}.
618 Node* rhs_map =
619 assembler->LoadObjectField(rhs, HeapObject::kMapOffset);
620
621 // Check if {rhs} is also a HeapNumber.
622 Label if_rhsisnumber(assembler), if_rhsisnotnumber(assembler);
623 assembler->Branch(assembler->WordEqual(rhs_map, number_map),
624 &if_rhsisnumber, &if_rhsisnotnumber);
625
626 assembler->Bind(&if_rhsisnumber);
627 {
628 // Convert {lhs} and {rhs} to floating point values.
629 Node* lhs_value = assembler->LoadHeapNumberValue(lhs);
630 Node* rhs_value = assembler->LoadHeapNumberValue(rhs);
631
632 // Perform a floating point comparison of {lhs} and {rhs}.
633 assembler->BranchIfFloat64Equal(lhs_value, rhs_value, &if_true,
634 &if_false);
635 }
636
637 assembler->Bind(&if_rhsisnotnumber);
638 assembler->Goto(&if_false);
639 }
640 }
641
642 assembler->Bind(&if_lhsisnotnumber);
643 {
644 // Check if {rhs} is a Smi or a HeapObject.
645 Label if_rhsissmi(assembler), if_rhsisnotsmi(assembler);
646 assembler->Branch(assembler->WordIsSmi(rhs), &if_rhsissmi,
647 &if_rhsisnotsmi);
648
649 assembler->Bind(&if_rhsissmi);
650 assembler->Goto(&if_false);
651
652 assembler->Bind(&if_rhsisnotsmi);
653 {
654 // Load the instance type of {lhs}.
655 Node* lhs_instance_type = assembler->LoadMapInstanceType(lhs_map);
656
657 // Check if {lhs} is a String.
658 Label if_lhsisstring(assembler), if_lhsisnotstring(assembler);
659 assembler->Branch(assembler->Int32LessThan(
660 lhs_instance_type,
661 assembler->Int32Constant(FIRST_NONSTRING_TYPE)),
662 &if_lhsisstring, &if_lhsisnotstring);
663
664 assembler->Bind(&if_lhsisstring);
665 {
666 // Load the instance type of {rhs}.
667 Node* rhs_instance_type = assembler->LoadInstanceType(rhs);
668
669 // Check if {rhs} is also a String.
670 Label if_rhsisstring(assembler), if_rhsisnotstring(assembler);
671 assembler->Branch(assembler->Int32LessThan(
672 rhs_instance_type, assembler->Int32Constant(
673 FIRST_NONSTRING_TYPE)),
674 &if_rhsisstring, &if_rhsisnotstring);
675
676 assembler->Bind(&if_rhsisstring);
677 {
678 // TODO(bmeurer): Optimize this further once the StringEqual
679 // functionality is available in TurboFan land.
680 assembler->TailCallRuntime(Runtime::kStringEqual, context, lhs,
681 rhs);
682 }
683
684 assembler->Bind(&if_rhsisnotstring);
685 assembler->Goto(&if_false);
686 }
687
688 assembler->Bind(&if_lhsisnotstring);
689 {
690 // Check if {lhs} is a Simd128Value.
691 Label if_lhsissimd128value(assembler),
692 if_lhsisnotsimd128value(assembler);
693 assembler->Branch(assembler->Word32Equal(
694 lhs_instance_type,
695 assembler->Int32Constant(SIMD128_VALUE_TYPE)),
696 &if_lhsissimd128value, &if_lhsisnotsimd128value);
697
698 assembler->Bind(&if_lhsissimd128value);
699 {
700 // TODO(bmeurer): Inline the Simd128Value equality check.
701 assembler->TailCallRuntime(Runtime::kStrictEqual, context, lhs,
702 rhs);
703 }
704
705 assembler->Bind(&if_lhsisnotsimd128value);
706 assembler->Goto(&if_false);
707 }
708 }
709 }
710 }
711
712 assembler->Bind(&if_lhsissmi);
713 {
714 // We already know that {lhs} and {rhs} are not reference equal, and {lhs}
715 // is a Smi; so {lhs} and {rhs} can only be strictly equal if {rhs} is a
716 // HeapNumber with an equal floating point value.
717
718 // Check if {rhs} is a Smi or a HeapObject.
719 Label if_rhsissmi(assembler), if_rhsisnotsmi(assembler);
720 assembler->Branch(assembler->WordIsSmi(rhs), &if_rhsissmi,
721 &if_rhsisnotsmi);
722
723 assembler->Bind(&if_rhsissmi);
724 assembler->Goto(&if_false);
725
726 assembler->Bind(&if_rhsisnotsmi);
727 {
728 // Load the map of the {rhs}.
729 Node* rhs_map = assembler->LoadObjectField(rhs, HeapObject::kMapOffset);
730
731 // The {rhs} could be a HeapNumber with the same value as {lhs}.
732 Label if_rhsisnumber(assembler), if_rhsisnotnumber(assembler);
733 assembler->Branch(assembler->WordEqual(rhs_map, number_map),
734 &if_rhsisnumber, &if_rhsisnotnumber);
735
736 assembler->Bind(&if_rhsisnumber);
737 {
738 // Convert {lhs} and {rhs} to floating point values.
739 Node* lhs_value = assembler->SmiToFloat64(lhs);
740 Node* rhs_value = assembler->LoadHeapNumberValue(rhs);
741
742 // Perform a floating point comparison of {lhs} and {rhs}.
743 assembler->BranchIfFloat64Equal(lhs_value, rhs_value, &if_true,
744 &if_false);
745 }
746
747 assembler->Bind(&if_rhsisnotnumber);
748 assembler->Goto(&if_false);
749 }
750 }
751 }
752
753 assembler->Bind(&if_true);
754 assembler->Return(assembler->BooleanConstant(true));
755
756 assembler->Bind(&if_false);
757 assembler->Return(assembler->BooleanConstant(false));
758 }
759
476 void ToBooleanStub::GenerateAssembly( 760 void ToBooleanStub::GenerateAssembly(
477 compiler::CodeStubAssembler* assembler) const { 761 compiler::CodeStubAssembler* assembler) const {
478 typedef compiler::Node Node; 762 typedef compiler::Node Node;
479 typedef compiler::CodeStubAssembler::Label Label; 763 typedef compiler::CodeStubAssembler::Label Label;
480 764
481 Node* value = assembler->Parameter(0); 765 Node* value = assembler->Parameter(0);
482 Label if_valueissmi(assembler), if_valueisnotsmi(assembler); 766 Label if_valueissmi(assembler), if_valueisnotsmi(assembler);
483 767
484 // Check if {value} is a Smi or a HeapObject. 768 // Check if {value} is a Smi or a HeapObject.
485 assembler->Branch(assembler->WordIsSmi(value), &if_valueissmi, 769 assembler->Branch(assembler->WordIsSmi(value), &if_valueissmi,
(...skipping 555 matching lines...) Expand 10 before | Expand all | Expand 10 after
1041 if (type->Is(Type::UntaggedPointer())) { 1325 if (type->Is(Type::UntaggedPointer())) {
1042 return Representation::External(); 1326 return Representation::External();
1043 } 1327 }
1044 1328
1045 DCHECK(!type->Is(Type::Untagged())); 1329 DCHECK(!type->Is(Type::Untagged()));
1046 return Representation::Tagged(); 1330 return Representation::Tagged();
1047 } 1331 }
1048 1332
1049 } // namespace internal 1333 } // namespace internal
1050 } // namespace v8 1334 } // namespace v8
OLDNEW
« no previous file with comments | « src/code-stubs.h ('k') | src/compiler/code-stub-assembler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698