| 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; | |
| 605 bool IsMonomorphic() const; | |
| 606 intptr_t MonomorphicReceiverCid() const; | |
| 607 | |
| 608 private: | |
| 609 GrowableArray<CidRangeTarget> cid_ranges_; | |
| 610 }; | |
| 611 | |
| 612 | |
| 613 class Instruction : public ZoneAllocated { | 551 class Instruction : public ZoneAllocated { |
| 614 public: | 552 public: |
| 615 #define DECLARE_TAG(type) k##type, | 553 #define DECLARE_TAG(type) k##type, |
| 616 enum Tag { FOR_EACH_INSTRUCTION(DECLARE_TAG) }; | 554 enum Tag { FOR_EACH_INSTRUCTION(DECLARE_TAG) }; |
| 617 #undef DECLARE_TAG | 555 #undef DECLARE_TAG |
| 618 | 556 |
| 619 explicit Instruction(intptr_t deopt_id = Thread::kNoDeoptId) | 557 explicit Instruction(intptr_t deopt_id = Thread::kNoDeoptId) |
| 620 : deopt_id_(deopt_id), | 558 : deopt_id_(deopt_id), |
| 621 lifetime_position_(kNoPlaceId), | 559 lifetime_position_(kNoPlaceId), |
| 622 previous_(NULL), | 560 previous_(NULL), |
| (...skipping 2219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2842 const intptr_t checked_argument_count_; | 2780 const intptr_t checked_argument_count_; |
| 2843 bool has_unique_selector_; | 2781 bool has_unique_selector_; |
| 2844 | 2782 |
| 2845 DISALLOW_COPY_AND_ASSIGN(InstanceCallInstr); | 2783 DISALLOW_COPY_AND_ASSIGN(InstanceCallInstr); |
| 2846 }; | 2784 }; |
| 2847 | 2785 |
| 2848 | 2786 |
| 2849 class PolymorphicInstanceCallInstr : public TemplateDefinition<0, Throws> { | 2787 class PolymorphicInstanceCallInstr : public TemplateDefinition<0, Throws> { |
| 2850 public: | 2788 public: |
| 2851 PolymorphicInstanceCallInstr(InstanceCallInstr* instance_call, | 2789 PolymorphicInstanceCallInstr(InstanceCallInstr* instance_call, |
| 2852 const CallTargets& targets, | 2790 const ICData& ic_data, |
| 2853 bool with_checks, | 2791 bool with_checks, |
| 2854 bool complete) | 2792 bool complete) |
| 2855 : TemplateDefinition(instance_call->deopt_id()), | 2793 : TemplateDefinition(instance_call->deopt_id()), |
| 2856 instance_call_(instance_call), | 2794 instance_call_(instance_call), |
| 2857 targets_(targets), | 2795 ic_data_(ic_data), |
| 2858 with_checks_(with_checks), | 2796 with_checks_(with_checks), |
| 2859 complete_(complete) { | 2797 complete_(complete) { |
| 2860 ASSERT(instance_call_ != NULL); | 2798 ASSERT(instance_call_ != NULL); |
| 2861 ASSERT(targets.length() != 0); | 2799 ASSERT(!ic_data.NumberOfChecksIs(0)); |
| 2862 total_call_count_ = CallCount(); | 2800 total_call_count_ = CallCount(); |
| 2863 } | 2801 } |
| 2864 | 2802 |
| 2865 InstanceCallInstr* instance_call() const { return instance_call_; } | 2803 InstanceCallInstr* instance_call() const { return instance_call_; } |
| 2866 bool with_checks() const { return with_checks_; } | 2804 bool with_checks() const { return with_checks_; } |
| 2867 void set_with_checks(bool b) { with_checks_ = b; } | 2805 void set_with_checks(bool b) { with_checks_ = b; } |
| 2868 bool complete() const { return complete_; } | 2806 bool complete() const { return complete_; } |
| 2869 virtual TokenPosition token_pos() const { | 2807 virtual TokenPosition token_pos() const { |
| 2870 return instance_call_->token_pos(); | 2808 return instance_call_->token_pos(); |
| 2871 } | 2809 } |
| 2872 | 2810 |
| 2873 virtual CompileType ComputeType() const; | 2811 virtual CompileType ComputeType() const; |
| 2874 | 2812 |
| 2875 virtual intptr_t ArgumentCount() const { | 2813 virtual intptr_t ArgumentCount() const { |
| 2876 return instance_call()->ArgumentCount(); | 2814 return instance_call()->ArgumentCount(); |
| 2877 } | 2815 } |
| 2878 virtual PushArgumentInstr* PushArgumentAt(intptr_t index) const { | 2816 virtual PushArgumentInstr* PushArgumentAt(intptr_t index) const { |
| 2879 return instance_call()->PushArgumentAt(index); | 2817 return instance_call()->PushArgumentAt(index); |
| 2880 } | 2818 } |
| 2881 | 2819 |
| 2882 bool HasOnlyDispatcherOrImplicitAccessorTargets() const; | 2820 bool HasSingleRecognizedTarget() const; |
| 2883 | 2821 |
| 2884 const CallTargets& targets() const { return targets_; } | 2822 virtual intptr_t CallCount() const { return ic_data().AggregateCount(); } |
| 2885 intptr_t NumberOfChecks() const { return targets_.length(); } | |
| 2886 | |
| 2887 virtual intptr_t CallCount() const; | |
| 2888 | 2823 |
| 2889 // If this polymophic call site was created to cover the remaining cids after | 2824 // If this polymophic call site was created to cover the remaining cids after |
| 2890 // inlinng then we need to keep track of the total number of calls including | 2825 // inlinng then we need to keep track of the total number of calls including |
| 2891 // the ones that wer inlined. This is different from the CallCount above: Eg | 2826 // the ones that wer inlined. This is different from the CallCount above: Eg |
| 2892 // if there were 100 calls originally, distributed across three class-ids in | 2827 // if there were 100 calls originally, distributed across three class-ids in |
| 2893 // the ratio 50, 40, 7, 3. The first two were inlined, so now we have only | 2828 // the ratio 50, 40, 7, 3. The first two were inlined, so now we have only |
| 2894 // 10 calls in the CallCount above, but the heuristics need to know that the | 2829 // 10 calls in the CallCount above, but the heuristics need to know that the |
| 2895 // last two cids cover 7% and 3% of the calls, not 70% and 30%. | 2830 // last two cids cover 7% and 3% of the calls, not 70% and 30%. |
| 2896 intptr_t total_call_count() { return total_call_count_; } | 2831 intptr_t total_call_count() { return total_call_count_; } |
| 2897 | 2832 |
| 2898 void set_total_call_count(intptr_t count) { total_call_count_ = count; } | 2833 void set_total_call_count(intptr_t count) { total_call_count_ = count; } |
| 2899 | 2834 |
| 2900 DECLARE_INSTRUCTION(PolymorphicInstanceCall) | 2835 DECLARE_INSTRUCTION(PolymorphicInstanceCall) |
| 2901 | 2836 |
| 2837 const ICData& ic_data() const { return ic_data_; } |
| 2838 |
| 2902 virtual bool ComputeCanDeoptimize() const { return true; } | 2839 virtual bool ComputeCanDeoptimize() const { return true; } |
| 2903 | 2840 |
| 2904 virtual EffectSet Effects() const { return EffectSet::All(); } | 2841 virtual EffectSet Effects() const { return EffectSet::All(); } |
| 2905 | 2842 |
| 2906 virtual Definition* Canonicalize(FlowGraph* graph); | 2843 virtual Definition* Canonicalize(FlowGraph* graph); |
| 2907 | 2844 |
| 2908 static RawType* ComputeRuntimeType(const CallTargets& targets); | 2845 static RawType* ComputeRuntimeType(const ICData& ic_data); |
| 2909 | 2846 |
| 2910 PRINT_OPERANDS_TO_SUPPORT | 2847 PRINT_OPERANDS_TO_SUPPORT |
| 2911 | 2848 |
| 2912 private: | 2849 private: |
| 2913 InstanceCallInstr* instance_call_; | 2850 InstanceCallInstr* instance_call_; |
| 2914 const CallTargets& targets_; | 2851 const ICData& ic_data_; |
| 2915 bool with_checks_; | 2852 bool with_checks_; |
| 2916 const bool complete_; | 2853 const bool complete_; |
| 2917 intptr_t total_call_count_; | 2854 intptr_t total_call_count_; |
| 2918 | 2855 |
| 2919 friend class PolymorphicInliner; | |
| 2920 | |
| 2921 DISALLOW_COPY_AND_ASSIGN(PolymorphicInstanceCallInstr); | 2856 DISALLOW_COPY_AND_ASSIGN(PolymorphicInstanceCallInstr); |
| 2922 }; | 2857 }; |
| 2923 | 2858 |
| 2924 | 2859 |
| 2925 class StrictCompareInstr : public TemplateComparison<2, NoThrow, Pure> { | 2860 class StrictCompareInstr : public TemplateComparison<2, NoThrow, Pure> { |
| 2926 public: | 2861 public: |
| 2927 StrictCompareInstr(TokenPosition token_pos, | 2862 StrictCompareInstr(TokenPosition token_pos, |
| 2928 Token::Kind kind, | 2863 Token::Kind kind, |
| 2929 Value* left, | 2864 Value* left, |
| 2930 Value* right, | 2865 Value* right, |
| (...skipping 5181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8112 LocationSummary* Name::MakeLocationSummary(Zone* zone, bool opt) const { \ | 8047 LocationSummary* Name::MakeLocationSummary(Zone* zone, bool opt) const { \ |
| 8113 UNIMPLEMENTED(); \ | 8048 UNIMPLEMENTED(); \ |
| 8114 return NULL; \ | 8049 return NULL; \ |
| 8115 } \ | 8050 } \ |
| 8116 void Name::EmitNativeCode(FlowGraphCompiler* compiler) { UNIMPLEMENTED(); } | 8051 void Name::EmitNativeCode(FlowGraphCompiler* compiler) { UNIMPLEMENTED(); } |
| 8117 | 8052 |
| 8118 | 8053 |
| 8119 } // namespace dart | 8054 } // namespace dart |
| 8120 | 8055 |
| 8121 #endif // RUNTIME_VM_INTERMEDIATE_LANGUAGE_H_ | 8056 #endif // RUNTIME_VM_INTERMEDIATE_LANGUAGE_H_ |
| OLD | NEW |