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

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

Issue 1744163002: [stubs] Introduce a proper ToBooleanStub. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fix mips 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/code-stubs-hydrogen.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 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 ToBooleanStub::GenerateAssembly(
477 compiler::CodeStubAssembler* assembler) const {
478 typedef compiler::Node Node;
479 typedef compiler::CodeStubAssembler::Label Label;
480
481 Node* value = assembler->Parameter(0);
482 Label if_valueissmi(assembler), if_valueisnotsmi(assembler);
483
484 // Check if {value} is a Smi or a HeapObject.
485 assembler->Branch(assembler->WordIsSmi(value), &if_valueissmi,
486 &if_valueisnotsmi);
487
488 assembler->Bind(&if_valueissmi);
489 {
490 // The {value} is a Smi, only need to check against zero.
491 Label if_valueiszero(assembler), if_valueisnotzero(assembler);
492 assembler->Branch(assembler->SmiEqual(value, assembler->SmiConstant(0)),
493 &if_valueiszero, &if_valueisnotzero);
494
495 assembler->Bind(&if_valueiszero);
496 assembler->Return(assembler->BooleanConstant(false));
497
498 assembler->Bind(&if_valueisnotzero);
499 assembler->Return(assembler->BooleanConstant(true));
500 }
501
502 assembler->Bind(&if_valueisnotsmi);
503 {
504 Label if_valueisstring(assembler), if_valueisheapnumber(assembler),
505 if_valueisoddball(assembler), if_valueisother(assembler);
506
507 // The {value} is a HeapObject, load its map.
508 Node* value_map = assembler->LoadObjectField(value, HeapObject::kMapOffset);
509
510 // Load the {value}s instance type.
511 Node* value_instancetype = assembler->Load(
512 MachineType::Uint8(), value_map,
513 assembler->IntPtrConstant(Map::kInstanceTypeOffset - kHeapObjectTag));
514
515 // Dispatch based on the instance type; we distinguish all String instance
516 // types, the HeapNumber type and the Oddball type.
517 size_t const kNumCases = FIRST_NONSTRING_TYPE + 2;
518 Label* case_labels[kNumCases];
519 int32_t case_values[kNumCases];
520 for (int32_t i = 0; i < FIRST_NONSTRING_TYPE; ++i) {
521 case_labels[i] = new Label(assembler);
522 case_values[i] = i;
523 }
524 case_labels[FIRST_NONSTRING_TYPE + 0] = &if_valueisheapnumber;
525 case_values[FIRST_NONSTRING_TYPE + 0] = HEAP_NUMBER_TYPE;
526 case_labels[FIRST_NONSTRING_TYPE + 1] = &if_valueisoddball;
527 case_values[FIRST_NONSTRING_TYPE + 1] = ODDBALL_TYPE;
528 assembler->Switch(value_instancetype, &if_valueisother, case_values,
529 case_labels, arraysize(case_values));
530 for (int32_t i = 0; i < FIRST_NONSTRING_TYPE; ++i) {
531 assembler->Bind(case_labels[i]);
532 assembler->Goto(&if_valueisstring);
533 delete case_labels[i];
534 }
535
536 assembler->Bind(&if_valueisstring);
537 {
538 // Load the string length field of the {value}.
539 Node* value_length =
540 assembler->LoadObjectField(value, String::kLengthOffset);
541
542 // Check if the {value} is the empty string.
543 Label if_valueisempty(assembler), if_valueisnotempty(assembler);
544 assembler->Branch(
545 assembler->SmiEqual(value_length, assembler->SmiConstant(0)),
546 &if_valueisempty, &if_valueisnotempty);
547
548 assembler->Bind(&if_valueisempty);
549 assembler->Return(assembler->BooleanConstant(false));
550
551 assembler->Bind(&if_valueisnotempty);
552 assembler->Return(assembler->BooleanConstant(true));
553 }
554
555 assembler->Bind(&if_valueisheapnumber);
556 {
557 Node* value_value = assembler->Load(
558 MachineType::Float64(), value,
559 assembler->IntPtrConstant(HeapNumber::kValueOffset - kHeapObjectTag));
560
561 Label if_valueispositive(assembler), if_valueisnotpositive(assembler),
562 if_valueisnegative(assembler), if_valueisnanorzero(assembler);
563 assembler->Branch(assembler->Float64LessThan(
564 assembler->Float64Constant(0.0), value_value),
565 &if_valueispositive, &if_valueisnotpositive);
566
567 assembler->Bind(&if_valueispositive);
568 assembler->Return(assembler->BooleanConstant(true));
569
570 assembler->Bind(&if_valueisnotpositive);
571 assembler->Branch(assembler->Float64LessThan(
572 value_value, assembler->Float64Constant(0.0)),
573 &if_valueisnegative, &if_valueisnanorzero);
574
575 assembler->Bind(&if_valueisnegative);
576 assembler->Return(assembler->BooleanConstant(true));
577
578 assembler->Bind(&if_valueisnanorzero);
579 assembler->Return(assembler->BooleanConstant(false));
580 }
581
582 assembler->Bind(&if_valueisoddball);
583 {
584 // The {value} is an Oddball, and every Oddball knows its boolean value.
585 Node* value_toboolean =
586 assembler->LoadObjectField(value, Oddball::kToBooleanOffset);
587 assembler->Return(value_toboolean);
588 }
589
590 assembler->Bind(&if_valueisother);
591 {
592 Node* value_map_bitfield = assembler->Load(
593 MachineType::Uint8(), value_map,
594 assembler->IntPtrConstant(Map::kBitFieldOffset - kHeapObjectTag));
595 Node* value_map_undetectable = assembler->Word32And(
596 value_map_bitfield,
597 assembler->Int32Constant(1 << Map::kIsUndetectable));
598
599 // Check if the {value} is undetectable.
600 Label if_valueisundetectable(assembler),
601 if_valueisnotundetectable(assembler);
602 assembler->Branch(assembler->Word32Equal(value_map_undetectable,
603 assembler->Int32Constant(0)),
604 &if_valueisnotundetectable, &if_valueisundetectable);
605
606 assembler->Bind(&if_valueisundetectable);
607 assembler->Return(assembler->BooleanConstant(false));
608
609 assembler->Bind(&if_valueisnotundetectable);
610 assembler->Return(assembler->BooleanConstant(true));
611 }
612 }
613 }
476 614
477 template<class StateType> 615 template<class StateType>
478 void HydrogenCodeStub::TraceTransition(StateType from, StateType to) { 616 void HydrogenCodeStub::TraceTransition(StateType from, StateType to) {
479 // Note: Although a no-op transition is semantically OK, it is hinting at a 617 // Note: Although a no-op transition is semantically OK, it is hinting at a
480 // bug somewhere in our state transition machinery. 618 // bug somewhere in our state transition machinery.
481 DCHECK(from != to); 619 DCHECK(from != to);
482 if (!FLAG_trace_ic) return; 620 if (!FLAG_trace_ic) return;
483 OFStream os(stdout); 621 OFStream os(stdout);
484 os << "["; 622 os << "[";
485 PrintBaseName(os); 623 PrintBaseName(os);
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
660 CodeStubDescriptor* descriptor) { 798 CodeStubDescriptor* descriptor) {
661 descriptor->Initialize(); 799 descriptor->Initialize();
662 } 800 }
663 801
664 802
665 void AllocateInNewSpaceStub::InitializeDescriptor( 803 void AllocateInNewSpaceStub::InitializeDescriptor(
666 CodeStubDescriptor* descriptor) { 804 CodeStubDescriptor* descriptor) {
667 descriptor->Initialize(); 805 descriptor->Initialize();
668 } 806 }
669 807
670 808 void ToBooleanICStub::InitializeDescriptor(CodeStubDescriptor* descriptor) {
671 void ToBooleanStub::InitializeDescriptor(CodeStubDescriptor* descriptor) {
672 descriptor->Initialize(FUNCTION_ADDR(Runtime_ToBooleanIC_Miss)); 809 descriptor->Initialize(FUNCTION_ADDR(Runtime_ToBooleanIC_Miss));
673 descriptor->SetMissHandler(ExternalReference( 810 descriptor->SetMissHandler(ExternalReference(
674 Runtime::FunctionForId(Runtime::kToBooleanIC_Miss), isolate())); 811 Runtime::FunctionForId(Runtime::kToBooleanIC_Miss), isolate()));
675 } 812 }
676 813
677 814
678 void BinaryOpICStub::InitializeDescriptor(CodeStubDescriptor* descriptor) { 815 void BinaryOpICStub::InitializeDescriptor(CodeStubDescriptor* descriptor) {
679 descriptor->Initialize(FUNCTION_ADDR(Runtime_BinaryOpIC_Miss)); 816 descriptor->Initialize(FUNCTION_ADDR(Runtime_BinaryOpIC_Miss));
680 descriptor->SetMissHandler(ExternalReference( 817 descriptor->SetMissHandler(ExternalReference(
681 Runtime::FunctionForId(Runtime::kBinaryOpIC_Miss), isolate())); 818 Runtime::FunctionForId(Runtime::kBinaryOpIC_Miss), isolate()));
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
763 std::ostream& ArrayConstructorStubBase::BasePrintName( 900 std::ostream& ArrayConstructorStubBase::BasePrintName(
764 std::ostream& os, // NOLINT 901 std::ostream& os, // NOLINT
765 const char* name) const { 902 const char* name) const {
766 os << name << "_" << ElementsKindToString(elements_kind()); 903 os << name << "_" << ElementsKindToString(elements_kind());
767 if (override_mode() == DISABLE_ALLOCATION_SITES) { 904 if (override_mode() == DISABLE_ALLOCATION_SITES) {
768 os << "_DISABLE_ALLOCATION_SITES"; 905 os << "_DISABLE_ALLOCATION_SITES";
769 } 906 }
770 return os; 907 return os;
771 } 908 }
772 909
773 910 bool ToBooleanICStub::UpdateStatus(Handle<Object> object) {
774 bool ToBooleanStub::UpdateStatus(Handle<Object> object) {
775 Types new_types = types(); 911 Types new_types = types();
776 Types old_types = new_types; 912 Types old_types = new_types;
777 bool to_boolean_value = new_types.UpdateStatus(object); 913 bool to_boolean_value = new_types.UpdateStatus(object);
778 TraceTransition(old_types, new_types); 914 TraceTransition(old_types, new_types);
779 set_sub_minor_key(TypesBits::update(sub_minor_key(), new_types.ToIntegral())); 915 set_sub_minor_key(TypesBits::update(sub_minor_key(), new_types.ToIntegral()));
780 return to_boolean_value; 916 return to_boolean_value;
781 } 917 }
782 918
783 919 void ToBooleanICStub::PrintState(std::ostream& os) const { // NOLINT
784 void ToBooleanStub::PrintState(std::ostream& os) const { // NOLINT
785 os << types(); 920 os << types();
786 } 921 }
787 922
788 923 std::ostream& operator<<(std::ostream& os, const ToBooleanICStub::Types& s) {
789 std::ostream& operator<<(std::ostream& os, const ToBooleanStub::Types& s) {
790 os << "("; 924 os << "(";
791 SimpleListPrinter p(os); 925 SimpleListPrinter p(os);
792 if (s.IsEmpty()) p.Add("None"); 926 if (s.IsEmpty()) p.Add("None");
793 if (s.Contains(ToBooleanStub::UNDEFINED)) p.Add("Undefined"); 927 if (s.Contains(ToBooleanICStub::UNDEFINED)) p.Add("Undefined");
794 if (s.Contains(ToBooleanStub::BOOLEAN)) p.Add("Bool"); 928 if (s.Contains(ToBooleanICStub::BOOLEAN)) p.Add("Bool");
795 if (s.Contains(ToBooleanStub::NULL_TYPE)) p.Add("Null"); 929 if (s.Contains(ToBooleanICStub::NULL_TYPE)) p.Add("Null");
796 if (s.Contains(ToBooleanStub::SMI)) p.Add("Smi"); 930 if (s.Contains(ToBooleanICStub::SMI)) p.Add("Smi");
797 if (s.Contains(ToBooleanStub::SPEC_OBJECT)) p.Add("SpecObject"); 931 if (s.Contains(ToBooleanICStub::SPEC_OBJECT)) p.Add("SpecObject");
798 if (s.Contains(ToBooleanStub::STRING)) p.Add("String"); 932 if (s.Contains(ToBooleanICStub::STRING)) p.Add("String");
799 if (s.Contains(ToBooleanStub::SYMBOL)) p.Add("Symbol"); 933 if (s.Contains(ToBooleanICStub::SYMBOL)) p.Add("Symbol");
800 if (s.Contains(ToBooleanStub::HEAP_NUMBER)) p.Add("HeapNumber"); 934 if (s.Contains(ToBooleanICStub::HEAP_NUMBER)) p.Add("HeapNumber");
801 if (s.Contains(ToBooleanStub::SIMD_VALUE)) p.Add("SimdValue"); 935 if (s.Contains(ToBooleanICStub::SIMD_VALUE)) p.Add("SimdValue");
802 return os << ")"; 936 return os << ")";
803 } 937 }
804 938
805 939 bool ToBooleanICStub::Types::UpdateStatus(Handle<Object> object) {
806 bool ToBooleanStub::Types::UpdateStatus(Handle<Object> object) {
807 if (object->IsUndefined()) { 940 if (object->IsUndefined()) {
808 Add(UNDEFINED); 941 Add(UNDEFINED);
809 return false; 942 return false;
810 } else if (object->IsBoolean()) { 943 } else if (object->IsBoolean()) {
811 Add(BOOLEAN); 944 Add(BOOLEAN);
812 return object->IsTrue(); 945 return object->IsTrue();
813 } else if (object->IsNull()) { 946 } else if (object->IsNull()) {
814 Add(NULL_TYPE); 947 Add(NULL_TYPE);
815 return false; 948 return false;
816 } else if (object->IsSmi()) { 949 } else if (object->IsSmi()) {
(...skipping 17 matching lines...) Expand all
834 } else if (object->IsSimd128Value()) { 967 } else if (object->IsSimd128Value()) {
835 Add(SIMD_VALUE); 968 Add(SIMD_VALUE);
836 return true; 969 return true;
837 } else { 970 } else {
838 // We should never see an internal object at runtime here! 971 // We should never see an internal object at runtime here!
839 UNREACHABLE(); 972 UNREACHABLE();
840 return true; 973 return true;
841 } 974 }
842 } 975 }
843 976
844 977 bool ToBooleanICStub::Types::NeedsMap() const {
845 bool ToBooleanStub::Types::NeedsMap() const { 978 return Contains(ToBooleanICStub::SPEC_OBJECT) ||
846 return Contains(ToBooleanStub::SPEC_OBJECT) || 979 Contains(ToBooleanICStub::STRING) ||
847 Contains(ToBooleanStub::STRING) || Contains(ToBooleanStub::SYMBOL) || 980 Contains(ToBooleanICStub::SYMBOL) ||
848 Contains(ToBooleanStub::HEAP_NUMBER) || 981 Contains(ToBooleanICStub::HEAP_NUMBER) ||
849 Contains(ToBooleanStub::SIMD_VALUE); 982 Contains(ToBooleanICStub::SIMD_VALUE);
850 } 983 }
851 984
852 985
853 void StubFailureTrampolineStub::GenerateAheadOfTime(Isolate* isolate) { 986 void StubFailureTrampolineStub::GenerateAheadOfTime(Isolate* isolate) {
854 StubFailureTrampolineStub stub1(isolate, NOT_JS_FUNCTION_STUB_MODE); 987 StubFailureTrampolineStub stub1(isolate, NOT_JS_FUNCTION_STUB_MODE);
855 StubFailureTrampolineStub stub2(isolate, JS_FUNCTION_STUB_MODE); 988 StubFailureTrampolineStub stub2(isolate, JS_FUNCTION_STUB_MODE);
856 stub1.GetCode(); 989 stub1.GetCode();
857 stub2.GetCode(); 990 stub2.GetCode();
858 } 991 }
859 992
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
908 if (type->Is(Type::UntaggedPointer())) { 1041 if (type->Is(Type::UntaggedPointer())) {
909 return Representation::External(); 1042 return Representation::External();
910 } 1043 }
911 1044
912 DCHECK(!type->Is(Type::Untagged())); 1045 DCHECK(!type->Is(Type::Untagged()));
913 return Representation::Tagged(); 1046 return Representation::Tagged();
914 } 1047 }
915 1048
916 } // namespace internal 1049 } // namespace internal
917 } // namespace v8 1050 } // namespace v8
OLDNEW
« no previous file with comments | « src/code-stubs.h ('k') | src/code-stubs-hydrogen.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698