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

Side by Side Diff: src/compiler/frame-states.cc

Issue 1485183002: [turbofan] Deopt support for escape analysis (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@ea-local
Patch Set: Created 5 years 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 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 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/compiler/frame-states.h"
6
5 #include "src/base/functional.h" 7 #include "src/base/functional.h"
6 #include "src/compiler/frame-states.h" 8 #include "src/compiler/code-generator.h"
9 #include "src/compiler/instruction-selector-impl.h"
10 #include "src/compiler/node.h"
11 #include "src/compiler/state-values-utils.h"
7 #include "src/handles-inl.h" 12 #include "src/handles-inl.h"
8 13
9 namespace v8 { 14 namespace v8 {
10 namespace internal { 15 namespace internal {
11 namespace compiler { 16 namespace compiler {
12 17
13 size_t hash_value(OutputFrameStateCombine const& sc) { 18 size_t hash_value(OutputFrameStateCombine const& sc) {
14 return base::hash_combine(sc.kind_, sc.parameter_); 19 return base::hash_combine(sc.kind_, sc.parameter_);
15 } 20 }
16 21
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
65 std::ostream& operator<<(std::ostream& os, FrameStateInfo const& info) { 70 std::ostream& operator<<(std::ostream& os, FrameStateInfo const& info) {
66 os << info.type() << ", " << info.bailout_id() << ", " 71 os << info.type() << ", " << info.bailout_id() << ", "
67 << info.state_combine(); 72 << info.state_combine();
68 Handle<SharedFunctionInfo> shared_info; 73 Handle<SharedFunctionInfo> shared_info;
69 if (info.shared_info().ToHandle(&shared_info)) { 74 if (info.shared_info().ToHandle(&shared_info)) {
70 os << ", " << Brief(*shared_info); 75 os << ", " << Brief(*shared_info);
71 } 76 }
72 return os; 77 return os;
73 } 78 }
74 79
80
81 FrameStateDescriptor::FrameStateDescriptor(
82 Zone* zone, FrameStateType type, BailoutId bailout_id,
83 OutputFrameStateCombine state_combine, size_t parameters_count,
84 size_t locals_count, size_t stack_count,
85 MaybeHandle<SharedFunctionInfo> shared_info,
86 FrameStateDescriptor* outer_state)
87 : type_(type),
88 bailout_id_(bailout_id),
89 frame_state_combine_(state_combine),
90 parameters_count_(parameters_count),
91 locals_count_(locals_count),
92 stack_count_(stack_count),
93 values_(zone, kMachAnyTagged),
94 shared_info_(shared_info),
95 outer_state_(outer_state) {}
96
97
98 size_t FrameStateDescriptor::GetSize(OutputFrameStateCombine combine) const {
99 size_t size = 1 + parameters_count() + locals_count() + stack_count() +
100 (HasContext() ? 1 : 0);
101 switch (combine.kind()) {
102 case OutputFrameStateCombine::kPushOutput:
103 size += combine.GetPushCount();
104 break;
105 case OutputFrameStateCombine::kPokeAt:
106 break;
107 }
108 return size;
109 }
110
111
112 size_t FrameStateDescriptor::GetTotalSize() const {
113 size_t total_size = 0;
114 for (const FrameStateDescriptor* iter = this; iter != NULL;
115 iter = iter->outer_state_) {
116 total_size += iter->GetSize();
117 }
118 return total_size;
119 }
120
121
122 size_t FrameStateDescriptor::GetFrameCount() const {
123 size_t count = 0;
124 for (const FrameStateDescriptor* iter = this; iter != NULL;
125 iter = iter->outer_state_) {
126 ++count;
127 }
128 return count;
129 }
130
131
132 size_t FrameStateDescriptor::GetJSFrameCount() const {
133 size_t count = 0;
134 for (const FrameStateDescriptor* iter = this; iter != NULL;
135 iter = iter->outer_state_) {
136 if (iter->type_ == FrameStateType::kJavaScriptFunction) {
137 ++count;
138 }
139 }
140 return count;
141 }
142
143
144 size_t StateValueDescriptor::AddOperand(InstructionOperandVector* inputs,
Jarin 2015/12/02 12:24:34 Could we have a comment explaining what the return
sigurds 2015/12/02 16:35:13 Done.
145 OperandGenerator* g,
146 StateObjectCache* cache, Node* input,
147 MachineType type,
148 FrameStateInputKind kind, Zone* zone) {
149 switch (input->opcode()) {
150 case IrOpcode::kObjectState: {
151 size_t id = cache->GetObjectId(input);
152 if (id == StateObjectCache::kNotCached) {
153 size_t entries = 0;
154 id = cache->InsertObject(input);
155 fields_.push_back(StateValueDescriptor(zone, kMachAnyTagged, id));
156 StateValueDescriptor& desc = fields_.back();
157 for (Edge edge : input->input_edges()) {
158 entries += desc.AddOperand(inputs, g, cache, edge.to(),
159 kMachAnyTagged, kind, zone);
160 }
161 return entries;
162 } else {
163 fields_.push_back(StateValueDescriptor(zone, kMachAnyTagged, id));
Jarin 2015/12/02 12:24:34 I think it would be nice to somehow signal in the
sigurds 2015/12/02 16:35:13 Great idea, thanks.
164 return 0;
165 }
166 } break;
Jarin 2015/12/02 12:24:34 The "break;" should go before the brace.
sigurds 2015/12/02 16:35:12 Done.
167 default:
168 inputs->push_back(g->UseForDeopt(input, kind));
169 fields_.push_back(StateValueDescriptor(zone, type));
170 return 1;
171 }
172 }
173
174
175 size_t FrameStateDescriptor::AddInputs(Node* state, OperandGenerator* g,
176 StateObjectCache* cache,
177 InstructionOperandVector* inputs,
178 FrameStateInputKind kind, Zone* zone) {
179 DCHECK_EQ(IrOpcode::kFrameState, state->op()->opcode());
180
181 size_t entries = 0;
182 size_t initial_size = inputs->size();
183
184 if (outer_state()) {
185 entries +=
186 outer_state()->AddInputs(state->InputAt(kFrameStateOuterStateInput), g,
187 cache, inputs, kind, zone);
188 }
189
190 Node* parameters = state->InputAt(kFrameStateParametersInput);
191 Node* locals = state->InputAt(kFrameStateLocalsInput);
192 Node* stack = state->InputAt(kFrameStateStackInput);
193 Node* context = state->InputAt(kFrameStateContextInput);
194 Node* function = state->InputAt(kFrameStateFunctionInput);
195
196 DCHECK_EQ(parameters_count(), StateValuesAccess(parameters).size());
197 DCHECK_EQ(locals_count(), StateValuesAccess(locals).size());
198 DCHECK_EQ(stack_count(), StateValuesAccess(stack).size());
199
200 StateValueDescriptor* desc = GetStateValueDescriptor();
201 entries +=
202 desc->AddOperand(inputs, g, cache, function, kMachAnyTagged, kind, zone);
203 for (StateValuesAccess::TypedNode input_node :
204 StateValuesAccess(parameters)) {
205 entries += desc->AddOperand(inputs, g, cache, input_node.node,
206 input_node.type, kind, zone);
207 }
208 if (HasContext()) {
209 entries +=
210 desc->AddOperand(inputs, g, cache, context, kMachAnyTagged, kind, zone);
211 }
212 for (StateValuesAccess::TypedNode input_node : StateValuesAccess(locals)) {
213 entries += desc->AddOperand(inputs, g, cache, input_node.node,
214 input_node.type, kind, zone);
215 }
216 for (StateValuesAccess::TypedNode input_node : StateValuesAccess(stack)) {
217 entries += desc->AddOperand(inputs, g, cache, input_node.node,
218 input_node.type, kind, zone);
219 }
220 DCHECK_EQ(initial_size + entries, inputs->size());
221 return entries;
222 }
223
224
225 size_t StateValueDescriptor::Translate(CodeGenerator* gen,
Jarin 2015/12/02 12:24:34 Description of return value, please. (Number of co
sigurds 2015/12/02 16:35:13 Done.
226 Translation* translation,
227 Instruction* instr,
228 size_t frame_state_offset) {
229 if (IsRecursive()) {
230 size_t entries = 0;
231 translation->BeginCapturedObject(static_cast<int>(size()));
232 for (size_t index = 0; index < fields_.size(); index++) {
233 entries += fields_[index].Translate(gen, translation, instr,
234 frame_state_offset + index);
235 }
236 return entries;
237 } else if (IsDuplicate()) {
238 translation->DuplicateObject(static_cast<int>(id_));
239 return 0;
240 } else {
241 gen->AddTranslationForOperand(translation, instr,
242 instr->InputAt(frame_state_offset), type_);
243 return 1;
244 }
245 }
246
247
248 size_t StateValueDescriptor::TranslateOperand(size_t index, CodeGenerator* gen,
249 Translation* translation,
250 Instruction* instr,
251 size_t frame_state_offset) {
252 return fields_[index].Translate(gen, translation, instr,
253 frame_state_offset + index);
254 }
255
256
257 void FrameStateDescriptor::TranslateOperands(CodeGenerator* gen,
258 Instruction* instr,
259 size_t frame_state_offset,
260 OutputFrameStateCombine combine,
261 Translation* translation) {
262 for (size_t index = 0; index < GetSize(combine); index++) {
263 switch (combine.kind()) {
264 case OutputFrameStateCombine::kPushOutput: {
265 DCHECK(combine.GetPushCount() <= instr->OutputCount());
266 size_t size_without_output = GetSize(OutputFrameStateCombine::Ignore());
267 // If the index is past the existing stack items in values_.
268 if (index >= size_without_output) {
269 // Materialize the result of the call instruction in this slot.
270 gen->AddTranslationForOperand(
271 translation, instr, instr->OutputAt(index - size_without_output),
272 kMachAnyTagged);
273 continue;
274 }
275 break;
276 }
277 case OutputFrameStateCombine::kPokeAt:
278 // The result of the call should be placed at position
279 // [index_from_top] in the stack (overwriting whatever was
280 // previously there).
281 size_t index_from_top =
282 GetSize(combine) - 1 - combine.GetOffsetToPokeAt();
283 if (index >= index_from_top &&
284 index < index_from_top + instr->OutputCount()) {
285 gen->AddTranslationForOperand(translation, instr,
286 instr->OutputAt(index - index_from_top),
287 kMachAnyTagged);
288 continue;
289 }
290 break;
291 }
292 // Add the additional fields we read during materialization.
293 frame_state_offset += values_.TranslateOperand(index, gen, translation,
294 instr, frame_state_offset) -
295 1;
296 }
297 }
298
75 } // namespace compiler 299 } // namespace compiler
76 } // namespace internal 300 } // namespace internal
77 } // namespace v8 301 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698