Revert "Revert "Optimize code generation of check-cast and instance-of.""
This reverts commit 7537437c6a2f89249a48e30effcc27d4e7c5a04f.
Change-Id: If759cb08646e47b62829bebc3c5b1e2f2969cf84
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h
index 3c57180..8dd31be 100644
--- a/compiler/optimizing/nodes.h
+++ b/compiler/optimizing/nodes.h
@@ -4719,16 +4719,29 @@
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);
@@ -4744,20 +4757,25 @@
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);
@@ -4813,10 +4831,10 @@
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);
@@ -4837,14 +4855,14 @@
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);