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