| Index: src/compiler/linkage.cc
|
| diff --git a/src/compiler/linkage.cc b/src/compiler/linkage.cc
|
| index 691a3b38614fce0d045bc86af0584ae8d5b876c0..a460f4a980bd19db7dd688b9677bc2916077ed58 100644
|
| --- a/src/compiler/linkage.cc
|
| +++ b/src/compiler/linkage.cc
|
| @@ -53,6 +53,25 @@ bool CallDescriptor::HasSameReturnLocationsAs(
|
|
|
|
|
| bool CallDescriptor::CanTailCall(const Node* node) const {
|
| + // Determine the number of stack parameters passed in
|
| + size_t stack_params = 0;
|
| + for (size_t i = 0; i < InputCount(); ++i) {
|
| + if (!GetInputLocation(i).is_register()) {
|
| + ++stack_params;
|
| + }
|
| + }
|
| + // Ensure the input linkage contains the stack parameters in the right order
|
| + size_t current_stack_param = 0;
|
| + for (size_t i = 0; i < InputCount(); ++i) {
|
| + if (!GetInputLocation(i).is_register()) {
|
| + if (GetInputLocation(i) !=
|
| + LinkageLocation(static_cast<int>(current_stack_param) -
|
| + static_cast<int>(stack_params))) {
|
| + return false;
|
| + }
|
| + ++current_stack_param;
|
| + }
|
| + }
|
| // Tail calling is currently allowed if return locations match and all
|
| // parameters are either in registers or on the stack but match exactly in
|
| // number and content.
|
| @@ -60,10 +79,9 @@ bool CallDescriptor::CanTailCall(const Node* node) const {
|
| if (!HasSameReturnLocationsAs(other)) return false;
|
| size_t current_input = 0;
|
| size_t other_input = 0;
|
| - size_t stack_parameter = 0;
|
| while (true) {
|
| if (other_input >= other->InputCount()) {
|
| - while (current_input <= InputCount()) {
|
| + while (current_input < InputCount()) {
|
| if (!GetInputLocation(current_input).is_register()) {
|
| return false;
|
| }
|
| @@ -96,11 +114,12 @@ bool CallDescriptor::CanTailCall(const Node* node) const {
|
| if (input->opcode() != IrOpcode::kParameter) {
|
| return false;
|
| }
|
| + // Make sure that the parameter input passed through to the tail call
|
| + // corresponds to the correct stack slot.
|
| size_t param_index = ParameterIndexOf(input->op());
|
| - if (param_index != stack_parameter) {
|
| + if (param_index != current_input - 1) {
|
| return false;
|
| }
|
| - ++stack_parameter;
|
| ++current_input;
|
| ++other_input;
|
| }
|
|
|