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