RFR(M): 8209134: [lworld] New nmethod entry point for unscalarized (nullable) value type arguments
Tobias Hartmann
tobias.hartmann at oracle.com
Wed Aug 8 16:39:34 UTC 2018
Hi,
please review the following patch:
https://bugs.openjdk.java.net/browse/JDK-8209134
http://cr.openjdk.java.net/~thartmann/8209134/webrev.00/
This patch adds a new entry point to nmethods that have a value type argument. This "Verified Value
Entry Point" jumps to the c2i adapter if any of the value type arguments is null. Like this, we can
avoid explicit null checks in the C2 IR which significantly reduces code size and complexity. More
important, we can now completely avoid null checking when calling from compiled code by using the
"normal" entry point. The "Verified Value Entry Point" is only used in the i2c adapter and the
method handle dispatch code (because both may pass NULL for a value type whereas compiled code never
passes NULL).
The nmethod entries for TestValueTypeEntryPoint.test1 now look like this:
[Verified Value Entry Point]
0x00007fc7751ffb60: test %rdx,%rdx
0x00007fc7751ffb63: je 0x00007fc7751ecc62 ; {runtime_call I2C/C2I adapters}
0x00007fc7751ffb69: test %rcx,%rcx
0x00007fc7751ffb6c: je 0x00007fc7751ecc62 ; {runtime_call I2C/C2I adapters}
[...]
0x00007fc7751ffbba: cmpq $0x0,0x20(%rsp)
0x00007fc7751ffbc3: je 0x00007fc7751ecc62 ; {runtime_call I2C/C2I adapters}
0x00007fc7751ffbc9: jmpq 0x00007fc7751ffbf0
[Entry Point]
0x00007fc7751ffbce: mov 0x8(%rsi),%r10d
0x00007fc7751ffbd2: movabs $0x800000000,%r12
0x00007fc7751ffbdc: add %r12,%r10
0x00007fc7751ffbdf: xor %r12,%r12
0x00007fc7751ffbe2: cmp %r10,%rax
0x00007fc7751ffbe5: jne 0x00007fc7750577a0 ; {runtime_call ic_miss_stub}
0x00007fc7751ffbeb: nop
0x00007fc7751ffbec: nop
0x00007fc7751ffbed: nop
0x00007fc7751ffbee: nop
0x00007fc7751ffbef: nop
[Verified Entry Point]
[...]
For details, compare the generated code with [1] and without [2] the patch. An unverified entry
point is not required because it's only called from compiled code (inline caches).
I also came up with branchless null checking using setne instructions:
[Verified Value Entry Point]
0x00007f7b89164540: xor %r13,%r13
0x00007f7b89164543: test %rdx,%rdx
0x00007f7b89164546: setne %r13b
0x00007f7b8916454a: dec %r13
0x00007f7b8916454d: test %rcx,%rcx
0x00007f7b89164550: setne %r13b
0x00007f7b89164554: dec %r13
[...]
0x00007f7b891645a5: cmpq $0x0,0x20(%rsp)
0x00007f7b891645ae: setne %r13b
0x00007f7b891645b2: dec %r13
0x00007f7b891645b5: jne 0x00007f7b8915f0e2 ; {runtime_call I2C/C2I adapters}
0x00007f7b891645bb: jmpq 0x00007f7b891645e0
But since I couldn't measure any performance difference, I went with the explicit checks.
All tests pass.
Thanks,
Tobias
[1] https://bugs.openjdk.java.net/secure/attachment/78094/TestValueTypeEntryPoint.log
[2] https://bugs.openjdk.java.net/secure/attachment/78095/TestValueTypeEntryPoint_Old.log
More information about the valhalla-dev
mailing list