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

Unified Diff: src/code-stubs.cc

Issue 2372113004: [turbofan] JSGenericLowering mostly uses builtins instead of code stubs now (Closed)
Patch Set: Ross' comments Created 4 years, 2 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/crankshaft/hydrogen.cc » ('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 365ededc1bed166bf09d463337b0153c01701626..3798b79e2bd7ee834c44d7979f5b096e926608e6 100644
--- a/src/code-stubs.cc
+++ b/src/code-stubs.cc
@@ -662,368 +662,6 @@ void StringLengthStub::GenerateAssembly(CodeStubAssembler* assembler) const {
}
// static
-compiler::Node* AddStub::Generate(CodeStubAssembler* assembler,
- compiler::Node* left, compiler::Node* right,
- compiler::Node* context) {
- typedef CodeStubAssembler::Label Label;
- typedef compiler::Node Node;
- typedef CodeStubAssembler::Variable Variable;
-
- // Shared entry for floating point addition.
- Label do_fadd(assembler);
- Variable var_fadd_lhs(assembler, MachineRepresentation::kFloat64),
- var_fadd_rhs(assembler, MachineRepresentation::kFloat64);
-
- // We might need to loop several times due to ToPrimitive, ToString and/or
- // ToNumber conversions.
- Variable var_lhs(assembler, MachineRepresentation::kTagged),
- var_rhs(assembler, MachineRepresentation::kTagged),
- var_result(assembler, MachineRepresentation::kTagged);
- Variable* loop_vars[2] = {&var_lhs, &var_rhs};
- Label loop(assembler, 2, loop_vars), end(assembler),
- string_add_convert_left(assembler, Label::kDeferred),
- string_add_convert_right(assembler, Label::kDeferred);
- var_lhs.Bind(left);
- var_rhs.Bind(right);
- assembler->Goto(&loop);
- 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);
- {
- // Try fast Smi addition first.
- Node* pair = assembler->SmiAddWithOverflow(lhs, rhs);
- Node* overflow = assembler->Projection(1, pair);
-
- // Check if the Smi additon overflowed.
- Label if_overflow(assembler), if_notoverflow(assembler);
- assembler->Branch(overflow, &if_overflow, &if_notoverflow);
-
- assembler->Bind(&if_overflow);
- {
- var_fadd_lhs.Bind(assembler->SmiToFloat64(lhs));
- var_fadd_rhs.Bind(assembler->SmiToFloat64(rhs));
- assembler->Goto(&do_fadd);
- }
-
- assembler->Bind(&if_notoverflow);
- var_result.Bind(assembler->Projection(0, pair));
- assembler->Goto(&end);
- }
-
- assembler->Bind(&if_rhsisnotsmi);
- {
- // Load the map of {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->IsHeapNumberMap(rhs_map), &if_rhsisnumber,
- &if_rhsisnotnumber);
-
- assembler->Bind(&if_rhsisnumber);
- {
- var_fadd_lhs.Bind(assembler->SmiToFloat64(lhs));
- var_fadd_rhs.Bind(assembler->LoadHeapNumberValue(rhs));
- assembler->Goto(&do_fadd);
- }
-
- assembler->Bind(&if_rhsisnotnumber);
- {
- // Load the instance type of {rhs}.
- Node* rhs_instance_type = assembler->LoadMapInstanceType(rhs_map);
-
- // Check if the {rhs} is a String.
- Label if_rhsisstring(assembler, Label::kDeferred),
- if_rhsisnotstring(assembler, Label::kDeferred);
- assembler->Branch(assembler->IsStringInstanceType(rhs_instance_type),
- &if_rhsisstring, &if_rhsisnotstring);
-
- assembler->Bind(&if_rhsisstring);
- {
- var_lhs.Bind(lhs);
- var_rhs.Bind(rhs);
- assembler->Goto(&string_add_convert_left);
- }
-
- assembler->Bind(&if_rhsisnotstring);
- {
- // Check if {rhs} is a JSReceiver.
- Label if_rhsisreceiver(assembler, Label::kDeferred),
- if_rhsisnotreceiver(assembler, Label::kDeferred);
- assembler->Branch(
- assembler->IsJSReceiverInstanceType(rhs_instance_type),
- &if_rhsisreceiver, &if_rhsisnotreceiver);
-
- assembler->Bind(&if_rhsisreceiver);
- {
- // Convert {rhs} to a primitive first passing no hint.
- Callable callable =
- CodeFactory::NonPrimitiveToPrimitive(assembler->isolate());
- var_rhs.Bind(assembler->CallStub(callable, context, rhs));
- assembler->Goto(&loop);
- }
-
- assembler->Bind(&if_rhsisnotreceiver);
- {
- // Convert {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 and instance type of {lhs}.
- Node* lhs_instance_type = assembler->LoadInstanceType(lhs);
-
- // Check if {lhs} is a String.
- Label if_lhsisstring(assembler), if_lhsisnotstring(assembler);
- assembler->Branch(assembler->IsStringInstanceType(lhs_instance_type),
- &if_lhsisstring, &if_lhsisnotstring);
-
- assembler->Bind(&if_lhsisstring);
- {
- var_lhs.Bind(lhs);
- var_rhs.Bind(rhs);
- assembler->Goto(&string_add_convert_right);
- }
-
- assembler->Bind(&if_lhsisnotstring);
- {
- // Check if {rhs} is a Smi.
- Label if_rhsissmi(assembler), if_rhsisnotsmi(assembler);
- assembler->Branch(assembler->WordIsSmi(rhs), &if_rhsissmi,
- &if_rhsisnotsmi);
-
- assembler->Bind(&if_rhsissmi);
- {
- // Check if {lhs} is a Number.
- Label if_lhsisnumber(assembler),
- if_lhsisnotnumber(assembler, Label::kDeferred);
- assembler->Branch(assembler->Word32Equal(
- lhs_instance_type,
- assembler->Int32Constant(HEAP_NUMBER_TYPE)),
- &if_lhsisnumber, &if_lhsisnotnumber);
-
- assembler->Bind(&if_lhsisnumber);
- {
- // The {lhs} is a HeapNumber, the {rhs} is a Smi, just add them.
- var_fadd_lhs.Bind(assembler->LoadHeapNumberValue(lhs));
- var_fadd_rhs.Bind(assembler->SmiToFloat64(rhs));
- assembler->Goto(&do_fadd);
- }
-
- assembler->Bind(&if_lhsisnotnumber);
- {
- // The {lhs} is neither a Number nor a String, and the {rhs} is a
- // Smi.
- Label if_lhsisreceiver(assembler, Label::kDeferred),
- if_lhsisnotreceiver(assembler, Label::kDeferred);
- assembler->Branch(
- assembler->IsJSReceiverInstanceType(lhs_instance_type),
- &if_lhsisreceiver, &if_lhsisnotreceiver);
-
- assembler->Bind(&if_lhsisreceiver);
- {
- // Convert {lhs} to a primitive first passing no hint.
- Callable callable =
- CodeFactory::NonPrimitiveToPrimitive(assembler->isolate());
- var_lhs.Bind(assembler->CallStub(callable, context, lhs));
- assembler->Goto(&loop);
- }
-
- assembler->Bind(&if_lhsisnotreceiver);
- {
- // Convert {lhs} to a Number first.
- Callable callable =
- CodeFactory::NonNumberToNumber(assembler->isolate());
- var_lhs.Bind(assembler->CallStub(callable, context, lhs));
- assembler->Goto(&loop);
- }
- }
- }
-
- assembler->Bind(&if_rhsisnotsmi);
- {
- // Load the instance type of {rhs}.
- Node* rhs_instance_type = assembler->LoadInstanceType(rhs);
-
- // Check if {rhs} is a String.
- Label if_rhsisstring(assembler), if_rhsisnotstring(assembler);
- assembler->Branch(assembler->IsStringInstanceType(rhs_instance_type),
- &if_rhsisstring, &if_rhsisnotstring);
-
- assembler->Bind(&if_rhsisstring);
- {
- var_lhs.Bind(lhs);
- var_rhs.Bind(rhs);
- assembler->Goto(&string_add_convert_left);
- }
-
- assembler->Bind(&if_rhsisnotstring);
- {
- // Check if {lhs} is a HeapNumber.
- Label if_lhsisnumber(assembler), if_lhsisnotnumber(assembler);
- assembler->Branch(assembler->Word32Equal(
- lhs_instance_type,
- assembler->Int32Constant(HEAP_NUMBER_TYPE)),
- &if_lhsisnumber, &if_lhsisnotnumber);
-
- assembler->Bind(&if_lhsisnumber);
- {
- // Check if {rhs} is also a HeapNumber.
- Label if_rhsisnumber(assembler),
- if_rhsisnotnumber(assembler, Label::kDeferred);
- assembler->Branch(assembler->Word32Equal(
- rhs_instance_type,
- assembler->Int32Constant(HEAP_NUMBER_TYPE)),
- &if_rhsisnumber, &if_rhsisnotnumber);
-
- assembler->Bind(&if_rhsisnumber);
- {
- // Perform a floating point addition.
- var_fadd_lhs.Bind(assembler->LoadHeapNumberValue(lhs));
- var_fadd_rhs.Bind(assembler->LoadHeapNumberValue(rhs));
- assembler->Goto(&do_fadd);
- }
-
- assembler->Bind(&if_rhsisnotnumber);
- {
- // Check if {rhs} is a JSReceiver.
- Label if_rhsisreceiver(assembler, Label::kDeferred),
- if_rhsisnotreceiver(assembler, Label::kDeferred);
- assembler->Branch(
- assembler->IsJSReceiverInstanceType(rhs_instance_type),
- &if_rhsisreceiver, &if_rhsisnotreceiver);
-
- assembler->Bind(&if_rhsisreceiver);
- {
- // Convert {rhs} to a primitive first passing no hint.
- Callable callable = CodeFactory::NonPrimitiveToPrimitive(
- assembler->isolate());
- var_rhs.Bind(assembler->CallStub(callable, context, rhs));
- assembler->Goto(&loop);
- }
-
- assembler->Bind(&if_rhsisnotreceiver);
- {
- // Convert {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);
- {
- // Check if {lhs} is a JSReceiver.
- Label if_lhsisreceiver(assembler, Label::kDeferred),
- if_lhsisnotreceiver(assembler);
- assembler->Branch(
- assembler->IsJSReceiverInstanceType(lhs_instance_type),
- &if_lhsisreceiver, &if_lhsisnotreceiver);
-
- assembler->Bind(&if_lhsisreceiver);
- {
- // Convert {lhs} to a primitive first passing no hint.
- Callable callable =
- CodeFactory::NonPrimitiveToPrimitive(assembler->isolate());
- var_lhs.Bind(assembler->CallStub(callable, context, lhs));
- assembler->Goto(&loop);
- }
-
- assembler->Bind(&if_lhsisnotreceiver);
- {
- // Check if {rhs} is a JSReceiver.
- Label if_rhsisreceiver(assembler, Label::kDeferred),
- if_rhsisnotreceiver(assembler, Label::kDeferred);
- assembler->Branch(
- assembler->IsJSReceiverInstanceType(rhs_instance_type),
- &if_rhsisreceiver, &if_rhsisnotreceiver);
-
- assembler->Bind(&if_rhsisreceiver);
- {
- // Convert {rhs} to a primitive first passing no hint.
- Callable callable = CodeFactory::NonPrimitiveToPrimitive(
- assembler->isolate());
- var_rhs.Bind(assembler->CallStub(callable, context, rhs));
- assembler->Goto(&loop);
- }
-
- assembler->Bind(&if_rhsisnotreceiver);
- {
- // Convert {lhs} to a Number first.
- Callable callable =
- CodeFactory::NonNumberToNumber(assembler->isolate());
- var_lhs.Bind(assembler->CallStub(callable, context, lhs));
- assembler->Goto(&loop);
- }
- }
- }
- }
- }
- }
- }
- }
- assembler->Bind(&string_add_convert_left);
- {
- // Convert {lhs}, which is a Smi, to a String and concatenate the
- // resulting string with the String {rhs}.
- Callable callable = CodeFactory::StringAdd(
- assembler->isolate(), STRING_ADD_CONVERT_LEFT, NOT_TENURED);
- var_result.Bind(assembler->CallStub(callable, context, var_lhs.value(),
- var_rhs.value()));
- assembler->Goto(&end);
- }
-
- assembler->Bind(&string_add_convert_right);
- {
- // Convert {lhs}, which is a Smi, to a String and concatenate the
- // resulting string with the String {rhs}.
- Callable callable = CodeFactory::StringAdd(
- assembler->isolate(), STRING_ADD_CONVERT_RIGHT, NOT_TENURED);
- var_result.Bind(assembler->CallStub(callable, context, var_lhs.value(),
- var_rhs.value()));
- assembler->Goto(&end);
- }
-
- assembler->Bind(&do_fadd);
- {
- Node* lhs_value = var_fadd_lhs.value();
- Node* rhs_value = var_fadd_rhs.value();
- Node* value = assembler->Float64Add(lhs_value, rhs_value);
- Node* result = assembler->ChangeFloat64ToTagged(value);
- var_result.Bind(result);
- assembler->Goto(&end);
- }
- assembler->Bind(&end);
- return var_result.value();
-}
-
-// static
compiler::Node* AddWithFeedbackStub::Generate(
CodeStubAssembler* assembler, compiler::Node* lhs, compiler::Node* rhs,
compiler::Node* slot_id, compiler::Node* type_feedback_vector,
@@ -1180,180 +818,6 @@ compiler::Node* AddWithFeedbackStub::Generate(
}
// static
-compiler::Node* SubtractStub::Generate(CodeStubAssembler* assembler,
- compiler::Node* left,
- compiler::Node* right,
- compiler::Node* context) {
- typedef CodeStubAssembler::Label Label;
- typedef compiler::Node Node;
- typedef CodeStubAssembler::Variable Variable;
-
- // Shared entry for floating point subtraction.
- Label do_fsub(assembler), end(assembler);
- Variable var_fsub_lhs(assembler, MachineRepresentation::kFloat64),
- var_fsub_rhs(assembler, MachineRepresentation::kFloat64);
-
- // We might need to loop several times due to ToPrimitive and/or ToNumber
- // conversions.
- Variable var_lhs(assembler, MachineRepresentation::kTagged),
- var_rhs(assembler, MachineRepresentation::kTagged),
- var_result(assembler, MachineRepresentation::kTagged);
- Variable* loop_vars[2] = {&var_lhs, &var_rhs};
- Label loop(assembler, 2, loop_vars);
- var_lhs.Bind(left);
- var_rhs.Bind(right);
- assembler->Goto(&loop);
- 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);
- {
- // Try a fast Smi subtraction first.
- Node* pair = assembler->SmiSubWithOverflow(lhs, rhs);
- Node* overflow = assembler->Projection(1, pair);
-
- // Check if the Smi subtraction overflowed.
- Label if_overflow(assembler), if_notoverflow(assembler);
- assembler->Branch(overflow, &if_overflow, &if_notoverflow);
-
- assembler->Bind(&if_overflow);
- {
- // The result doesn't fit into Smi range.
- var_fsub_lhs.Bind(assembler->SmiToFloat64(lhs));
- var_fsub_rhs.Bind(assembler->SmiToFloat64(rhs));
- assembler->Goto(&do_fsub);
- }
-
- assembler->Bind(&if_notoverflow);
- var_result.Bind(assembler->Projection(0, pair));
- assembler->Goto(&end);
- }
-
- 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);
- assembler->Branch(assembler->IsHeapNumberMap(rhs_map), &if_rhsisnumber,
- &if_rhsisnotnumber);
-
- assembler->Bind(&if_rhsisnumber);
- {
- // Perform a floating point subtraction.
- var_fsub_lhs.Bind(assembler->SmiToFloat64(lhs));
- var_fsub_rhs.Bind(assembler->LoadHeapNumberValue(rhs));
- assembler->Goto(&do_fsub);
- }
-
- 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 a floating point subtraction.
- var_fsub_lhs.Bind(assembler->LoadHeapNumberValue(lhs));
- var_fsub_rhs.Bind(assembler->SmiToFloat64(rhs));
- assembler->Goto(&do_fsub);
- }
-
- 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 a floating point subtraction.
- var_fsub_lhs.Bind(assembler->LoadHeapNumberValue(lhs));
- var_fsub_rhs.Bind(assembler->LoadHeapNumberValue(rhs));
- assembler->Goto(&do_fsub);
- }
-
- 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_fsub);
- {
- Node* lhs_value = var_fsub_lhs.value();
- Node* rhs_value = var_fsub_rhs.value();
- Node* value = assembler->Float64Sub(lhs_value, rhs_value);
- var_result.Bind(assembler->ChangeFloat64ToTagged(value));
- assembler->Goto(&end);
- }
- assembler->Bind(&end);
- return var_result.value();
-}
-
-// static
compiler::Node* SubtractWithFeedbackStub::Generate(
CodeStubAssembler* assembler, compiler::Node* lhs, compiler::Node* rhs,
compiler::Node* slot_id, compiler::Node* type_feedback_vector,
@@ -1486,158 +950,6 @@ compiler::Node* SubtractWithFeedbackStub::Generate(
return var_result.value();
}
-// static
-compiler::Node* MultiplyStub::Generate(CodeStubAssembler* assembler,
- compiler::Node* left,
- compiler::Node* right,
- compiler::Node* context) {
- using compiler::Node;
- typedef CodeStubAssembler::Label Label;
- typedef CodeStubAssembler::Variable Variable;
-
- // Shared entry point for floating point multiplication.
- Label do_fmul(assembler), return_result(assembler);
- Variable var_lhs_float64(assembler, MachineRepresentation::kFloat64),
- var_rhs_float64(assembler, MachineRepresentation::kFloat64);
-
- Node* number_map = assembler->HeapNumberMapConstant();
-
- // We might need to loop one or two times due to ToNumber conversions.
- Variable var_lhs(assembler, MachineRepresentation::kTagged),
- var_rhs(assembler, MachineRepresentation::kTagged),
- var_result(assembler, MachineRepresentation::kTagged);
- Variable* loop_variables[] = {&var_lhs, &var_rhs};
- Label loop(assembler, 2, loop_variables);
- var_lhs.Bind(left);
- var_rhs.Bind(right);
- assembler->Goto(&loop);
- assembler->Bind(&loop);
- {
- Node* lhs = var_lhs.value();
- Node* rhs = var_rhs.value();
-
- Label lhs_is_smi(assembler), lhs_is_not_smi(assembler);
- assembler->Branch(assembler->WordIsSmi(lhs), &lhs_is_smi, &lhs_is_not_smi);
-
- assembler->Bind(&lhs_is_smi);
- {
- Label rhs_is_smi(assembler), rhs_is_not_smi(assembler);
- assembler->Branch(assembler->WordIsSmi(rhs), &rhs_is_smi,
- &rhs_is_not_smi);
-
- assembler->Bind(&rhs_is_smi);
- {
- // Both {lhs} and {rhs} are Smis. The result is not necessarily a smi,
- // in case of overflow.
- var_result.Bind(assembler->SmiMul(lhs, rhs));
- assembler->Goto(&return_result);
- }
-
- assembler->Bind(&rhs_is_not_smi);
- {
- Node* rhs_map = assembler->LoadMap(rhs);
-
- // Check if {rhs} is a HeapNumber.
- Label rhs_is_number(assembler),
- rhs_is_not_number(assembler, Label::kDeferred);
- assembler->Branch(assembler->WordEqual(rhs_map, number_map),
- &rhs_is_number, &rhs_is_not_number);
-
- assembler->Bind(&rhs_is_number);
- {
- // Convert {lhs} to a double and multiply it with the value of {rhs}.
- var_lhs_float64.Bind(assembler->SmiToFloat64(lhs));
- var_rhs_float64.Bind(assembler->LoadHeapNumberValue(rhs));
- assembler->Goto(&do_fmul);
- }
-
- assembler->Bind(&rhs_is_not_number);
- {
- // Multiplication is commutative, swap {lhs} with {rhs} and loop.
- var_lhs.Bind(rhs);
- var_rhs.Bind(lhs);
- assembler->Goto(&loop);
- }
- }
- }
-
- assembler->Bind(&lhs_is_not_smi);
- {
- Node* lhs_map = assembler->LoadMap(lhs);
-
- // Check if {lhs} is a HeapNumber.
- Label lhs_is_number(assembler),
- lhs_is_not_number(assembler, Label::kDeferred);
- assembler->Branch(assembler->WordEqual(lhs_map, number_map),
- &lhs_is_number, &lhs_is_not_number);
-
- assembler->Bind(&lhs_is_number);
- {
- // Check if {rhs} is a Smi.
- Label rhs_is_smi(assembler), rhs_is_not_smi(assembler);
- assembler->Branch(assembler->WordIsSmi(rhs), &rhs_is_smi,
- &rhs_is_not_smi);
-
- assembler->Bind(&rhs_is_smi);
- {
- // Convert {rhs} to a double and multiply it with the value of {lhs}.
- var_lhs_float64.Bind(assembler->LoadHeapNumberValue(lhs));
- var_rhs_float64.Bind(assembler->SmiToFloat64(rhs));
- assembler->Goto(&do_fmul);
- }
-
- assembler->Bind(&rhs_is_not_smi);
- {
- Node* rhs_map = assembler->LoadMap(rhs);
-
- // Check if {rhs} is a HeapNumber.
- Label rhs_is_number(assembler),
- rhs_is_not_number(assembler, Label::kDeferred);
- assembler->Branch(assembler->WordEqual(rhs_map, number_map),
- &rhs_is_number, &rhs_is_not_number);
-
- assembler->Bind(&rhs_is_number);
- {
- // Both {lhs} and {rhs} are HeapNumbers. Load their values and
- // multiply them.
- var_lhs_float64.Bind(assembler->LoadHeapNumberValue(lhs));
- var_rhs_float64.Bind(assembler->LoadHeapNumberValue(rhs));
- assembler->Goto(&do_fmul);
- }
-
- assembler->Bind(&rhs_is_not_number);
- {
- // Multiplication is commutative, swap {lhs} with {rhs} and loop.
- var_lhs.Bind(rhs);
- var_rhs.Bind(lhs);
- assembler->Goto(&loop);
- }
- }
- }
-
- assembler->Bind(&lhs_is_not_number);
- {
- // Convert {lhs} to a Number and loop.
- Callable callable =
- CodeFactory::NonNumberToNumber(assembler->isolate());
- var_lhs.Bind(assembler->CallStub(callable, context, lhs));
- assembler->Goto(&loop);
- }
- }
- }
-
- assembler->Bind(&do_fmul);
- {
- Node* value =
- assembler->Float64Mul(var_lhs_float64.value(), var_rhs_float64.value());
- Node* result = assembler->ChangeFloat64ToTagged(value);
- var_result.Bind(result);
- assembler->Goto(&return_result);
- }
-
- assembler->Bind(&return_result);
- return var_result.value();
-}
// static
compiler::Node* MultiplyWithFeedbackStub::Generate(
@@ -1756,290 +1068,73 @@ compiler::Node* MultiplyWithFeedbackStub::Generate(
return var_result.value();
}
+
// static
-compiler::Node* DivideStub::Generate(CodeStubAssembler* assembler,
- compiler::Node* left,
- compiler::Node* right,
- compiler::Node* context) {
+compiler::Node* DivideWithFeedbackStub::Generate(
+ CodeStubAssembler* assembler, compiler::Node* dividend,
+ compiler::Node* divisor, compiler::Node* slot_id,
+ compiler::Node* type_feedback_vector, compiler::Node* context) {
using compiler::Node;
typedef CodeStubAssembler::Label Label;
typedef CodeStubAssembler::Variable Variable;
// Shared entry point for floating point division.
- Label do_fdiv(assembler), end(assembler);
+ Label do_fdiv(assembler), end(assembler), call_divide_stub(assembler);
Variable var_dividend_float64(assembler, MachineRepresentation::kFloat64),
- var_divisor_float64(assembler, MachineRepresentation::kFloat64);
+ var_divisor_float64(assembler, MachineRepresentation::kFloat64),
+ var_result(assembler, MachineRepresentation::kTagged),
+ var_type_feedback(assembler, MachineRepresentation::kWord32);
Node* number_map = assembler->HeapNumberMapConstant();
- // We might need to loop one or two times due to ToNumber conversions.
- Variable var_dividend(assembler, MachineRepresentation::kTagged),
- var_divisor(assembler, MachineRepresentation::kTagged),
- var_result(assembler, MachineRepresentation::kTagged);
- Variable* loop_variables[] = {&var_dividend, &var_divisor};
- Label loop(assembler, 2, loop_variables);
- var_dividend.Bind(left);
- var_divisor.Bind(right);
- assembler->Goto(&loop);
- assembler->Bind(&loop);
- {
- Node* dividend = var_dividend.value();
- Node* divisor = var_divisor.value();
+ Label dividend_is_smi(assembler), dividend_is_not_smi(assembler);
+ assembler->Branch(assembler->WordIsSmi(dividend), &dividend_is_smi,
+ &dividend_is_not_smi);
- Label dividend_is_smi(assembler), dividend_is_not_smi(assembler);
- assembler->Branch(assembler->WordIsSmi(dividend), &dividend_is_smi,
- &dividend_is_not_smi);
+ assembler->Bind(&dividend_is_smi);
+ {
+ Label divisor_is_smi(assembler), divisor_is_not_smi(assembler);
+ assembler->Branch(assembler->WordIsSmi(divisor), &divisor_is_smi,
+ &divisor_is_not_smi);
- assembler->Bind(&dividend_is_smi);
+ assembler->Bind(&divisor_is_smi);
{
- Label divisor_is_smi(assembler), divisor_is_not_smi(assembler);
- assembler->Branch(assembler->WordIsSmi(divisor), &divisor_is_smi,
- &divisor_is_not_smi);
+ Label bailout(assembler);
- assembler->Bind(&divisor_is_smi);
- {
- Label bailout(assembler);
+ // Do floating point division if {divisor} is zero.
+ assembler->GotoIf(
+ assembler->WordEqual(divisor, assembler->IntPtrConstant(0)),
+ &bailout);
+
+ // Do floating point division {dividend} is zero and {divisor} is
+ // negative.
+ Label dividend_is_zero(assembler), dividend_is_not_zero(assembler);
+ assembler->Branch(
+ assembler->WordEqual(dividend, assembler->IntPtrConstant(0)),
+ &dividend_is_zero, &dividend_is_not_zero);
- // Do floating point division if {divisor} is zero.
+ assembler->Bind(&dividend_is_zero);
+ {
assembler->GotoIf(
- assembler->WordEqual(divisor, assembler->IntPtrConstant(0)),
+ assembler->IntPtrLessThan(divisor, assembler->IntPtrConstant(0)),
&bailout);
+ assembler->Goto(&dividend_is_not_zero);
+ }
+ assembler->Bind(&dividend_is_not_zero);
- // Do floating point division {dividend} is zero and {divisor} is
- // negative.
- Label dividend_is_zero(assembler), dividend_is_not_zero(assembler);
- assembler->Branch(
- assembler->WordEqual(dividend, assembler->IntPtrConstant(0)),
- &dividend_is_zero, &dividend_is_not_zero);
-
- assembler->Bind(&dividend_is_zero);
- {
- assembler->GotoIf(
- assembler->IntPtrLessThan(divisor, assembler->IntPtrConstant(0)),
- &bailout);
- assembler->Goto(&dividend_is_not_zero);
- }
- assembler->Bind(&dividend_is_not_zero);
-
- Node* untagged_divisor = assembler->SmiUntag(divisor);
- Node* untagged_dividend = assembler->SmiUntag(dividend);
+ Node* untagged_divisor = assembler->SmiUntag(divisor);
+ Node* untagged_dividend = assembler->SmiUntag(dividend);
- // Do floating point division if {dividend} is kMinInt (or kMinInt - 1
- // if the Smi size is 31) and {divisor} is -1.
- Label divisor_is_minus_one(assembler),
- divisor_is_not_minus_one(assembler);
- assembler->Branch(assembler->Word32Equal(untagged_divisor,
- assembler->Int32Constant(-1)),
- &divisor_is_minus_one, &divisor_is_not_minus_one);
+ // Do floating point division if {dividend} is kMinInt (or kMinInt - 1
+ // if the Smi size is 31) and {divisor} is -1.
+ Label divisor_is_minus_one(assembler),
+ divisor_is_not_minus_one(assembler);
+ assembler->Branch(assembler->Word32Equal(untagged_divisor,
+ assembler->Int32Constant(-1)),
+ &divisor_is_minus_one, &divisor_is_not_minus_one);
- assembler->Bind(&divisor_is_minus_one);
- {
- assembler->GotoIf(
- assembler->Word32Equal(
- untagged_dividend,
- assembler->Int32Constant(
- kSmiValueSize == 32 ? kMinInt : (kMinInt >> 1))),
- &bailout);
- assembler->Goto(&divisor_is_not_minus_one);
- }
- assembler->Bind(&divisor_is_not_minus_one);
-
- // TODO(epertoso): consider adding a machine instruction that returns
- // both the result and the remainder.
- Node* untagged_result =
- assembler->Int32Div(untagged_dividend, untagged_divisor);
- Node* truncated =
- assembler->Int32Mul(untagged_result, untagged_divisor);
- // Do floating point division if the remainder is not 0.
- assembler->GotoIf(
- assembler->Word32NotEqual(untagged_dividend, truncated), &bailout);
- var_result.Bind(assembler->SmiTag(untagged_result));
- assembler->Goto(&end);
-
- // Bailout: convert {dividend} and {divisor} to double and do double
- // division.
- assembler->Bind(&bailout);
- {
- var_dividend_float64.Bind(assembler->SmiToFloat64(dividend));
- var_divisor_float64.Bind(assembler->SmiToFloat64(divisor));
- assembler->Goto(&do_fdiv);
- }
- }
-
- assembler->Bind(&divisor_is_not_smi);
- {
- Node* divisor_map = assembler->LoadMap(divisor);
-
- // Check if {divisor} is a HeapNumber.
- Label divisor_is_number(assembler),
- divisor_is_not_number(assembler, Label::kDeferred);
- assembler->Branch(assembler->WordEqual(divisor_map, number_map),
- &divisor_is_number, &divisor_is_not_number);
-
- assembler->Bind(&divisor_is_number);
- {
- // Convert {dividend} to a double and divide it with the value of
- // {divisor}.
- var_dividend_float64.Bind(assembler->SmiToFloat64(dividend));
- var_divisor_float64.Bind(assembler->LoadHeapNumberValue(divisor));
- assembler->Goto(&do_fdiv);
- }
-
- assembler->Bind(&divisor_is_not_number);
- {
- // Convert {divisor} to a number and loop.
- Callable callable =
- CodeFactory::NonNumberToNumber(assembler->isolate());
- var_divisor.Bind(assembler->CallStub(callable, context, divisor));
- assembler->Goto(&loop);
- }
- }
- }
-
- assembler->Bind(&dividend_is_not_smi);
- {
- Node* dividend_map = assembler->LoadMap(dividend);
-
- // Check if {dividend} is a HeapNumber.
- Label dividend_is_number(assembler),
- dividend_is_not_number(assembler, Label::kDeferred);
- assembler->Branch(assembler->WordEqual(dividend_map, number_map),
- &dividend_is_number, &dividend_is_not_number);
-
- assembler->Bind(&dividend_is_number);
- {
- // Check if {divisor} is a Smi.
- Label divisor_is_smi(assembler), divisor_is_not_smi(assembler);
- assembler->Branch(assembler->WordIsSmi(divisor), &divisor_is_smi,
- &divisor_is_not_smi);
-
- assembler->Bind(&divisor_is_smi);
- {
- // Convert {divisor} to a double and use it for a floating point
- // division.
- var_dividend_float64.Bind(assembler->LoadHeapNumberValue(dividend));
- var_divisor_float64.Bind(assembler->SmiToFloat64(divisor));
- assembler->Goto(&do_fdiv);
- }
-
- assembler->Bind(&divisor_is_not_smi);
- {
- Node* divisor_map = assembler->LoadMap(divisor);
-
- // Check if {divisor} is a HeapNumber.
- Label divisor_is_number(assembler),
- divisor_is_not_number(assembler, Label::kDeferred);
- assembler->Branch(assembler->WordEqual(divisor_map, number_map),
- &divisor_is_number, &divisor_is_not_number);
-
- assembler->Bind(&divisor_is_number);
- {
- // Both {dividend} and {divisor} are HeapNumbers. Load their values
- // and divide them.
- var_dividend_float64.Bind(assembler->LoadHeapNumberValue(dividend));
- var_divisor_float64.Bind(assembler->LoadHeapNumberValue(divisor));
- assembler->Goto(&do_fdiv);
- }
-
- assembler->Bind(&divisor_is_not_number);
- {
- // Convert {divisor} to a number and loop.
- Callable callable =
- CodeFactory::NonNumberToNumber(assembler->isolate());
- var_divisor.Bind(assembler->CallStub(callable, context, divisor));
- assembler->Goto(&loop);
- }
- }
- }
-
- assembler->Bind(&dividend_is_not_number);
- {
- // Convert {dividend} to a Number and loop.
- Callable callable =
- CodeFactory::NonNumberToNumber(assembler->isolate());
- var_dividend.Bind(assembler->CallStub(callable, context, dividend));
- assembler->Goto(&loop);
- }
- }
- }
-
- assembler->Bind(&do_fdiv);
- {
- Node* value = assembler->Float64Div(var_dividend_float64.value(),
- var_divisor_float64.value());
- var_result.Bind(assembler->ChangeFloat64ToTagged(value));
- assembler->Goto(&end);
- }
- assembler->Bind(&end);
- return var_result.value();
-}
-
-// static
-compiler::Node* DivideWithFeedbackStub::Generate(
- CodeStubAssembler* assembler, compiler::Node* dividend,
- compiler::Node* divisor, compiler::Node* slot_id,
- compiler::Node* type_feedback_vector, compiler::Node* context) {
- using compiler::Node;
- typedef CodeStubAssembler::Label Label;
- typedef CodeStubAssembler::Variable Variable;
-
- // Shared entry point for floating point division.
- Label do_fdiv(assembler), end(assembler), call_divide_stub(assembler);
- Variable var_dividend_float64(assembler, MachineRepresentation::kFloat64),
- var_divisor_float64(assembler, MachineRepresentation::kFloat64),
- var_result(assembler, MachineRepresentation::kTagged),
- var_type_feedback(assembler, MachineRepresentation::kWord32);
-
- Node* number_map = assembler->HeapNumberMapConstant();
-
- Label dividend_is_smi(assembler), dividend_is_not_smi(assembler);
- assembler->Branch(assembler->WordIsSmi(dividend), &dividend_is_smi,
- &dividend_is_not_smi);
-
- assembler->Bind(&dividend_is_smi);
- {
- Label divisor_is_smi(assembler), divisor_is_not_smi(assembler);
- assembler->Branch(assembler->WordIsSmi(divisor), &divisor_is_smi,
- &divisor_is_not_smi);
-
- assembler->Bind(&divisor_is_smi);
- {
- Label bailout(assembler);
-
- // Do floating point division if {divisor} is zero.
- assembler->GotoIf(
- assembler->WordEqual(divisor, assembler->IntPtrConstant(0)),
- &bailout);
-
- // Do floating point division {dividend} is zero and {divisor} is
- // negative.
- Label dividend_is_zero(assembler), dividend_is_not_zero(assembler);
- assembler->Branch(
- assembler->WordEqual(dividend, assembler->IntPtrConstant(0)),
- &dividend_is_zero, &dividend_is_not_zero);
-
- assembler->Bind(&dividend_is_zero);
- {
- assembler->GotoIf(
- assembler->IntPtrLessThan(divisor, assembler->IntPtrConstant(0)),
- &bailout);
- assembler->Goto(&dividend_is_not_zero);
- }
- assembler->Bind(&dividend_is_not_zero);
-
- Node* untagged_divisor = assembler->SmiUntag(divisor);
- Node* untagged_dividend = assembler->SmiUntag(dividend);
-
- // Do floating point division if {dividend} is kMinInt (or kMinInt - 1
- // if the Smi size is 31) and {divisor} is -1.
- Label divisor_is_minus_one(assembler),
- divisor_is_not_minus_one(assembler);
- assembler->Branch(assembler->Word32Equal(untagged_divisor,
- assembler->Int32Constant(-1)),
- &divisor_is_minus_one, &divisor_is_not_minus_one);
-
- assembler->Bind(&divisor_is_minus_one);
- {
+ assembler->Bind(&divisor_is_minus_one);
+ {
assembler->GotoIf(
assembler->Word32Equal(
untagged_dividend,
@@ -2151,165 +1246,6 @@ compiler::Node* DivideWithFeedbackStub::Generate(
}
// static
-compiler::Node* ModulusStub::Generate(CodeStubAssembler* assembler,
- compiler::Node* left,
- compiler::Node* right,
- compiler::Node* context) {
- using compiler::Node;
- typedef CodeStubAssembler::Label Label;
- typedef CodeStubAssembler::Variable Variable;
-
- Variable var_result(assembler, MachineRepresentation::kTagged);
- Label return_result(assembler, &var_result);
-
- // Shared entry point for floating point modulus.
- Label do_fmod(assembler);
- Variable var_dividend_float64(assembler, MachineRepresentation::kFloat64),
- var_divisor_float64(assembler, MachineRepresentation::kFloat64);
-
- Node* number_map = assembler->HeapNumberMapConstant();
-
- // We might need to loop one or two times due to ToNumber conversions.
- Variable var_dividend(assembler, MachineRepresentation::kTagged),
- var_divisor(assembler, MachineRepresentation::kTagged);
- Variable* loop_variables[] = {&var_dividend, &var_divisor};
- Label loop(assembler, 2, loop_variables);
- var_dividend.Bind(left);
- var_divisor.Bind(right);
- assembler->Goto(&loop);
- assembler->Bind(&loop);
- {
- Node* dividend = var_dividend.value();
- Node* divisor = var_divisor.value();
-
- Label dividend_is_smi(assembler), dividend_is_not_smi(assembler);
- assembler->Branch(assembler->WordIsSmi(dividend), &dividend_is_smi,
- &dividend_is_not_smi);
-
- assembler->Bind(&dividend_is_smi);
- {
- Label dividend_is_not_zero(assembler);
- Label divisor_is_smi(assembler), divisor_is_not_smi(assembler);
- assembler->Branch(assembler->WordIsSmi(divisor), &divisor_is_smi,
- &divisor_is_not_smi);
-
- assembler->Bind(&divisor_is_smi);
- {
- // Compute the modulus of two Smis.
- var_result.Bind(assembler->SmiMod(dividend, divisor));
- assembler->Goto(&return_result);
- }
-
- assembler->Bind(&divisor_is_not_smi);
- {
- Node* divisor_map = assembler->LoadMap(divisor);
-
- // Check if {divisor} is a HeapNumber.
- Label divisor_is_number(assembler),
- divisor_is_not_number(assembler, Label::kDeferred);
- assembler->Branch(assembler->WordEqual(divisor_map, number_map),
- &divisor_is_number, &divisor_is_not_number);
-
- assembler->Bind(&divisor_is_number);
- {
- // Convert {dividend} to a double and compute its modulus with the
- // value of {dividend}.
- var_dividend_float64.Bind(assembler->SmiToFloat64(dividend));
- var_divisor_float64.Bind(assembler->LoadHeapNumberValue(divisor));
- assembler->Goto(&do_fmod);
- }
-
- assembler->Bind(&divisor_is_not_number);
- {
- // Convert {divisor} to a number and loop.
- Callable callable =
- CodeFactory::NonNumberToNumber(assembler->isolate());
- var_divisor.Bind(assembler->CallStub(callable, context, divisor));
- assembler->Goto(&loop);
- }
- }
- }
-
- assembler->Bind(&dividend_is_not_smi);
- {
- Node* dividend_map = assembler->LoadMap(dividend);
-
- // Check if {dividend} is a HeapNumber.
- Label dividend_is_number(assembler),
- dividend_is_not_number(assembler, Label::kDeferred);
- assembler->Branch(assembler->WordEqual(dividend_map, number_map),
- &dividend_is_number, &dividend_is_not_number);
-
- assembler->Bind(&dividend_is_number);
- {
- // Check if {divisor} is a Smi.
- Label divisor_is_smi(assembler), divisor_is_not_smi(assembler);
- assembler->Branch(assembler->WordIsSmi(divisor), &divisor_is_smi,
- &divisor_is_not_smi);
-
- assembler->Bind(&divisor_is_smi);
- {
- // Convert {divisor} to a double and compute {dividend}'s modulus with
- // it.
- var_dividend_float64.Bind(assembler->LoadHeapNumberValue(dividend));
- var_divisor_float64.Bind(assembler->SmiToFloat64(divisor));
- assembler->Goto(&do_fmod);
- }
-
- assembler->Bind(&divisor_is_not_smi);
- {
- Node* divisor_map = assembler->LoadMap(divisor);
-
- // Check if {divisor} is a HeapNumber.
- Label divisor_is_number(assembler),
- divisor_is_not_number(assembler, Label::kDeferred);
- assembler->Branch(assembler->WordEqual(divisor_map, number_map),
- &divisor_is_number, &divisor_is_not_number);
-
- assembler->Bind(&divisor_is_number);
- {
- // Both {dividend} and {divisor} are HeapNumbers. Load their values
- // and compute their modulus.
- var_dividend_float64.Bind(assembler->LoadHeapNumberValue(dividend));
- var_divisor_float64.Bind(assembler->LoadHeapNumberValue(divisor));
- assembler->Goto(&do_fmod);
- }
-
- assembler->Bind(&divisor_is_not_number);
- {
- // Convert {divisor} to a number and loop.
- Callable callable =
- CodeFactory::NonNumberToNumber(assembler->isolate());
- var_divisor.Bind(assembler->CallStub(callable, context, divisor));
- assembler->Goto(&loop);
- }
- }
- }
-
- assembler->Bind(&dividend_is_not_number);
- {
- // Convert {dividend} to a Number and loop.
- Callable callable =
- CodeFactory::NonNumberToNumber(assembler->isolate());
- var_dividend.Bind(assembler->CallStub(callable, context, dividend));
- assembler->Goto(&loop);
- }
- }
- }
-
- assembler->Bind(&do_fmod);
- {
- Node* value = assembler->Float64Mod(var_dividend_float64.value(),
- var_divisor_float64.value());
- var_result.Bind(assembler->ChangeFloat64ToTagged(value));
- assembler->Goto(&return_result);
- }
-
- assembler->Bind(&return_result);
- return var_result.value();
-}
-
-// static
compiler::Node* ModulusWithFeedbackStub::Generate(
CodeStubAssembler* assembler, compiler::Node* dividend,
compiler::Node* divisor, compiler::Node* slot_id,
@@ -2425,95 +1361,6 @@ compiler::Node* ModulusWithFeedbackStub::Generate(
slot_id);
return var_result.value();
}
-// static
-compiler::Node* ShiftLeftStub::Generate(CodeStubAssembler* assembler,
- compiler::Node* left,
- compiler::Node* right,
- compiler::Node* context) {
- using compiler::Node;
-
- Node* lhs_value = assembler->TruncateTaggedToWord32(context, left);
- Node* rhs_value = assembler->TruncateTaggedToWord32(context, right);
- Node* shift_count =
- assembler->Word32And(rhs_value, assembler->Int32Constant(0x1f));
- Node* value = assembler->Word32Shl(lhs_value, shift_count);
- Node* result = assembler->ChangeInt32ToTagged(value);
- return result;
-}
-
-// static
-compiler::Node* ShiftRightStub::Generate(CodeStubAssembler* assembler,
- compiler::Node* left,
- compiler::Node* right,
- compiler::Node* context) {
- using compiler::Node;
-
- Node* lhs_value = assembler->TruncateTaggedToWord32(context, left);
- Node* rhs_value = assembler->TruncateTaggedToWord32(context, right);
- Node* shift_count =
- assembler->Word32And(rhs_value, assembler->Int32Constant(0x1f));
- Node* value = assembler->Word32Sar(lhs_value, shift_count);
- Node* result = assembler->ChangeInt32ToTagged(value);
- return result;
-}
-
-// static
-compiler::Node* ShiftRightLogicalStub::Generate(CodeStubAssembler* assembler,
- compiler::Node* left,
- compiler::Node* right,
- compiler::Node* context) {
- using compiler::Node;
-
- Node* lhs_value = assembler->TruncateTaggedToWord32(context, left);
- Node* rhs_value = assembler->TruncateTaggedToWord32(context, right);
- Node* shift_count =
- assembler->Word32And(rhs_value, assembler->Int32Constant(0x1f));
- Node* value = assembler->Word32Shr(lhs_value, shift_count);
- Node* result = assembler->ChangeUint32ToTagged(value);
- return result;
-}
-
-// static
-compiler::Node* BitwiseAndStub::Generate(CodeStubAssembler* assembler,
- compiler::Node* left,
- compiler::Node* right,
- compiler::Node* context) {
- using compiler::Node;
-
- Node* lhs_value = assembler->TruncateTaggedToWord32(context, left);
- Node* rhs_value = assembler->TruncateTaggedToWord32(context, right);
- Node* value = assembler->Word32And(lhs_value, rhs_value);
- Node* result = assembler->ChangeInt32ToTagged(value);
- return result;
-}
-
-// static
-compiler::Node* BitwiseOrStub::Generate(CodeStubAssembler* assembler,
- compiler::Node* left,
- compiler::Node* right,
- compiler::Node* context) {
- using compiler::Node;
-
- Node* lhs_value = assembler->TruncateTaggedToWord32(context, left);
- Node* rhs_value = assembler->TruncateTaggedToWord32(context, right);
- Node* value = assembler->Word32Or(lhs_value, rhs_value);
- Node* result = assembler->ChangeInt32ToTagged(value);
- return result;
-}
-
-// static
-compiler::Node* BitwiseXorStub::Generate(CodeStubAssembler* assembler,
- compiler::Node* left,
- compiler::Node* right,
- compiler::Node* context) {
- using compiler::Node;
-
- Node* lhs_value = assembler->TruncateTaggedToWord32(context, left);
- Node* rhs_value = assembler->TruncateTaggedToWord32(context, right);
- Node* value = assembler->Word32Xor(lhs_value, rhs_value);
- Node* result = assembler->ChangeInt32ToTagged(value);
- return result;
-}
// static
compiler::Node* IncStub::Generate(CodeStubAssembler* assembler,
@@ -2595,1573 +1442,140 @@ compiler::Node* IncStub::Generate(CodeStubAssembler* assembler,
var_type_feedback.Bind(
assembler->Int32Constant(BinaryOperationFeedback::kAny));
value_var.Bind(assembler->CallStub(callable, context, value));
- assembler->Goto(&start);
- }
- }
- }
-
- assembler->Bind(&do_finc);
- {
- Node* finc_value = var_finc_value.value();
- Node* one = assembler->Float64Constant(1.0);
- Node* finc_result = assembler->Float64Add(finc_value, one);
- var_type_feedback.Bind(assembler->Word32Or(
- var_type_feedback.value(),
- assembler->Int32Constant(BinaryOperationFeedback::kNumber)));
- result_var.Bind(assembler->ChangeFloat64ToTagged(finc_result));
- assembler->Goto(&end);
- }
-
- assembler->Bind(&end);
- assembler->UpdateFeedback(var_type_feedback.value(), type_feedback_vector,
- slot_id);
- return result_var.value();
-}
-
-// static
-compiler::Node* DecStub::Generate(CodeStubAssembler* assembler,
- compiler::Node* value,
- compiler::Node* context,
- compiler::Node* type_feedback_vector,
- compiler::Node* slot_id) {
- typedef CodeStubAssembler::Label Label;
- typedef compiler::Node Node;
- typedef CodeStubAssembler::Variable Variable;
-
- // Shared entry for floating point decrement.
- Label do_fdec(assembler), end(assembler);
- Variable var_fdec_value(assembler, MachineRepresentation::kFloat64);
-
- // We might need to try again due to ToNumber conversion.
- Variable value_var(assembler, MachineRepresentation::kTagged);
- Variable result_var(assembler, MachineRepresentation::kTagged);
- Variable var_type_feedback(assembler, MachineRepresentation::kWord32);
- Variable* loop_vars[] = {&value_var, &var_type_feedback};
- Label start(assembler, 2, loop_vars);
- var_type_feedback.Bind(
- assembler->Int32Constant(BinaryOperationFeedback::kNone));
- value_var.Bind(value);
- assembler->Goto(&start);
- assembler->Bind(&start);
- {
- value = value_var.value();
-
- Label if_issmi(assembler), if_isnotsmi(assembler);
- assembler->Branch(assembler->WordIsSmi(value), &if_issmi, &if_isnotsmi);
-
- assembler->Bind(&if_issmi);
- {
- // Try fast Smi subtraction first.
- Node* one = assembler->SmiConstant(Smi::FromInt(1));
- Node* pair = assembler->SmiSubWithOverflow(value, one);
- Node* overflow = assembler->Projection(1, pair);
-
- // Check if the Smi subtraction overflowed.
- Label if_overflow(assembler), if_notoverflow(assembler);
- assembler->Branch(overflow, &if_overflow, &if_notoverflow);
-
- assembler->Bind(&if_notoverflow);
- var_type_feedback.Bind(assembler->Word32Or(
- var_type_feedback.value(),
- assembler->Int32Constant(BinaryOperationFeedback::kSignedSmall)));
- result_var.Bind(assembler->Projection(0, pair));
- assembler->Goto(&end);
-
- assembler->Bind(&if_overflow);
- {
- var_fdec_value.Bind(assembler->SmiToFloat64(value));
- assembler->Goto(&do_fdec);
- }
- }
-
- assembler->Bind(&if_isnotsmi);
- {
- // Check if the value is a HeapNumber.
- Label if_valueisnumber(assembler),
- if_valuenotnumber(assembler, Label::kDeferred);
- Node* value_map = assembler->LoadMap(value);
- assembler->Branch(assembler->IsHeapNumberMap(value_map),
- &if_valueisnumber, &if_valuenotnumber);
-
- assembler->Bind(&if_valueisnumber);
- {
- // Load the HeapNumber value.
- var_fdec_value.Bind(assembler->LoadHeapNumberValue(value));
- assembler->Goto(&do_fdec);
- }
-
- assembler->Bind(&if_valuenotnumber);
- {
- // Convert to a Number first and try again.
- Callable callable =
- CodeFactory::NonNumberToNumber(assembler->isolate());
- var_type_feedback.Bind(
- assembler->Int32Constant(BinaryOperationFeedback::kAny));
- value_var.Bind(assembler->CallStub(callable, context, value));
- assembler->Goto(&start);
- }
- }
- }
-
- assembler->Bind(&do_fdec);
- {
- Node* fdec_value = var_fdec_value.value();
- Node* one = assembler->Float64Constant(1.0);
- Node* fdec_result = assembler->Float64Sub(fdec_value, one);
- var_type_feedback.Bind(assembler->Word32Or(
- var_type_feedback.value(),
- assembler->Int32Constant(BinaryOperationFeedback::kNumber)));
- result_var.Bind(assembler->ChangeFloat64ToTagged(fdec_result));
- assembler->Goto(&end);
- }
-
- assembler->Bind(&end);
- assembler->UpdateFeedback(var_type_feedback.value(), type_feedback_vector,
- slot_id);
- return result_var.value();
-}
-
-// ES6 section 21.1.3.19 String.prototype.substring ( start, end )
-compiler::Node* SubStringStub::Generate(CodeStubAssembler* assembler,
- compiler::Node* string,
- compiler::Node* from,
- compiler::Node* to,
- compiler::Node* context) {
- return assembler->SubString(context, string, from, to);
-}
-
-// ES6 section 7.1.13 ToObject (argument)
-void ToObjectStub::GenerateAssembly(CodeStubAssembler* assembler) const {
- typedef compiler::Node Node;
- typedef CodeStubAssembler::Label Label;
- typedef CodeStubAssembler::Variable Variable;
-
- Label if_number(assembler, Label::kDeferred), if_notsmi(assembler),
- if_jsreceiver(assembler), if_noconstructor(assembler, Label::kDeferred),
- if_wrapjsvalue(assembler);
-
- Node* object = assembler->Parameter(Descriptor::kArgument);
- Node* context = assembler->Parameter(Descriptor::kContext);
-
- Variable constructor_function_index_var(assembler,
- MachineType::PointerRepresentation());
-
- assembler->Branch(assembler->WordIsSmi(object), &if_number, &if_notsmi);
-
- assembler->Bind(&if_notsmi);
- Node* map = assembler->LoadMap(object);
-
- assembler->GotoIf(assembler->IsHeapNumberMap(map), &if_number);
-
- Node* instance_type = assembler->LoadMapInstanceType(map);
- assembler->GotoIf(assembler->IsJSReceiverInstanceType(instance_type),
- &if_jsreceiver);
-
- Node* constructor_function_index =
- assembler->LoadMapConstructorFunctionIndex(map);
- assembler->GotoIf(assembler->WordEqual(constructor_function_index,
- assembler->IntPtrConstant(
- Map::kNoConstructorFunctionIndex)),
- &if_noconstructor);
- constructor_function_index_var.Bind(constructor_function_index);
- assembler->Goto(&if_wrapjsvalue);
-
- assembler->Bind(&if_number);
- constructor_function_index_var.Bind(
- assembler->IntPtrConstant(Context::NUMBER_FUNCTION_INDEX));
- assembler->Goto(&if_wrapjsvalue);
-
- assembler->Bind(&if_wrapjsvalue);
- Node* native_context = assembler->LoadNativeContext(context);
- Node* constructor = assembler->LoadFixedArrayElement(
- native_context, constructor_function_index_var.value(), 0,
- CodeStubAssembler::INTPTR_PARAMETERS);
- Node* initial_map = assembler->LoadObjectField(
- constructor, JSFunction::kPrototypeOrInitialMapOffset);
- Node* js_value = assembler->Allocate(JSValue::kSize);
- assembler->StoreMapNoWriteBarrier(js_value, initial_map);
- assembler->StoreObjectFieldRoot(js_value, JSValue::kPropertiesOffset,
- Heap::kEmptyFixedArrayRootIndex);
- assembler->StoreObjectFieldRoot(js_value, JSObject::kElementsOffset,
- Heap::kEmptyFixedArrayRootIndex);
- assembler->StoreObjectField(js_value, JSValue::kValueOffset, object);
- assembler->Return(js_value);
-
- assembler->Bind(&if_noconstructor);
- assembler->TailCallRuntime(
- Runtime::kThrowUndefinedOrNullToObject, context,
- assembler->HeapConstant(assembler->factory()->NewStringFromAsciiChecked(
- "ToObject", TENURED)));
-
- assembler->Bind(&if_jsreceiver);
- assembler->Return(object);
-}
-
-// static
-// ES6 section 12.5.5 typeof operator
-compiler::Node* TypeofStub::Generate(CodeStubAssembler* assembler,
- compiler::Node* value,
- compiler::Node* context) {
- typedef compiler::Node Node;
- typedef CodeStubAssembler::Label Label;
- typedef CodeStubAssembler::Variable Variable;
-
- Variable result_var(assembler, MachineRepresentation::kTagged);
-
- Label return_number(assembler, Label::kDeferred), if_oddball(assembler),
- return_function(assembler), return_undefined(assembler),
- return_object(assembler), return_string(assembler),
- return_result(assembler);
-
- assembler->GotoIf(assembler->WordIsSmi(value), &return_number);
-
- Node* map = assembler->LoadMap(value);
-
- assembler->GotoIf(assembler->IsHeapNumberMap(map), &return_number);
-
- Node* instance_type = assembler->LoadMapInstanceType(map);
-
- assembler->GotoIf(assembler->Word32Equal(
- instance_type, assembler->Int32Constant(ODDBALL_TYPE)),
- &if_oddball);
-
- Node* callable_or_undetectable_mask =
- assembler->Word32And(assembler->LoadMapBitField(map),
- assembler->Int32Constant(1 << Map::kIsCallable |
- 1 << Map::kIsUndetectable));
-
- assembler->GotoIf(
- assembler->Word32Equal(callable_or_undetectable_mask,
- assembler->Int32Constant(1 << Map::kIsCallable)),
- &return_function);
-
- assembler->GotoUnless(assembler->Word32Equal(callable_or_undetectable_mask,
- assembler->Int32Constant(0)),
- &return_undefined);
-
- assembler->GotoIf(assembler->IsJSReceiverInstanceType(instance_type),
- &return_object);
-
- assembler->GotoIf(assembler->IsStringInstanceType(instance_type),
- &return_string);
-
-#define SIMD128_BRANCH(TYPE, Type, type, lane_count, lane_type) \
- Label return_##type(assembler); \
- Node* type##_map = \
- assembler->HeapConstant(assembler->factory()->type##_map()); \
- assembler->GotoIf(assembler->WordEqual(map, type##_map), &return_##type);
- SIMD128_TYPES(SIMD128_BRANCH)
-#undef SIMD128_BRANCH
-
- assembler->Assert(assembler->Word32Equal(
- instance_type, assembler->Int32Constant(SYMBOL_TYPE)));
- result_var.Bind(assembler->HeapConstant(
- assembler->isolate()->factory()->symbol_string()));
- assembler->Goto(&return_result);
-
- assembler->Bind(&return_number);
- {
- result_var.Bind(assembler->HeapConstant(
- assembler->isolate()->factory()->number_string()));
- assembler->Goto(&return_result);
- }
-
- assembler->Bind(&if_oddball);
- {
- Node* type = assembler->LoadObjectField(value, Oddball::kTypeOfOffset);
- result_var.Bind(type);
- assembler->Goto(&return_result);
- }
-
- assembler->Bind(&return_function);
- {
- result_var.Bind(assembler->HeapConstant(
- assembler->isolate()->factory()->function_string()));
- assembler->Goto(&return_result);
- }
-
- assembler->Bind(&return_undefined);
- {
- result_var.Bind(assembler->HeapConstant(
- assembler->isolate()->factory()->undefined_string()));
- assembler->Goto(&return_result);
- }
-
- assembler->Bind(&return_object);
- {
- result_var.Bind(assembler->HeapConstant(
- assembler->isolate()->factory()->object_string()));
- assembler->Goto(&return_result);
- }
-
- assembler->Bind(&return_string);
- {
- result_var.Bind(assembler->HeapConstant(
- assembler->isolate()->factory()->string_string()));
- assembler->Goto(&return_result);
- }
-
-#define SIMD128_BIND_RETURN(TYPE, Type, type, lane_count, lane_type) \
- assembler->Bind(&return_##type); \
- { \
- result_var.Bind(assembler->HeapConstant( \
- assembler->isolate()->factory()->type##_string())); \
- assembler->Goto(&return_result); \
- }
- SIMD128_TYPES(SIMD128_BIND_RETURN)
-#undef SIMD128_BIND_RETURN
-
- assembler->Bind(&return_result);
- return result_var.value();
-}
-
-// static
-compiler::Node* InstanceOfStub::Generate(CodeStubAssembler* assembler,
- compiler::Node* object,
- compiler::Node* callable,
- compiler::Node* context) {
- typedef CodeStubAssembler::Label Label;
- typedef CodeStubAssembler::Variable Variable;
-
- Label return_runtime(assembler, Label::kDeferred), end(assembler);
- Variable result(assembler, MachineRepresentation::kTagged);
-
- // Check if no one installed @@hasInstance somewhere.
- assembler->GotoUnless(
- assembler->WordEqual(
- assembler->LoadObjectField(
- assembler->LoadRoot(Heap::kHasInstanceProtectorRootIndex),
- PropertyCell::kValueOffset),
- assembler->SmiConstant(Smi::FromInt(Isolate::kArrayProtectorValid))),
- &return_runtime);
-
- // Check if {callable} is a valid receiver.
- assembler->GotoIf(assembler->WordIsSmi(callable), &return_runtime);
- assembler->GotoIf(
- assembler->Word32Equal(
- assembler->Word32And(
- assembler->LoadMapBitField(assembler->LoadMap(callable)),
- assembler->Int32Constant(1 << Map::kIsCallable)),
- assembler->Int32Constant(0)),
- &return_runtime);
-
- // Use the inline OrdinaryHasInstance directly.
- result.Bind(assembler->OrdinaryHasInstance(context, callable, object));
- assembler->Goto(&end);
-
- // TODO(bmeurer): Use GetPropertyStub here once available.
- assembler->Bind(&return_runtime);
- {
- result.Bind(assembler->CallRuntime(Runtime::kInstanceOf, context, object,
- callable));
- assembler->Goto(&end);
- }
-
- assembler->Bind(&end);
- return result.value();
-}
-
-namespace {
-
-enum RelationalComparisonMode {
- kLessThan,
- kLessThanOrEqual,
- kGreaterThan,
- kGreaterThanOrEqual
-};
-
-compiler::Node* GenerateAbstractRelationalComparison(
- CodeStubAssembler* assembler, RelationalComparisonMode mode,
- compiler::Node* lhs, compiler::Node* rhs, compiler::Node* context) {
- typedef CodeStubAssembler::Label Label;
- typedef compiler::Node Node;
- typedef CodeStubAssembler::Variable Variable;
-
- Label return_true(assembler), return_false(assembler), end(assembler);
- Variable result(assembler, MachineRepresentation::kTagged);
-
- // Shared entry for floating point comparison.
- Label do_fcmp(assembler);
- Variable var_fcmp_lhs(assembler, MachineRepresentation::kFloat64),
- var_fcmp_rhs(assembler, MachineRepresentation::kFloat64);
-
- // We might need to loop several times due to ToPrimitive and/or 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(lhs);
- var_rhs.Bind(rhs);
- assembler->Goto(&loop);
- assembler->Bind(&loop);
- {
- // Load the current {lhs} and {rhs} values.
- lhs = var_lhs.value();
- 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 {rhs} is a Smi or a HeapObject.
- Label if_rhsissmi(assembler), if_rhsisnotsmi(assembler);
- assembler->Branch(assembler->WordIsSmi(rhs), &if_rhsissmi,
- &if_rhsisnotsmi);
-
- assembler->Bind(&if_rhsissmi);
- {
- // Both {lhs} and {rhs} are Smi, so just perform a fast Smi comparison.
- switch (mode) {
- case kLessThan:
- assembler->BranchIfSmiLessThan(lhs, rhs, &return_true,
- &return_false);
- break;
- case kLessThanOrEqual:
- assembler->BranchIfSmiLessThanOrEqual(lhs, rhs, &return_true,
- &return_false);
- break;
- case kGreaterThan:
- assembler->BranchIfSmiLessThan(rhs, lhs, &return_true,
- &return_false);
- break;
- case kGreaterThanOrEqual:
- assembler->BranchIfSmiLessThanOrEqual(rhs, lhs, &return_true,
- &return_false);
- break;
- }
- }
-
- assembler->Bind(&if_rhsisnotsmi);
- {
- // Load the map of {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->IsHeapNumberMap(rhs_map), &if_rhsisnumber,
- &if_rhsisnotnumber);
-
- assembler->Bind(&if_rhsisnumber);
- {
- // Convert the {lhs} and {rhs} to floating point values, and
- // perform a floating point comparison.
- var_fcmp_lhs.Bind(assembler->SmiToFloat64(lhs));
- var_fcmp_rhs.Bind(assembler->LoadHeapNumberValue(rhs));
- assembler->Goto(&do_fcmp);
- }
-
- assembler->Bind(&if_rhsisnotnumber);
- {
- // Convert the {rhs} to a Number; we don't need to perform the
- // dedicated ToPrimitive(rhs, hint Number) operation, as the
- // ToNumber(rhs) will by itself already invoke ToPrimitive with
- // a Number hint.
- Callable callable =
- CodeFactory::NonNumberToNumber(assembler->isolate());
- var_rhs.Bind(assembler->CallStub(callable, context, rhs));
- assembler->Goto(&loop);
- }
- }
- }
-
- assembler->Bind(&if_lhsisnotsmi);
- {
- // Load the HeapNumber map for later comparisons.
- Node* number_map = assembler->HeapNumberMapConstant();
-
- // Load the map of {lhs}.
- Node* lhs_map = assembler->LoadMap(lhs);
-
- // Check if {rhs} is a Smi or a HeapObject.
- Label if_rhsissmi(assembler), if_rhsisnotsmi(assembler);
- assembler->Branch(assembler->WordIsSmi(rhs), &if_rhsissmi,
- &if_rhsisnotsmi);
-
- assembler->Bind(&if_rhsissmi);
- {
- // Check if the {lhs} is a HeapNumber.
- Label if_lhsisnumber(assembler),
- if_lhsisnotnumber(assembler, Label::kDeferred);
- assembler->Branch(assembler->WordEqual(lhs_map, number_map),
- &if_lhsisnumber, &if_lhsisnotnumber);
-
- assembler->Bind(&if_lhsisnumber);
- {
- // Convert the {lhs} and {rhs} to floating point values, and
- // perform a floating point comparison.
- var_fcmp_lhs.Bind(assembler->LoadHeapNumberValue(lhs));
- var_fcmp_rhs.Bind(assembler->SmiToFloat64(rhs));
- assembler->Goto(&do_fcmp);
- }
-
- assembler->Bind(&if_lhsisnotnumber);
- {
- // Convert the {lhs} to a Number; we don't need to perform the
- // dedicated ToPrimitive(lhs, hint Number) operation, as the
- // ToNumber(lhs) will by itself already invoke ToPrimitive with
- // a Number hint.
- Callable callable =
- CodeFactory::NonNumberToNumber(assembler->isolate());
- var_lhs.Bind(assembler->CallStub(callable, context, lhs));
- assembler->Goto(&loop);
- }
- }
-
- assembler->Bind(&if_rhsisnotsmi);
- {
- // Load the map of {rhs}.
- Node* rhs_map = assembler->LoadMap(rhs);
-
- // Check if {lhs} is a HeapNumber.
- Label if_lhsisnumber(assembler), if_lhsisnotnumber(assembler);
- assembler->Branch(assembler->WordEqual(lhs_map, number_map),
- &if_lhsisnumber, &if_lhsisnotnumber);
-
- assembler->Bind(&if_lhsisnumber);
- {
- // Check if {rhs} is also a HeapNumber.
- Label if_rhsisnumber(assembler),
- if_rhsisnotnumber(assembler, Label::kDeferred);
- assembler->Branch(assembler->WordEqual(lhs_map, rhs_map),
- &if_rhsisnumber, &if_rhsisnotnumber);
-
- assembler->Bind(&if_rhsisnumber);
- {
- // Convert the {lhs} and {rhs} to floating point values, and
- // perform a floating point comparison.
- var_fcmp_lhs.Bind(assembler->LoadHeapNumberValue(lhs));
- var_fcmp_rhs.Bind(assembler->LoadHeapNumberValue(rhs));
- assembler->Goto(&do_fcmp);
- }
-
- assembler->Bind(&if_rhsisnotnumber);
- {
- // Convert the {rhs} to a Number; we don't need to perform
- // dedicated ToPrimitive(rhs, hint Number) operation, as the
- // ToNumber(rhs) will by itself already invoke ToPrimitive with
- // a Number hint.
- Callable callable =
- CodeFactory::NonNumberToNumber(assembler->isolate());
- var_rhs.Bind(assembler->CallStub(callable, context, rhs));
- assembler->Goto(&loop);
- }
- }
-
- assembler->Bind(&if_lhsisnotnumber);
- {
- // Load the instance type of {lhs}.
- Node* lhs_instance_type = assembler->LoadMapInstanceType(lhs_map);
-
- // Check if {lhs} is a String.
- Label if_lhsisstring(assembler),
- if_lhsisnotstring(assembler, Label::kDeferred);
- assembler->Branch(assembler->IsStringInstanceType(lhs_instance_type),
- &if_lhsisstring, &if_lhsisnotstring);
-
- assembler->Bind(&if_lhsisstring);
- {
- // Load the instance type of {rhs}.
- Node* rhs_instance_type = assembler->LoadMapInstanceType(rhs_map);
-
- // Check if {rhs} is also a String.
- Label if_rhsisstring(assembler, Label::kDeferred),
- if_rhsisnotstring(assembler, Label::kDeferred);
- assembler->Branch(
- assembler->IsStringInstanceType(rhs_instance_type),
- &if_rhsisstring, &if_rhsisnotstring);
-
- assembler->Bind(&if_rhsisstring);
- {
- // Both {lhs} and {rhs} are strings.
- switch (mode) {
- case kLessThan:
- result.Bind(assembler->CallStub(
- CodeFactory::StringLessThan(assembler->isolate()),
- context, lhs, rhs));
- assembler->Goto(&end);
- break;
- case kLessThanOrEqual:
- result.Bind(assembler->CallStub(
- CodeFactory::StringLessThanOrEqual(assembler->isolate()),
- context, lhs, rhs));
- assembler->Goto(&end);
- break;
- case kGreaterThan:
- result.Bind(assembler->CallStub(
- CodeFactory::StringGreaterThan(assembler->isolate()),
- context, lhs, rhs));
- assembler->Goto(&end);
- break;
- case kGreaterThanOrEqual:
- result.Bind(
- assembler->CallStub(CodeFactory::StringGreaterThanOrEqual(
- assembler->isolate()),
- context, lhs, rhs));
- assembler->Goto(&end);
- break;
- }
- }
-
- assembler->Bind(&if_rhsisnotstring);
- {
- // The {lhs} is a String, while {rhs} is neither a Number nor a
- // String, so we need to call ToPrimitive(rhs, hint Number) if
- // {rhs} is a receiver or ToNumber(lhs) and ToNumber(rhs) in the
- // other cases.
- STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE);
- Label if_rhsisreceiver(assembler, Label::kDeferred),
- if_rhsisnotreceiver(assembler, Label::kDeferred);
- assembler->Branch(
- assembler->IsJSReceiverInstanceType(rhs_instance_type),
- &if_rhsisreceiver, &if_rhsisnotreceiver);
-
- assembler->Bind(&if_rhsisreceiver);
- {
- // Convert {rhs} to a primitive first passing Number hint.
- Callable callable = CodeFactory::NonPrimitiveToPrimitive(
- assembler->isolate(), ToPrimitiveHint::kNumber);
- var_rhs.Bind(assembler->CallStub(callable, context, rhs));
- assembler->Goto(&loop);
- }
-
- assembler->Bind(&if_rhsisnotreceiver);
- {
- // Convert both {lhs} and {rhs} to Number.
- Callable callable = CodeFactory::ToNumber(assembler->isolate());
- var_lhs.Bind(assembler->CallStub(callable, context, lhs));
- var_rhs.Bind(assembler->CallStub(callable, context, rhs));
- assembler->Goto(&loop);
- }
- }
- }
-
- assembler->Bind(&if_lhsisnotstring);
- {
- // The {lhs} is neither a Number nor a String, so we need to call
- // ToPrimitive(lhs, hint Number) if {lhs} is a receiver or
- // ToNumber(lhs) and ToNumber(rhs) in the other cases.
- STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE);
- Label if_lhsisreceiver(assembler, Label::kDeferred),
- if_lhsisnotreceiver(assembler, Label::kDeferred);
- assembler->Branch(
- assembler->IsJSReceiverInstanceType(lhs_instance_type),
- &if_lhsisreceiver, &if_lhsisnotreceiver);
-
- assembler->Bind(&if_lhsisreceiver);
- {
- // Convert {lhs} to a primitive first passing Number hint.
- Callable callable = CodeFactory::NonPrimitiveToPrimitive(
- assembler->isolate(), ToPrimitiveHint::kNumber);
- var_lhs.Bind(assembler->CallStub(callable, context, lhs));
- assembler->Goto(&loop);
- }
-
- assembler->Bind(&if_lhsisnotreceiver);
- {
- // Convert both {lhs} and {rhs} to Number.
- Callable callable = CodeFactory::ToNumber(assembler->isolate());
- var_lhs.Bind(assembler->CallStub(callable, context, lhs));
- var_rhs.Bind(assembler->CallStub(callable, context, rhs));
- assembler->Goto(&loop);
- }
- }
- }
- }
- }
- }
-
- assembler->Bind(&do_fcmp);
- {
- // Load the {lhs} and {rhs} floating point values.
- Node* lhs = var_fcmp_lhs.value();
- Node* rhs = var_fcmp_rhs.value();
-
- // Perform a fast floating point comparison.
- switch (mode) {
- case kLessThan:
- assembler->BranchIfFloat64LessThan(lhs, rhs, &return_true,
- &return_false);
- break;
- case kLessThanOrEqual:
- assembler->BranchIfFloat64LessThanOrEqual(lhs, rhs, &return_true,
- &return_false);
- break;
- case kGreaterThan:
- assembler->BranchIfFloat64GreaterThan(lhs, rhs, &return_true,
- &return_false);
- break;
- case kGreaterThanOrEqual:
- assembler->BranchIfFloat64GreaterThanOrEqual(lhs, rhs, &return_true,
- &return_false);
- break;
- }
- }
-
- assembler->Bind(&return_true);
- {
- result.Bind(assembler->BooleanConstant(true));
- assembler->Goto(&end);
- }
-
- assembler->Bind(&return_false);
- {
- result.Bind(assembler->BooleanConstant(false));
- assembler->Goto(&end);
- }
-
- assembler->Bind(&end);
- return result.value();
-}
-
-enum ResultMode { kDontNegateResult, kNegateResult };
-
-void GenerateEqual_Same(CodeStubAssembler* assembler, compiler::Node* value,
- CodeStubAssembler::Label* if_equal,
- CodeStubAssembler::Label* if_notequal) {
- // In case of abstract or strict equality checks, we need additional checks
- // for NaN values because they are not considered equal, even if both the
- // left and the right hand side reference exactly the same value.
- // TODO(bmeurer): This seems to violate the SIMD.js specification, but it
- // seems to be what is tested in the current SIMD.js testsuite.
-
- typedef CodeStubAssembler::Label Label;
- typedef compiler::Node Node;
-
- // Check if {value} is a Smi or a HeapObject.
- Label if_valueissmi(assembler), if_valueisnotsmi(assembler);
- assembler->Branch(assembler->WordIsSmi(value), &if_valueissmi,
- &if_valueisnotsmi);
-
- assembler->Bind(&if_valueisnotsmi);
- {
- // Load the map of {value}.
- Node* value_map = assembler->LoadMap(value);
-
- // Check if {value} (and therefore {rhs}) is a HeapNumber.
- Label if_valueisnumber(assembler), if_valueisnotnumber(assembler);
- assembler->Branch(assembler->IsHeapNumberMap(value_map), &if_valueisnumber,
- &if_valueisnotnumber);
-
- assembler->Bind(&if_valueisnumber);
- {
- // Convert {value} (and therefore {rhs}) to floating point value.
- Node* value_value = assembler->LoadHeapNumberValue(value);
-
- // Check if the HeapNumber value is a NaN.
- assembler->BranchIfFloat64IsNaN(value_value, if_notequal, if_equal);
- }
-
- assembler->Bind(&if_valueisnotnumber);
- assembler->Goto(if_equal);
- }
-
- assembler->Bind(&if_valueissmi);
- assembler->Goto(if_equal);
-}
-
-void GenerateEqual_Simd128Value_HeapObject(
- CodeStubAssembler* assembler, compiler::Node* lhs, compiler::Node* lhs_map,
- compiler::Node* rhs, compiler::Node* rhs_map,
- CodeStubAssembler::Label* if_equal, CodeStubAssembler::Label* if_notequal) {
- assembler->BranchIfSimd128Equal(lhs, lhs_map, rhs, rhs_map, if_equal,
- if_notequal);
-}
-
-// ES6 section 7.2.12 Abstract Equality Comparison
-compiler::Node* GenerateEqual(CodeStubAssembler* assembler, ResultMode mode,
- compiler::Node* lhs, compiler::Node* rhs,
- compiler::Node* context) {
- // This is a slightly optimized version of Object::Equals represented as
- // scheduled TurboFan graph utilizing the CodeStubAssembler. Whenever you
- // change something functionality wise in here, remember to update the
- // Object::Equals method as well.
- typedef CodeStubAssembler::Label Label;
- typedef compiler::Node Node;
- typedef CodeStubAssembler::Variable Variable;
-
- Label if_equal(assembler), if_notequal(assembler),
- do_rhsstringtonumber(assembler, Label::kDeferred), end(assembler);
- Variable result(assembler, MachineRepresentation::kTagged);
-
- // Shared entry for floating point comparison.
- Label do_fcmp(assembler);
- Variable var_fcmp_lhs(assembler, MachineRepresentation::kFloat64),
- var_fcmp_rhs(assembler, MachineRepresentation::kFloat64);
-
- // We might need to loop several times due to ToPrimitive and/or 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(lhs);
- var_rhs.Bind(rhs);
- assembler->Goto(&loop);
- assembler->Bind(&loop);
- {
- // Load the current {lhs} and {rhs} values.
- lhs = var_lhs.value();
- rhs = var_rhs.value();
-
- // Check if {lhs} and {rhs} refer to the same object.
- Label if_same(assembler), if_notsame(assembler);
- assembler->Branch(assembler->WordEqual(lhs, rhs), &if_same, &if_notsame);
-
- assembler->Bind(&if_same);
- {
- // The {lhs} and {rhs} reference the exact same value, yet we need special
- // treatment for HeapNumber, as NaN is not equal to NaN.
- GenerateEqual_Same(assembler, lhs, &if_equal, &if_notequal);
- }
-
- assembler->Bind(&if_notsame);
- {
- // Check if {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 {rhs} is a Smi or a HeapObject.
- Label if_rhsissmi(assembler), if_rhsisnotsmi(assembler);
- assembler->Branch(assembler->WordIsSmi(rhs), &if_rhsissmi,
- &if_rhsisnotsmi);
-
- assembler->Bind(&if_rhsissmi);
- // We have already checked for {lhs} and {rhs} being the same value, so
- // if both are Smis when we get here they must not be equal.
- assembler->Goto(&if_notequal);
-
- assembler->Bind(&if_rhsisnotsmi);
- {
- // Load the map of {rhs}.
- Node* rhs_map = assembler->LoadMap(rhs);
-
- // Check if {rhs} is a HeapNumber.
- Node* number_map = assembler->HeapNumberMapConstant();
- Label if_rhsisnumber(assembler), if_rhsisnotnumber(assembler);
- assembler->Branch(assembler->WordEqual(rhs_map, number_map),
- &if_rhsisnumber, &if_rhsisnotnumber);
-
- assembler->Bind(&if_rhsisnumber);
- {
- // Convert {lhs} and {rhs} to floating point values, and
- // perform a floating point comparison.
- var_fcmp_lhs.Bind(assembler->SmiToFloat64(lhs));
- var_fcmp_rhs.Bind(assembler->LoadHeapNumberValue(rhs));
- assembler->Goto(&do_fcmp);
- }
-
- assembler->Bind(&if_rhsisnotnumber);
- {
- // Load the instance type of the {rhs}.
- Node* rhs_instance_type = assembler->LoadMapInstanceType(rhs_map);
-
- // Check if the {rhs} is a String.
- Label if_rhsisstring(assembler, Label::kDeferred),
- if_rhsisnotstring(assembler);
- assembler->Branch(
- assembler->IsStringInstanceType(rhs_instance_type),
- &if_rhsisstring, &if_rhsisnotstring);
-
- assembler->Bind(&if_rhsisstring);
- {
- // The {rhs} is a String and the {lhs} is a Smi; we need
- // to convert the {rhs} to a Number and compare the output to
- // the Number on the {lhs}.
- assembler->Goto(&do_rhsstringtonumber);
- }
-
- assembler->Bind(&if_rhsisnotstring);
- {
- // Check if the {rhs} is a Boolean.
- Label if_rhsisboolean(assembler), if_rhsisnotboolean(assembler);
- assembler->Branch(assembler->IsBooleanMap(rhs_map),
- &if_rhsisboolean, &if_rhsisnotboolean);
-
- assembler->Bind(&if_rhsisboolean);
- {
- // The {rhs} is a Boolean, load its number value.
- var_rhs.Bind(
- assembler->LoadObjectField(rhs, Oddball::kToNumberOffset));
- assembler->Goto(&loop);
- }
-
- assembler->Bind(&if_rhsisnotboolean);
- {
- // Check if the {rhs} is a Receiver.
- STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE);
- Label if_rhsisreceiver(assembler, Label::kDeferred),
- if_rhsisnotreceiver(assembler);
- assembler->Branch(
- assembler->IsJSReceiverInstanceType(rhs_instance_type),
- &if_rhsisreceiver, &if_rhsisnotreceiver);
-
- assembler->Bind(&if_rhsisreceiver);
- {
- // Convert {rhs} to a primitive first (passing no hint).
- Callable callable = CodeFactory::NonPrimitiveToPrimitive(
- assembler->isolate());
- var_rhs.Bind(assembler->CallStub(callable, context, rhs));
- assembler->Goto(&loop);
- }
-
- assembler->Bind(&if_rhsisnotreceiver);
- assembler->Goto(&if_notequal);
- }
- }
- }
- }
- }
-
- assembler->Bind(&if_lhsisnotsmi);
- {
- // Check if {rhs} is a Smi or a HeapObject.
- Label if_rhsissmi(assembler), if_rhsisnotsmi(assembler);
- assembler->Branch(assembler->WordIsSmi(rhs), &if_rhsissmi,
- &if_rhsisnotsmi);
-
- assembler->Bind(&if_rhsissmi);
- {
- // The {lhs} is a HeapObject and the {rhs} is a Smi; swapping {lhs}
- // and {rhs} is not observable and doesn't matter for the result, so
- // we can just swap them and use the Smi handling above (for {lhs}
- // being a Smi).
- var_lhs.Bind(rhs);
- var_rhs.Bind(lhs);
- assembler->Goto(&loop);
- }
-
- assembler->Bind(&if_rhsisnotsmi);
- {
- Label if_lhsisstring(assembler), if_lhsisnumber(assembler),
- if_lhsissymbol(assembler), if_lhsissimd128value(assembler),
- if_lhsisoddball(assembler), if_lhsisreceiver(assembler);
-
- // Both {lhs} and {rhs} are HeapObjects, load their maps
- // and their instance types.
- Node* lhs_map = assembler->LoadMap(lhs);
- Node* rhs_map = assembler->LoadMap(rhs);
-
- // Load the instance types of {lhs} and {rhs}.
- Node* lhs_instance_type = assembler->LoadMapInstanceType(lhs_map);
- Node* rhs_instance_type = assembler->LoadMapInstanceType(rhs_map);
-
- // Dispatch based on the instance type of {lhs}.
- size_t const kNumCases = FIRST_NONSTRING_TYPE + 4;
- Label* case_labels[kNumCases];
- int32_t case_values[kNumCases];
- for (int32_t i = 0; i < FIRST_NONSTRING_TYPE; ++i) {
- case_labels[i] = new Label(assembler);
- case_values[i] = i;
- }
- case_labels[FIRST_NONSTRING_TYPE + 0] = &if_lhsisnumber;
- case_values[FIRST_NONSTRING_TYPE + 0] = HEAP_NUMBER_TYPE;
- case_labels[FIRST_NONSTRING_TYPE + 1] = &if_lhsissymbol;
- case_values[FIRST_NONSTRING_TYPE + 1] = SYMBOL_TYPE;
- case_labels[FIRST_NONSTRING_TYPE + 2] = &if_lhsissimd128value;
- case_values[FIRST_NONSTRING_TYPE + 2] = SIMD128_VALUE_TYPE;
- case_labels[FIRST_NONSTRING_TYPE + 3] = &if_lhsisoddball;
- case_values[FIRST_NONSTRING_TYPE + 3] = ODDBALL_TYPE;
- assembler->Switch(lhs_instance_type, &if_lhsisreceiver, case_values,
- case_labels, arraysize(case_values));
- for (int32_t i = 0; i < FIRST_NONSTRING_TYPE; ++i) {
- assembler->Bind(case_labels[i]);
- assembler->Goto(&if_lhsisstring);
- delete case_labels[i];
- }
-
- assembler->Bind(&if_lhsisstring);
- {
- // Check if {rhs} is also a String.
- Label if_rhsisstring(assembler, Label::kDeferred),
- if_rhsisnotstring(assembler);
- assembler->Branch(
- assembler->IsStringInstanceType(rhs_instance_type),
- &if_rhsisstring, &if_rhsisnotstring);
-
- assembler->Bind(&if_rhsisstring);
- {
- // Both {lhs} and {rhs} are of type String, just do the
- // string comparison then.
- Callable callable =
- (mode == kDontNegateResult)
- ? CodeFactory::StringEqual(assembler->isolate())
- : CodeFactory::StringNotEqual(assembler->isolate());
- result.Bind(assembler->CallStub(callable, context, lhs, rhs));
- assembler->Goto(&end);
- }
-
- assembler->Bind(&if_rhsisnotstring);
- {
- // The {lhs} is a String and the {rhs} is some other HeapObject.
- // Swapping {lhs} and {rhs} is not observable and doesn't matter
- // for the result, so we can just swap them and use the String
- // handling below (for {rhs} being a String).
- var_lhs.Bind(rhs);
- var_rhs.Bind(lhs);
- assembler->Goto(&loop);
- }
- }
-
- assembler->Bind(&if_lhsisnumber);
- {
- // Check if {rhs} is also a HeapNumber.
- Label if_rhsisnumber(assembler), if_rhsisnotnumber(assembler);
- assembler->Branch(
- assembler->Word32Equal(lhs_instance_type, rhs_instance_type),
- &if_rhsisnumber, &if_rhsisnotnumber);
-
- assembler->Bind(&if_rhsisnumber);
- {
- // Convert {lhs} and {rhs} to floating point values, and
- // perform a floating point comparison.
- var_fcmp_lhs.Bind(assembler->LoadHeapNumberValue(lhs));
- var_fcmp_rhs.Bind(assembler->LoadHeapNumberValue(rhs));
- assembler->Goto(&do_fcmp);
- }
-
- assembler->Bind(&if_rhsisnotnumber);
- {
- // The {lhs} is a Number, the {rhs} is some other HeapObject.
- Label if_rhsisstring(assembler, Label::kDeferred),
- if_rhsisnotstring(assembler);
- assembler->Branch(
- assembler->IsStringInstanceType(rhs_instance_type),
- &if_rhsisstring, &if_rhsisnotstring);
-
- assembler->Bind(&if_rhsisstring);
- {
- // The {rhs} is a String and the {lhs} is a HeapNumber; we need
- // to convert the {rhs} to a Number and compare the output to
- // the Number on the {lhs}.
- assembler->Goto(&do_rhsstringtonumber);
- }
-
- assembler->Bind(&if_rhsisnotstring);
- {
- // Check if the {rhs} is a JSReceiver.
- Label if_rhsisreceiver(assembler),
- if_rhsisnotreceiver(assembler);
- STATIC_ASSERT(LAST_TYPE == LAST_JS_RECEIVER_TYPE);
- assembler->Branch(
- assembler->IsJSReceiverInstanceType(rhs_instance_type),
- &if_rhsisreceiver, &if_rhsisnotreceiver);
-
- assembler->Bind(&if_rhsisreceiver);
- {
- // The {lhs} is a Primitive and the {rhs} is a JSReceiver.
- // Swapping {lhs} and {rhs} is not observable and doesn't
- // matter for the result, so we can just swap them and use
- // the JSReceiver handling below (for {lhs} being a
- // JSReceiver).
- var_lhs.Bind(rhs);
- var_rhs.Bind(lhs);
- assembler->Goto(&loop);
- }
-
- assembler->Bind(&if_rhsisnotreceiver);
- {
- // Check if {rhs} is a Boolean.
- Label if_rhsisboolean(assembler),
- if_rhsisnotboolean(assembler);
- assembler->Branch(assembler->IsBooleanMap(rhs_map),
- &if_rhsisboolean, &if_rhsisnotboolean);
-
- assembler->Bind(&if_rhsisboolean);
- {
- // The {rhs} is a Boolean, convert it to a Smi first.
- var_rhs.Bind(assembler->LoadObjectField(
- rhs, Oddball::kToNumberOffset));
- assembler->Goto(&loop);
- }
-
- assembler->Bind(&if_rhsisnotboolean);
- assembler->Goto(&if_notequal);
- }
- }
- }
- }
-
- assembler->Bind(&if_lhsisoddball);
- {
- // The {lhs} is an Oddball and {rhs} is some other HeapObject.
- Label if_lhsisboolean(assembler), if_lhsisnotboolean(assembler);
- Node* boolean_map = assembler->BooleanMapConstant();
- assembler->Branch(assembler->WordEqual(lhs_map, boolean_map),
- &if_lhsisboolean, &if_lhsisnotboolean);
-
- assembler->Bind(&if_lhsisboolean);
- {
- // The {lhs} is a Boolean, check if {rhs} is also a Boolean.
- Label if_rhsisboolean(assembler), if_rhsisnotboolean(assembler);
- assembler->Branch(assembler->WordEqual(rhs_map, boolean_map),
- &if_rhsisboolean, &if_rhsisnotboolean);
-
- assembler->Bind(&if_rhsisboolean);
- {
- // Both {lhs} and {rhs} are distinct Boolean values.
- assembler->Goto(&if_notequal);
- }
-
- assembler->Bind(&if_rhsisnotboolean);
- {
- // Convert the {lhs} to a Number first.
- var_lhs.Bind(
- assembler->LoadObjectField(lhs, Oddball::kToNumberOffset));
- assembler->Goto(&loop);
- }
- }
-
- assembler->Bind(&if_lhsisnotboolean);
- {
- // The {lhs} is either Null or Undefined; check if the {rhs} is
- // undetectable (i.e. either also Null or Undefined or some
- // undetectable JSReceiver).
- Node* rhs_bitfield = assembler->LoadMapBitField(rhs_map);
- assembler->BranchIfWord32Equal(
- assembler->Word32And(
- rhs_bitfield,
- assembler->Int32Constant(1 << Map::kIsUndetectable)),
- assembler->Int32Constant(0), &if_notequal, &if_equal);
- }
- }
-
- assembler->Bind(&if_lhsissymbol);
- {
- // Check if the {rhs} is a JSReceiver.
- Label if_rhsisreceiver(assembler), if_rhsisnotreceiver(assembler);
- STATIC_ASSERT(LAST_TYPE == LAST_JS_RECEIVER_TYPE);
- assembler->Branch(
- assembler->IsJSReceiverInstanceType(rhs_instance_type),
- &if_rhsisreceiver, &if_rhsisnotreceiver);
-
- assembler->Bind(&if_rhsisreceiver);
- {
- // The {lhs} is a Primitive and the {rhs} is a JSReceiver.
- // Swapping {lhs} and {rhs} is not observable and doesn't
- // matter for the result, so we can just swap them and use
- // the JSReceiver handling below (for {lhs} being a JSReceiver).
- var_lhs.Bind(rhs);
- var_rhs.Bind(lhs);
- assembler->Goto(&loop);
- }
-
- assembler->Bind(&if_rhsisnotreceiver);
- {
- // The {rhs} is not a JSReceiver and also not the same Symbol
- // as the {lhs}, so this is equality check is considered false.
- assembler->Goto(&if_notequal);
- }
- }
-
- assembler->Bind(&if_lhsissimd128value);
- {
- // Check if the {rhs} is also a Simd128Value.
- Label if_rhsissimd128value(assembler),
- if_rhsisnotsimd128value(assembler);
- assembler->Branch(
- assembler->Word32Equal(lhs_instance_type, rhs_instance_type),
- &if_rhsissimd128value, &if_rhsisnotsimd128value);
-
- assembler->Bind(&if_rhsissimd128value);
- {
- // Both {lhs} and {rhs} is a Simd128Value.
- GenerateEqual_Simd128Value_HeapObject(assembler, lhs, lhs_map,
- rhs, rhs_map, &if_equal,
- &if_notequal);
- }
-
- assembler->Bind(&if_rhsisnotsimd128value);
- {
- // Check if the {rhs} is a JSReceiver.
- Label if_rhsisreceiver(assembler), if_rhsisnotreceiver(assembler);
- STATIC_ASSERT(LAST_TYPE == LAST_JS_RECEIVER_TYPE);
- assembler->Branch(
- assembler->IsJSReceiverInstanceType(rhs_instance_type),
- &if_rhsisreceiver, &if_rhsisnotreceiver);
-
- assembler->Bind(&if_rhsisreceiver);
- {
- // The {lhs} is a Primitive and the {rhs} is a JSReceiver.
- // Swapping {lhs} and {rhs} is not observable and doesn't
- // matter for the result, so we can just swap them and use
- // the JSReceiver handling below (for {lhs} being a JSReceiver).
- var_lhs.Bind(rhs);
- var_rhs.Bind(lhs);
- assembler->Goto(&loop);
- }
-
- assembler->Bind(&if_rhsisnotreceiver);
- {
- // The {rhs} is some other Primitive.
- assembler->Goto(&if_notequal);
- }
- }
- }
-
- assembler->Bind(&if_lhsisreceiver);
- {
- // Check if the {rhs} is also a JSReceiver.
- Label if_rhsisreceiver(assembler), if_rhsisnotreceiver(assembler);
- STATIC_ASSERT(LAST_TYPE == LAST_JS_RECEIVER_TYPE);
- assembler->Branch(
- assembler->IsJSReceiverInstanceType(rhs_instance_type),
- &if_rhsisreceiver, &if_rhsisnotreceiver);
-
- assembler->Bind(&if_rhsisreceiver);
- {
- // Both {lhs} and {rhs} are different JSReceiver references, so
- // this cannot be considered equal.
- assembler->Goto(&if_notequal);
- }
-
- assembler->Bind(&if_rhsisnotreceiver);
- {
- // Check if {rhs} is Null or Undefined (an undetectable check
- // is sufficient here, since we already know that {rhs} is not
- // a JSReceiver).
- Label if_rhsisundetectable(assembler),
- if_rhsisnotundetectable(assembler, Label::kDeferred);
- Node* rhs_bitfield = assembler->LoadMapBitField(rhs_map);
- assembler->BranchIfWord32Equal(
- assembler->Word32And(
- rhs_bitfield,
- assembler->Int32Constant(1 << Map::kIsUndetectable)),
- assembler->Int32Constant(0), &if_rhsisnotundetectable,
- &if_rhsisundetectable);
-
- assembler->Bind(&if_rhsisundetectable);
- {
- // Check if {lhs} is an undetectable JSReceiver.
- Node* lhs_bitfield = assembler->LoadMapBitField(lhs_map);
- assembler->BranchIfWord32Equal(
- assembler->Word32And(
- lhs_bitfield,
- assembler->Int32Constant(1 << Map::kIsUndetectable)),
- assembler->Int32Constant(0), &if_notequal, &if_equal);
- }
-
- assembler->Bind(&if_rhsisnotundetectable);
- {
- // The {rhs} is some Primitive different from Null and
- // Undefined, need to convert {lhs} to Primitive first.
- Callable callable =
- CodeFactory::NonPrimitiveToPrimitive(assembler->isolate());
- var_lhs.Bind(assembler->CallStub(callable, context, lhs));
- assembler->Goto(&loop);
- }
- }
- }
- }
+ assembler->Goto(&start);
}
}
-
- assembler->Bind(&do_rhsstringtonumber);
- {
- Callable callable = CodeFactory::StringToNumber(assembler->isolate());
- var_rhs.Bind(assembler->CallStub(callable, context, rhs));
- assembler->Goto(&loop);
- }
- }
-
- assembler->Bind(&do_fcmp);
- {
- // Load the {lhs} and {rhs} floating point values.
- Node* lhs = var_fcmp_lhs.value();
- Node* rhs = var_fcmp_rhs.value();
-
- // Perform a fast floating point comparison.
- assembler->BranchIfFloat64Equal(lhs, rhs, &if_equal, &if_notequal);
}
- assembler->Bind(&if_equal);
- {
- result.Bind(assembler->BooleanConstant(mode == kDontNegateResult));
- assembler->Goto(&end);
- }
-
- assembler->Bind(&if_notequal);
+ assembler->Bind(&do_finc);
{
- result.Bind(assembler->BooleanConstant(mode == kNegateResult));
+ Node* finc_value = var_finc_value.value();
+ Node* one = assembler->Float64Constant(1.0);
+ Node* finc_result = assembler->Float64Add(finc_value, one);
+ var_type_feedback.Bind(assembler->Word32Or(
+ var_type_feedback.value(),
+ assembler->Int32Constant(BinaryOperationFeedback::kNumber)));
+ result_var.Bind(assembler->ChangeFloat64ToTagged(finc_result));
assembler->Goto(&end);
}
assembler->Bind(&end);
- return result.value();
+ assembler->UpdateFeedback(var_type_feedback.value(), type_feedback_vector,
+ slot_id);
+ return result_var.value();
}
-compiler::Node* GenerateStrictEqual(CodeStubAssembler* assembler,
- ResultMode mode, compiler::Node* lhs,
- compiler::Node* rhs,
- compiler::Node* context) {
- // Here's pseudo-code for the algorithm below in case of kDontNegateResult
- // mode; for kNegateResult mode we properly negate the result.
- //
- // if (lhs == rhs) {
- // if (lhs->IsHeapNumber()) return HeapNumber::cast(lhs)->value() != NaN;
- // return true;
- // }
- // if (!lhs->IsSmi()) {
- // if (lhs->IsHeapNumber()) {
- // if (rhs->IsSmi()) {
- // return Smi::cast(rhs)->value() == HeapNumber::cast(lhs)->value();
- // } else if (rhs->IsHeapNumber()) {
- // return HeapNumber::cast(rhs)->value() ==
- // HeapNumber::cast(lhs)->value();
- // } else {
- // return false;
- // }
- // } else {
- // if (rhs->IsSmi()) {
- // return false;
- // } else {
- // if (lhs->IsString()) {
- // if (rhs->IsString()) {
- // return %StringEqual(lhs, rhs);
- // } else {
- // return false;
- // }
- // } else if (lhs->IsSimd128()) {
- // if (rhs->IsSimd128()) {
- // return %StrictEqual(lhs, rhs);
- // }
- // } else {
- // return false;
- // }
- // }
- // }
- // } else {
- // if (rhs->IsSmi()) {
- // return false;
- // } else {
- // if (rhs->IsHeapNumber()) {
- // return Smi::cast(lhs)->value() == HeapNumber::cast(rhs)->value();
- // } else {
- // return false;
- // }
- // }
- // }
-
+// static
+compiler::Node* DecStub::Generate(CodeStubAssembler* assembler,
+ compiler::Node* value,
+ compiler::Node* context,
+ compiler::Node* type_feedback_vector,
+ compiler::Node* slot_id) {
typedef CodeStubAssembler::Label Label;
- typedef CodeStubAssembler::Variable Variable;
typedef compiler::Node Node;
+ typedef CodeStubAssembler::Variable Variable;
- Label if_equal(assembler), if_notequal(assembler), end(assembler);
- Variable result(assembler, MachineRepresentation::kTagged);
-
- // Check if {lhs} and {rhs} refer to the same object.
- Label if_same(assembler), if_notsame(assembler);
- assembler->Branch(assembler->WordEqual(lhs, rhs), &if_same, &if_notsame);
-
- assembler->Bind(&if_same);
- {
- // The {lhs} and {rhs} reference the exact same value, yet we need special
- // treatment for HeapNumber, as NaN is not equal to NaN.
- GenerateEqual_Same(assembler, lhs, &if_equal, &if_notequal);
- }
+ // Shared entry for floating point decrement.
+ Label do_fdec(assembler), end(assembler);
+ Variable var_fdec_value(assembler, MachineRepresentation::kFloat64);
- assembler->Bind(&if_notsame);
+ // We might need to try again due to ToNumber conversion.
+ Variable value_var(assembler, MachineRepresentation::kTagged);
+ Variable result_var(assembler, MachineRepresentation::kTagged);
+ Variable var_type_feedback(assembler, MachineRepresentation::kWord32);
+ Variable* loop_vars[] = {&value_var, &var_type_feedback};
+ Label start(assembler, 2, loop_vars);
+ var_type_feedback.Bind(
+ assembler->Int32Constant(BinaryOperationFeedback::kNone));
+ value_var.Bind(value);
+ assembler->Goto(&start);
+ assembler->Bind(&start);
{
- // The {lhs} and {rhs} reference different objects, yet for Smi, HeapNumber,
- // String and Simd128Value they can still be considered equal.
- Node* number_map = assembler->HeapNumberMapConstant();
+ value = value_var.value();
- // Check if {lhs} is a Smi or a HeapObject.
- Label if_lhsissmi(assembler), if_lhsisnotsmi(assembler);
- assembler->Branch(assembler->WordIsSmi(lhs), &if_lhsissmi, &if_lhsisnotsmi);
+ Label if_issmi(assembler), if_isnotsmi(assembler);
+ assembler->Branch(assembler->WordIsSmi(value), &if_issmi, &if_isnotsmi);
- assembler->Bind(&if_lhsisnotsmi);
+ assembler->Bind(&if_issmi);
{
- // Load the map of {lhs}.
- Node* lhs_map = assembler->LoadMap(lhs);
-
- // Check if {lhs} is a HeapNumber.
- Label if_lhsisnumber(assembler), if_lhsisnotnumber(assembler);
- assembler->Branch(assembler->WordEqual(lhs_map, number_map),
- &if_lhsisnumber, &if_lhsisnotnumber);
-
- assembler->Bind(&if_lhsisnumber);
- {
- // Check if {rhs} is a Smi or a HeapObject.
- Label if_rhsissmi(assembler), if_rhsisnotsmi(assembler);
- assembler->Branch(assembler->WordIsSmi(rhs), &if_rhsissmi,
- &if_rhsisnotsmi);
-
- assembler->Bind(&if_rhsissmi);
- {
- // Convert {lhs} and {rhs} to floating point values.
- Node* lhs_value = assembler->LoadHeapNumberValue(lhs);
- Node* rhs_value = assembler->SmiToFloat64(rhs);
+ // Try fast Smi subtraction first.
+ Node* one = assembler->SmiConstant(Smi::FromInt(1));
+ Node* pair = assembler->SmiSubWithOverflow(value, one);
+ Node* overflow = assembler->Projection(1, pair);
- // Perform a floating point comparison of {lhs} and {rhs}.
- assembler->BranchIfFloat64Equal(lhs_value, rhs_value, &if_equal,
- &if_notequal);
- }
+ // Check if the Smi subtraction overflowed.
+ Label if_overflow(assembler), if_notoverflow(assembler);
+ assembler->Branch(overflow, &if_overflow, &if_notoverflow);
- assembler->Bind(&if_rhsisnotsmi);
- {
- // Load the map of {rhs}.
- Node* rhs_map = assembler->LoadMap(rhs);
-
- // Check if {rhs} is also a HeapNumber.
- Label if_rhsisnumber(assembler), if_rhsisnotnumber(assembler);
- assembler->Branch(assembler->WordEqual(rhs_map, number_map),
- &if_rhsisnumber, &if_rhsisnotnumber);
-
- assembler->Bind(&if_rhsisnumber);
- {
- // Convert {lhs} and {rhs} to floating point values.
- Node* lhs_value = assembler->LoadHeapNumberValue(lhs);
- Node* rhs_value = assembler->LoadHeapNumberValue(rhs);
-
- // Perform a floating point comparison of {lhs} and {rhs}.
- assembler->BranchIfFloat64Equal(lhs_value, rhs_value, &if_equal,
- &if_notequal);
- }
-
- assembler->Bind(&if_rhsisnotnumber);
- assembler->Goto(&if_notequal);
- }
- }
+ assembler->Bind(&if_notoverflow);
+ var_type_feedback.Bind(assembler->Word32Or(
+ var_type_feedback.value(),
+ assembler->Int32Constant(BinaryOperationFeedback::kSignedSmall)));
+ result_var.Bind(assembler->Projection(0, pair));
+ assembler->Goto(&end);
- assembler->Bind(&if_lhsisnotnumber);
+ assembler->Bind(&if_overflow);
{
- // Check if {rhs} is a Smi or a HeapObject.
- Label if_rhsissmi(assembler), if_rhsisnotsmi(assembler);
- assembler->Branch(assembler->WordIsSmi(rhs), &if_rhsissmi,
- &if_rhsisnotsmi);
-
- assembler->Bind(&if_rhsissmi);
- assembler->Goto(&if_notequal);
-
- assembler->Bind(&if_rhsisnotsmi);
- {
- // Load the instance type of {lhs}.
- Node* lhs_instance_type = assembler->LoadMapInstanceType(lhs_map);
-
- // Check if {lhs} is a String.
- Label if_lhsisstring(assembler), if_lhsisnotstring(assembler);
- assembler->Branch(assembler->IsStringInstanceType(lhs_instance_type),
- &if_lhsisstring, &if_lhsisnotstring);
-
- assembler->Bind(&if_lhsisstring);
- {
- // Load the instance type of {rhs}.
- Node* rhs_instance_type = assembler->LoadInstanceType(rhs);
-
- // Check if {rhs} is also a String.
- Label if_rhsisstring(assembler, Label::kDeferred),
- if_rhsisnotstring(assembler);
- assembler->Branch(
- assembler->IsStringInstanceType(rhs_instance_type),
- &if_rhsisstring, &if_rhsisnotstring);
-
- assembler->Bind(&if_rhsisstring);
- {
- Callable callable =
- (mode == kDontNegateResult)
- ? CodeFactory::StringEqual(assembler->isolate())
- : CodeFactory::StringNotEqual(assembler->isolate());
- result.Bind(assembler->CallStub(callable, context, lhs, rhs));
- assembler->Goto(&end);
- }
-
- assembler->Bind(&if_rhsisnotstring);
- assembler->Goto(&if_notequal);
- }
-
- assembler->Bind(&if_lhsisnotstring);
- {
- // Check if {lhs} is a Simd128Value.
- Label if_lhsissimd128value(assembler),
- if_lhsisnotsimd128value(assembler);
- assembler->Branch(assembler->Word32Equal(
- lhs_instance_type,
- assembler->Int32Constant(SIMD128_VALUE_TYPE)),
- &if_lhsissimd128value, &if_lhsisnotsimd128value);
-
- assembler->Bind(&if_lhsissimd128value);
- {
- // Load the map of {rhs}.
- Node* rhs_map = assembler->LoadMap(rhs);
-
- // Check if {rhs} is also a Simd128Value that is equal to {lhs}.
- GenerateEqual_Simd128Value_HeapObject(assembler, lhs, lhs_map,
- rhs, rhs_map, &if_equal,
- &if_notequal);
- }
-
- assembler->Bind(&if_lhsisnotsimd128value);
- assembler->Goto(&if_notequal);
- }
- }
+ var_fdec_value.Bind(assembler->SmiToFloat64(value));
+ assembler->Goto(&do_fdec);
}
}
- assembler->Bind(&if_lhsissmi);
+ assembler->Bind(&if_isnotsmi);
{
- // We already know that {lhs} and {rhs} are not reference equal, and {lhs}
- // is a Smi; so {lhs} and {rhs} can only be strictly equal if {rhs} is a
- // HeapNumber with an equal floating point value.
-
- // Check if {rhs} is a Smi or a HeapObject.
- Label if_rhsissmi(assembler), if_rhsisnotsmi(assembler);
- assembler->Branch(assembler->WordIsSmi(rhs), &if_rhsissmi,
- &if_rhsisnotsmi);
-
- assembler->Bind(&if_rhsissmi);
- assembler->Goto(&if_notequal);
+ // Check if the value is a HeapNumber.
+ Label if_valueisnumber(assembler),
+ if_valuenotnumber(assembler, Label::kDeferred);
+ Node* value_map = assembler->LoadMap(value);
+ assembler->Branch(assembler->IsHeapNumberMap(value_map),
+ &if_valueisnumber, &if_valuenotnumber);
- assembler->Bind(&if_rhsisnotsmi);
+ assembler->Bind(&if_valueisnumber);
{
- // Load the map of the {rhs}.
- Node* rhs_map = assembler->LoadMap(rhs);
-
- // The {rhs} could be a HeapNumber with the same value as {lhs}.
- Label if_rhsisnumber(assembler), if_rhsisnotnumber(assembler);
- assembler->Branch(assembler->WordEqual(rhs_map, number_map),
- &if_rhsisnumber, &if_rhsisnotnumber);
-
- assembler->Bind(&if_rhsisnumber);
- {
- // Convert {lhs} and {rhs} to floating point values.
- Node* lhs_value = assembler->SmiToFloat64(lhs);
- Node* rhs_value = assembler->LoadHeapNumberValue(rhs);
-
- // Perform a floating point comparison of {lhs} and {rhs}.
- assembler->BranchIfFloat64Equal(lhs_value, rhs_value, &if_equal,
- &if_notequal);
- }
+ // Load the HeapNumber value.
+ var_fdec_value.Bind(assembler->LoadHeapNumberValue(value));
+ assembler->Goto(&do_fdec);
+ }
- assembler->Bind(&if_rhsisnotnumber);
- assembler->Goto(&if_notequal);
+ assembler->Bind(&if_valuenotnumber);
+ {
+ // Convert to a Number first and try again.
+ Callable callable =
+ CodeFactory::NonNumberToNumber(assembler->isolate());
+ var_type_feedback.Bind(
+ assembler->Int32Constant(BinaryOperationFeedback::kAny));
+ value_var.Bind(assembler->CallStub(callable, context, value));
+ assembler->Goto(&start);
}
}
}
- assembler->Bind(&if_equal);
- {
- result.Bind(assembler->BooleanConstant(mode == kDontNegateResult));
- assembler->Goto(&end);
- }
-
- assembler->Bind(&if_notequal);
+ assembler->Bind(&do_fdec);
{
- result.Bind(assembler->BooleanConstant(mode == kNegateResult));
+ Node* fdec_value = var_fdec_value.value();
+ Node* one = assembler->Float64Constant(1.0);
+ Node* fdec_result = assembler->Float64Sub(fdec_value, one);
+ var_type_feedback.Bind(assembler->Word32Or(
+ var_type_feedback.value(),
+ assembler->Int32Constant(BinaryOperationFeedback::kNumber)));
+ result_var.Bind(assembler->ChangeFloat64ToTagged(fdec_result));
assembler->Goto(&end);
}
assembler->Bind(&end);
- return result.value();
+ assembler->UpdateFeedback(var_type_feedback.value(), type_feedback_vector,
+ slot_id);
+ return result_var.value();
}
-} // namespace
+// ES6 section 21.1.3.19 String.prototype.substring ( start, end )
+compiler::Node* SubStringStub::Generate(CodeStubAssembler* assembler,
+ compiler::Node* string,
+ compiler::Node* from,
+ compiler::Node* to,
+ compiler::Node* context) {
+ return assembler->SubString(context, string, from, to);
+}
void LoadApiGetterStub::GenerateAssembly(CodeStubAssembler* assembler) const {
typedef compiler::Node Node;
@@ -4392,155 +1806,6 @@ void StoreScriptContextFieldStub::GenerateAssembly(
assembler->Return(value);
}
-// static
-compiler::Node* LessThanStub::Generate(CodeStubAssembler* assembler,
- compiler::Node* lhs, compiler::Node* rhs,
- compiler::Node* context) {
- return GenerateAbstractRelationalComparison(assembler, kLessThan, lhs, rhs,
- context);
-}
-
-// static
-compiler::Node* LessThanOrEqualStub::Generate(CodeStubAssembler* assembler,
- compiler::Node* lhs,
- compiler::Node* rhs,
- compiler::Node* context) {
- return GenerateAbstractRelationalComparison(assembler, kLessThanOrEqual, lhs,
- rhs, context);
-}
-
-// static
-compiler::Node* GreaterThanStub::Generate(CodeStubAssembler* assembler,
- compiler::Node* lhs,
- compiler::Node* rhs,
- compiler::Node* context) {
- return GenerateAbstractRelationalComparison(assembler, kGreaterThan, lhs, rhs,
- context);
-}
-
-// static
-compiler::Node* GreaterThanOrEqualStub::Generate(CodeStubAssembler* assembler,
- compiler::Node* lhs,
- compiler::Node* rhs,
- compiler::Node* context) {
- return GenerateAbstractRelationalComparison(assembler, kGreaterThanOrEqual,
- lhs, rhs, context);
-}
-
-// static
-compiler::Node* EqualStub::Generate(CodeStubAssembler* assembler,
- compiler::Node* lhs, compiler::Node* rhs,
- compiler::Node* context) {
- return GenerateEqual(assembler, kDontNegateResult, lhs, rhs, context);
-}
-
-// static
-compiler::Node* NotEqualStub::Generate(CodeStubAssembler* assembler,
- compiler::Node* lhs, compiler::Node* rhs,
- compiler::Node* context) {
- return GenerateEqual(assembler, kNegateResult, lhs, rhs, context);
-}
-
-// static
-compiler::Node* StrictEqualStub::Generate(CodeStubAssembler* assembler,
- compiler::Node* lhs,
- compiler::Node* rhs,
- compiler::Node* context) {
- return GenerateStrictEqual(assembler, kDontNegateResult, lhs, rhs, context);
-}
-
-// static
-compiler::Node* StrictNotEqualStub::Generate(CodeStubAssembler* assembler,
- compiler::Node* lhs,
- compiler::Node* rhs,
- compiler::Node* context) {
- return GenerateStrictEqual(assembler, kNegateResult, lhs, rhs, context);
-}
-
-void ToLengthStub::GenerateAssembly(CodeStubAssembler* assembler) const {
- typedef CodeStubAssembler::Label Label;
- typedef compiler::Node Node;
- typedef CodeStubAssembler::Variable Variable;
-
- Node* context = assembler->Parameter(1);
-
- // We might need to loop once for ToNumber conversion.
- Variable var_len(assembler, MachineRepresentation::kTagged);
- Label loop(assembler, &var_len);
- var_len.Bind(assembler->Parameter(0));
- assembler->Goto(&loop);
- assembler->Bind(&loop);
- {
- // Shared entry points.
- Label return_len(assembler),
- return_two53minus1(assembler, Label::kDeferred),
- return_zero(assembler, Label::kDeferred);
-
- // Load the current {len} value.
- Node* len = var_len.value();
-
- // Check if {len} is a positive Smi.
- assembler->GotoIf(assembler->WordIsPositiveSmi(len), &return_len);
-
- // Check if {len} is a (negative) Smi.
- assembler->GotoIf(assembler->WordIsSmi(len), &return_zero);
-
- // Check if {len} is a HeapNumber.
- Label if_lenisheapnumber(assembler),
- if_lenisnotheapnumber(assembler, Label::kDeferred);
- assembler->Branch(assembler->IsHeapNumberMap(assembler->LoadMap(len)),
- &if_lenisheapnumber, &if_lenisnotheapnumber);
-
- assembler->Bind(&if_lenisheapnumber);
- {
- // Load the floating-point value of {len}.
- Node* len_value = assembler->LoadHeapNumberValue(len);
-
- // Check if {len} is not greater than zero.
- assembler->GotoUnless(assembler->Float64GreaterThan(
- len_value, assembler->Float64Constant(0.0)),
- &return_zero);
-
- // Check if {len} is greater than or equal to 2^53-1.
- assembler->GotoIf(
- assembler->Float64GreaterThanOrEqual(
- len_value, assembler->Float64Constant(kMaxSafeInteger)),
- &return_two53minus1);
-
- // Round the {len} towards -Infinity.
- Node* value = assembler->Float64Floor(len_value);
- Node* result = assembler->ChangeFloat64ToTagged(value);
- assembler->Return(result);
- }
-
- assembler->Bind(&if_lenisnotheapnumber);
- {
- // Need to convert {len} to a Number first.
- Callable callable = CodeFactory::NonNumberToNumber(assembler->isolate());
- var_len.Bind(assembler->CallStub(callable, context, len));
- assembler->Goto(&loop);
- }
-
- assembler->Bind(&return_len);
- assembler->Return(var_len.value());
-
- assembler->Bind(&return_two53minus1);
- assembler->Return(assembler->NumberConstant(kMaxSafeInteger));
-
- assembler->Bind(&return_zero);
- assembler->Return(assembler->SmiConstant(Smi::FromInt(0)));
- }
-}
-
-void ToIntegerStub::GenerateAssembly(CodeStubAssembler* assembler) const {
- typedef compiler::Node Node;
-
- Node* input = assembler->Parameter(Descriptor::kArgument);
- Node* context = assembler->Parameter(Descriptor::kContext);
-
- assembler->Return(assembler->ToInteger(context, input));
-}
-
void StoreInterceptorStub::GenerateAssembly(
CodeStubAssembler* assembler) const {
typedef compiler::Node Node;
@@ -4841,111 +2106,6 @@ void StringAddStub::InitializeDescriptor(CodeStubDescriptor* descriptor) {
descriptor->SetMissHandler(Runtime::kStringAdd);
}
-namespace {
-
-compiler::Node* GenerateHasProperty(
- CodeStubAssembler* assembler, compiler::Node* object, compiler::Node* key,
- compiler::Node* context, Runtime::FunctionId fallback_runtime_function_id) {
- typedef compiler::Node Node;
- typedef CodeStubAssembler::Label Label;
- typedef CodeStubAssembler::Variable Variable;
-
- Label call_runtime(assembler, Label::kDeferred), return_true(assembler),
- return_false(assembler), end(assembler);
-
- CodeStubAssembler::LookupInHolder lookup_property_in_holder =
- [assembler, &return_true](Node* receiver, Node* holder, Node* holder_map,
- Node* holder_instance_type, Node* unique_name,
- Label* next_holder, Label* if_bailout) {
- assembler->TryHasOwnProperty(holder, holder_map, holder_instance_type,
- unique_name, &return_true, next_holder,
- if_bailout);
- };
-
- CodeStubAssembler::LookupInHolder lookup_element_in_holder =
- [assembler, &return_true](Node* receiver, Node* holder, Node* holder_map,
- Node* holder_instance_type, Node* index,
- Label* next_holder, Label* if_bailout) {
- assembler->TryLookupElement(holder, holder_map, holder_instance_type,
- index, &return_true, next_holder,
- if_bailout);
- };
-
- assembler->TryPrototypeChainLookup(object, key, lookup_property_in_holder,
- lookup_element_in_holder, &return_false,
- &call_runtime);
-
- Variable result(assembler, MachineRepresentation::kTagged);
- assembler->Bind(&return_true);
- {
- result.Bind(assembler->BooleanConstant(true));
- assembler->Goto(&end);
- }
-
- assembler->Bind(&return_false);
- {
- result.Bind(assembler->BooleanConstant(false));
- assembler->Goto(&end);
- }
-
- assembler->Bind(&call_runtime);
- {
- result.Bind(assembler->CallRuntime(fallback_runtime_function_id, context,
- object, key));
- assembler->Goto(&end);
- }
-
- assembler->Bind(&end);
- return result.value();
-}
-
-} // namespace
-
-// static
-compiler::Node* HasPropertyStub::Generate(CodeStubAssembler* assembler,
- compiler::Node* key,
- compiler::Node* object,
- compiler::Node* context) {
- return GenerateHasProperty(assembler, object, key, context,
- Runtime::kHasProperty);
-}
-
-// static
-compiler::Node* ForInFilterStub::Generate(CodeStubAssembler* assembler,
- compiler::Node* key,
- compiler::Node* object,
- compiler::Node* context) {
- typedef compiler::Node Node;
- typedef CodeStubAssembler::Label Label;
- typedef CodeStubAssembler::Variable Variable;
-
- Label return_undefined(assembler, Label::kDeferred),
- return_to_name(assembler), end(assembler);
-
- Variable var_result(assembler, MachineRepresentation::kTagged);
-
- Node* has_property = GenerateHasProperty(assembler, object, key, context,
- Runtime::kForInHasProperty);
-
- assembler->Branch(
- assembler->WordEqual(has_property, assembler->BooleanConstant(true)),
- &return_to_name, &return_undefined);
-
- assembler->Bind(&return_to_name);
- {
- var_result.Bind(assembler->ToName(context, key));
- assembler->Goto(&end);
- }
-
- assembler->Bind(&return_undefined);
- {
- var_result.Bind(assembler->UndefinedConstant());
- assembler->Goto(&end);
- }
-
- assembler->Bind(&end);
- return var_result.value();
-}
void GetPropertyStub::GenerateAssembly(CodeStubAssembler* assembler) const {
typedef compiler::Node Node;
« no previous file with comments | « src/code-stubs.h ('k') | src/crankshaft/hydrogen.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698