[PATCH] 8202414: Unsafe crash in C2

Andy Law 944797358 at qq.com
Tue Sep 11 11:16:10 UTC 2018


Hi Lutz,

Nice summary and I totally agree with your points.

Thanks,
Andy

> On Sep 11, 2018, at 18:43, Schmidt, Lutz <lutz.schmidt at sap.com> wrote:
> 
> Hi Andy, 
> 
> unfortunately, we have two mail thread heads on the same topic. So I will try to give a very brief summary: 
> 
>  -  I agree, it's not your fault. The "user" is InitializeNode::complete_stores().
>  -  clear_memory() is not prepared to handle unaligned (less than BytesPerInt) offsets.
>  -  Your patch just leaves the memory uninitialized in case of unaligned offsets.
>  -  Vladimir's patch fixes the root cause, i.e. the caller of clear_memory().
>  -  Your patch removes the safety net from clear_memory(). Another reason why I don't like it.
> 
> In essence, I suggest to go with Vladimir's patch, provided the tests Vladimir requested work out ok: 
> 
> ---BEGIN Vladimir's patch ---
> diff -r b9f6a4427da9 src/hotspot/share/opto/memnode.cpp
> --- a/src/hotspot/share/opto/memnode.cpp
> +++ b/src/hotspot/share/opto/memnode.cpp
> @@ -4095,10 +4095,11 @@
>        // See if this store needs a zero before it or under it.
>        intptr_t zeroes_needed = st_off;
> 
> -      if (st_size < BytesPerInt) {
> +      if (st_size < BytesPerInt || (zeroes_needed % BytesPerInt) != 0) {
>          // Look for subword stores which only partially initialize words.
>          // If we find some, we must lay down some word-level zeroes first,
>          // underneath the subword stores.
> +        // Do the same for unaligned stores.
>          //
>          // Examples:
>          //   byte[] a = { p,q,r,s }  =>  a[0]=p,a[1]=q,a[2]=r,a[3]=s
> ---END Vladimir's patch ---
> 
> BTW, I requested to be precise, so I have to correct myself. The length field of ArrayOop is at offset 12 (@klass_gap_offset_in_bytes()) only if UseCompressedClassPointers is true. It does not depend on UseCompressedOops.
> 
> Thanks,
> Lutz
> 
> From: Andy Law <944797358 at qq.com>
> Date: Tuesday, 11. September 2018 at 02:36
> To: "hotspot-compiler-dev at openjdk.java.net" <hotspot-compiler-dev at openjdk.java.net>, Lutz Schmidt <lutz.schmidt at sap.com>, "aph at redhat.com" <aph at redhat.com>
> Subject: Re: [PATCH] 8202414: Unsafe crash in C2
> 
> Hi Lutz and Andrew, 
> 
> Thank you for your reply and sorry for my typos :)
> 
> TL;DR
> I think it is the optimization of `clear_memory()`which cause this problem, in my understanding it may not be a user fault :)
> 
> When running the example on the bug list using `-XX:DisableIntrinsic=_putInt`, or use interpreter/C1 only will make this problem go away, due to the fact that program will go to another branch.
> 
> In function `clear_memory()`, it will make an optimization which will clear the context of the memory, in fact
> 
>     if (done_offset > start_offset) {  // [1]
>         // it will clear the memory from start_offset to done_offset
>     }
> 
>     if (done_offset < end_offset) {  // [2]
>         // it will clear the memory by using a Int (0) to clear the memory of done_offset
>     }
> 
> |<--------------- 16-byte header —--——>| <—— 4-byte arr length (new byte[397]) ———>
>                                                               |       0000     0001     1000     1101     |
> If it is aligned, it won’t have any problem but, if it is not aligned as the example, this optimization will mis-clear the `0000 0001` to `0000 0000`, so the array length becomes 141. Then it will crash when gc happens.
> 
> It is the optimization which cause this problem, so when it is not aligned, we don’t do this optimization for this unaligned address may solve the problem.
> By the way I didn’t find the unaligned message on the doc:( but I think you’re right and it should be aligned when using Unsafe, though it is an deprecated API :) It won’t be reproduced using the templateInterpreter or C1 compiler, due to the fact that they won’t do this optimization.
> 
> Thank you:),
> Andy
> 





More information about the hotspot-compiler-dev mailing list