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

Allow inlining of java/lang/ref/Reference.refersTo method #13619

Merged
merged 3 commits into from May 4, 2023

Conversation

hzongaro
Copy link
Member

@hzongaro hzongaro commented Oct 4, 2021

The Reference.refersTo(Object) method, introduced in Java 16, tests whether the referent is the same object as the parameter. Some places in the JCL that used to perform comparisons of the referent using a call to Reference.get now use Reference.refersTo. That affects performance of such uses as Reference.get was implemented using a call to Reference.getImpl which the JIT compiler recognized and inlined if possible.

This change adds recognition of Reference.refersTo to the JIT, which will now inline a call to it under the same conditions as it would inline a call to Reference.getImpl.

In addition, there are several methods in the JIT that are used to record or test whether Reference.getImpl can be inlined. This change introduces duplicate methods that are used for the both getImpl and refersTo. References to the old methods that mention getImpl alone still exist in OMR and will be removed after this pull request is merged.

Resolves issue #13596

@hzongaro hzongaro requested review from mpirvu and removed request for mpirvu October 4, 2021 20:27
Copy link
Contributor

@mpirvu mpirvu left a comment

Choose a reason for hiding this comment

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

LGTM. I would like @0xdaryl or someone else from the opt team to review the new code from TR_J9VM::inlineNativeCall(), though.

Also, I know that the existing code tests if (comp->getGetImplInlineable()), but is that really necessary? Can't we query fe->getGetImplInlineable() directly and eliminate those accesors from the comp object?

@@ -6715,6 +6715,12 @@ TR_J9VM::classHasBeenReplaced(TR_OpaqueClassBlock * clazzPointer)

bool
TR_J9VMBase::isGetImplInliningSupported()
Copy link
Contributor

Choose a reason for hiding this comment

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

After delivering this PR, maybe we can change OMRCompilation.cpp to not use
self()->setGetImplInlineable(self()->fej9()->isGetImplInliningSupported()); anymore, so that we can eliminate TR_J9VMBase::isGetImplInliningSupported() and rely only on TR_J9VMBase::isGetImplAndRefersToInliningSupported()

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks, Marius @mpirvu. Yes - I have another pair of pull requests that I'll open to do that. One to change OMRCompilation.cpp, and another to remove the getImpl-specific methods from OpenJ9.

@hzongaro
Copy link
Member Author

hzongaro commented Oct 5, 2021

I'm just in the process of doing one last set of performance runs. Assuming that completes successfully, I'll move this PR from "draft" to "ready for review" status.

@hzongaro hzongaro marked this pull request as ready for review October 6, 2021 02:03
@hzongaro
Copy link
Member Author

hzongaro commented Oct 6, 2021

This fix appears to resolve the performance problem identified in issue #13596, so I'm marking it as ready for review.

The original benchmark I was analyzing still shows a performance regression when run with a JDK 17 build of OpenJ9 versus a JDK 11 build. I'll open a separate issue for that, once I've identified the reason.

@hzongaro hzongaro requested a review from 0xdaryl October 6, 2021 02:07
@hzongaro
Copy link
Member Author

hzongaro commented Oct 6, 2021

Daryl @0xdaryl, may I ask you to review, or can you suggest a reviewer?

@hzongaro
Copy link
Member Author

hzongaro commented Oct 6, 2021

Sorry for the churn. I've moved this back to draft status as I've seen an unexpected test failure.

The refersTo method was introduced to java.lang.ref.Reference in
Java 16.  The JIT compiler is able to inline the method under the same
conditions as it is able to inline Reference.getImpl.  This change
introduces new query methods and fields to check and record whether both
methods can be inlined.

The existing VM::isGetImplInliningSupported and
Compilation::setGetImplInlineable methods are invoked by OMR, so
they will remain in OpenJ9 until a subsequent pull request against OMR
replaces calls to those now obsolete methods.

