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 |