| Index: src/code-stubs.cc
|
| diff --git a/src/code-stubs.cc b/src/code-stubs.cc
|
| index 273c5380a5bd6cb248f3f3d88f24b4c186136d3d..4d14e8fdf9b9da58398e9d433820cb5b36ef931a 100644
|
| --- a/src/code-stubs.cc
|
| +++ b/src/code-stubs.cc
|
| @@ -1639,6 +1639,168 @@ compiler::Node* BitwiseXorStub::Generate(CodeStubAssembler* assembler,
|
| return result;
|
| }
|
|
|
| +void IncStub::GenerateAssembly(CodeStubAssembler* assembler) const {
|
| + typedef CodeStubAssembler::Label Label;
|
| + typedef compiler::Node Node;
|
| + typedef CodeStubAssembler::Variable Variable;
|
| +
|
| + Node* context = assembler->Parameter(1);
|
| +
|
| + // Shared entry for floating point increment.
|
| + Label do_finc(assembler);
|
| + Variable var_finc_value(assembler, MachineRepresentation::kFloat64);
|
| +
|
| + // We might need to try again due to ToNumber conversion.
|
| + Variable value_var(assembler, MachineRepresentation::kTagged);
|
| + Label start(assembler, &value_var);
|
| + value_var.Bind(assembler->Parameter(0));
|
| + assembler->Goto(&start);
|
| + assembler->Bind(&start);
|
| + {
|
| + Node* 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 addition first.
|
| + Node* one = assembler->SmiConstant(Smi::FromInt(1));
|
| + Node* pair = assembler->SmiAddWithOverflow(value, one);
|
| + 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_notoverflow);
|
| + assembler->Return(assembler->Projection(0, pair));
|
| +
|
| + assembler->Bind(&if_overflow);
|
| + {
|
| + var_finc_value.Bind(assembler->SmiToFloat64(value));
|
| + assembler->Goto(&do_finc);
|
| + }
|
| + }
|
| +
|
| + 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);
|
| + Node* number_map = assembler->HeapNumberMapConstant();
|
| + assembler->Branch(assembler->WordEqual(value_map, number_map),
|
| + &if_valueisnumber, &if_valuenotnumber);
|
| +
|
| + assembler->Bind(&if_valueisnumber);
|
| + {
|
| + // Load the HeapNumber value.
|
| + var_finc_value.Bind(assembler->LoadHeapNumberValue(value));
|
| + assembler->Goto(&do_finc);
|
| + }
|
| +
|
| + assembler->Bind(&if_valuenotnumber);
|
| + {
|
| + // Convert to a Number first and try again.
|
| + Callable callable = CodeFactory::NonNumberToNumber(isolate());
|
| + 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);
|
| + Node* result = assembler->ChangeFloat64ToTagged(finc_result);
|
| + assembler->Return(result);
|
| + }
|
| +}
|
| +
|
| +void DecStub::GenerateAssembly(CodeStubAssembler* assembler) const {
|
| + typedef CodeStubAssembler::Label Label;
|
| + typedef compiler::Node Node;
|
| + typedef CodeStubAssembler::Variable Variable;
|
| +
|
| + Node* context = assembler->Parameter(1);
|
| +
|
| + // Shared entry for floating point decrement.
|
| + Label do_fdec(assembler);
|
| + Variable var_fdec_value(assembler, MachineRepresentation::kFloat64);
|
| +
|
| + // We might need to try again due to ToNumber conversion.
|
| + Variable value_var(assembler, MachineRepresentation::kTagged);
|
| + Label start(assembler, &value_var);
|
| + value_var.Bind(assembler->Parameter(0));
|
| + assembler->Goto(&start);
|
| + assembler->Bind(&start);
|
| + {
|
| + Node* 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);
|
| + assembler->Return(assembler->Projection(0, pair));
|
| +
|
| + 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);
|
| + Node* number_map = assembler->HeapNumberMapConstant();
|
| + assembler->Branch(assembler->WordEqual(value_map, number_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(isolate());
|
| + 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);
|
| + Node* result = assembler->ChangeFloat64ToTagged(fdec_result);
|
| + assembler->Return(result);
|
| + }
|
| +}
|
| +
|
| namespace {
|
|
|
| enum RelationalComparisonMode {
|
|
|