Redundant dereferences in C2 shenandoah_wb?
Aleksey Shipilev
ashipile at redhat.com
Wed Sep 7 12:32:50 UTC 2016
AFAIU, implicit NPE checks are prepared on a higher level, e.g. at
GraphKit::null_check, which sets up uncommon_trap with appropriate
dependencies. Placing a lowered memory access in .ad does not yield an
implicit null check, this is just a potential SEGV.
Anyhow, I see the null check before emitting the ShenandoahWriteBarrier
in GraphKit::shenandoah_write_barrier:
Node* not_null_obj = null_check_oop(obj, &null_ctrl);
...
Node* n = shenandoah_write_barrier_helper(*this, not_null_obj, adr_type);
...
static Node* shenandoah_write_barrier_helper(GraphKit& kit, Node* obj,
const TypePtr* adr_type) {
ShenandoahWriteBarrierNode* wb = new
ShenandoahWriteBarrierNode(kit.control(), kit.memory(adr_type), obj);
...
}
Therefore it seems we already have null pointer checks at the high-level
IR before the barrier, and having a dereference in barrier low-level
encoding still feels redundant. I must be missing something!
Thanks,
-Aleksey
On 09/07/2016 02:01 PM, Roman Kennke wrote:
> The compiler can replace explicit null checks with implicit null
checks, and rely on the first instruction of the wb (or any load or
store for that matter) blowing a SIGSEGV. I suppose this happens when
the compiler figures that null is rare or impossible.
>
> RomanAm 07.09.2016 12:41 nachm. schrieb Aleksey Shipilev <ashipile at redhat.com>:
>>
>> Wait a minute, can you elaborate the scenario where we want to intercept
>> null there? Because this code:
>>
>> @Benchmark
>> @CompilerControl(CompilerControl.Mode.DONT_INLINE)
>> public void storeToNull() {
>> try {
>> targetNull.field = null;
>> } catch (NullPointerException e) {
>> // expected
>> }
>> }
>>
>> static class Target {
>> Object field;
>> }
>>
>> ...triggers NPE much earlier (look for "WHY THIS CHECK?"):
>> http://cr.openjdk.java.net/~shade/shenandoah/wb.deref.1/storeToNull.perfasm
>>
>> How could that check fire a SEGV, if we already tested %r11 is not null?
>> I assume this is universal, and we nullcheck before doing shenandoahWB code?
>>
>> Thanks,
>> -Aleksey
>>
>> On 09/07/2016 01:10 PM, Roman Kennke wrote:
>>> The first is only there to trigger a SIGSEGV/NPE on null. The 2nd
>>> absolutely needs to come after the check for evacuation in progress
>>> to avoid a load load race at the end of evacuation. I don't think it
>>> affects performance much. If you have a solution to trigger NPE
>>> correctly on the 2nd instruction and not only the first (e.g. improve
>>> the signal handling), that would be very welcome!
>>>
>>> Cheers, RomanAm 07.09.2016 12:01 nachm. schrieb Aleksey Shipilev
>>> <ashipile at redhat.com>:
>>>>
>>>> Hi,
>>>>
>>>> I am studying the generated code for Shenandoah barriers. These two
>>>> dereferences seem excessive:
>>>> http://cr.openjdk.java.net/~shade/shenandoah/wb.deref.1/webrev.00/
>>>>
>>>>
>>>> C1 and interpreter code for both x86_64 and AArch64 do not seem to
>>>> do the additional read barrier before testing
>>>> evacuation_in_progress, doing that only after. Am I missing
>>>> something?
>>>>
>>>> Thanks, -Aleksey
More information about the shenandoah-dev
mailing list