Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(259)

Side by Side Diff: src/compiler/linkage.cc

Issue 1259203002: [turbofan] Implement tail calls with differing stack parameter counts (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fix bugs in frameless tail calls Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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/linkage.h" 8 #include "src/compiler/linkage.h"
9 #include "src/compiler/node.h" 9 #include "src/compiler/node.h"
10 #include "src/compiler/pipeline.h" 10 #include "src/compiler/pipeline.h"
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
45 bool CallDescriptor::HasSameReturnLocationsAs( 45 bool CallDescriptor::HasSameReturnLocationsAs(
46 const CallDescriptor* other) const { 46 const CallDescriptor* other) const {
47 if (ReturnCount() != other->ReturnCount()) return false; 47 if (ReturnCount() != other->ReturnCount()) return false;
48 for (size_t i = 0; i < ReturnCount(); ++i) { 48 for (size_t i = 0; i < ReturnCount(); ++i) {
49 if (GetReturnLocation(i) != other->GetReturnLocation(i)) return false; 49 if (GetReturnLocation(i) != other->GetReturnLocation(i)) return false;
50 } 50 }
51 return true; 51 return true;
52 } 52 }
53 53
54 54
55 bool CallDescriptor::CanTailCall(const Node* node) const { 55 bool CallDescriptor::CanTailCall(const Node* node, size_t* stack_parameters_in,
56 size_t* preserved_stack_parameters_in,
57 size_t* stack_parameters_out,
58 size_t* register_parameters_out) const {
59 *stack_parameters_in = 0;
60 *stack_parameters_out = 0;
61 *preserved_stack_parameters_in = 0;
62 *register_parameters_out = 0;
63
56 // Determine the number of stack parameters passed in 64 // Determine the number of stack parameters passed in
57 size_t stack_params = 0;
58 for (size_t i = 0; i < InputCount(); ++i) { 65 for (size_t i = 0; i < InputCount(); ++i) {
59 if (!GetInputLocation(i).is_register()) { 66 if (!GetInputLocation(i).is_register()) {
60 ++stack_params; 67 ++(*stack_parameters_in);
61 } 68 }
62 } 69 }
63 // Ensure the input linkage contains the stack parameters in the right order 70 // Ensure the input linkage contains the stack parameters in the right order
64 size_t current_stack_param = 0; 71 size_t current_stack_param = 0;
65 for (size_t i = 0; i < InputCount(); ++i) { 72 for (size_t i = 0; i < InputCount(); ++i) {
66 if (!GetInputLocation(i).is_register()) { 73 if (!GetInputLocation(i).is_register()) {
67 if (GetInputLocation(i) != 74 if (GetInputLocation(i) !=
68 LinkageLocation(static_cast<int>(current_stack_param) - 75 LinkageLocation(static_cast<int>(current_stack_param) -
69 static_cast<int>(stack_params))) { 76 static_cast<int>(*stack_parameters_in))) {
70 return false; 77 return false;
71 } 78 }
72 ++current_stack_param; 79 ++current_stack_param;
73 } 80 }
74 } 81 }
75 // Tail calling is currently allowed if return locations match and all 82 // Tail calling is currently allowed if return locations match and all
76 // parameters are either in registers or on the stack but match exactly in 83 // parameters are either in registers or on the stack but match exactly in
77 // number and content. 84 // number and content.
78 CallDescriptor const* other = OpParameter<CallDescriptor const*>(node); 85 CallDescriptor const* other = OpParameter<CallDescriptor const*>(node);
79 if (!HasSameReturnLocationsAs(other)) return false; 86 if (!HasSameReturnLocationsAs(other)) return false;
87
80 size_t current_input = 0; 88 size_t current_input = 0;
81 size_t other_input = 0; 89 size_t other_input = 0;
90 bool stack_param_match = true;
82 while (true) { 91 while (true) {
83 if (other_input >= other->InputCount()) { 92 if (other_input >= other->InputCount()) {
84 while (current_input < InputCount()) {
85 if (!GetInputLocation(current_input).is_register()) {
86 return false;
87 }
88 ++current_input;
89 }
90 return true; 93 return true;
91 } 94 }
92 if (current_input >= InputCount()) { 95 if (current_input >= InputCount()) {
93 while (other_input < other->InputCount()) { 96 while (other_input < other->InputCount()) {
94 if (!other->GetInputLocation(other_input).is_register()) { 97 if (!other->GetInputLocation(other_input).is_register()) {
95 return false; 98 (*stack_parameters_out)++;
99 } else {
100 ++(*register_parameters_out);
96 } 101 }
97 ++other_input; 102 ++other_input;
98 } 103 }
104 // Allow adding stack parameters for the tail call
99 return true; 105 return true;
100 } 106 }
101 if (GetInputLocation(current_input).is_register()) { 107 if (GetInputLocation(current_input).is_register()) {
102 ++current_input; 108 ++current_input;
103 continue; 109 continue;
104 } 110 }
105 if (other->GetInputLocation(other_input).is_register()) { 111 if (other->GetInputLocation(other_input).is_register()) {
106 ++other_input; 112 ++other_input;
113 ++(*register_parameters_out);
107 continue; 114 continue;
108 } 115 }
109 if (GetInputLocation(current_input) !=
110 other->GetInputLocation(other_input)) {
111 return false;
112 }
113 Node* input = node->InputAt(static_cast<int>(other_input)); 116 Node* input = node->InputAt(static_cast<int>(other_input));
114 if (input->opcode() != IrOpcode::kParameter) { 117 if (input->opcode() != IrOpcode::kParameter) {
115 return false; 118 stack_param_match = false;
119 } else {
120 // Make sure that the parameter input passed through to the tail call
121 // corresponds to the correct stack slot.
122 size_t param_index = ParameterIndexOf(input->op());
123 if (param_index != current_input - 1) {
124 stack_param_match = false;
125 }
116 } 126 }
117 // Make sure that the parameter input passed through to the tail call 127 if (stack_param_match) {
118 // corresponds to the correct stack slot. 128 (*preserved_stack_parameters_in)++;
119 size_t param_index = ParameterIndexOf(input->op());
120 if (param_index != current_input - 1) {
121 return false;
122 } 129 }
130 (*stack_parameters_out)++;
123 ++current_input; 131 ++current_input;
124 ++other_input; 132 ++other_input;
125 } 133 }
126 UNREACHABLE(); 134 UNREACHABLE();
127 return false; 135 return false;
128 } 136 }
129 137
130 138
131 CallDescriptor* Linkage::ComputeIncoming(Zone* zone, CompilationInfo* info) { 139 CallDescriptor* Linkage::ComputeIncoming(Zone* zone, CompilationInfo* info) {
132 if (info->code_stub() != NULL) { 140 if (info->code_stub() != NULL) {
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
282 290
283 CallDescriptor* Linkage::GetSimplifiedCDescriptor(Zone* zone, 291 CallDescriptor* Linkage::GetSimplifiedCDescriptor(Zone* zone,
284 const MachineSignature* sig) { 292 const MachineSignature* sig) {
285 UNIMPLEMENTED(); 293 UNIMPLEMENTED();
286 return NULL; 294 return NULL;
287 } 295 }
288 #endif // !V8_TURBOFAN_BACKEND 296 #endif // !V8_TURBOFAN_BACKEND
289 } // namespace compiler 297 } // namespace compiler
290 } // namespace internal 298 } // namespace internal
291 } // namespace v8 299 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698