Further refinements to checkcast/instanceof.
- Use setcc when possible.
- Do an exact check in the Object[] case before checking the
component type.
Change-Id: Ic11c60643af9b41fe4ef2beb59dfe7769bef388f
diff --git a/compiler/optimizing/code_generator_x86_64.cc b/compiler/optimizing/code_generator_x86_64.cc
index 32a1db5..b78b017 100644
--- a/compiler/optimizing/code_generator_x86_64.cc
+++ b/compiler/optimizing/code_generator_x86_64.cc
@@ -4766,10 +4766,16 @@
DCHECK(cls.IsStackSlot()) << cls;
__ cmpl(out, Address(CpuRegister(RSP), cls.GetStackIndex()));
}
- // Classes must be equal for the instanceof to succeed.
- __ j(kNotEqual, &zero);
- __ movl(out, Immediate(1));
- __ jmp(&done);
+ if (zero.IsLinked()) {
+ // Classes must be equal for the instanceof to succeed.
+ __ j(kNotEqual, &zero);
+ __ movl(out, Immediate(1));
+ __ jmp(&done);
+ } else {
+ __ setcc(kEqual, out);
+ // setcc only sets the low byte.
+ __ andl(out, Immediate(1));
+ }
break;
}
case TypeCheckKind::kAbstractClassCheck: {
@@ -4820,7 +4826,16 @@
break;
}
case TypeCheckKind::kArrayObjectCheck: {
- // Just need to check that the object's class is a non primitive array.
+ // Do an exact check.
+ NearLabel exact_check;
+ if (cls.IsRegister()) {
+ __ cmpl(out, cls.AsRegister<CpuRegister>());
+ } else {
+ DCHECK(cls.IsStackSlot()) << cls;
+ __ cmpl(out, Address(CpuRegister(RSP), cls.GetStackIndex()));
+ }
+ __ j(kEqual, &exact_check);
+ // Otherwise, we need to check that the object's class is a non primitive array.
__ movl(out, Address(out, component_offset));
__ MaybeUnpoisonHeapReference(out);
__ testl(out, out);
@@ -4828,6 +4843,7 @@
__ j(kEqual, &done);
__ cmpw(Address(out, primitive_offset), Immediate(Primitive::kPrimNot));
__ j(kNotEqual, &zero);
+ __ Bind(&exact_check);
__ movl(out, Immediate(1));
__ jmp(&done);
break;
@@ -4983,7 +4999,7 @@
}
case TypeCheckKind::kClassHierarchyCheck: {
// Walk over the class hierarchy to find a match.
- NearLabel loop, success;
+ NearLabel loop;
__ Bind(&loop);
if (cls.IsRegister()) {
__ cmpl(temp, cls.AsRegister<CpuRegister>());
@@ -4991,18 +5007,25 @@
DCHECK(cls.IsStackSlot()) << cls;
__ cmpl(temp, Address(CpuRegister(RSP), cls.GetStackIndex()));
}
- __ j(kEqual, &success);
+ __ j(kEqual, &done);
__ movl(temp, Address(temp, super_offset));
__ MaybeUnpoisonHeapReference(temp);
__ testl(temp, temp);
__ j(kNotEqual, &loop);
// Jump to the slow path to throw the exception.
__ jmp(slow_path->GetEntryLabel());
- __ Bind(&success);
break;
}
case TypeCheckKind::kArrayObjectCheck: {
- // Just need to check that the object's class is a non primitive array.
+ // Do an exact check.
+ if (cls.IsRegister()) {
+ __ cmpl(temp, cls.AsRegister<CpuRegister>());
+ } else {
+ DCHECK(cls.IsStackSlot()) << cls;
+ __ cmpl(temp, Address(CpuRegister(RSP), cls.GetStackIndex()));
+ }
+ __ j(kEqual, &done);
+ // Otherwise, we need to check that the object's class is a non primitive array.
__ movl(temp, Address(temp, component_offset));
__ MaybeUnpoisonHeapReference(temp);
__ testl(temp, temp);