Signed-off-by:  Henry Zongaro <zongaro@ca.ibm.com>
A Reference.refersTo(Object) method, introduced in Java 16, tests
whether the referent is the same object as the parameter.  Some
places in the JCL that used to perform comparisons of the referent using
Reference.get now use Reference.refersTo.  That affects performance of
such uses as Reference.get was implemented using a call to
Reference.getImpl which the JIT compiler recognized and inlined if
possible.

This change adds recognition of Reference.refersTo to the JIT, which
will now inline a call to it under the same conditions as it would
inline a call to Reference.getImpl.

Signed-off-by:  Henry Zongaro <zongaro@ca.ibm.com>
If TR_J9VM::inlineNativeCall fails to inline a method, it sometimes
returns NULL and sometimes returns the original call node.  If it
returns NULL and the call node is a JNI call, the caller considers
whether any special processing of the call node is required by calling
TR::Node::processJNICall.

In the case of Reference.refersTo, the call is not inlined if the
Metronome GC policy is in effect, but inlineNativeCall was returning the
original call node.  That signalled to the caller that no special
consideration of whether the call node was a JNI call was needed, but it
was in fact needed.

Fixed this by having TR_J9VM::inlineNativeCall return NULL if it is
unable to inline Reference.refersTo.

Signed-off-by:  Henry Zongaro <zongaro@ca.ibm.com>
@hzongaro hzongaro force-pushed the inline-reference-refersto branch from 399b27f to 97af55c Compare May 4, 2023 14:44
@hzongaro hzongaro marked this pull request as ready for review May 4, 2023 14:48
@hzongaro
Copy link
Member Author

hzongaro commented May 4, 2023

Eighteen months later. . . . I mentioned in an earlier comment that I had seen unexpected failures with my fix - those failures were seen with the Metronome gcpolicy.

I spent some time last week investigating those failures, and discovered that it had to do with how TR_J9VM::inlineNativeCall handles cases that it's unable to inline. That problem is fixed in commit 97af55c. The other two commits are essentially the same as they were in the original version of this pull request that Marius @mpirvu had reviewed. They're simply rebased onto the latest version of the OpenJ9 source, with merge conflicts resolved.

Here are performance results using the microbenchmark I mentioned in a comment in issue 13596 running with and without these changes in JDK 8 and JDK 17 - three runs of each. Higher numbers for "score" are better:

JDK 8 without the fix

  • ThreadLocalBench score: 96585128.000000 (96.59M 1838.6%)
  • ThreadLocalBench score: 95079560.000000 (95.08M 1837.0%)
  • ThreadLocalBench score: 94945608.000000 (94.95M 1836.9%)

JDK 17 without the fix

  • ThreadLocalBench score: 38396348.000000 (38.40M 1746.3%)
  • ThreadLocalBench score: 46301872.000000 (46.30M 1765.1%)
  • ThreadLocalBench score: 39043940.000000 (39.04M 1748.0%)

JDK 8 with the fix

  • ThreadLocalBench score: 95024704.000000 (95.02M 1837.0%)
  • ThreadLocalBench score: 92359720.000000 (92.36M 1834.1%)
  • ThreadLocalBench score: 92475136.000000 (92.48M 1834.2%)

JDK 17 with the fix

  • ThreadLocalBench score: 99357464.000000 (99.36M 1841.4%)
  • ThreadLocalBench score: 98060152.000000 (98.06M 1840.1%)
  • ThreadLocalBench score: 100043416.000000 (100.0M 1842.1%)

@0xdaryl
Copy link
Contributor

0xdaryl commented May 4, 2023

Jenkins test sanity all jdk8,jdk17

@0xdaryl 0xdaryl self-assigned this May 4, 2023
@0xdaryl
Copy link
Contributor

0xdaryl commented May 4, 2023

Jenkins test sanity aix jdk17

Previous failure is infrastructural.

@0xdaryl
Copy link
Contributor

0xdaryl commented May 4, 2023

CRIU test failure is infrastructural. I highly doubt that test has anything to do with the code in this PR.

@0xdaryl 0xdaryl merged commit 74c5450 into eclipse-openj9:master May 4, 2023
34 of 35 checks passed
@hzongaro hzongaro deleted the inline-reference-refersto branch May 5, 2023 13:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants