Index: runtime/vm/intermediate_language.h |
diff --git a/runtime/vm/intermediate_language.h b/runtime/vm/intermediate_language.h |
index 823f4774b718309cd26bfb9df3363c42e2245f6f..f0bb315e91214407e4cdd0f121e1bff28b66ec5b 100644 |
--- a/runtime/vm/intermediate_language.h |
+++ b/runtime/vm/intermediate_language.h |
@@ -556,17 +556,17 @@ FOR_EACH_ABSTRACT_INSTRUCTION(FORWARD_DECLARATION) |
struct CidRangeTarget { |
intptr_t cid_start; |
intptr_t cid_end; |
- Function* target; |
+ const Function* target; |
intptr_t count; |
CidRangeTarget(intptr_t cid_start_arg, |
intptr_t cid_end_arg, |
- Function* target_arg, |
+ const 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()); |
+ ASSERT(target == NULL || target->IsZoneHandle()); |
} |
}; |
@@ -574,12 +574,22 @@ struct CidRangeTarget { |
class CallTargets : public ZoneAllocated { |
Vyacheslav Egorov (Google)
2017/05/01 12:21:25
It feels a bit strange to use CallTargets as a "ci
erikcorry
2017/05/05 15:15:51
I tried several things here. In the end the one t
|
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); |
+ // of the on-VM-heap IC data. |
+ static CallTargets* Create(Zone* zone, |
+ const ICData& ic_data, |
+ int argument_number); |
+ |
+ // This variant always uses the IC data for argument 0 (the receiver) and |
+ // also expands the class-ids to neighbouring classes that inherit the same |
+ // method. |
+ static CallTargets* CreateAndExpand(Zone* zone, const ICData& ic_data); |
void Add(const CidRangeTarget& target) { cid_ranges_.Add(target); } |
+ bool Equals(const CallTargets& other) const; |
+ |
+ bool HasClassId(intptr_t cid) const; |
+ |
CidRangeTarget& operator[](intptr_t index) const { |
return cid_ranges_[index]; |
} |
@@ -600,12 +610,22 @@ class CallTargets : public ZoneAllocated { |
bool HasSingleTarget() const; |
bool HasSingleRecognizedTarget() const; |
- Function& FirstTarget() const; |
- Function& MostPopularTarget() const; |
+ const Function& FirstTarget() const; |
+ const Function& MostPopularTarget() const; |
bool IsMonomorphic() const; |
intptr_t MonomorphicReceiverCid() const; |
+ bool AreAllChecksImmutable() const; |
+ bool HasReceiverClassId(intptr_t cid) const; |
+ intptr_t ComputeLowestCid() const; |
+ intptr_t ComputeHighestCid() const; |
+ |
private: |
+ void MergeIntoRanges(); |
+ static CallTargets* CreateHelper(Zone* zone, |
+ const ICData& ic_data, |
+ int argument_number); |
+ |
GrowableArray<CidRangeTarget> cid_ranges_; |
}; |
@@ -7591,7 +7611,7 @@ class CheckClassInstr : public TemplateInstruction<1, NoThrow> { |
public: |
CheckClassInstr(Value* value, |
intptr_t deopt_id, |
- const ICData& unary_checks, |
+ const CallTargets& targets, |
TokenPosition token_pos); |
DECLARE_INSTRUCTION(CheckClass) |
@@ -7602,21 +7622,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 CallTargets& targets() const { return targets_; } |
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); |
+ static bool IsDenseCidRange(const CallTargets& targets); |
intptr_t ComputeCidMask() const; |
- static bool IsDenseMask(intptr_t mask); |
virtual bool AllowsCSE() const { return true; } |
virtual EffectSet Dependencies() const; |
@@ -7629,12 +7646,26 @@ class CheckClassInstr : public TemplateInstruction<1, NoThrow> { |
PRINT_OPERANDS_TO_SUPPORT |
private: |
- const ICData& unary_checks_; |
- GrowableArray<intptr_t> cids_; // Sorted, lowest first. |
+ const CallTargets& targets_; |
bool licm_hoisted_; |
bool is_dense_switch_; |
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 EmitDenseSwitch(FlowGraphCompiler* compiler, |
+ intptr_t min, |
+ intptr_t max, |
+ intptr_t mask, |
+ Label* deopt); |
+ void EmitNullCheck(FlowGraphCompiler* compiler, Label* deopt); |
+ |
DISALLOW_COPY_AND_ASSIGN(CheckClassInstr); |
}; |