[9] RFR [XS] 8054492: Casting can result in redundant null checks in generated code

Vladimir Kozlov vladimir.kozlov at oracle.com
Fri Oct 10 23:41:06 UTC 2014


https://bugs.openjdk.java.net/browse/JDK-8054492
http://cr.openjdk.java.net/~kvn/8054492/webrev/

Thanks to Roland for the evaluation of this problem.

Class.cast has an explicit null check:

    public T cast(Object obj) {
         if (obj != null && !isInstance(obj))
             throw new ClassCastException(cannotCastMsg(obj));
         return (T) obj;
    }

Compiler generates null check and uncommon trap when it did not see null 
values in profiled data. In most cases when Class.cast is inlined 
isInstance() is folded and as result compiled code is looks like:

if (obj != null) {
   return obj;
} else {
   uncommon_trap(); // which triggers deoptimization and Interpreter
                    // will execute the same 'return obj;' code.
}

The same result you will get with next compiled code. So the null check 
is noop and will be removed from compiled code (it is the goal of this 
change):

if (obj != null) {
}
return obj;

Even if isInstance() is not folded we don't need to generate uncommon 
trap for obj == null case:

if (obj != null) {
    if (!isInstance(obj)) {
       uncommon_trap(); // or throw code
    }
}
return obj;

One benefit from having uncommon trap is it could be converted to 
implicit null check by folding it into a following memory instruction 
(load or store). In Class.cast() we don't have such memory instruction 
so we don't benefit from uncommon trap.

The fix is rise probability of not-taken path to avoid generation of 
uncommon trap when processing ifnull bytecode in Class.cast method.

Tested with JPRT, jtreg

Thanks,
Vladimir


More information about the hotspot-compiler-dev mailing list