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

Side by Side Diff: src/hydrogen.h

Issue 5992011: Fix a bug in deoptimization environments. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 9 years, 11 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
« no previous file with comments | « src/flag-definitions.h ('k') | src/hydrogen.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after
394 DISALLOW_COPY_AND_ASSIGN(HGraph); 394 DISALLOW_COPY_AND_ASSIGN(HGraph);
395 }; 395 };
396 396
397 397
398 class HEnvironment: public ZoneObject { 398 class HEnvironment: public ZoneObject {
399 public: 399 public:
400 HEnvironment(HEnvironment* outer, 400 HEnvironment(HEnvironment* outer,
401 Scope* scope, 401 Scope* scope,
402 Handle<JSFunction> closure); 402 Handle<JSFunction> closure);
403 403
404 // Simple accessors.
405 Handle<JSFunction> closure() const { return closure_; }
406 const ZoneList<HValue*>* values() const { return &values_; }
407 const ZoneList<int>* assigned_variables() const {
408 return &assigned_variables_;
409 }
410 int parameter_count() const { return parameter_count_; }
411 int local_count() const { return local_count_; }
412 HEnvironment* outer() const { return outer_; }
413 int pop_count() const { return pop_count_; }
414 int push_count() const { return push_count_; }
415
416 int ast_id() const { return ast_id_; }
417 void set_ast_id(int id) { ast_id_ = id; }
418
419 int length() const { return values_.length(); }
420
404 void Bind(Variable* variable, HValue* value) { 421 void Bind(Variable* variable, HValue* value) {
405 Bind(IndexFor(variable), value); 422 Bind(IndexFor(variable), value);
406
407 if (FLAG_trace_environment) {
408 PrintF("Slot index=%d name=%s\n",
409 variable->AsSlot()->index(),
410 *variable->name()->ToCString());
411 }
412 } 423 }
413 424
414 void Bind(int index, HValue* value) { 425 void Bind(int index, HValue* value);
415 ASSERT(value != NULL);
416 if (!assigned_variables_.Contains(index)) {
417 assigned_variables_.Add(index);
418 }
419 values_[index] = value;
420 }
421 426
422 HValue* Lookup(Variable* variable) const { 427 HValue* Lookup(Variable* variable) const {
423 return Lookup(IndexFor(variable)); 428 return Lookup(IndexFor(variable));
424 } 429 }
430
425 HValue* Lookup(int index) const { 431 HValue* Lookup(int index) const {
426 HValue* result = values_[index]; 432 HValue* result = values_[index];
427 ASSERT(result != NULL); 433 ASSERT(result != NULL);
428 return result; 434 return result;
429 } 435 }
430 436
431 void Push(HValue* value) { 437 void Push(HValue* value) {
432 ASSERT(value != NULL); 438 ASSERT(value != NULL);
433 ++push_count_; 439 ++push_count_;
434 values_.Add(value); 440 values_.Add(value);
435 } 441 }
436 442
437 HValue* Top() const { return ExpressionStackAt(0); }
438
439 HValue* ExpressionStackAt(int index_from_top) const {
440 int index = values_.length() - index_from_top - 1;
441 ASSERT(IsExpressionStackIndex(index));
442 return values_[index];
443 }
444
445 void SetExpressionStackAt(int index_from_top, HValue* value) {
446 int index = values_.length() - index_from_top - 1;
447 ASSERT(IsExpressionStackIndex(index));
448 values_[index] = value;
449 }
450
451 HValue* Pop() { 443 HValue* Pop() {
452 ASSERT(!IsExpressionStackEmpty()); 444 ASSERT(!ExpressionStackIsEmpty());
453 if (push_count_ > 0) { 445 if (push_count_ > 0) {
454 --push_count_; 446 --push_count_;
455 ASSERT(push_count_ >= 0);
456 } else { 447 } else {
457 ++pop_count_; 448 ++pop_count_;
458 } 449 }
459 return values_.RemoveLast(); 450 return values_.RemoveLast();
460 } 451 }
461 452
462 void Drop(int count) { 453 void Drop(int count);
463 for (int i = 0; i < count; ++i) { 454
464 Pop(); 455 HValue* Top() const { return ExpressionStackAt(0); }
465 } 456
457 HValue* ExpressionStackAt(int index_from_top) const {
458 int index = length() - index_from_top - 1;
459 ASSERT(HasExpressionAt(index));
460 return values_[index];
466 } 461 }
467 462
468 Handle<JSFunction> closure() const { return closure_; } 463 void SetExpressionStackAt(int index_from_top, HValue* value);
469 464
470 // ID of the original AST node to identify deoptimization points.
471 int ast_id() const { return ast_id_; }
472 void set_ast_id(int id) { ast_id_ = id; }
473
474 const ZoneList<HValue*>* values() const { return &values_; }
475 const ZoneList<int>* assigned_variables() const {
476 return &assigned_variables_;
477 }
478 int parameter_count() const { return parameter_count_; }
479 int local_count() const { return local_count_; }
480 int push_count() const { return push_count_; }
481 int pop_count() const { return pop_count_; }
482 int total_count() const { return values_.length(); }
483 HEnvironment* outer() const { return outer_; }
484 HEnvironment* Copy() const; 465 HEnvironment* Copy() const;
485 HEnvironment* CopyWithoutHistory() const; 466 HEnvironment* CopyWithoutHistory() const;
486 HEnvironment* CopyAsLoopHeader(HBasicBlock* block) const; 467 HEnvironment* CopyAsLoopHeader(HBasicBlock* block) const;
487 468
488 // Create an "inlined version" of this environment, where the original 469 // Create an "inlined version" of this environment, where the original
489 // environment is the outer environment but the top expression stack 470 // environment is the outer environment but the top expression stack
490 // elements are moved to an inner environment as parameters. If 471 // elements are moved to an inner environment as parameters. If
491 // is_speculative, the argument values are expected to be PushArgument 472 // is_speculative, the argument values are expected to be PushArgument
492 // instructions, otherwise they are the actual values. 473 // instructions, otherwise they are the actual values.
493 HEnvironment* CopyForInlining(Handle<JSFunction> target, 474 HEnvironment* CopyForInlining(Handle<JSFunction> target,
494 FunctionLiteral* function, 475 FunctionLiteral* function,
495 bool is_speculative, 476 bool is_speculative,
496 HConstant* undefined) const; 477 HConstant* undefined) const;
497 478
498 void AddIncomingEdge(HBasicBlock* block, HEnvironment* other); 479 void AddIncomingEdge(HBasicBlock* block, HEnvironment* other);
480
499 void ClearHistory() { 481 void ClearHistory() {
500 pop_count_ = 0; 482 pop_count_ = 0;
501 push_count_ = 0; 483 push_count_ = 0;
502 assigned_variables_.Clear(); 484 assigned_variables_.Clear();
503 } 485 }
486
504 void SetValueAt(int index, HValue* value) { 487 void SetValueAt(int index, HValue* value) {
505 ASSERT(index < total_count()); 488 ASSERT(index < length());
506 values_[index] = value; 489 values_[index] = value;
507 } 490 }
508 491
509 void PrintTo(StringStream* stream); 492 void PrintTo(StringStream* stream);
510 void PrintToStd(); 493 void PrintToStd();
511 494
512 private: 495 private:
513 explicit HEnvironment(const HEnvironment* other); 496 explicit HEnvironment(const HEnvironment* other);
514 497
515 bool IsExpressionStackIndex(int index) const { 498 // True if index is included in the expression stack part of the environment.
516 return index >= parameter_count_ + local_count_; 499 bool HasExpressionAt(int index) const;
517 } 500
518 bool IsExpressionStackEmpty() const { 501 bool ExpressionStackIsEmpty() const;
519 int length = values_.length(); 502
520 int first_expression = parameter_count() + local_count();
521 ASSERT(length >= first_expression);
522 return length == first_expression;
523 }
524 void Initialize(int parameter_count, int local_count, int stack_height); 503 void Initialize(int parameter_count, int local_count, int stack_height);
525 void Initialize(const HEnvironment* other); 504 void Initialize(const HEnvironment* other);
526 int VariableToIndex(Variable* var); 505
527 int IndexFor(Variable* variable) const; 506 // Map a variable to an environment index. Parameter indices are shifted
507 // by 1 (receiver is parameter index -1 but environment index 0).
508 // Stack-allocated local indices are shifted by the number of parameters.
509 int IndexFor(Variable* variable) const {
510 Slot* slot = variable->AsSlot();
511 ASSERT(slot != NULL && slot->IsStackAllocated());
512 int shift = (slot->type() == Slot::PARAMETER) ? 1 : parameter_count_;
513 return slot->index() + shift;
514 }
528 515
529 Handle<JSFunction> closure_; 516 Handle<JSFunction> closure_;
530 // Value array [parameters] [locals] [temporaries]. 517 // Value array [parameters] [locals] [temporaries].
531 ZoneList<HValue*> values_; 518 ZoneList<HValue*> values_;
532 ZoneList<int> assigned_variables_; 519 ZoneList<int> assigned_variables_;
533 int parameter_count_; 520 int parameter_count_;
534 int local_count_; 521 int local_count_;
535 HEnvironment* outer_; 522 HEnvironment* outer_;
536 int pop_count_; 523 int pop_count_;
537 int push_count_; 524 int push_count_;
(...skipping 22 matching lines...) Expand all
560 547
561 protected: 548 protected:
562 AstContext(HGraphBuilder* owner, Expression::Context kind); 549 AstContext(HGraphBuilder* owner, Expression::Context kind);
563 virtual ~AstContext(); 550 virtual ~AstContext();
564 551
565 HGraphBuilder* owner() const { return owner_; } 552 HGraphBuilder* owner() const { return owner_; }
566 553
567 // We want to be able to assert, in a context-specific way, that the stack 554 // We want to be able to assert, in a context-specific way, that the stack
568 // height makes sense when the context is filled. 555 // height makes sense when the context is filled.
569 #ifdef DEBUG 556 #ifdef DEBUG
570 int original_count_; 557 int original_length_;
571 #endif 558 #endif
572 559
573 private: 560 private:
574 HGraphBuilder* owner_; 561 HGraphBuilder* owner_;
575 Expression::Context kind_; 562 Expression::Context kind_;
576 AstContext* outer_; 563 AstContext* outer_;
577 }; 564 };
578 565
579 566
580 class EffectContext: public AstContext { 567 class EffectContext: public AstContext {
(...skipping 480 matching lines...) Expand 10 before | Expand all | Expand 10 after
1061 const char* filename_; 1048 const char* filename_;
1062 HeapStringAllocator string_allocator_; 1049 HeapStringAllocator string_allocator_;
1063 StringStream trace_; 1050 StringStream trace_;
1064 int indent_; 1051 int indent_;
1065 }; 1052 };
1066 1053
1067 1054
1068 } } // namespace v8::internal 1055 } } // namespace v8::internal
1069 1056
1070 #endif // V8_HYDROGEN_H_ 1057 #endif // V8_HYDROGEN_H_
OLDNEW
« no previous file with comments | « src/flag-definitions.h ('k') | src/hydrogen.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698