[9] RFR [XS] 8054492: Casting can result in redundant null checks in generated code
Vladimir Kozlov
vladimir.kozlov at oracle.com
Wed Oct 22 00:02:06 UTC 2014
Here is intrinsic implementation:
http://cr.openjdk.java.net/~kvn/8054492/webrev.01/
It will only optimize (removes NULL check) if isInstance() can be
collapsed during parsing. NULL check will not be removed if types are
improved after parsing during igvn or CCP phases.
It is targeting only cases when object's class and Class's class are
known statically:
void testLoopOne(String s) {
ssink = String.class.cast(s);
ssink = (String) MH_CAST.invokeExact(String.class, s);
Paul, is it enough for you?
Thanks,
Vladimir
On 10/21/14 2:22 PM, Vladimir Kozlov wrote:
> You have valid point.
>
> When I changed the test to pass Object to testLoopOne() the NULL check
> with uncommon trap was folded into implicit NULL:
>
> 02c movl R10, [RDX + #8 (8-bit)] # compressed klass ptr
> 030 NullCheck RDX
> 030
> 030 B2: # B4 B3 <- B1 Freq: 0.999999
> 030 cmpl R10, narrowklass: precise klass java/lang/String:
> 0x00007fe7ba0367e0:Constant:exact * # compressed klass ptr
> 037 jne,u B4 P=0.000000 C=-1.000000
> 037
>
> So my original statement (no load in Class.cast()) was incorrect.
> With my changes it did not and it has more instructions generated.
>
> Also checkcast is placed on exit block - it dominates following code as
> you said.
>
> I will try intrinsic and see how it works. The problem with intrinsic we
> don't get profiling info from Class.cast() MDO. That is why I tried to
> avoid it.
>
> Thanks,
> Vladimir
>
> On 10/21/14 2:36 AM, Roland Westrelin wrote:
>>> 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.
>>
>> Another benefit is that if we compile the isInstance as an exact check
>> for a particular class, we can change the type of obj to that
>> particular class:
>>
>> if (obj.klass != myklass) {
>> uncommon_trap();
>> }
>>
>> // obj is of type myklass from here on
>>
>> If we don’t compile the null check as an uncommon trap we loose the
>> exact type:
>>
>> if (obj != null) {
>> if (obj.klass != myklass) {
>> uncommon_trap();
>> }
>>
>> // obj is of type myklass
>> }
>> // we don’t don’t know anything about obj’s type here
>>
>> Wouldn’t it be better to have an intrinsic for Class.cast where we
>> check whether the isInstance goes away entirely and then we don’t
>> compile the null check at all. Otherwise, we compile a null check with
>> an uncommon trap so we can propagate an exact type forward?
>>
>> Roland.
>>
More information about the hotspot-compiler-dev
mailing list