Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/code-stubs.h" | 5 #include "src/code-stubs.h" |
| 6 #include "src/compiler.h" | 6 #include "src/compiler.h" |
| 7 #include "src/compiler/common-operator.h" | 7 #include "src/compiler/common-operator.h" |
| 8 #include "src/compiler/frame.h" | 8 #include "src/compiler/frame.h" |
| 9 #include "src/compiler/linkage.h" | 9 #include "src/compiler/linkage.h" |
| 10 #include "src/compiler/node.h" | 10 #include "src/compiler/node.h" |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 82 bool CallDescriptor::HasSameReturnLocationsAs( | 82 bool CallDescriptor::HasSameReturnLocationsAs( |
| 83 const CallDescriptor* other) const { | 83 const CallDescriptor* other) const { |
| 84 if (ReturnCount() != other->ReturnCount()) return false; | 84 if (ReturnCount() != other->ReturnCount()) return false; |
| 85 for (size_t i = 0; i < ReturnCount(); ++i) { | 85 for (size_t i = 0; i < ReturnCount(); ++i) { |
| 86 if (GetReturnLocation(i) != other->GetReturnLocation(i)) return false; | 86 if (GetReturnLocation(i) != other->GetReturnLocation(i)) return false; |
| 87 } | 87 } |
| 88 return true; | 88 return true; |
| 89 } | 89 } |
| 90 | 90 |
| 91 | 91 |
| 92 bool CallDescriptor::CanTailCall(const Node* node) const { | 92 bool CallDescriptor::CanTailCall(const Node* node, |
| 93 // Determine the number of stack parameters passed in | 93 int* stack_param_delta) const { |
| 94 size_t stack_params = 0; | |
| 95 for (size_t i = 0; i < InputCount(); ++i) { | |
| 96 if (!GetInputLocation(i).IsRegister()) { | |
| 97 ++stack_params; | |
| 98 } | |
| 99 } | |
| 100 // Ensure the input linkage contains the stack parameters in the right order | |
| 101 size_t current_stack_param = 0; | |
| 102 for (size_t i = 0; i < InputCount(); ++i) { | |
| 103 if (!GetInputLocation(i).IsRegister()) { | |
| 104 if (GetInputLocation(i) != LinkageLocation::ForCallerFrameSlot( | |
| 105 static_cast<int>(current_stack_param) - | |
| 106 static_cast<int>(stack_params))) { | |
| 107 return false; | |
| 108 } | |
| 109 ++current_stack_param; | |
| 110 } | |
| 111 } | |
| 112 // Tail calling is currently allowed if return locations match and all | 94 // Tail calling is currently allowed if return locations match and all |
| 113 // parameters are either in registers or on the stack but match exactly in | 95 // parameters are either in registers or on the stack but match exactly in |
| 114 // number and content. | 96 // number and content. |
|
Jarin
2015/11/12 13:45:12
Update the comment, please.
danno
2015/11/13 10:04:17
Done.
| |
| 115 CallDescriptor const* other = OpParameter<CallDescriptor const*>(node); | 97 CallDescriptor const* other = OpParameter<CallDescriptor const*>(node); |
| 116 if (!HasSameReturnLocationsAs(other)) return false; | 98 if (!HasSameReturnLocationsAs(other)) return false; |
| 117 size_t current_input = 0; | 99 size_t current_input = 0; |
| 118 size_t other_input = 0; | 100 size_t other_input = 0; |
| 119 while (true) { | 101 *stack_param_delta = 0; |
| 120 if (other_input >= other->InputCount()) { | 102 bool more_other = true; |
| 121 while (current_input < InputCount()) { | 103 bool more_this = true; |
| 122 if (!GetInputLocation(current_input).IsRegister()) { | 104 while (more_other || more_this) { |
| 123 return false; | 105 if (other_input < other->InputCount()) { |
| 124 } | 106 if (!other->GetInputLocation(other_input).IsRegister()) { |
| 125 ++current_input; | 107 (*stack_param_delta)++; |
| 126 } | 108 } |
| 127 return true; | 109 } else { |
| 110 more_other = false; | |
| 128 } | 111 } |
| 129 if (current_input >= InputCount()) { | 112 if (current_input < InputCount()) { |
| 130 while (other_input < other->InputCount()) { | 113 if (!GetInputLocation(current_input).IsRegister()) { |
| 131 if (!other->GetInputLocation(other_input).IsRegister()) { | 114 (*stack_param_delta)--; |
| 132 return false; | |
| 133 } | |
| 134 ++other_input; | |
| 135 } | 115 } |
| 136 return true; | 116 } else { |
| 137 } | 117 more_this = false; |
| 138 if (GetInputLocation(current_input).IsRegister()) { | |
| 139 ++current_input; | |
| 140 continue; | |
| 141 } | |
| 142 if (other->GetInputLocation(other_input).IsRegister()) { | |
| 143 ++other_input; | |
| 144 continue; | |
| 145 } | |
| 146 if (GetInputLocation(current_input) != | |
| 147 other->GetInputLocation(other_input)) { | |
| 148 return false; | |
| 149 } | |
| 150 Node* input = node->InputAt(static_cast<int>(other_input)); | |
| 151 if (input->opcode() != IrOpcode::kParameter) { | |
| 152 return false; | |
| 153 } | |
| 154 // Make sure that the parameter input passed through to the tail call | |
| 155 // corresponds to the correct stack slot. | |
| 156 size_t param_index = ParameterIndexOf(input->op()); | |
| 157 if (param_index != current_input - 1) { | |
| 158 return false; | |
| 159 } | 118 } |
| 160 ++current_input; | 119 ++current_input; |
| 161 ++other_input; | 120 ++other_input; |
| 162 } | 121 } |
| 163 UNREACHABLE(); | 122 // TODO(danno): TF only current supports tail calls where the number of |
| 164 return false; | 123 // parameters is the same or fewer. |
| 124 return *stack_param_delta <= 0; | |
| 165 } | 125 } |
| 166 | 126 |
| 167 | 127 |
| 168 CallDescriptor* Linkage::ComputeIncoming(Zone* zone, CompilationInfo* info) { | 128 CallDescriptor* Linkage::ComputeIncoming(Zone* zone, CompilationInfo* info) { |
| 169 if (info->code_stub() != NULL) { | 129 if (info->code_stub() != NULL) { |
| 170 // Use the code stub interface descriptor. | 130 // Use the code stub interface descriptor. |
| 171 CodeStub* stub = info->code_stub(); | 131 CodeStub* stub = info->code_stub(); |
| 172 CallInterfaceDescriptor descriptor = stub->GetCallInterfaceDescriptor(); | 132 CallInterfaceDescriptor descriptor = stub->GetCallInterfaceDescriptor(); |
| 173 return GetStubCallDescriptor( | 133 return GetStubCallDescriptor( |
| 174 info->isolate(), zone, descriptor, stub->GetStackParameterCount(), | 134 info->isolate(), zone, descriptor, stub->GetStackParameterCount(), |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 250 case Runtime::kInlineToLength: | 210 case Runtime::kInlineToLength: |
| 251 case Runtime::kInlineToName: | 211 case Runtime::kInlineToName: |
| 252 case Runtime::kInlineToNumber: | 212 case Runtime::kInlineToNumber: |
| 253 case Runtime::kInlineToObject: | 213 case Runtime::kInlineToObject: |
| 254 case Runtime::kInlineToPrimitive_Number: | 214 case Runtime::kInlineToPrimitive_Number: |
| 255 case Runtime::kInlineToPrimitive_String: | 215 case Runtime::kInlineToPrimitive_String: |
| 256 case Runtime::kInlineToPrimitive: | 216 case Runtime::kInlineToPrimitive: |
| 257 case Runtime::kInlineToString: | 217 case Runtime::kInlineToString: |
| 258 return 1; | 218 return 1; |
| 259 case Runtime::kInlineCall: | 219 case Runtime::kInlineCall: |
| 220 case Runtime::kInlineTailCall: | |
| 260 case Runtime::kInlineDeoptimizeNow: | 221 case Runtime::kInlineDeoptimizeNow: |
| 261 case Runtime::kInlineThrowNotDateError: | 222 case Runtime::kInlineThrowNotDateError: |
| 262 return 2; | 223 return 2; |
| 263 default: | 224 default: |
| 264 break; | 225 break; |
| 265 } | 226 } |
| 266 | 227 |
| 267 // Most inlined runtime functions (except the ones listed above) can be called | 228 // Most inlined runtime functions (except the ones listed above) can be called |
| 268 // without a FrameState or will be lowered by JSIntrinsicLowering internally. | 229 // without a FrameState or will be lowered by JSIntrinsicLowering internally. |
| 269 const Runtime::Function* const f = Runtime::FunctionForId(function); | 230 const Runtime::Function* const f = Runtime::FunctionForId(function); |
| (...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 561 return LinkageLocation::ForCalleeFrameSlot(spill_index); | 522 return LinkageLocation::ForCalleeFrameSlot(spill_index); |
| 562 } else { | 523 } else { |
| 563 // Parameter. Use the assigned location from the incoming call descriptor. | 524 // Parameter. Use the assigned location from the incoming call descriptor. |
| 564 int parameter_index = 1 + index; // skip index 0, which is the target. | 525 int parameter_index = 1 + index; // skip index 0, which is the target. |
| 565 return incoming_->GetInputLocation(parameter_index); | 526 return incoming_->GetInputLocation(parameter_index); |
| 566 } | 527 } |
| 567 } | 528 } |
| 568 } // namespace compiler | 529 } // namespace compiler |
| 569 } // namespace internal | 530 } // namespace internal |
| 570 } // namespace v8 | 531 } // namespace v8 |
| OLD | NEW |