| 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);
|
| };
|
|
|
|
|