Chromium Code Reviews| Index: runtime/vm/intermediate_language.h |
| diff --git a/runtime/vm/intermediate_language.h b/runtime/vm/intermediate_language.h |
| index 823f4774b718309cd26bfb9df3363c42e2245f6f..08c3334d597f056df5f1f5b892334323d0c3b02e 100644 |
| --- a/runtime/vm/intermediate_language.h |
| +++ b/runtime/vm/intermediate_language.h |
| @@ -20,6 +20,7 @@ class BitVector; |
| class BlockEntryInstr; |
| class BoxIntegerInstr; |
| class BufferFormatter; |
| +class CallTargets; |
| class CatchBlockEntryInstr; |
| class ComparisonInstr; |
| class Definition; |
| @@ -549,42 +550,61 @@ FOR_EACH_ABSTRACT_INSTRUCTION(FORWARD_DECLARATION) |
| #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 { |
| +// Represents a range of class-ids for use in class checks and polymorphic |
| +// dispatches. |
| +struct CidRange : public ZoneAllocated { |
| 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), |
| + CidRange(const CidRange& o) |
|
Vyacheslav Egorov (Google)
2017/05/09 21:07:27
Please order constructors before fields.
erikcorry
2017/05/10 08:47:43
Done.
|
| + : ZoneAllocated(), cid_start(o.cid_start), cid_end(o.cid_end) {} |
| + CidRange(intptr_t cid_start_arg, intptr_t cid_end_arg) |
| + : cid_start(cid_start_arg), cid_end(cid_end_arg) {} |
| + CidRange(intptr_t cid_start_arg, |
|
Vyacheslav Egorov (Google)
2017/05/09 21:07:27
I don't think this constructor is used.
erikcorry
2017/05/10 08:47:43
Gone
|
| + intptr_t cid_end_arg, |
| + const Function* target_arg, |
| + intptr_t count_arg) |
| + : cid_start(cid_start_arg), cid_end(cid_end_arg) {} |
| +}; |
| + |
| + |
| +// Together with CidRange, this 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 TargetInfo : public CidRange { |
| + TargetInfo(intptr_t cid_start_arg, |
| + intptr_t cid_end_arg, |
| + const Function* target_arg, |
| + intptr_t count_arg) |
| + : CidRange(cid_start_arg, cid_end_arg), |
| target(target_arg), |
| count(count_arg) { |
| ASSERT(target->IsZoneHandle()); |
| } |
| + const Function* target; |
| + intptr_t count; |
| }; |
| -class CallTargets : public ZoneAllocated { |
| +// A set of class-ids, arranged in ranges. Used for the CheckClass |
| +// and PolymorphicInstanceCall instructions. |
| +class Cids : 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); |
| + explicit Cids(Zone* zone) : zone_(zone) {} |
| + // Creates the off-heap Cids object that reflects the contents |
| + // of the on-VM-heap IC data. |
| + static Cids* Create(Zone* zone, const ICData& ic_data, int argument_number); |
| + static Cids* CreateMonomorphic(Zone* zone, intptr_t cid); |
| - void Add(const CidRangeTarget& target) { cid_ranges_.Add(target); } |
| + bool Equals(const Cids& other) const; |
| - CidRangeTarget& operator[](intptr_t index) const { |
| - return cid_ranges_[index]; |
| - } |
| + bool HasClassId(intptr_t cid) const; |
| + |
| + void Add(CidRange* target) { cid_ranges_.Add(target); } |
| + |
| + CidRange& operator[](intptr_t index) const { return *cid_ranges_[index]; } |
| - CidRangeTarget At(int index) { return cid_ranges_.At(index); } |
| + CidRange* At(int index) const { return cid_ranges_[index]; } |
| intptr_t length() const { return cid_ranges_.length(); } |
| @@ -592,21 +612,53 @@ class CallTargets : public ZoneAllocated { |
| bool is_empty() const { return cid_ranges_.is_empty(); } |
| - void Sort(int compare(const CidRangeTarget* a, const CidRangeTarget* b)) { |
| + void Sort(int compare(CidRange* const* a, CidRange* const* b)) { |
| cid_ranges_.Sort(compare); |
| } |
| + bool IsMonomorphic() const; |
| + intptr_t MonomorphicReceiverCid() const; |
| + bool ContainsExternalizableCids() const; |
| + intptr_t ComputeLowestCid() const; |
| + intptr_t ComputeHighestCid() const; |
| + |
| + protected: |
| + void CreateHelper(Zone* zone, |
| + const ICData& ic_data, |
| + int argument_number, |
| + bool include_targets); |
| + GrowableArray<CidRange*> cid_ranges_; |
| + Zone* zone_; |
| + |
| + private: |
| + DISALLOW_IMPLICIT_CONSTRUCTORS(Cids); |
| +}; |
| + |
| + |
| +class CallTargets : public Cids { |
| + public: |
| + explicit CallTargets(Zone* zone) : Cids(zone) {} |
| + // Creates the off-heap CallTargets object that reflects the contents |
| + // of the on-VM-heap IC data. |
| + static CallTargets* Create(Zone* zone, const ICData& ic_data); |
| + |
| + // This variant also expands the class-ids to neighbouring classes that |
| + // inherit the same method. |
| + static CallTargets* CreateAndExpand(Zone* zone, const ICData& ic_data); |
| + |
| + TargetInfo* TargetAt(int i) const { |
| + return reinterpret_cast<TargetInfo*>(At(i)); |
|
Vyacheslav Egorov (Google)
2017/05/09 21:07:27
static_cast<TargetInfo*>(...)
erikcorry
2017/05/10 08:47:43
Done.
|
| + } |
| + |
| intptr_t AggregateCallCount() const; |
| bool HasSingleTarget() const; |
| bool HasSingleRecognizedTarget() const; |
| - Function& FirstTarget() const; |
| - Function& MostPopularTarget() const; |
| - bool IsMonomorphic() const; |
| - intptr_t MonomorphicReceiverCid() const; |
| + const Function& FirstTarget() const; |
| + const Function& MostPopularTarget() const; |
| private: |
| - GrowableArray<CidRangeTarget> cid_ranges_; |
| + void MergeIntoRanges(); |
| }; |
| @@ -7591,7 +7643,7 @@ class CheckClassInstr : public TemplateInstruction<1, NoThrow> { |
| public: |
| CheckClassInstr(Value* value, |
| intptr_t deopt_id, |
| - const ICData& unary_checks, |
| + const Cids& cids, |
| TokenPosition token_pos); |
| DECLARE_INSTRUCTION(CheckClass) |
| @@ -7602,21 +7654,18 @@ class CheckClassInstr : public TemplateInstruction<1, NoThrow> { |
| Value* value() const { return inputs_[0]; } |
| - const ICData& unary_checks() const { return unary_checks_; } |
| - |
| - const GrowableArray<intptr_t>& cids() const { return cids_; } |
| + const Cids& cids() const { return cids_; } |
| virtual Instruction* Canonicalize(FlowGraph* flow_graph); |
| - bool IsNullCheck() const { return DeoptIfNull() || DeoptIfNotNull(); } |
| + bool IsNullCheck() const { return IsDeoptIfNull() || IsDeoptIfNotNull(); } |
| - bool DeoptIfNull() const; |
| - bool DeoptIfNotNull() const; |
| + bool IsDeoptIfNull() const; |
| + bool IsDeoptIfNotNull() const; |
| - bool IsDenseSwitch() const; |
| - static bool IsDenseCidRange(const ICData& unary_checks); |
| + bool IsBitTest() const; |
| + static bool IsCompactCidRange(const Cids& cids); |
| intptr_t ComputeCidMask() const; |
| - static bool IsDenseMask(intptr_t mask); |
| virtual bool AllowsCSE() const { return true; } |
| virtual EffectSet Dependencies() const; |
| @@ -7629,12 +7678,26 @@ class CheckClassInstr : public TemplateInstruction<1, NoThrow> { |
| PRINT_OPERANDS_TO_SUPPORT |
| private: |
| - const ICData& unary_checks_; |
| - GrowableArray<intptr_t> cids_; // Sorted, lowest first. |
| + const Cids& cids_; |
| bool licm_hoisted_; |
| - bool is_dense_switch_; |
| + bool is_bit_test_; |
| const TokenPosition token_pos_; |
| + int EmitCheckCid(FlowGraphCompiler* compiler, |
| + int bias, |
| + intptr_t cid_start, |
| + intptr_t cid_end, |
| + bool is_last, |
| + Label* is_ok, |
| + Label* deopt, |
| + bool use_near_jump); |
| + void EmitBitTest(FlowGraphCompiler* compiler, |
| + intptr_t min, |
| + intptr_t max, |
| + intptr_t mask, |
| + Label* deopt); |
| + void EmitNullCheck(FlowGraphCompiler* compiler, Label* deopt); |
| + |
| DISALLOW_COPY_AND_ASSIGN(CheckClassInstr); |
| }; |