Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 539 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 550 | 550 |
| 551 | 551 |
| 552 class HGraphBuilder; | 552 class HGraphBuilder; |
| 553 | 553 |
| 554 class AstContext { | 554 class AstContext { |
| 555 public: | 555 public: |
| 556 bool IsEffect() const { return kind_ == Expression::kEffect; } | 556 bool IsEffect() const { return kind_ == Expression::kEffect; } |
| 557 bool IsValue() const { return kind_ == Expression::kValue; } | 557 bool IsValue() const { return kind_ == Expression::kValue; } |
| 558 bool IsTest() const { return kind_ == Expression::kTest; } | 558 bool IsTest() const { return kind_ == Expression::kTest; } |
| 559 | 559 |
| 560 // 'Fill' this context with a hydrogen value. The value is assumed to | |
| 561 // have already been inserted in the instruction stream (or not need to | |
| 562 // be, e.g., HPhi). Call this function in tail position in the Visit | |
| 563 // functions for expressions. | |
|
Kasper Lund
2010/12/09 11:40:08
I guess you can only 'fill' a context once. Would
Kevin Millikin (Chromium)
2010/12/09 12:45:54
I'm not sure about that---it depends on how much s
| |
| 564 virtual void ReturnValue(HValue* value) = 0; | |
| 565 | |
| 566 // Add a hydrogen instruction to the instruction stream (recording an | |
| 567 // environment simulation if necessary) and then fill this context with | |
| 568 // the instruction as value. | |
| 569 virtual void ReturnInstruction(HInstruction* instr, int ast_id) = 0; | |
| 570 | |
| 560 protected: | 571 protected: |
| 561 AstContext(HGraphBuilder* owner, Expression::Context kind); | 572 AstContext(HGraphBuilder* owner, Expression::Context kind); |
| 562 virtual ~AstContext(); | 573 virtual ~AstContext(); |
| 563 | 574 |
| 575 HGraphBuilder* owner() const { return owner_; } | |
| 576 | |
| 577 // We want to be able to assert, in a context-specific way, that the stack | |
| 578 // height makes sense when the context is filled. | |
| 579 #ifdef DEBUG | |
| 580 int original_count_; | |
|
Kasper Lund
2010/12/09 11:40:08
The comment mentions stack height. The name mentio
| |
| 581 #endif | |
| 582 | |
| 564 private: | 583 private: |
| 565 HGraphBuilder* owner_; | 584 HGraphBuilder* owner_; |
| 566 Expression::Context kind_; | 585 Expression::Context kind_; |
| 567 AstContext* outer_; | 586 AstContext* outer_; |
| 568 }; | 587 }; |
| 569 | 588 |
| 570 | 589 |
| 571 class EffectContext: public AstContext { | 590 class EffectContext: public AstContext { |
| 572 public: | 591 public: |
| 573 explicit EffectContext(HGraphBuilder* owner) | 592 explicit EffectContext(HGraphBuilder* owner) |
| 574 : AstContext(owner, Expression::kEffect) { | 593 : AstContext(owner, Expression::kEffect) { |
| 575 } | 594 } |
| 595 virtual ~EffectContext(); | |
| 596 | |
| 597 virtual void ReturnValue(HValue* value); | |
| 598 virtual void ReturnInstruction(HInstruction* instr, int ast_id); | |
| 576 }; | 599 }; |
| 577 | 600 |
| 578 | 601 |
| 579 class ValueContext: public AstContext { | 602 class ValueContext: public AstContext { |
| 580 public: | 603 public: |
| 581 explicit ValueContext(HGraphBuilder* owner) | 604 explicit ValueContext(HGraphBuilder* owner) |
| 582 : AstContext(owner, Expression::kValue) { | 605 : AstContext(owner, Expression::kValue) { |
| 583 } | 606 } |
| 607 virtual ~ValueContext(); | |
| 608 | |
| 609 virtual void ReturnValue(HValue* value); | |
| 610 virtual void ReturnInstruction(HInstruction* instr, int ast_id); | |
| 584 }; | 611 }; |
| 585 | 612 |
| 586 | 613 |
| 587 class TestContext: public AstContext { | 614 class TestContext: public AstContext { |
| 588 public: | 615 public: |
| 589 TestContext(HGraphBuilder* owner, | 616 TestContext(HGraphBuilder* owner, |
| 590 HBasicBlock* if_true, | 617 HBasicBlock* if_true, |
| 591 HBasicBlock* if_false, | 618 HBasicBlock* if_false, |
| 592 bool invert_true, | 619 bool invert_true, |
| 593 bool invert_false) | 620 bool invert_false) |
| 594 : AstContext(owner, Expression::kTest), | 621 : AstContext(owner, Expression::kTest), |
| 595 if_true_(if_true), | 622 if_true_(if_true), |
| 596 if_false_(if_false), | 623 if_false_(if_false), |
| 597 invert_true_(invert_true), | 624 invert_true_(invert_true), |
| 598 invert_false_(invert_false) { | 625 invert_false_(invert_false) { |
| 599 } | 626 } |
| 600 | 627 |
| 628 virtual void ReturnValue(HValue* value); | |
| 629 virtual void ReturnInstruction(HInstruction* instr, int ast_id); | |
| 630 | |
| 601 static TestContext* cast(AstContext* context) { | 631 static TestContext* cast(AstContext* context) { |
| 602 ASSERT(context->IsTest()); | 632 ASSERT(context->IsTest()); |
| 603 return reinterpret_cast<TestContext*>(context); | 633 return reinterpret_cast<TestContext*>(context); |
| 604 } | 634 } |
| 605 | 635 |
| 606 HBasicBlock* if_true() const { return if_true_; } | 636 HBasicBlock* if_true() const { return if_true_; } |
| 607 HBasicBlock* if_false() const { return if_false_; } | 637 HBasicBlock* if_false() const { return if_false_; } |
| 608 | 638 |
| 609 bool invert_true() { return invert_true_; } | 639 bool invert_true() { return invert_true_; } |
| 610 bool invert_false() { return invert_false_; } | 640 bool invert_false() { return invert_false_; } |
| 611 | 641 |
| 612 private: | 642 private: |
| 643 // Build the shared core part of the translation unpacking a value into | |
| 644 // control flow. | |
| 645 void BuildBranch(HValue* value); | |
| 646 | |
| 613 HBasicBlock* if_true_; | 647 HBasicBlock* if_true_; |
| 614 HBasicBlock* if_false_; | 648 HBasicBlock* if_false_; |
| 615 bool invert_true_; | 649 bool invert_true_; |
| 616 bool invert_false_; | 650 bool invert_false_; |
| 617 }; | 651 }; |
| 618 | 652 |
| 619 | 653 |
| 620 class HGraphBuilder: public AstVisitor { | 654 class HGraphBuilder: public AstVisitor { |
| 621 public: | 655 public: |
| 622 explicit HGraphBuilder(TypeFeedbackOracle* oracle) | 656 explicit HGraphBuilder(TypeFeedbackOracle* oracle) |
| 623 : oracle_(oracle), | 657 : oracle_(oracle), |
| 624 graph_(NULL), | 658 graph_(NULL), |
| 625 current_subgraph_(NULL), | 659 current_subgraph_(NULL), |
| 626 peeled_statement_(NULL), | 660 peeled_statement_(NULL), |
| 627 ast_context_(NULL), | 661 ast_context_(NULL), |
| 628 call_context_(NULL), | 662 call_context_(NULL), |
| 629 function_return_(NULL), | 663 function_return_(NULL), |
| 630 inlined_count_(0) { } | 664 inlined_count_(0) { } |
| 631 | 665 |
| 632 HGraph* CreateGraph(CompilationInfo* info); | 666 HGraph* CreateGraph(CompilationInfo* info); |
| 633 | 667 |
| 668 // Simple accessors. | |
| 669 HGraph* graph() const { return graph_; } | |
| 670 HSubgraph* subgraph() const { return current_subgraph_; } | |
| 671 | |
| 672 HEnvironment* environment() const { return subgraph()->environment(); } | |
|
Kasper Lund
2010/12/09 11:40:08
Long term maybe this should be Environment?
Kevin Millikin (Chromium)
2010/12/09 12:45:54
Probably. Or else we should get rid of the two or
| |
| 673 HBasicBlock* CurrentBlock() const { return subgraph()->exit_block(); } | |
| 674 | |
| 675 // Adding instructions. | |
| 676 HInstruction* AddInstruction(HInstruction* instr); | |
| 677 void AddSimulate(int id); | |
| 678 | |
| 679 // Bailout environment manipulation. | |
| 680 void Push(HValue* value) { environment()->Push(value); } | |
| 681 HValue* Pop() { return environment()->Pop(); } | |
| 682 | |
| 634 private: | 683 private: |
| 635 // Type of a member function that generates inline code for a native function. | 684 // Type of a member function that generates inline code for a native function. |
| 636 typedef void (HGraphBuilder::*InlineFunctionGenerator)(int argument_count); | 685 typedef void (HGraphBuilder::*InlineFunctionGenerator)(int argument_count, |
| 686 int ast_id); | |
| 637 | 687 |
| 638 // Forward declarations for inner scope classes. | 688 // Forward declarations for inner scope classes. |
| 639 class SubgraphScope; | 689 class SubgraphScope; |
| 640 | 690 |
| 641 static const InlineFunctionGenerator kInlineFunctionGenerators[]; | 691 static const InlineFunctionGenerator kInlineFunctionGenerators[]; |
| 642 | 692 |
| 643 static const int kMaxCallPolymorphism = 4; | 693 static const int kMaxCallPolymorphism = 4; |
| 644 static const int kMaxLoadPolymorphism = 4; | 694 static const int kMaxLoadPolymorphism = 4; |
| 645 static const int kMaxStorePolymorphism = 4; | 695 static const int kMaxStorePolymorphism = 4; |
| 646 | 696 |
| 647 static const int kMaxInlinedNodes = 196; | 697 static const int kMaxInlinedNodes = 196; |
| 648 static const int kMaxInlinedSize = 196; | 698 static const int kMaxInlinedSize = 196; |
| 649 static const int kMaxSourceSize = 600; | 699 static const int kMaxSourceSize = 600; |
| 650 | 700 |
| 651 // Simple accessors. | 701 // Simple accessors. |
| 652 TypeFeedbackOracle* oracle() const { return oracle_; } | 702 TypeFeedbackOracle* oracle() const { return oracle_; } |
| 653 HGraph* graph() const { return graph_; } | |
| 654 HSubgraph* subgraph() const { return current_subgraph_; } | |
| 655 AstContext* ast_context() const { return ast_context_; } | 703 AstContext* ast_context() const { return ast_context_; } |
| 656 void set_ast_context(AstContext* context) { ast_context_ = context; } | 704 void set_ast_context(AstContext* context) { ast_context_ = context; } |
| 657 AstContext* call_context() const { return call_context_; } | 705 AstContext* call_context() const { return call_context_; } |
| 658 HBasicBlock* function_return() const { return function_return_; } | 706 HBasicBlock* function_return() const { return function_return_; } |
| 659 HEnvironment* environment() const { return subgraph()->environment(); } | |
| 660 | |
| 661 HBasicBlock* CurrentBlock() const { return subgraph()->exit_block(); } | |
| 662 | 707 |
| 663 // Generators for inline runtime functions. | 708 // Generators for inline runtime functions. |
| 664 #define INLINE_FUNCTION_GENERATOR_DECLARATION(Name, argc, ressize) \ | 709 #define INLINE_FUNCTION_GENERATOR_DECLARATION(Name, argc, ressize) \ |
| 665 void Generate##Name(int argument_count); | 710 void Generate##Name(int argument_count, int ast_id); |
| 666 | 711 |
| 667 INLINE_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_DECLARATION) | 712 INLINE_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_DECLARATION) |
| 668 INLINE_RUNTIME_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_DECLARATION) | 713 INLINE_RUNTIME_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_DECLARATION) |
| 669 #undef INLINE_FUNCTION_GENERATOR_DECLARATION | 714 #undef INLINE_FUNCTION_GENERATOR_DECLARATION |
| 670 | 715 |
| 671 void Bailout(const char* reason); | 716 void Bailout(const char* reason); |
| 672 | 717 |
| 673 void AppendPeeledWhile(IterationStatement* stmt, | 718 void AppendPeeledWhile(IterationStatement* stmt, |
| 674 HSubgraph* cond_graph, | 719 HSubgraph* cond_graph, |
| 675 HSubgraph* body_graph, | 720 HSubgraph* body_graph, |
| 676 HSubgraph* exit_graph); | 721 HSubgraph* exit_graph); |
| 677 | 722 |
| 678 void AddToSubgraph(HSubgraph* graph, ZoneList<Statement*>* stmts); | 723 void AddToSubgraph(HSubgraph* graph, ZoneList<Statement*>* stmts); |
| 679 void AddToSubgraph(HSubgraph* graph, Statement* stmt); | 724 void AddToSubgraph(HSubgraph* graph, Statement* stmt); |
| 680 void AddToSubgraph(HSubgraph* graph, Expression* expr); | 725 void AddToSubgraph(HSubgraph* graph, Expression* expr); |
| 681 void AddConditionToSubgraph(HSubgraph* subgraph, | 726 void AddConditionToSubgraph(HSubgraph* subgraph, |
| 682 Expression* expr, | 727 Expression* expr, |
| 683 HSubgraph* true_graph, | 728 HSubgraph* true_graph, |
| 684 HSubgraph* false_graph); | 729 HSubgraph* false_graph); |
| 685 | 730 |
| 686 void Push(HValue* value) { environment()->Push(value); } | |
| 687 HValue* Pop() { return environment()->Pop(); } | |
| 688 HValue* Top() const { return environment()->Top(); } | 731 HValue* Top() const { return environment()->Top(); } |
| 689 void Drop(int n) { environment()->Drop(n); } | 732 void Drop(int n) { environment()->Drop(n); } |
| 690 void Bind(Variable* var, HValue* value) { environment()->Bind(var, value); } | 733 void Bind(Variable* var, HValue* value) { environment()->Bind(var, value); } |
| 691 | 734 |
| 692 void VisitForValue(Expression* expr); | 735 void VisitForValue(Expression* expr); |
| 693 void VisitForEffect(Expression* expr); | 736 void VisitForEffect(Expression* expr); |
| 694 void VisitForControl(Expression* expr, | 737 void VisitForControl(Expression* expr, |
| 695 HBasicBlock* true_block, | 738 HBasicBlock* true_block, |
| 696 HBasicBlock* false_block, | 739 HBasicBlock* false_block, |
| 697 bool invert_true, | 740 bool invert_true, |
| 698 bool invert_false); | 741 bool invert_false); |
| 699 | 742 |
| 700 // Visit an expression in a 'condition' context, i.e., in a control | 743 // Visit an expression in a 'condition' context, i.e., in a control |
| 701 // context but not a subexpression of logical and, or, or not. | 744 // context but not a subexpression of logical and, or, or not. |
| 702 void VisitCondition(Expression* expr, | 745 void VisitCondition(Expression* expr, |
| 703 HBasicBlock* true_graph, | 746 HBasicBlock* true_graph, |
| 704 HBasicBlock* false_graph, | 747 HBasicBlock* false_graph, |
| 705 bool invert_true, | 748 bool invert_true, |
| 706 bool invert_false); | 749 bool invert_false); |
| 707 // Visit an argument and wrap it in a PushArgument instruction. | 750 // Visit an argument and wrap it in a PushArgument instruction. |
| 708 HValue* VisitArgument(Expression* expr); | 751 HValue* VisitArgument(Expression* expr); |
| 709 void VisitArgumentList(ZoneList<Expression*>* arguments); | 752 void VisitArgumentList(ZoneList<Expression*>* arguments); |
| 710 | 753 |
| 711 HInstruction* AddInstruction(HInstruction* instr); | |
| 712 void AddSimulate(int id); | |
| 713 void AddPhi(HPhi* phi); | 754 void AddPhi(HPhi* phi); |
| 714 | 755 |
| 715 void PushAndAdd(HInstruction* instr); | 756 void PushAndAdd(HInstruction* instr); |
| 716 void PushAndAdd(HInstruction* instr, int position); | |
| 717 | 757 |
| 718 void PushArgumentsForStubCall(int argument_count); | 758 void PushArgumentsForStubCall(int argument_count); |
| 719 | 759 |
| 720 // Initialize the arguments to the call based on then environment, add it | 760 // Remove the arguments from the bailout environment and emit instructions |
| 721 // to the graph, and drop the arguments from the environment. | 761 // to push them as outgoing parameters. |
| 722 void ProcessCall(HCall* call, int source_position); | 762 void ProcessCall(HCall* call); |
| 723 | 763 |
| 724 void AssumeRepresentation(HValue* value, Representation r); | 764 void AssumeRepresentation(HValue* value, Representation r); |
| 725 static Representation ToRepresentation(TypeInfo info); | 765 static Representation ToRepresentation(TypeInfo info); |
| 726 | 766 |
| 727 void SetupScope(Scope* scope); | 767 void SetupScope(Scope* scope); |
| 728 virtual void VisitStatements(ZoneList<Statement*>* statements); | 768 virtual void VisitStatements(ZoneList<Statement*>* statements); |
| 729 | 769 |
| 730 #define DECLARE_VISIT(type) virtual void Visit##type(type* node); | 770 #define DECLARE_VISIT(type) virtual void Visit##type(type* node); |
| 731 AST_NODE_LIST(DECLARE_VISIT) | 771 AST_NODE_LIST(DECLARE_VISIT) |
| 732 #undef DECLARE_VISIT | 772 #undef DECLARE_VISIT |
| 733 | 773 |
| 734 bool ShouldPeel(HSubgraph* cond, HSubgraph* body); | 774 bool ShouldPeel(HSubgraph* cond, HSubgraph* body); |
| 735 | 775 |
| 736 HBasicBlock* CreateBasicBlock(HEnvironment* env); | 776 HBasicBlock* CreateBasicBlock(HEnvironment* env); |
| 737 HSubgraph* CreateEmptySubgraph(); | 777 HSubgraph* CreateEmptySubgraph(); |
| 738 HSubgraph* CreateGotoSubgraph(HEnvironment* env); | 778 HSubgraph* CreateGotoSubgraph(HEnvironment* env); |
| 739 HSubgraph* CreateBranchSubgraph(HEnvironment* env); | 779 HSubgraph* CreateBranchSubgraph(HEnvironment* env); |
| 740 HSubgraph* CreateLoopHeaderSubgraph(HEnvironment* env); | 780 HSubgraph* CreateLoopHeaderSubgraph(HEnvironment* env); |
| 741 HSubgraph* CreateInlinedSubgraph(HEnvironment* outer, | 781 HSubgraph* CreateInlinedSubgraph(HEnvironment* outer, |
| 742 Handle<JSFunction> target, | 782 Handle<JSFunction> target, |
| 743 FunctionLiteral* function); | 783 FunctionLiteral* function); |
| 744 | 784 |
| 745 // Helpers for flow graph construction. | 785 // Helpers for flow graph construction. |
| 746 void LookupGlobalPropertyCell(VariableProxy* expr, | 786 void LookupGlobalPropertyCell(Variable* var, |
| 747 LookupResult* lookup, | 787 LookupResult* lookup, |
| 748 bool is_store); | 788 bool is_store); |
| 749 | 789 |
| 750 bool TryArgumentsAccess(Property* expr); | 790 bool TryArgumentsAccess(Property* expr); |
| 751 bool TryCallApply(Call* expr); | 791 bool TryCallApply(Call* expr); |
| 752 bool TryInline(Call* expr); | 792 bool TryInline(Call* expr); |
| 753 bool TryMathFunctionInline(Call* expr); | 793 bool TryMathFunctionInline(Call* expr); |
| 754 void TraceInline(Handle<JSFunction> target, bool result); | 794 void TraceInline(Handle<JSFunction> target, bool result); |
| 755 | 795 |
| 756 void HandleGlobalVariableAssignment(VariableProxy* proxy, | 796 void HandleGlobalVariableAssignment(Variable* var, |
| 757 HValue* value, | 797 HValue* value, |
| 758 int position); | 798 int position, |
| 759 void HandleGlobalVariableLoad(VariableProxy* expr); | 799 int ast_id); |
| 800 | |
| 760 void HandlePropertyAssignment(Assignment* expr); | 801 void HandlePropertyAssignment(Assignment* expr); |
| 761 void HandleCompoundAssignment(Assignment* expr); | 802 void HandleCompoundAssignment(Assignment* expr); |
| 762 void HandlePolymorphicLoadNamedField(Property* expr, | 803 void HandlePolymorphicLoadNamedField(Property* expr, |
| 763 HValue* object, | 804 HValue* object, |
| 764 ZoneMapList* types, | 805 ZoneMapList* types, |
| 765 Handle<String> name); | 806 Handle<String> name); |
| 766 void HandlePolymorphicStoreNamedField(Assignment* expr, | 807 void HandlePolymorphicStoreNamedField(Assignment* expr, |
| 767 HValue* object, | 808 HValue* object, |
| 768 HValue* value, | 809 HValue* value, |
| 769 ZoneMapList* types, | 810 ZoneMapList* types, |
| (...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1052 const char* filename_; | 1093 const char* filename_; |
| 1053 HeapStringAllocator string_allocator_; | 1094 HeapStringAllocator string_allocator_; |
| 1054 StringStream trace_; | 1095 StringStream trace_; |
| 1055 int indent_; | 1096 int indent_; |
| 1056 }; | 1097 }; |
| 1057 | 1098 |
| 1058 | 1099 |
| 1059 } } // namespace v8::internal | 1100 } } // namespace v8::internal |
| 1060 | 1101 |
| 1061 #endif // V8_HYDROGEN_H_ | 1102 #endif // V8_HYDROGEN_H_ |
| OLD | NEW |