| Index: src/compiler/linkage.cc
|
| diff --git a/src/compiler/linkage.cc b/src/compiler/linkage.cc
|
| index 9338a5bed7029d4783618b9734df6fb06bcd0a4e..93bf21a84291918f40b2d63b65f6a52f9aa6e083 100644
|
| --- a/src/compiler/linkage.cc
|
| +++ b/src/compiler/linkage.cc
|
| @@ -4,6 +4,7 @@
|
|
|
| #include "src/code-stubs.h"
|
| #include "src/compiler.h"
|
| +#include "src/compiler/common-operator.h"
|
| #include "src/compiler/linkage.h"
|
| #include "src/compiler/node.h"
|
| #include "src/compiler/pipeline.h"
|
| @@ -48,6 +49,63 @@ bool CallDescriptor::HasSameReturnLocationsAs(
|
| }
|
|
|
|
|
| +bool CallDescriptor::CanTailCall(const Node* node) const {
|
| + // 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.
|
| + CallDescriptor const* other = OpParameter<CallDescriptor const*>(node);
|
| + 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()) {
|
| + if (!GetInputLocation(current_input).is_register()) {
|
| + return false;
|
| + }
|
| + ++current_input;
|
| + }
|
| + return true;
|
| + }
|
| + if (current_input >= InputCount()) {
|
| + while (other_input < other->InputCount()) {
|
| + if (!other->GetInputLocation(other_input).is_register()) {
|
| + return false;
|
| + }
|
| + ++other_input;
|
| + }
|
| + return true;
|
| + }
|
| + if (GetInputLocation(current_input).is_register()) {
|
| + ++current_input;
|
| + continue;
|
| + }
|
| + if (other->GetInputLocation(other_input).is_register()) {
|
| + ++other_input;
|
| + continue;
|
| + }
|
| + if (GetInputLocation(current_input) !=
|
| + other->GetInputLocation(other_input)) {
|
| + return false;
|
| + }
|
| + Node* input = node->InputAt(static_cast<int>(other_input));
|
| + if (input->opcode() != IrOpcode::kParameter) {
|
| + return false;
|
| + }
|
| + size_t param_index = ParameterIndexOf(input->op());
|
| + if (param_index != stack_parameter) {
|
| + return false;
|
| + }
|
| + ++stack_parameter;
|
| + ++current_input;
|
| + ++other_input;
|
| + }
|
| + UNREACHABLE();
|
| + return false;
|
| +}
|
| +
|
| +
|
| CallDescriptor* Linkage::ComputeIncoming(Zone* zone, CompilationInfo* info) {
|
| if (info->code_stub() != NULL) {
|
| // Use the code stub interface descriptor.
|
|
|