Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optimize primitive unboxing method calls #18794

Merged
merged 1 commit into from
Apr 1, 2024

Conversation

jmesyou
Copy link
Contributor

@jmesyou jmesyou commented Jan 22, 2024

Boxed primitive classes have a method that unboxes their value, which are implemented as simple getter methods. These methods are marked as @IntrinsicCandidates, intended for simplification by the compiler.

This commit recognizes the primitive unboxing methods and generates simplified IL during IL generation instead of emitting the call where possible.

@jmesyou jmesyou requested a review from dsouzai as a code owner January 22, 2024 22:50
@0xdaryl
Copy link
Contributor

0xdaryl commented Jan 23, 2024

Doing it this way will still consume inliner budget if I'm not mistaken (@nbhuiyan, please keep me honest).

I wonder if it would be better to recognize and inline these simple methods during ILGen by genInvoke() instead (see plenty of other cases in that function where we do this). That way, the inliner never has to consider them at all.

TR_J9ByteCodeIlGenerator::genInvoke(TR::SymbolReference * symRef, TR::Node *indirectCallFirstChild, TR::Node *invokedynamicReceiver)

@nbhuiyan
Copy link
Member

Yes, methods under alwaysWorthInlining would have their inlineable status protected through most conditions that would have otherwise eliminated them, such as when the callee size exceeds some threshold. @jmesyou , if by reducing load from the inliner you meant to have these methods not consume inlining budget, then each of these methods would need special handling in TR_MultipleCallTargetInliner::weighCallSite or EstimateCodeSize to adjust their size/weight and not compete with other methods for the inlining budget. Preferably, if these can be handled in genInvoke as Daryl suggested, then none of that will be necessary.

@jmesyou jmesyou force-pushed the intrinsics/unboxing branch 2 times, most recently from 5d3d93a to a39adc7 Compare January 26, 2024 18:32
@jmesyou jmesyou changed the title Always inline primitive unboxing methods Optimize primitive unboxing method calls Jan 26, 2024
@jmesyou
Copy link
Contributor Author

jmesyou commented Jan 26, 2024

I was able to move this optimization into the ILGen phase during genInvoke. Instead of emitting the method call during ILGen, if the known field for the boxed value can be found in the class block, a corresponding load of the field and null check of the receiver is emitted instead of the call. If the field doesn't exist for whatever reason, the implementation changes in the future, the call is emitted instead.

Copy link
Member

@hzongaro hzongaro left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the changes look good overall. Just one minor issue that trips up some compilers.

runtime/compiler/ilgen/Walker.cpp Outdated Show resolved Hide resolved
runtime/compiler/ilgen/Walker.cpp Show resolved Hide resolved
runtime/compiler/ilgen/Walker.cpp Outdated Show resolved Hide resolved
runtime/compiler/ilgen/Walker.cpp Outdated Show resolved Hide resolved
runtime/compiler/ilgen/Walker.cpp Outdated Show resolved Hide resolved
runtime/compiler/ilgen/Walker.cpp Outdated Show resolved Hide resolved
runtime/compiler/ilgen/Walker.cpp Outdated Show resolved Hide resolved
Copy link
Member

@hzongaro hzongaro left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops! Accidentally approved when I hadn't intended to.

@hzongaro hzongaro self-requested a review January 27, 2024 16:16
@jmesyou jmesyou force-pushed the intrinsics/unboxing branch from a39adc7 to aac6a8e Compare January 29, 2024 19:47
@jmesyou
Copy link
Contributor Author

jmesyou commented Jan 29, 2024

@hzongaro ready for another pass

Copy link
Member

@hzongaro hzongaro left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the changes look good - just one cosmetic change request. Otherwise approved. Thanks!

runtime/compiler/ilgen/Walker.cpp Outdated Show resolved Hide resolved
@jmesyou jmesyou force-pushed the intrinsics/unboxing branch from aac6a8e to 9ab9c24 Compare January 30, 2024 21:36
@jmesyou jmesyou requested a review from hzongaro January 30, 2024 21:36
@hzongaro
Copy link
Member

Jenkins test sanity all jdk8,jdk11,jdk17,jdk21

Copy link
Member

@hzongaro hzongaro left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good.

@hzongaro
Copy link
Member

Looks like at least some of the build failures are real. For example, from the JDK 11 PPC64LE build:

