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/linkage.h" | 8 #include "src/compiler/linkage.h" |
8 #include "src/compiler/node.h" | 9 #include "src/compiler/node.h" |
9 #include "src/compiler/pipeline.h" | 10 #include "src/compiler/pipeline.h" |
10 #include "src/scopes.h" | 11 #include "src/scopes.h" |
11 | 12 |
12 namespace v8 { | 13 namespace v8 { |
13 namespace internal { | 14 namespace internal { |
14 namespace compiler { | 15 namespace compiler { |
15 | 16 |
16 | 17 |
(...skipping 24 matching lines...) Expand all Loading... |
41 bool CallDescriptor::HasSameReturnLocationsAs( | 42 bool CallDescriptor::HasSameReturnLocationsAs( |
42 const CallDescriptor* other) const { | 43 const CallDescriptor* other) const { |
43 if (ReturnCount() != other->ReturnCount()) return false; | 44 if (ReturnCount() != other->ReturnCount()) return false; |
44 for (size_t i = 0; i < ReturnCount(); ++i) { | 45 for (size_t i = 0; i < ReturnCount(); ++i) { |
45 if (GetReturnLocation(i) != other->GetReturnLocation(i)) return false; | 46 if (GetReturnLocation(i) != other->GetReturnLocation(i)) return false; |
46 } | 47 } |
47 return true; | 48 return true; |
48 } | 49 } |
49 | 50 |
50 | 51 |
| 52 bool CallDescriptor::CanTailCall(const Node* node) const { |
| 53 // Tail calling is currently allowed if return locations match and all |
| 54 // parameters are either in registers or on the stack but match exactly in |
| 55 // number and content. |
| 56 CallDescriptor const* other = OpParameter<CallDescriptor const*>(node); |
| 57 if (!HasSameReturnLocationsAs(other)) return false; |
| 58 size_t current_input = 0; |
| 59 size_t other_input = 0; |
| 60 size_t stack_parameter = 0; |
| 61 while (true) { |
| 62 if (other_input >= other->InputCount()) { |
| 63 while (current_input <= InputCount()) { |
| 64 if (!GetInputLocation(current_input).is_register()) { |
| 65 return false; |
| 66 } |
| 67 ++current_input; |
| 68 } |
| 69 return true; |
| 70 } |
| 71 if (current_input >= InputCount()) { |
| 72 while (other_input < other->InputCount()) { |
| 73 if (!other->GetInputLocation(other_input).is_register()) { |
| 74 return false; |
| 75 } |
| 76 ++other_input; |
| 77 } |
| 78 return true; |
| 79 } |
| 80 if (GetInputLocation(current_input).is_register()) { |
| 81 ++current_input; |
| 82 continue; |
| 83 } |
| 84 if (other->GetInputLocation(other_input).is_register()) { |
| 85 ++other_input; |
| 86 continue; |
| 87 } |
| 88 if (GetInputLocation(current_input) != |
| 89 other->GetInputLocation(other_input)) { |
| 90 return false; |
| 91 } |
| 92 Node* input = node->InputAt(static_cast<int>(other_input)); |
| 93 if (input->opcode() != IrOpcode::kParameter) { |
| 94 return false; |
| 95 } |
| 96 size_t param_index = ParameterIndexOf(input->op()); |
| 97 if (param_index != stack_parameter) { |
| 98 return false; |
| 99 } |
| 100 ++stack_parameter; |
| 101 ++current_input; |
| 102 ++other_input; |
| 103 } |
| 104 UNREACHABLE(); |
| 105 return false; |
| 106 } |
| 107 |
| 108 |
51 CallDescriptor* Linkage::ComputeIncoming(Zone* zone, CompilationInfo* info) { | 109 CallDescriptor* Linkage::ComputeIncoming(Zone* zone, CompilationInfo* info) { |
52 if (info->code_stub() != NULL) { | 110 if (info->code_stub() != NULL) { |
53 // Use the code stub interface descriptor. | 111 // Use the code stub interface descriptor. |
54 CodeStub* stub = info->code_stub(); | 112 CodeStub* stub = info->code_stub(); |
55 CallInterfaceDescriptor descriptor = stub->GetCallInterfaceDescriptor(); | 113 CallInterfaceDescriptor descriptor = stub->GetCallInterfaceDescriptor(); |
56 return GetStubCallDescriptor( | 114 return GetStubCallDescriptor( |
57 info->isolate(), zone, descriptor, stub->GetStackParameterCount(), | 115 info->isolate(), zone, descriptor, stub->GetStackParameterCount(), |
58 CallDescriptor::kNoFlags, Operator::kNoProperties); | 116 CallDescriptor::kNoFlags, Operator::kNoProperties); |
59 } | 117 } |
60 if (info->function() != NULL) { | 118 if (info->function() != NULL) { |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
200 | 258 |
201 CallDescriptor* Linkage::GetSimplifiedCDescriptor(Zone* zone, | 259 CallDescriptor* Linkage::GetSimplifiedCDescriptor(Zone* zone, |
202 const MachineSignature* sig) { | 260 const MachineSignature* sig) { |
203 UNIMPLEMENTED(); | 261 UNIMPLEMENTED(); |
204 return NULL; | 262 return NULL; |
205 } | 263 } |
206 #endif // !V8_TURBOFAN_BACKEND | 264 #endif // !V8_TURBOFAN_BACKEND |
207 } // namespace compiler | 265 } // namespace compiler |
208 } // namespace internal | 266 } // namespace internal |
209 } // namespace v8 | 267 } // namespace v8 |
OLD | NEW |