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 |