[9] RFR(S): 8173373: C1: NPE is thrown instead of LinkageError when accessing inaccessible field on NULL receiver

Tobias Hartmann tobias.hartmann at oracle.com
Fri Jan 27 16:04:35 UTC 2017


Hi,

please review the following patch:
https://bugs.openjdk.java.net/browse/JDK-8173373

An unresolved field access on a null receiver throws a NPE instead of a NoClassDefFoundError if the method is compiled by C1.

The problem is that C1 inserts the null check before the field access that gets patched at runtime. The PatchingStub that would throw a NoClassDefFoundError is only executed after the null check:

  0x00007efc985eb2ec: movabs $0x0,%rsi          ;   {oop(NULL)}
  0x00007efc985eb2f6: cmp    (%rsi),%rax        ; implicit exception: dispatches to 0x00007efc985eb312
  [some nops]
  0x00007efc985eb300: jmpq   0x00007efc985eb415  ; implicit exception: dispatches to 0x00007efc985eb38e
  0x00007efc985eb305: nop                       ;*getfield f {reexecute=0 rethrow=0 return_oop=0}
                                                ; - compiler.c1.TestUnresolvedField::test at 1

The jmpq jumps to the PatchingStub and is patched at runtime to a mov (see Runtime1::patch_code) with the correct field offset.

I think there are multiple ways to fix this:

1) We could omit the explicit null check when the receiver is unresolved at compile time and only insert the check after patching. This is complex and would require lots of changes to the patching code.

2) We could deoptimize if the class is not loaded and the receiver is null by setting CodeEmitInfo::_deoptimize_on_exception = true for the load:
http://cr.openjdk.java.net/~thartmann/8173373/webrev.00/
This has the disadvantage that we call Runtime1::predicate_failed_trap() which sets the nmethod to non-entrant.

3) We could emit an explicit null check if the receiver is not resolved at compile time and call the deoptimize stub with Action_none if the check fails:
http://cr.openjdk.java.net/~thartmann/8173373/webrev.01/
This way we don't make the nmethod non-entrant but have an explicit instead of an implicit null check.

What do you think?

Tested with regression test and RBT (running).

Thanks,
Tobias


More information about the hotspot-compiler-dev mailing list