OLD | NEW |
---|---|
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #ifndef RUNTIME_VM_INTERMEDIATE_LANGUAGE_H_ | 5 #ifndef RUNTIME_VM_INTERMEDIATE_LANGUAGE_H_ |
6 #define RUNTIME_VM_INTERMEDIATE_LANGUAGE_H_ | 6 #define RUNTIME_VM_INTERMEDIATE_LANGUAGE_H_ |
7 | 7 |
8 #include "vm/allocation.h" | 8 #include "vm/allocation.h" |
9 #include "vm/ast.h" | 9 #include "vm/ast.h" |
10 #include "vm/growable_array.h" | 10 #include "vm/growable_array.h" |
(...skipping 530 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
541 #define PRINT_TO_SUPPORT | 541 #define PRINT_TO_SUPPORT |
542 #endif // !PRODUCT | 542 #endif // !PRODUCT |
543 | 543 |
544 #ifndef PRODUCT | 544 #ifndef PRODUCT |
545 #define PRINT_OPERANDS_TO_SUPPORT \ | 545 #define PRINT_OPERANDS_TO_SUPPORT \ |
546 virtual void PrintOperandsTo(BufferFormatter* f) const; | 546 virtual void PrintOperandsTo(BufferFormatter* f) const; |
547 #else | 547 #else |
548 #define PRINT_OPERANDS_TO_SUPPORT | 548 #define PRINT_OPERANDS_TO_SUPPORT |
549 #endif // !PRODUCT | 549 #endif // !PRODUCT |
550 | 550 |
551 | |
552 // Represents a mapping from a range of class-ids to a method for a given | |
553 // selector (method name). Also can contain an indication of how frequently a | |
554 // given method has been called at a call site. This information can be | |
555 // harvested from the inline caches (ICs). | |
556 struct CidRangeTarget { | |
557 intptr_t cid_start; | |
558 intptr_t cid_end; | |
559 Function* target; | |
560 intptr_t count; | |
561 CidRangeTarget(intptr_t cid_start_arg, | |
562 intptr_t cid_end_arg, | |
563 Function* target_arg, | |
564 intptr_t count_arg) | |
565 : cid_start(cid_start_arg), | |
566 cid_end(cid_end_arg), | |
567 target(target_arg), | |
568 count(count_arg) { | |
569 ASSERT(target->IsZoneHandle()); | |
570 } | |
571 }; | |
572 | |
573 | |
574 class CallTargets : public ZoneAllocated { | |
575 public: | |
576 // Creates the off-heap CallTargets object that reflects the contents | |
577 // of the on-VM-heap IC data. Also expands the class-ids to neighbouring | |
578 // classes that inherit the same method. | |
579 static CallTargets* Create(Zone* zone, const ICData& ic_data); | |
580 | |
581 void Add(const CidRangeTarget& target) { cid_ranges_.Add(target); } | |
582 | |
583 CidRangeTarget& operator[](intptr_t index) const { | |
584 return cid_ranges_[index]; | |
585 } | |
586 | |
587 CidRangeTarget At(int index) { return cid_ranges_.At(index); } | |
588 | |
589 intptr_t length() const { return cid_ranges_.length(); } | |
590 | |
591 void SetLength(intptr_t len) { cid_ranges_.SetLength(len); } | |
592 | |
593 bool is_empty() const { return cid_ranges_.is_empty(); } | |
594 | |
595 void Sort(int compare(const CidRangeTarget* a, const CidRangeTarget* b)) { | |
596 cid_ranges_.Sort(compare); | |
597 } | |
598 | |
599 intptr_t AggregateCallCount() const; | |
600 | |
601 bool HasSingleTarget() const; | |
602 bool HasSingleRecognizedTarget() const; | |
603 Function& FirstTarget() const; | |
604 Function& MostPopularTarget() const { return FirstTarget(); } | |
Vyacheslav Egorov (Google)
2017/04/20 16:45:33
It might be worth adding an assertion here that Ca
erikcorry
2017/04/21 13:04:44
Done.
| |
605 bool IsMonomorphic() const; | |
606 intptr_t MonomorphicReceiverCid() const; | |
607 | |
608 private: | |
609 GrowableArray<CidRangeTarget> cid_ranges_; | |
610 }; | |
611 | |
612 | |
551 class Instruction : public ZoneAllocated { | 613 class Instruction : public ZoneAllocated { |
552 public: | 614 public: |
553 #define DECLARE_TAG(type) k##type, | 615 #define DECLARE_TAG(type) k##type, |
554 enum Tag { FOR_EACH_INSTRUCTION(DECLARE_TAG) }; | 616 enum Tag { FOR_EACH_INSTRUCTION(DECLARE_TAG) }; |
555 #undef DECLARE_TAG | 617 #undef DECLARE_TAG |
556 | 618 |
557 explicit Instruction(intptr_t deopt_id = Thread::kNoDeoptId) | 619 explicit Instruction(intptr_t deopt_id = Thread::kNoDeoptId) |
558 : deopt_id_(deopt_id), | 620 : deopt_id_(deopt_id), |
559 lifetime_position_(kNoPlaceId), | 621 lifetime_position_(kNoPlaceId), |
560 previous_(NULL), | 622 previous_(NULL), |
(...skipping 2127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2688 PRINT_OPERANDS_TO_SUPPORT | 2750 PRINT_OPERANDS_TO_SUPPORT |
2689 | 2751 |
2690 private: | 2752 private: |
2691 const Array& argument_names_; | 2753 const Array& argument_names_; |
2692 TokenPosition token_pos_; | 2754 TokenPosition token_pos_; |
2693 ZoneGrowableArray<PushArgumentInstr*>* arguments_; | 2755 ZoneGrowableArray<PushArgumentInstr*>* arguments_; |
2694 | 2756 |
2695 DISALLOW_COPY_AND_ASSIGN(ClosureCallInstr); | 2757 DISALLOW_COPY_AND_ASSIGN(ClosureCallInstr); |
2696 }; | 2758 }; |
2697 | 2759 |
2698 | |
Vyacheslav Egorov (Google)
2017/04/20 16:45:33
restore the deleted new line
erikcorry
2017/04/21 13:04:44
Done.
| |
2699 class InstanceCallInstr : public TemplateDefinition<0, Throws> { | 2760 class InstanceCallInstr : public TemplateDefinition<0, Throws> { |
2700 public: | 2761 public: |
2701 InstanceCallInstr(TokenPosition token_pos, | 2762 InstanceCallInstr(TokenPosition token_pos, |
2702 const String& function_name, | 2763 const String& function_name, |
2703 Token::Kind token_kind, | 2764 Token::Kind token_kind, |
2704 ZoneGrowableArray<PushArgumentInstr*>* arguments, | 2765 ZoneGrowableArray<PushArgumentInstr*>* arguments, |
2705 const Array& argument_names, | 2766 const Array& argument_names, |
2706 intptr_t checked_argument_count, | 2767 intptr_t checked_argument_count, |
2707 const ZoneGrowableArray<const ICData*>& ic_data_array) | 2768 const ZoneGrowableArray<const ICData*>& ic_data_array) |
2708 : TemplateDefinition(Thread::Current()->GetNextDeoptId()), | 2769 : TemplateDefinition(Thread::Current()->GetNextDeoptId()), |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2779 const intptr_t checked_argument_count_; | 2840 const intptr_t checked_argument_count_; |
2780 bool has_unique_selector_; | 2841 bool has_unique_selector_; |
2781 | 2842 |
2782 DISALLOW_COPY_AND_ASSIGN(InstanceCallInstr); | 2843 DISALLOW_COPY_AND_ASSIGN(InstanceCallInstr); |
2783 }; | 2844 }; |
2784 | 2845 |
2785 | 2846 |
2786 class PolymorphicInstanceCallInstr : public TemplateDefinition<0, Throws> { | 2847 class PolymorphicInstanceCallInstr : public TemplateDefinition<0, Throws> { |
2787 public: | 2848 public: |
2788 PolymorphicInstanceCallInstr(InstanceCallInstr* instance_call, | 2849 PolymorphicInstanceCallInstr(InstanceCallInstr* instance_call, |
2789 const ICData& ic_data, | 2850 const CallTargets& targets, |
2790 bool with_checks, | 2851 bool with_checks, |
2791 bool complete) | 2852 bool complete) |
2792 : TemplateDefinition(instance_call->deopt_id()), | 2853 : TemplateDefinition(instance_call->deopt_id()), |
2793 instance_call_(instance_call), | 2854 instance_call_(instance_call), |
2794 ic_data_(ic_data), | 2855 targets_(targets), |
2795 with_checks_(with_checks), | 2856 with_checks_(with_checks), |
2796 complete_(complete) { | 2857 complete_(complete) { |
2797 ASSERT(instance_call_ != NULL); | 2858 ASSERT(instance_call_ != NULL); |
2798 ASSERT(!ic_data.NumberOfChecksIs(0)); | 2859 ASSERT(targets.length() != 0); |
2799 total_call_count_ = CallCount(); | 2860 total_call_count_ = CallCount(); |
2800 } | 2861 } |
2801 | 2862 |
2802 InstanceCallInstr* instance_call() const { return instance_call_; } | 2863 InstanceCallInstr* instance_call() const { return instance_call_; } |
2803 bool with_checks() const { return with_checks_; } | 2864 bool with_checks() const { return with_checks_; } |
2804 void set_with_checks(bool b) { with_checks_ = b; } | 2865 void set_with_checks(bool b) { with_checks_ = b; } |
2805 bool complete() const { return complete_; } | 2866 bool complete() const { return complete_; } |
2806 virtual TokenPosition token_pos() const { | 2867 virtual TokenPosition token_pos() const { |
2807 return instance_call_->token_pos(); | 2868 return instance_call_->token_pos(); |
2808 } | 2869 } |
2809 | 2870 |
2810 virtual CompileType ComputeType() const; | 2871 virtual CompileType ComputeType() const; |
2811 | 2872 |
2812 virtual intptr_t ArgumentCount() const { | 2873 virtual intptr_t ArgumentCount() const { |
2813 return instance_call()->ArgumentCount(); | 2874 return instance_call()->ArgumentCount(); |
2814 } | 2875 } |
2815 virtual PushArgumentInstr* PushArgumentAt(intptr_t index) const { | 2876 virtual PushArgumentInstr* PushArgumentAt(intptr_t index) const { |
2816 return instance_call()->PushArgumentAt(index); | 2877 return instance_call()->PushArgumentAt(index); |
2817 } | 2878 } |
2818 | 2879 |
2819 bool HasSingleRecognizedTarget() const; | 2880 bool HasOnlyDispatcherOrImplicitAccessorTargets() const; |
2820 | 2881 |
2821 virtual intptr_t CallCount() const { return ic_data().AggregateCount(); } | 2882 const CallTargets& targets() const { return targets_; } |
2883 intptr_t NumberOfChecks() const { return targets_.length(); } | |
2884 | |
2885 virtual intptr_t CallCount() const; | |
2822 | 2886 |
2823 // If this polymophic call site was created to cover the remaining cids after | 2887 // If this polymophic call site was created to cover the remaining cids after |
2824 // inlinng then we need to keep track of the total number of calls including | 2888 // inlinng then we need to keep track of the total number of calls including |
2825 // the ones that wer inlined. This is different from the CallCount above: Eg | 2889 // the ones that wer inlined. This is different from the CallCount above: Eg |
2826 // if there were 100 calls originally, distributed across three class-ids in | 2890 // if there were 100 calls originally, distributed across three class-ids in |
2827 // the ratio 50, 40, 7, 3. The first two were inlined, so now we have only | 2891 // the ratio 50, 40, 7, 3. The first two were inlined, so now we have only |
2828 // 10 calls in the CallCount above, but the heuristics need to know that the | 2892 // 10 calls in the CallCount above, but the heuristics need to know that the |
2829 // last two cids cover 7% and 3% of the calls, not 70% and 30%. | 2893 // last two cids cover 7% and 3% of the calls, not 70% and 30%. |
2830 intptr_t total_call_count() { return total_call_count_; } | 2894 intptr_t total_call_count() { return total_call_count_; } |
2831 | 2895 |
2832 void set_total_call_count(intptr_t count) { total_call_count_ = count; } | 2896 void set_total_call_count(intptr_t count) { total_call_count_ = count; } |
2833 | 2897 |
2834 DECLARE_INSTRUCTION(PolymorphicInstanceCall) | 2898 DECLARE_INSTRUCTION(PolymorphicInstanceCall) |
2835 | 2899 |
2836 const ICData& ic_data() const { return ic_data_; } | |
2837 | |
2838 virtual bool ComputeCanDeoptimize() const { return true; } | 2900 virtual bool ComputeCanDeoptimize() const { return true; } |
2839 | 2901 |
2840 virtual EffectSet Effects() const { return EffectSet::All(); } | 2902 virtual EffectSet Effects() const { return EffectSet::All(); } |
2841 | 2903 |
2842 virtual Definition* Canonicalize(FlowGraph* graph); | 2904 virtual Definition* Canonicalize(FlowGraph* graph); |
2843 | 2905 |
2844 static RawType* ComputeRuntimeType(const ICData& ic_data); | 2906 static RawType* ComputeRuntimeType(const CallTargets& targets); |
2845 | 2907 |
2846 PRINT_OPERANDS_TO_SUPPORT | 2908 PRINT_OPERANDS_TO_SUPPORT |
2847 | 2909 |
2848 private: | 2910 private: |
2849 InstanceCallInstr* instance_call_; | 2911 InstanceCallInstr* instance_call_; |
2850 const ICData& ic_data_; | 2912 const CallTargets& targets_; |
2851 bool with_checks_; | 2913 bool with_checks_; |
2852 const bool complete_; | 2914 const bool complete_; |
2853 intptr_t total_call_count_; | 2915 intptr_t total_call_count_; |
2854 | 2916 |
2917 friend class PolymorphicInliner; | |
2918 | |
2855 DISALLOW_COPY_AND_ASSIGN(PolymorphicInstanceCallInstr); | 2919 DISALLOW_COPY_AND_ASSIGN(PolymorphicInstanceCallInstr); |
2856 }; | 2920 }; |
2857 | 2921 |
2858 | 2922 |
2859 class StrictCompareInstr : public TemplateComparison<2, NoThrow, Pure> { | 2923 class StrictCompareInstr : public TemplateComparison<2, NoThrow, Pure> { |
2860 public: | 2924 public: |
2861 StrictCompareInstr(TokenPosition token_pos, | 2925 StrictCompareInstr(TokenPosition token_pos, |
2862 Token::Kind kind, | 2926 Token::Kind kind, |
2863 Value* left, | 2927 Value* left, |
2864 Value* right, | 2928 Value* right, |
(...skipping 5178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
8043 LocationSummary* Name::MakeLocationSummary(Zone* zone, bool opt) const { \ | 8107 LocationSummary* Name::MakeLocationSummary(Zone* zone, bool opt) const { \ |
8044 UNIMPLEMENTED(); \ | 8108 UNIMPLEMENTED(); \ |
8045 return NULL; \ | 8109 return NULL; \ |
8046 } \ | 8110 } \ |
8047 void Name::EmitNativeCode(FlowGraphCompiler* compiler) { UNIMPLEMENTED(); } | 8111 void Name::EmitNativeCode(FlowGraphCompiler* compiler) { UNIMPLEMENTED(); } |
8048 | 8112 |
8049 | 8113 |
8050 } // namespace dart | 8114 } // namespace dart |
8051 | 8115 |
8052 #endif // RUNTIME_VM_INTERMEDIATE_LANGUAGE_H_ | 8116 #endif // RUNTIME_VM_INTERMEDIATE_LANGUAGE_H_ |
OLD | NEW |