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

Unified Diff: src/code-stubs.cc

Issue 1825793002: [stubs] Introduce code stubs for bitwise binary operations. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/code-stubs.h ('k') | src/compiler/code-stub-assembler.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/code-stubs.cc
diff --git a/src/code-stubs.cc b/src/code-stubs.cc
index 2646787e3b8551ca008640fa9b686b421846168f..67438e5ac28932b0ade564aa2a78959dee0a4a19 100644
--- a/src/code-stubs.cc
+++ b/src/code-stubs.cc
@@ -1035,6 +1035,182 @@ void SubtractStub::GenerateAssembly(
namespace {
+void GenerateBitwiseOperation(
+ compiler::CodeStubAssembler* assembler,
+ compiler::Node* (compiler::CodeStubAssembler::*bitop)(compiler::Node*,
+ compiler::Node*)) {
+ typedef compiler::CodeStubAssembler::Label Label;
+ typedef compiler::Node Node;
+ typedef compiler::CodeStubAssembler::Variable Variable;
+
+ Node* context = assembler->Parameter(2);
+
+ // Shared entry for word32 bitwise operation.
+ Label do_bitop(assembler);
+ Variable var_bitop_lhs(assembler, MachineRepresentation::kWord32),
+ var_bitop_rhs(assembler, MachineRepresentation::kWord32);
+
+ // We might need to loop several times due to ToNumber conversions.
+ Variable var_lhs(assembler, MachineRepresentation::kTagged),
+ var_rhs(assembler, MachineRepresentation::kTagged);
+ Variable* loop_vars[2] = {&var_lhs, &var_rhs};
+ Label loop(assembler, 2, loop_vars);
+ var_lhs.Bind(assembler->Parameter(0));
+ var_rhs.Bind(assembler->Parameter(1));
+ assembler->Goto(&loop);
epertoso 2016/03/23 13:15:39 Wouldn't an 'ObjectToInt32' or similar-named metho
Benedikt Meurer 2016/03/23 13:23:03 Well, you'd still need to distinguish HeapNumber a
epertoso 2016/03/23 13:41:39 As discussed offline, let's leave it like this for
+ assembler->Bind(&loop);
+ {
+ // Load the current {lhs} and {rhs} values.
+ Node* lhs = var_lhs.value();
+ Node* rhs = var_rhs.value();
+
+ // Check if the {lhs} is a Smi or a HeapObject.
+ Label if_lhsissmi(assembler), if_lhsisnotsmi(assembler);
+ assembler->Branch(assembler->WordIsSmi(lhs), &if_lhsissmi, &if_lhsisnotsmi);
+
+ assembler->Bind(&if_lhsissmi);
+ {
+ // Check if the {rhs} is also a Smi.
+ Label if_rhsissmi(assembler), if_rhsisnotsmi(assembler);
+ assembler->Branch(assembler->WordIsSmi(rhs), &if_rhsissmi,
+ &if_rhsisnotsmi);
+
+ assembler->Bind(&if_rhsissmi);
+ {
+ // Perform the word32 bitwise operation.
+ var_bitop_lhs.Bind(assembler->SmiToInt32(lhs));
+ var_bitop_rhs.Bind(assembler->SmiToInt32(rhs));
+ assembler->Goto(&do_bitop);
+ }
+
+ assembler->Bind(&if_rhsisnotsmi);
+ {
+ // Load the map of the {rhs}.
+ Node* rhs_map = assembler->LoadMap(rhs);
+
+ // Check if {rhs} is a HeapNumber.
+ Label if_rhsisnumber(assembler),
+ if_rhsisnotnumber(assembler, Label::kDeferred);
+ Node* number_map = assembler->HeapNumberMapConstant();
+ assembler->Branch(assembler->WordEqual(rhs_map, number_map),
+ &if_rhsisnumber, &if_rhsisnotnumber);
+
+ assembler->Bind(&if_rhsisnumber);
+ {
+ // Perform the word32 bitwise operation.
+ var_bitop_lhs.Bind(assembler->SmiToInt32(lhs));
+ var_bitop_rhs.Bind(assembler->TruncateHeapNumberValueToInt32(rhs));
+ assembler->Goto(&do_bitop);
+ }
+
+ assembler->Bind(&if_rhsisnotnumber);
+ {
+ // Convert the {rhs} to a Number first.
+ Callable callable =
+ CodeFactory::NonNumberToNumber(assembler->isolate());
+ var_rhs.Bind(assembler->CallStub(callable, context, rhs));
+ assembler->Goto(&loop);
+ }
+ }
+ }
+
+ assembler->Bind(&if_lhsisnotsmi);
+ {
+ // Load the map of the {lhs}.
+ Node* lhs_map = assembler->LoadMap(lhs);
+
+ // Check if the {lhs} is a HeapNumber.
+ Label if_lhsisnumber(assembler),
+ if_lhsisnotnumber(assembler, Label::kDeferred);
+ Node* number_map = assembler->HeapNumberMapConstant();
+ assembler->Branch(assembler->WordEqual(lhs_map, number_map),
+ &if_lhsisnumber, &if_lhsisnotnumber);
+
+ assembler->Bind(&if_lhsisnumber);
+ {
+ // Check if the {rhs} is a Smi.
+ Label if_rhsissmi(assembler), if_rhsisnotsmi(assembler);
+ assembler->Branch(assembler->WordIsSmi(rhs), &if_rhsissmi,
+ &if_rhsisnotsmi);
+
+ assembler->Bind(&if_rhsissmi);
+ {
+ // Perform the word32 bitwise operation.
+ var_bitop_lhs.Bind(assembler->TruncateHeapNumberValueToInt32(lhs));
+ var_bitop_rhs.Bind(assembler->SmiToInt32(rhs));
+ assembler->Goto(&do_bitop);
+ }
+
+ assembler->Bind(&if_rhsisnotsmi);
+ {
+ // Load the map of the {rhs}.
+ Node* rhs_map = assembler->LoadMap(rhs);
+
+ // Check if the {rhs} is a HeapNumber.
+ Label if_rhsisnumber(assembler),
+ if_rhsisnotnumber(assembler, Label::kDeferred);
+ assembler->Branch(assembler->WordEqual(rhs_map, number_map),
+ &if_rhsisnumber, &if_rhsisnotnumber);
+
+ assembler->Bind(&if_rhsisnumber);
+ {
+ // Perform the word32 bitwise operation.
+ var_bitop_lhs.Bind(assembler->TruncateHeapNumberValueToInt32(lhs));
+ var_bitop_rhs.Bind(assembler->TruncateHeapNumberValueToInt32(rhs));
+ assembler->Goto(&do_bitop);
+ }
+
+ assembler->Bind(&if_rhsisnotnumber);
+ {
+ // Convert the {rhs} to a Number first.
+ Callable callable =
+ CodeFactory::NonNumberToNumber(assembler->isolate());
+ var_rhs.Bind(assembler->CallStub(callable, context, rhs));
+ assembler->Goto(&loop);
+ }
+ }
+ }
+
+ assembler->Bind(&if_lhsisnotnumber);
+ {
+ // Convert the {lhs} to a Number first.
+ Callable callable =
+ CodeFactory::NonNumberToNumber(assembler->isolate());
+ var_lhs.Bind(assembler->CallStub(callable, context, lhs));
+ assembler->Goto(&loop);
+ }
+ }
+ }
+
+ assembler->Bind(&do_bitop);
+ {
+ Node* lhs_value = var_bitop_lhs.value();
+ Node* rhs_value = var_bitop_rhs.value();
+ Node* value = (assembler->*bitop)(lhs_value, rhs_value);
+ Node* result = assembler->ChangeInt32ToTagged(value);
+ assembler->Return(result);
+ }
+}
+
+} // namespace
+
+void BitwiseAndStub::GenerateAssembly(
+ compiler::CodeStubAssembler* assembler) const {
+ GenerateBitwiseOperation(assembler, &compiler::CodeStubAssembler::Word32And);
+}
+
+void BitwiseOrStub::GenerateAssembly(
+ compiler::CodeStubAssembler* assembler) const {
+ GenerateBitwiseOperation(assembler, &compiler::CodeStubAssembler::Word32Or);
+}
+
+void BitwiseXorStub::GenerateAssembly(
+ compiler::CodeStubAssembler* assembler) const {
+ GenerateBitwiseOperation(assembler, &compiler::CodeStubAssembler::Word32Xor);
+}
+
+namespace {
+
enum RelationalComparisonMode {
kLessThan,
kLessThanOrEqual,
« 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