Unsafe vs MemorySegments / Bounds checking...

Brian S O'Neill bronee at gmail.com
Wed Oct 30 14:42:22 UTC 2024


Well, there's these inlining failures in FFM:

@ 6   jdk.internal.foreign.AbstractMemorySegmentImpl::<init> (21 bytes) 
  force inline by annotation
   @ 1   java.lang.Object::<init> (1 bytes)   failed to inline: inlining 
too deep


@ 7   jdk.internal.foreign.AbstractMemorySegmentImpl::reinterpret (14 
bytes)   failed to inline: callee uses too much stack


@ 10   java.lang.invoke.VarHandleSegmentAsChars::checkSegment (24 bytes) 
   force inline by annotation
   @ 1   java.util.Objects::requireNonNull (14 bytes)   force inline by 
annotation
     @ 8   java.lang.NullPointerException::<init> (5 bytes)   failed to 
inline: don't inline Throwable constructors





On 2024-10-30 07:18 AM, Maurizio Cimadamore wrote:
> Adding Vlad here.
> 
> In general this has always been a "known" issue with hotspot inlining - 
> there are cases where we _know_ the resulting assembly is gonna be very 
> good, but it takes a lot of work to get there, and the transient 
> compilations might yield something that is too big - which means JIT 
> will "give up".
> 
> This is why, AFAIU, method handles and var handles call are able to use 
> a deeper inlining treshold compared to regular method calls (because if 
> a MH or VH callsite can be inlined, the theory is that once we're done, 
> the resulting assembly will be quite small).
> 
> Failure to inline has effects on different areas - the most egregious 
> ones being escape analysis: if an object is passed to an out of line 
> call, then it MUST be allocated.
> 
> Summing up --- inlining heuristics are complex and can misbehave. And 
> when they do misbehave some performance loss can occur, which seems to 
> be the case here.
> 
> FFM-wise, the important thing is that all the paths that originates from 
> a VarHandle::get/set call are inlined as expected. If that is already 
> the case (and we have many benchmarks to make sure that's the case -- 
> but of course there could be corners we don't know about), then there's 
> not much else our implementation can do on that front.
> 
> That's not to say that that 2% will always stay there. In the past we 
> have raised the inlining depth for MH/VH calls, so, perhaps, with enough 
> evidence that trick can be applied again. Or, perhaps someday some 
> better inlining heuristics will replace the existing ones and overcome 
> some of the limitations with the current approach. It seems to me one of 
> those cases where "with time, things will get better" (as it's often the 
> case with the JVM).
> 
> (But if you find any evidence that the code failing to inline belongs to 
> FFM, that's something we might try and have a look at)
> 
> Maurizio
> 
> 
> On 30/10/2024 14:06, Brian S O'Neill wrote:
>> I was able to force inlining on a few key methods, and this appears to 
>> have improved performance a bit more, but inlining isn't always 
>> complete. Sometimes it gives up with messages like, "inlining too 
>> deep", "callee uses too much stack", and "don't inline Throwable 
>> constructors".
>>
>> When inlining does work, the chain of method calls is 73, but the 
>> equivalent Unsafe chain is only 5. This might explain why Unsafe 
>> inlining usually works -- it's much shorter.
>>
>> The inlining output will get screwed up in an email, so I pasted it here:
>>
>> https://urldefense.com/v3/__https://gist.github.com/broneill/ 
>> f1cd899ea7385acc26f23ef98070bb16__;!!ACWV5N9M2RV99hQ! 
>> MHEAnNQv3JjEMtuNRWZWKhMY1XB- 
>> PvTLJOQfXiQSkBFarqvRwUEnlM6vGiFwv5K1qmMvFspzebVf2Xu9LOZ5fQ$
>> One thing I find shocking is that when the method is inlined, the 
>> entire chain is processed again, every single time. There's no smaller 
>> intermediate representation being generated.
>>
>> When inlining is partial, one of the methods it skips is 
>> "java.lang.Object::<init> (1 bytes)   failed to inline: inlining too 
>> deep".  Will this subsequently prevent escape analysis from 
>> eliminating an unnecessary allocation?
>>
>> Inlining also fails sometimes with this message: "failed to inline: 
>> size > DesiredMethodLimit". The long method chain should ideally 
>> collapse into a single machine instruction, but if the intermediate 
>> representation is too large, is HotSpot just giving up?
>>
>>
>> On 2024-10-29 05:43 PM, Jorn Vernee wrote:
>>> On 29-10-2024 20:22, Brian S O'Neill wrote:
>>>>
>>>>>
>>>>> If you have a better benchmark, or you can pin point the exact 
>>>>> place where the inlining failure occurs that would help immensely. 
>>>>> You can play around with CompileCommand and force inline for 
>>>>> specific methods of your application. (perhaps after verifying that 
>>>>> such methods are not inlined, which you can verify with -XX: 
>>>>> +PrintInlining).
>>>>>
>>>>
>>>> How do I force inlining? I thought this was only possible the 
>>>> internal HotSpot annotation.
>>>
>>>
>>> See the output of 'java -XX:CompileCommand=help' (look at the output 
>>> before the standard help message). To force inlining of a method into 
>>> other compilation units you would use something like `- 
>>> XX:CompileCommand=inline,xyz.MyClass::myMethod`.
>>>
>>> Jorn
>>>
>>



More information about the panama-dev mailing list