Even though instanceof check (and reflective Class.isInstance call) narrows operand's type, sharpened type information is not explicitly materialized in the IR.
There's a SubTypeCheck node present, but it doesn't cover all the cases.
The difference can be illustrated with the following simple cases:
class A { void m() {} }
class B extends A { void m() {} }
void testInstanceOf(A obj) {
if (obj instanceof B) {
obj.m();
}
}
167 11 b InstanceOf::testInstanceOf (12 bytes)
@ 8 InstanceOf$A::m (0 bytes) failed to inline: virtual call
vs
void testInstanceOfCast(A obj) {
if (obj instanceof B) {
B b = (B)obj;
b.m();
}
}
173 12 b InstanceOf::testInstanceOfCast (17 bytes)
@ 13 InstanceOf$B::m (1 bytes) inline (hot)
There's a SubTypeCheck node present, but it doesn't cover all the cases.
The difference can be illustrated with the following simple cases:
class A { void m() {} }
class B extends A { void m() {} }
void testInstanceOf(A obj) {
if (obj instanceof B) {
obj.m();
}
}
167 11 b InstanceOf::testInstanceOf (12 bytes)
@ 8 InstanceOf$A::m (0 bytes) failed to inline: virtual call
vs
void testInstanceOfCast(A obj) {
if (obj instanceof B) {
B b = (B)obj;
b.m();
}
}
173 12 b InstanceOf::testInstanceOfCast (17 bytes)
@ 13 InstanceOf$B::m (1 bytes) inline (hot)
- links to
-
Review(master)
openjdk/jdk/28517