Chromium Code Reviews| Index: src/code-stubs.cc |
| diff --git a/src/code-stubs.cc b/src/code-stubs.cc |
| index f594b0f9e266955659e86e464cb6a4568de2c083..8ea9185337a1a6156502dc16dfe3f165a9462562 100644 |
| --- a/src/code-stubs.cc |
| +++ b/src/code-stubs.cc |
| @@ -1608,6 +1608,170 @@ void BitwiseXorStub::GenerateAssembly(CodeStubAssembler* assembler) const { |
| 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); |
| + Variable* start_vars[1] = {&value_var}; |
| + Label start(assembler, 1, start_vars); |
|
Benedikt Meurer
2016/04/21 11:37:35
You can just use Label start(assembler, &value_var
rmcilroy
2016/04/21 13:55:31
I'm sure I tried this first and it didn't work, bu
|
| + 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); |
| + Variable* start_vars[1] = {&value_var}; |
| + Label start(assembler, 1, start_vars); |
|
Benedikt Meurer
2016/04/21 11:37:35
You can just use Label start(assembler, &value_var
rmcilroy
2016/04/21 13:55:31
Done.
|
| + 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 { |