| Index: runtime/vm/intermediate_language.h | 
| diff --git a/runtime/vm/intermediate_language.h b/runtime/vm/intermediate_language.h | 
| index 715b5369ecdb54fae25395f31ec77ba52a025160..3521d11a98e72e7a38332d7d63b92c6ca41c3eca 100644 | 
| --- a/runtime/vm/intermediate_language.h | 
| +++ b/runtime/vm/intermediate_language.h | 
| @@ -548,6 +548,68 @@ FOR_EACH_ABSTRACT_INSTRUCTION(FORWARD_DECLARATION) | 
| #define PRINT_OPERANDS_TO_SUPPORT | 
| #endif  // !PRODUCT | 
|  | 
| + | 
| +// Represents a mapping from a range of class-ids to a method for a given | 
| +// selector (method name).  Also can contain an indication of how frequently a | 
| +// given method has been called at a call site.  This information can be | 
| +// harvested from the inline caches (ICs). | 
| +struct CidRangeTarget { | 
| +  intptr_t cid_start; | 
| +  intptr_t cid_end; | 
| +  Function* target; | 
| +  intptr_t count; | 
| +  CidRangeTarget(intptr_t cid_start_arg, | 
| +                 intptr_t cid_end_arg, | 
| +                 Function* target_arg, | 
| +                 intptr_t count_arg) | 
| +      : cid_start(cid_start_arg), | 
| +        cid_end(cid_end_arg), | 
| +        target(target_arg), | 
| +        count(count_arg) { | 
| +    ASSERT(target->IsZoneHandle()); | 
| +  } | 
| +}; | 
| + | 
| + | 
| +class CallTargets : public ZoneAllocated { | 
| + public: | 
| +  // Creates the off-heap CallTargets object that reflects the contents | 
| +  // of the on-VM-heap IC data. Also expands the class-ids to neighbouring | 
| +  // classes that inherit the same method. | 
| +  static CallTargets* Create(Zone* zone, const ICData& ic_data); | 
| + | 
| +  void Add(const CidRangeTarget& target) { cid_ranges_.Add(target); } | 
| + | 
| +  CidRangeTarget& operator[](intptr_t index) const { | 
| +    return cid_ranges_[index]; | 
| +  } | 
| + | 
| +  CidRangeTarget At(int index) { return cid_ranges_.At(index); } | 
| + | 
| +  intptr_t length() const { return cid_ranges_.length(); } | 
| + | 
| +  void SetLength(intptr_t len) { cid_ranges_.SetLength(len); } | 
| + | 
| +  bool is_empty() const { return cid_ranges_.is_empty(); } | 
| + | 
| +  void Sort(int compare(const CidRangeTarget* a, const CidRangeTarget* b)) { | 
| +    cid_ranges_.Sort(compare); | 
| +  } | 
| + | 
| +  intptr_t AggregateCallCount() const; | 
| + | 
| +  bool HasSingleTarget() const; | 
| +  bool HasSingleRecognizedTarget() const; | 
| +  Function& FirstTarget() const; | 
| +  Function& MostPopularTarget() const; | 
| +  bool IsMonomorphic() const; | 
| +  intptr_t MonomorphicReceiverCid() const; | 
| + | 
| + private: | 
| +  GrowableArray<CidRangeTarget> cid_ranges_; | 
| +}; | 
| + | 
| + | 
| class Instruction : public ZoneAllocated { | 
| public: | 
| #define DECLARE_TAG(type) k##type, | 
| @@ -2787,16 +2849,16 @@ class InstanceCallInstr : public TemplateDefinition<0, Throws> { | 
| class PolymorphicInstanceCallInstr : public TemplateDefinition<0, Throws> { | 
| public: | 
| PolymorphicInstanceCallInstr(InstanceCallInstr* instance_call, | 
| -                               const ICData& ic_data, | 
| +                               const CallTargets& targets, | 
| bool with_checks, | 
| bool complete) | 
| : TemplateDefinition(instance_call->deopt_id()), | 
| instance_call_(instance_call), | 
| -        ic_data_(ic_data), | 
| +        targets_(targets), | 
| with_checks_(with_checks), | 
| complete_(complete) { | 
| ASSERT(instance_call_ != NULL); | 
| -    ASSERT(!ic_data.NumberOfChecksIs(0)); | 
| +    ASSERT(targets.length() != 0); | 
| total_call_count_ = CallCount(); | 
| } | 
|  | 
| @@ -2817,9 +2879,14 @@ class PolymorphicInstanceCallInstr : public TemplateDefinition<0, Throws> { | 
| return instance_call()->PushArgumentAt(index); | 
| } | 
|  | 
| -  bool HasSingleRecognizedTarget() const; | 
| +  bool HasOnlyDispatcherOrImplicitAccessorTargets() const; | 
| + | 
| +  const CallTargets& targets() const { return targets_; } | 
| +  intptr_t NumberOfChecks() const { return targets_.length(); } | 
| + | 
| +  bool IsSureToCallSingleRecognizedTarget() const; | 
|  | 
| -  virtual intptr_t CallCount() const { return ic_data().AggregateCount(); } | 
| +  virtual intptr_t CallCount() const; | 
|  | 
| // If this polymophic call site was created to cover the remaining cids after | 
| // inlinng then we need to keep track of the total number of calls including | 
| @@ -2834,25 +2901,25 @@ class PolymorphicInstanceCallInstr : public TemplateDefinition<0, Throws> { | 
|  | 
| DECLARE_INSTRUCTION(PolymorphicInstanceCall) | 
|  | 
| -  const ICData& ic_data() const { return ic_data_; } | 
| - | 
| virtual bool ComputeCanDeoptimize() const { return true; } | 
|  | 
| virtual EffectSet Effects() const { return EffectSet::All(); } | 
|  | 
| virtual Definition* Canonicalize(FlowGraph* graph); | 
|  | 
| -  static RawType* ComputeRuntimeType(const ICData& ic_data); | 
| +  static RawType* ComputeRuntimeType(const CallTargets& targets); | 
|  | 
| PRINT_OPERANDS_TO_SUPPORT | 
|  | 
| private: | 
| InstanceCallInstr* instance_call_; | 
| -  const ICData& ic_data_; | 
| +  const CallTargets& targets_; | 
| bool with_checks_; | 
| const bool complete_; | 
| intptr_t total_call_count_; | 
|  | 
| +  friend class PolymorphicInliner; | 
| + | 
| DISALLOW_COPY_AND_ASSIGN(PolymorphicInstanceCallInstr); | 
| }; | 
|  | 
|  |