17:57:09  __kernel_sigtramp_rt64+0x0 (0x0000100000050478)
17:57:09  _ZN9TR_Memory19allocateStackMemoryEmN13TR_MemoryBase10ObjectTypeE+0x28 (0x00001000016CAF58 [libj9jit29.so+0x6daf58])
17:57:09  _ZN15TR_VMFieldsInfoC1EPN2TR11CompilationEP7J9Classi17TR_AllocationKind+0x114 (0x0000100001217C84 [libj9jit29.so+0x227c84])
17:57:09  _ZN2J98ClassEnv15enumerateFieldsERN2TR6RegionEP19TR_OpaqueClassBlockPNS1_11CompilationE+0x508 (0x0000100001214098 [libj9jit29.so+0x224098])
17:57:09  _ZN3OMR11Compilation10typeLayoutEP19TR_OpaqueClassBlock+0xc4 (0x00001000016B5334 [libj9jit29.so+0x6c5334])
17:57:09  _ZL21createLoadFieldSymRefPN2TR11CompilationEP19TR_OpaqueClassBlockPKcb+0x50 (0x00001000012FC740 [libj9jit29.so+0x30c740])
17:57:09  _ZN24TR_J9ByteCodeIlGenerator9genInvokeEPN2TR15SymbolReferenceEPNS0_4NodeES4_+0x1d14 (0x0000100001317AA4 [libj9jit29.so+0x327aa4])
17:57:09  _ZN24TR_J9ByteCodeIlGenerator16genInvokeVirtualEi+0x154 (0x000010000131C624 [libj9jit29.so+0x32c624])
17:57:09  _ZN24TR_J9ByteCodeIlGenerator6walkerEPN2TR5BlockE+0x2594 (0x0000100001323244 [libj9jit29.so+0x333244])
17:57:09  _ZN24TR_J9ByteCodeIlGenerator18genILFromByteCodesEv+0x3f8 (0x00001000012F27A8 [libj9jit29.so+0x3027a8])
17:57:09  _ZN24TR_J9ByteCodeIlGenerator13internalGenILEv+0x288 (0x00001000012F4788 [libj9jit29.so+0x304788])
17:57:09  _ZN24TR_J9ByteCodeIlGenerator5genILEv+0x78 (0x00001000012F4BD8 [libj9jit29.so+0x304bd8])

@jmesyou jmesyou force-pushed the intrinsics/unboxing branch from 9ab9c24 to 133548e Compare January 31, 2024 23:30
@jmesyou jmesyou force-pushed the intrinsics/unboxing branch from 133548e to 6e2c273 Compare February 1, 2024 15:32
@jmesyou
Copy link
Contributor Author

jmesyou commented Feb 1, 2024

Internal build #20439 passing after a check was inserted to check that loading a class from a signature did not result in NULL. Also, this optimization can now be disabled by TR_DisableIntrinsics

@jmesyou jmesyou force-pushed the intrinsics/unboxing branch from 6e2c273 to 8ea3390 Compare February 1, 2024 16:03
Copy link
Member

@hzongaro hzongaro left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the changes look correct. Just a couple of minor comments.

runtime/compiler/ilgen/Walker.cpp Show resolved Hide resolved
runtime/compiler/ilgen/Walker.cpp Outdated Show resolved Hide resolved
Copy link
Member

@hzongaro hzongaro left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! Thanks for the changes.

@hzongaro hzongaro self-assigned this Feb 8, 2024
@hzongaro
Copy link
Member

hzongaro commented Feb 8, 2024

@0xdaryl, if you're satisfied with the changes, I'll run PR testing.

@hzongaro
Copy link
Member

Jenkins test sanity all jdk8,jdk11,jdk17,jdk21

@hzongaro
Copy link
Member

@jmesyou, it looks like there are some test failures for JDK 8, JDK 17 and JDK 21, all on Windows. May I ask you to investigate?

The JDK 21 AIX test build failure appears to be infrastructure-related.

Boxed primitive classes have a method that unbox their value,
implemented as simple getter methods. These methods are marked
as @IntrinsicCandidates, intended for simplification by the compiler.

This commit recognizes the primitive unboxing methods and generates the
equivalent optimized IL during IL generation.
This is intended to remove load off of analysis during the inlining
phase.

Signed-off-by: James You <[email protected]>
@jmesyou jmesyou force-pushed the intrinsics/unboxing branch from fe7ab76 to 83fc28c Compare March 28, 2024 15:11
@hzongaro
Copy link
Member

@jmesyou, it looks like there are some test failures for JDK 8, JDK 17 and JDK 21, all on Windows. May I ask you to investigate?

I strongly suspect these failures might have been caused by the uncoordinated merges of #18876 and eclipse-omr/omr#7247 that I performed the same day that I kicked off the pull request testing in my comment above. My apologies for not noticing sooner!

Jenkins test sanity all jdk8,jdk11,jdk17,jdk21

@hzongaro
Copy link
Member

Failure in s390x_linux JDK 17 testing appears to be due to issue #17844.

Failure in x86-64_mac JDK 21 testing appears to be infrastructure-related. Restarting.

Jenkins test sanity xmac jdk21

@hzongaro hzongaro merged commit de1950c into eclipse-openj9:master Apr 1, 2024
66 of 67 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants