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