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

Side by Side Diff: src/compiler/ast-graph-builder.h

Issue 492203002: Initial support for debugger frame state in Turbofan. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Another attempt to fix Win64 Created 6 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 | Annotate | Revision Log
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 #ifndef V8_COMPILER_AST_GRAPH_BUILDER_H_ 5 #ifndef V8_COMPILER_AST_GRAPH_BUILDER_H_
6 #define V8_COMPILER_AST_GRAPH_BUILDER_H_ 6 #define V8_COMPILER_AST_GRAPH_BUILDER_H_
7 7
8 #include "src/v8.h" 8 #include "src/v8.h"
9 9
10 #include "src/ast.h" 10 #include "src/ast.h"
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
164 void VisitNot(UnaryOperation* expr); 164 void VisitNot(UnaryOperation* expr);
165 165
166 // Dispatched from VisitBinaryOperation. 166 // Dispatched from VisitBinaryOperation.
167 void VisitComma(BinaryOperation* expr); 167 void VisitComma(BinaryOperation* expr);
168 void VisitLogicalExpression(BinaryOperation* expr); 168 void VisitLogicalExpression(BinaryOperation* expr);
169 void VisitArithmeticExpression(BinaryOperation* expr); 169 void VisitArithmeticExpression(BinaryOperation* expr);
170 170
171 // Dispatched from VisitForInStatement. 171 // Dispatched from VisitForInStatement.
172 void VisitForInAssignment(Expression* expr, Node* value); 172 void VisitForInAssignment(Expression* expr, Node* value);
173 173
174 void BuildLazyBailout(Node* node, BailoutId ast_id); 174 // Flag that describes how to combine the current environment with
175 void BuildLazyBailoutWithPushedNode(Node* node, BailoutId ast_id); 175 // the output of a node to obtain a framestate for lazy bailout.
176 enum OutputFrameStateCombine {
177 PUSH_OUTPUT, // Push the output on the expression stack.
178 IGNORE_OUTPUT // Use the frame state as-is.
179 };
180
181 // Builds deoptimization for a given node.
182 void PrepareFrameState(Node* node, BailoutId ast_id,
183 OutputFrameStateCombine combine = IGNORE_OUTPUT);
184
185 OutputFrameStateCombine StateCombineFromAstContext();
176 186
177 DEFINE_AST_VISITOR_SUBCLASS_MEMBERS(); 187 DEFINE_AST_VISITOR_SUBCLASS_MEMBERS();
178 DISALLOW_COPY_AND_ASSIGN(AstGraphBuilder); 188 DISALLOW_COPY_AND_ASSIGN(AstGraphBuilder);
179 }; 189 };
180 190
181 191
182 // The abstract execution environment for generated code consists of 192 // The abstract execution environment for generated code consists of
183 // parameter variables, local variables and the operand stack. The 193 // parameter variables, local variables and the operand stack. The
184 // environment will perform proper SSA-renaming of all tracked nodes 194 // environment will perform proper SSA-renaming of all tracked nodes
185 // at split and merge points in the control flow. Internally all the 195 // at split and merge points in the control flow. Internally all the
(...skipping 13 matching lines...) Expand all
199 return static_cast<int>(values()->size()) - parameters_count_ - 209 return static_cast<int>(values()->size()) - parameters_count_ -
200 locals_count_; 210 locals_count_;
201 } 211 }
202 212
203 // Operations on parameter or local variables. The parameter indices are 213 // Operations on parameter or local variables. The parameter indices are
204 // shifted by 1 (receiver is parameter index -1 but environment index 0). 214 // shifted by 1 (receiver is parameter index -1 but environment index 0).
205 void Bind(Variable* variable, Node* node) { 215 void Bind(Variable* variable, Node* node) {
206 DCHECK(variable->IsStackAllocated()); 216 DCHECK(variable->IsStackAllocated());
207 if (variable->IsParameter()) { 217 if (variable->IsParameter()) {
208 values()->at(variable->index() + 1) = node; 218 values()->at(variable->index() + 1) = node;
209 parameters_dirty_ = true;
210 } else { 219 } else {
211 DCHECK(variable->IsStackLocal()); 220 DCHECK(variable->IsStackLocal());
212 values()->at(variable->index() + parameters_count_) = node; 221 values()->at(variable->index() + parameters_count_) = node;
213 locals_dirty_ = true;
214 } 222 }
215 } 223 }
216 Node* Lookup(Variable* variable) { 224 Node* Lookup(Variable* variable) {
217 DCHECK(variable->IsStackAllocated()); 225 DCHECK(variable->IsStackAllocated());
218 if (variable->IsParameter()) { 226 if (variable->IsParameter()) {
219 return values()->at(variable->index() + 1); 227 return values()->at(variable->index() + 1);
220 } else { 228 } else {
221 DCHECK(variable->IsStackLocal()); 229 DCHECK(variable->IsStackLocal());
222 return values()->at(variable->index() + parameters_count_); 230 return values()->at(variable->index() + parameters_count_);
223 } 231 }
224 } 232 }
225 233
226 // Operations on the operand stack. 234 // Operations on the operand stack.
227 void Push(Node* node) { 235 void Push(Node* node) {
228 values()->push_back(node); 236 values()->push_back(node);
229 stack_dirty_ = true;
230 } 237 }
231 Node* Top() { 238 Node* Top() {
232 DCHECK(stack_height() > 0); 239 DCHECK(stack_height() > 0);
233 return values()->back(); 240 return values()->back();
234 } 241 }
235 Node* Pop() { 242 Node* Pop() {
236 DCHECK(stack_height() > 0); 243 DCHECK(stack_height() > 0);
237 Node* back = values()->back(); 244 Node* back = values()->back();
238 values()->pop_back(); 245 values()->pop_back();
239 stack_dirty_ = true;
240 return back; 246 return back;
241 } 247 }
242 248
243 // Direct mutations of the operand stack. 249 // Direct mutations of the operand stack.
244 void Poke(int depth, Node* node) { 250 void Poke(int depth, Node* node) {
245 DCHECK(depth >= 0 && depth < stack_height()); 251 DCHECK(depth >= 0 && depth < stack_height());
246 int index = static_cast<int>(values()->size()) - depth - 1; 252 int index = static_cast<int>(values()->size()) - depth - 1;
247 values()->at(index) = node; 253 values()->at(index) = node;
248 stack_dirty_ = true;
249 } 254 }
250 Node* Peek(int depth) { 255 Node* Peek(int depth) {
251 DCHECK(depth >= 0 && depth < stack_height()); 256 DCHECK(depth >= 0 && depth < stack_height());
252 int index = static_cast<int>(values()->size()) - depth - 1; 257 int index = static_cast<int>(values()->size()) - depth - 1;
253 return values()->at(index); 258 return values()->at(index);
254 } 259 }
255 void Drop(int depth) { 260 void Drop(int depth) {
256 DCHECK(depth >= 0 && depth <= stack_height()); 261 DCHECK(depth >= 0 && depth <= stack_height());
257 values()->erase(values()->end() - depth, values()->end()); 262 values()->erase(values()->end() - depth, values()->end());
258 stack_dirty_ = true;
259 } 263 }
260 264
261 // Preserve a checkpoint of the environment for the IR graph. Any 265 // Preserve a checkpoint of the environment for the IR graph. Any
262 // further mutation of the environment will not affect checkpoints. 266 // further mutation of the environment will not affect checkpoints.
263 Node* Checkpoint(BailoutId ast_id); 267 Node* Checkpoint(BailoutId ast_id);
264 268
265 private: 269 private:
270 void UpdateStateValues(Node** state_values, int offset, int count);
271
266 int parameters_count_; 272 int parameters_count_;
267 int locals_count_; 273 int locals_count_;
268 Node* parameters_node_; 274 Node* parameters_node_;
269 Node* locals_node_; 275 Node* locals_node_;
270 Node* stack_node_; 276 Node* stack_node_;
271 bool parameters_dirty_;
272 bool locals_dirty_;
273 bool stack_dirty_;
274 }; 277 };
275 278
276 279
277 // Each expression in the AST is evaluated in a specific context. This context 280 // Each expression in the AST is evaluated in a specific context. This context
278 // decides how the evaluation result is passed up the visitor. 281 // decides how the evaluation result is passed up the visitor.
279 class AstGraphBuilder::AstContext BASE_EMBEDDED { 282 class AstGraphBuilder::AstContext BASE_EMBEDDED {
280 public: 283 public:
281 bool IsEffect() const { return kind_ == Expression::kEffect; } 284 bool IsEffect() const { return kind_ == Expression::kEffect; }
282 bool IsValue() const { return kind_ == Expression::kValue; } 285 bool IsValue() const { return kind_ == Expression::kValue; }
283 bool IsTest() const { return kind_ == Expression::kTest; } 286 bool IsTest() const { return kind_ == Expression::kTest; }
284 287
288 // Determines how to combine the frame state with the value
289 // that is about to be plugged into this AstContext.
290 AstGraphBuilder::OutputFrameStateCombine GetStateCombine() {
291 return IsEffect() ? IGNORE_OUTPUT : PUSH_OUTPUT;
292 }
293
285 // Plug a node into this expression context. Call this function in tail 294 // Plug a node into this expression context. Call this function in tail
286 // position in the Visit functions for expressions. 295 // position in the Visit functions for expressions.
287 virtual void ProduceValue(Node* value) = 0; 296 virtual void ProduceValue(Node* value) = 0;
288 virtual void ProduceValueWithLazyBailout(Node* value) = 0;
289 297
290 // Unplugs a node from this expression context. Call this to retrieve the 298 // Unplugs a node from this expression context. Call this to retrieve the
291 // result of another Visit function that already plugged the context. 299 // result of another Visit function that already plugged the context.
292 virtual Node* ConsumeValue() = 0; 300 virtual Node* ConsumeValue() = 0;
293 301
294 // Shortcut for "context->ProduceValue(context->ConsumeValue())". 302 // Shortcut for "context->ProduceValue(context->ConsumeValue())".
295 void ReplaceValue() { ProduceValue(ConsumeValue()); } 303 void ReplaceValue() { ProduceValue(ConsumeValue()); }
296 304
297 protected: 305 protected:
298 AstContext(AstGraphBuilder* owner, Expression::Context kind, 306 AstContext(AstGraphBuilder* owner, Expression::Context kind);
299 BailoutId bailout_id);
300 virtual ~AstContext(); 307 virtual ~AstContext();
301 308
302 AstGraphBuilder* owner() const { return owner_; } 309 AstGraphBuilder* owner() const { return owner_; }
303 Environment* environment() const { return owner_->environment(); } 310 Environment* environment() const { return owner_->environment(); }
304 311
305 // We want to be able to assert, in a context-specific way, that the stack 312 // We want to be able to assert, in a context-specific way, that the stack
306 // height makes sense when the context is filled. 313 // height makes sense when the context is filled.
307 #ifdef DEBUG 314 #ifdef DEBUG
308 int original_height_; 315 int original_height_;
309 #endif 316 #endif
310 317
311 BailoutId bailout_id_;
312
313 private: 318 private:
314 Expression::Context kind_; 319 Expression::Context kind_;
315 AstGraphBuilder* owner_; 320 AstGraphBuilder* owner_;
316 AstContext* outer_; 321 AstContext* outer_;
317 }; 322 };
318 323
319 324
320 // Context to evaluate expression for its side effects only. 325 // Context to evaluate expression for its side effects only.
321 class AstGraphBuilder::AstEffectContext V8_FINAL : public AstContext { 326 class AstGraphBuilder::AstEffectContext V8_FINAL : public AstContext {
322 public: 327 public:
323 explicit AstEffectContext(AstGraphBuilder* owner, BailoutId bailout_id) 328 explicit AstEffectContext(AstGraphBuilder* owner)
324 : AstContext(owner, Expression::kEffect, bailout_id) {} 329 : AstContext(owner, Expression::kEffect) {}
325 virtual ~AstEffectContext(); 330 virtual ~AstEffectContext();
326 virtual void ProduceValue(Node* value) V8_OVERRIDE; 331 virtual void ProduceValue(Node* value) V8_OVERRIDE;
327 virtual void ProduceValueWithLazyBailout(Node* value) V8_OVERRIDE;
328 virtual Node* ConsumeValue() V8_OVERRIDE; 332 virtual Node* ConsumeValue() V8_OVERRIDE;
329 }; 333 };
330 334
331 335
332 // Context to evaluate expression for its value (and side effects). 336 // Context to evaluate expression for its value (and side effects).
333 class AstGraphBuilder::AstValueContext V8_FINAL : public AstContext { 337 class AstGraphBuilder::AstValueContext V8_FINAL : public AstContext {
334 public: 338 public:
335 explicit AstValueContext(AstGraphBuilder* owner, BailoutId bailout_id) 339 explicit AstValueContext(AstGraphBuilder* owner)
336 : AstContext(owner, Expression::kValue, bailout_id) {} 340 : AstContext(owner, Expression::kValue) {}
337 virtual ~AstValueContext(); 341 virtual ~AstValueContext();
338 virtual void ProduceValue(Node* value) V8_OVERRIDE; 342 virtual void ProduceValue(Node* value) V8_OVERRIDE;
339 virtual void ProduceValueWithLazyBailout(Node* value) V8_OVERRIDE;
340 virtual Node* ConsumeValue() V8_OVERRIDE; 343 virtual Node* ConsumeValue() V8_OVERRIDE;
341 }; 344 };
342 345
343 346
344 // Context to evaluate expression for a condition value (and side effects). 347 // Context to evaluate expression for a condition value (and side effects).
345 class AstGraphBuilder::AstTestContext V8_FINAL : public AstContext { 348 class AstGraphBuilder::AstTestContext V8_FINAL : public AstContext {
346 public: 349 public:
347 explicit AstTestContext(AstGraphBuilder* owner, BailoutId bailout_id) 350 explicit AstTestContext(AstGraphBuilder* owner)
348 : AstContext(owner, Expression::kTest, bailout_id) {} 351 : AstContext(owner, Expression::kTest) {}
349 virtual ~AstTestContext(); 352 virtual ~AstTestContext();
350 virtual void ProduceValue(Node* value) V8_OVERRIDE; 353 virtual void ProduceValue(Node* value) V8_OVERRIDE;
351 virtual void ProduceValueWithLazyBailout(Node* value) V8_OVERRIDE;
352 virtual Node* ConsumeValue() V8_OVERRIDE; 354 virtual Node* ConsumeValue() V8_OVERRIDE;
353 }; 355 };
354 356
355 357
356 // Scoped class tracking breakable statements entered by the visitor. Allows to 358 // Scoped class tracking breakable statements entered by the visitor. Allows to
357 // properly 'break' and 'continue' iteration statements as well as to 'break' 359 // properly 'break' and 'continue' iteration statements as well as to 'break'
358 // from blocks within switch statements. 360 // from blocks within switch statements.
359 class AstGraphBuilder::BreakableScope BASE_EMBEDDED { 361 class AstGraphBuilder::BreakableScope BASE_EMBEDDED {
360 public: 362 public:
361 BreakableScope(AstGraphBuilder* owner, BreakableStatement* target, 363 BreakableScope(AstGraphBuilder* owner, BreakableStatement* target,
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
419 }; 421 };
420 422
421 Scope* AstGraphBuilder::current_scope() const { 423 Scope* AstGraphBuilder::current_scope() const {
422 return execution_context_->scope(); 424 return execution_context_->scope();
423 } 425 }
424 } 426 }
425 } 427 }
426 } // namespace v8::internal::compiler 428 } // namespace v8::internal::compiler
427 429
428 #endif // V8_COMPILER_AST_GRAPH_BUILDER_H_ 430 #endif // V8_COMPILER_AST_GRAPH_BUILDER_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698