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/code-stubs.cc

Issue 2151163002: [stubs] Improve code generation for ToBoolean. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: REBASE. Fix redness. Created 4 years, 5 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/factory.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/code-factory.h" 10 #include "src/code-factory.h"
(...skipping 3723 matching lines...) Expand 10 before | Expand all | Expand 10 after
3734 assembler->Return(var_len.value()); 3734 assembler->Return(var_len.value());
3735 3735
3736 assembler->Bind(&return_two53minus1); 3736 assembler->Bind(&return_two53minus1);
3737 assembler->Return(assembler->NumberConstant(kMaxSafeInteger)); 3737 assembler->Return(assembler->NumberConstant(kMaxSafeInteger));
3738 3738
3739 assembler->Bind(&return_zero); 3739 assembler->Bind(&return_zero);
3740 assembler->Return(assembler->SmiConstant(Smi::FromInt(0))); 3740 assembler->Return(assembler->SmiConstant(Smi::FromInt(0)));
3741 } 3741 }
3742 } 3742 }
3743 3743
3744 // static
3745 compiler::Node* ToBooleanStub::Generate(CodeStubAssembler* assembler,
3746 compiler::Node* value,
3747 compiler::Node* context) {
3748 typedef compiler::Node Node;
3749 typedef CodeStubAssembler::Label Label;
3750 typedef CodeStubAssembler::Variable Variable;
3751
3752 Variable result(assembler, MachineRepresentation::kTagged);
3753 Label if_valueissmi(assembler), if_valueisnotsmi(assembler),
3754 return_true(assembler), return_false(assembler), end(assembler);
3755
3756 // Check if {value} is a Smi or a HeapObject.
3757 assembler->Branch(assembler->WordIsSmi(value), &if_valueissmi,
3758 &if_valueisnotsmi);
3759
3760 assembler->Bind(&if_valueissmi);
3761 {
3762 // The {value} is a Smi, only need to check against zero.
3763 assembler->Branch(assembler->SmiEqual(value, assembler->SmiConstant(0)),
3764 &return_false, &return_true);
3765 }
3766
3767 assembler->Bind(&if_valueisnotsmi);
3768 {
3769 Label if_valueisstring(assembler), if_valueisnotstring(assembler),
3770 if_valueisheapnumber(assembler), if_valueisoddball(assembler),
3771 if_valueisother(assembler);
3772
3773 // The {value} is a HeapObject, load its map.
3774 Node* value_map = assembler->LoadMap(value);
3775
3776 // Load the {value}s instance type.
3777 Node* value_instance_type = assembler->Load(
3778 MachineType::Uint8(), value_map,
3779 assembler->IntPtrConstant(Map::kInstanceTypeOffset - kHeapObjectTag));
3780
3781 // Dispatch based on the instance type; we distinguish all String instance
3782 // types, the HeapNumber type and the Oddball type.
3783 assembler->Branch(assembler->Int32LessThan(
3784 value_instance_type,
3785 assembler->Int32Constant(FIRST_NONSTRING_TYPE)),
3786 &if_valueisstring, &if_valueisnotstring);
3787 assembler->Bind(&if_valueisnotstring);
3788 size_t const kNumCases = 2;
3789 Label* case_labels[kNumCases];
3790 int32_t case_values[kNumCases];
3791 case_labels[0] = &if_valueisheapnumber;
3792 case_values[0] = HEAP_NUMBER_TYPE;
3793 case_labels[1] = &if_valueisoddball;
3794 case_values[1] = ODDBALL_TYPE;
3795 assembler->Switch(value_instance_type, &if_valueisother, case_values,
3796 case_labels, arraysize(case_values));
3797
3798 assembler->Bind(&if_valueisstring);
3799 {
3800 // Load the string length field of the {value}.
3801 Node* value_length =
3802 assembler->LoadObjectField(value, String::kLengthOffset);
3803
3804 // Check if the {value} is the empty string.
3805 assembler->Branch(
3806 assembler->SmiEqual(value_length, assembler->SmiConstant(0)),
3807 &return_false, &return_true);
3808 }
3809
3810 assembler->Bind(&if_valueisheapnumber);
3811 {
3812 Node* value_value = assembler->Load(
3813 MachineType::Float64(), value,
3814 assembler->IntPtrConstant(HeapNumber::kValueOffset - kHeapObjectTag));
3815
3816 Label if_valueisnotpositive(assembler);
3817 assembler->Branch(assembler->Float64LessThan(
3818 assembler->Float64Constant(0.0), value_value),
3819 &return_true, &if_valueisnotpositive);
3820
3821 assembler->Bind(&if_valueisnotpositive);
3822 assembler->Branch(assembler->Float64LessThan(
3823 value_value, assembler->Float64Constant(0.0)),
3824 &return_true, &return_false);
3825 }
3826
3827 assembler->Bind(&if_valueisoddball);
3828 {
3829 // The {value} is an Oddball, and every Oddball knows its boolean value.
3830 Node* value_toboolean =
3831 assembler->LoadObjectField(value, Oddball::kToBooleanOffset);
3832 result.Bind(value_toboolean);
3833 assembler->Goto(&end);
3834 }
3835
3836 assembler->Bind(&if_valueisother);
3837 {
3838 Node* value_map_bitfield = assembler->Load(
3839 MachineType::Uint8(), value_map,
3840 assembler->IntPtrConstant(Map::kBitFieldOffset - kHeapObjectTag));
3841 Node* value_map_undetectable = assembler->Word32And(
3842 value_map_bitfield,
3843 assembler->Int32Constant(1 << Map::kIsUndetectable));
3844
3845 // Check if the {value} is undetectable.
3846 assembler->Branch(assembler->Word32Equal(value_map_undetectable,
3847 assembler->Int32Constant(0)),
3848 &return_true, &return_false);
3849 }
3850 }
3851
3852 assembler->Bind(&return_false);
3853 {
3854 result.Bind(assembler->BooleanConstant(false));
3855 assembler->Goto(&end);
3856 }
3857
3858 assembler->Bind(&return_true);
3859 {
3860 result.Bind(assembler->BooleanConstant(true));
3861 assembler->Goto(&end);
3862 }
3863
3864 assembler->Bind(&end);
3865 return result.value();
3866 }
3867
3868 void ToIntegerStub::GenerateAssembly(CodeStubAssembler* assembler) const { 3744 void ToIntegerStub::GenerateAssembly(CodeStubAssembler* assembler) const {
3869 typedef CodeStubAssembler::Label Label; 3745 typedef CodeStubAssembler::Label Label;
3870 typedef compiler::Node Node; 3746 typedef compiler::Node Node;
3871 typedef CodeStubAssembler::Variable Variable; 3747 typedef CodeStubAssembler::Variable Variable;
3872 3748
3873 Node* context = assembler->Parameter(1); 3749 Node* context = assembler->Parameter(1);
3874 3750
3875 // We might need to loop once for ToNumber conversion. 3751 // We might need to loop once for ToNumber conversion.
3876 Variable var_arg(assembler, MachineRepresentation::kTagged); 3752 Variable var_arg(assembler, MachineRepresentation::kTagged);
3877 Label loop(assembler, &var_arg); 3753 Label loop(assembler, &var_arg);
(...skipping 1058 matching lines...) Expand 10 before | Expand all | Expand 10 after
4936 if (type->Is(Type::UntaggedPointer())) { 4812 if (type->Is(Type::UntaggedPointer())) {
4937 return Representation::External(); 4813 return Representation::External();
4938 } 4814 }
4939 4815
4940 DCHECK(!type->Is(Type::Untagged())); 4816 DCHECK(!type->Is(Type::Untagged()));
4941 return Representation::Tagged(); 4817 return Representation::Tagged();
4942 } 4818 }
4943 4819
4944 } // namespace internal 4820 } // namespace internal
4945 } // namespace v8 4821 } // namespace v8
OLDNEW
« no previous file with comments | « src/code-stubs.h ('k') | src/factory.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698