diff options
author | 2015-09-14 22:20:29 +0100 | |
---|---|---|
committer | 2015-09-17 14:45:39 +0100 | |
commit | 64acf303eaa2f32c0b1d8cfcbf044a822c5eec08 (patch) | |
tree | 1e9829deb0621b3cb9b275846c8d08381956fecf /compiler/optimizing/nodes.h | |
parent | 017719a03c7c111a2069b5f85e3b9c81566c0902 (diff) |
Optimize code generation of check-cast and instance-of.
On x86/x64/arm/arm64. Improve code size of selected apks from 0.3% to 1%,
and performance of DeltaBlue by 20%.
Change-Id: Ib5799f7a53443cd880a121dd7f21932ae9f5c7aa
Diffstat (limited to 'compiler/optimizing/nodes.h')
-rw-r--r-- | compiler/optimizing/nodes.h | 42 |
1 files changed, 30 insertions, 12 deletions
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h index a44c9828d5..27bbff0104 100644 --- a/compiler/optimizing/nodes.h +++ b/compiler/optimizing/nodes.h @@ -4840,16 +4840,29 @@ class HThrow : public HTemplateInstruction<1> { DISALLOW_COPY_AND_ASSIGN(HThrow); }; +/** + * Implementation strategies for the code generator of a HInstanceOf + * or `HCheckCast`. + */ +enum class TypeCheckKind { + kExactCheck, // Can do a single class compare. + kClassHierarchyCheck, // Can just walk the super class chain. + kAbstractClassCheck, // Can just walk the super class chain, starting one up. + kInterfaceCheck, // No optimization yet when checking against an interface. + kArrayObjectCheck, // Can just check if the array is not primitive. + kArrayCheck // No optimization yet when checking against a generic array. +}; + class HInstanceOf : public HExpression<2> { public: HInstanceOf(HInstruction* object, HLoadClass* constant, - bool class_is_final, + TypeCheckKind check_kind, uint32_t dex_pc) : HExpression(Primitive::kPrimBoolean, - SideEffectsForArchRuntimeCalls(class_is_final), + SideEffectsForArchRuntimeCalls(check_kind), dex_pc), - class_is_final_(class_is_final), + check_kind_(check_kind), must_do_null_check_(true) { SetRawInputAt(0, object); SetRawInputAt(1, constant); @@ -4865,20 +4878,25 @@ class HInstanceOf : public HExpression<2> { return false; } - bool IsClassFinal() const { return class_is_final_; } + bool IsExactCheck() const { return check_kind_ == TypeCheckKind::kExactCheck; } + + TypeCheckKind GetTypeCheckKind() const { return check_kind_; } // Used only in code generation. bool MustDoNullCheck() const { return must_do_null_check_; } void ClearMustDoNullCheck() { must_do_null_check_ = false; } - static SideEffects SideEffectsForArchRuntimeCalls(bool class_is_final) { - return class_is_final ? SideEffects::None() : SideEffects::CanTriggerGC(); + static SideEffects SideEffectsForArchRuntimeCalls(TypeCheckKind check_kind) { + return (check_kind == TypeCheckKind::kExactCheck) + ? SideEffects::None() + // Mips currently does runtime calls for any other checks. + : SideEffects::CanTriggerGC(); } DECLARE_INSTRUCTION(InstanceOf); private: - const bool class_is_final_; + const TypeCheckKind check_kind_; bool must_do_null_check_; DISALLOW_COPY_AND_ASSIGN(HInstanceOf); @@ -4934,10 +4952,10 @@ class HCheckCast : public HTemplateInstruction<2> { public: HCheckCast(HInstruction* object, HLoadClass* constant, - bool class_is_final, + TypeCheckKind check_kind, uint32_t dex_pc) : HTemplateInstruction(SideEffects::CanTriggerGC(), dex_pc), - class_is_final_(class_is_final), + check_kind_(check_kind), must_do_null_check_(true) { SetRawInputAt(0, object); SetRawInputAt(1, constant); @@ -4958,14 +4976,14 @@ class HCheckCast : public HTemplateInstruction<2> { bool MustDoNullCheck() const { return must_do_null_check_; } void ClearMustDoNullCheck() { must_do_null_check_ = false; } + TypeCheckKind GetTypeCheckKind() const { return check_kind_; } - - bool IsClassFinal() const { return class_is_final_; } + bool IsExactCheck() const { return check_kind_ == TypeCheckKind::kExactCheck; } DECLARE_INSTRUCTION(CheckCast); private: - const bool class_is_final_; + const TypeCheckKind check_kind_; bool must_do_null_check_; DISALLOW_COPY_AND_ASSIGN(HCheckCast); |