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

Improve linkToVirtual() and linkToInterface() dispatch #17850

Merged
merged 2 commits into from
Aug 14, 2023

Conversation

jdmpapin
Copy link
Contributor

  • Remove the direct- and non-interface virtual-dispatch cases from linkToInterface() in the VM. They used to be needed, but they've been dead since 425a1f1.

  • Implement a recognized call transformation for linkToInterface(). The generated IL need only handle actual itable-based dispatch, and it does not introduce any control flow in the IL. This avoids doing a J2I transition whenever the callee is compiled.

  • Change jitLookupDynamicPublicInterfaceMethod (now used in the above-mentioned transformation) to take the MemberName instead of the interface class and iTable index. There's no need to generate IL to find them, since the helper can do that on its own. Cases where they are constant might get slightly slower, but the right way to improve those cases will be to refine and possibly inline linkToInterface().

  • Remove the direct-dispatch case from linkToVirtual() in the VM and in the IL generated by recognized call transformer. That case used to be needed, but like the removed linkToInterface() cases, it has been dead since 425a1f1.

  • Remove the interface-dispatch case from linkToVirtual() in the VM and in the IL generated by recognized call transformer. MemberName.vmindex is no longer a pointer to the J9JNIMethodID, but is now instead the vTable offset for invokevirtual, the iTable index for invokeinterface, and -1 for invokespecial and invokestatic. The interface dispatch case in linkToVirtual() used to occur whenever vmtarget was inherited from an interface. Now MemberName resolution/initialization detects that scenario and sets vmindex to the correct vTable offset for clazz so that linkToVirtual() can dispatch the call the same way as any other. Note that in combination with the previous point, this means that the linkToVirtual() recognized call transformation no longer introduces control flow into the IL.

  • Refine linkToVirtual() calls in inliner and method handle transformer even when vmtarget has been inherited from an interface. Virtual calls to such methods can occur naturally in the bytecode, and the compiler is able to deal with them.

  • Delete jitLookupDynamicInterfaceMethod, since it's no longer used.

@jdmpapin
Copy link
Contributor Author

Requesting review from @vijaysun-omr and @0xdaryl for JIT, and from @gacholio for VM

@gacholio
Copy link
Contributor

@babsingh Please look over the VM changes.

@gacholio gacholio requested a review from babsingh July 26, 2023 16:55
@jdmpapin
Copy link
Contributor Author

Pushed a slight correction to a comment

Copy link
Contributor

@gacholio gacholio 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 to me.

@jdmpapin
Copy link
Contributor Author

Rebased to fix the CommunicationStream::MINOR_NUMBER conflict

Copy link
Contributor

@babsingh babsingh left a comment

Choose a reason for hiding this comment

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

For functional verification, my recommendation is jekins test sanity.functional,extended.functional,sanity.system,sanity.openjdk,extended.openjdk alinux64 jdk17,jdk21 and a compile on Windows. Deliberate typo in jekins -> jenkins to avoid launching the PR builds.

runtime/oti/j9nonbuilder.h Outdated Show resolved Hide resolved
runtime/util/hshelp.c Outdated Show resolved Hide resolved
runtime/util/hshelp.c Show resolved Hide resolved
runtime/util/hshelp.c Outdated Show resolved Hide resolved
runtime/vm/BytecodeInterpreter.hpp Outdated Show resolved Hide resolved
runtime/util/hshelp.c Outdated Show resolved Hide resolved
runtime/util/hshelp.c Outdated Show resolved Hide resolved
runtime/util/hshelp.c Outdated Show resolved Hide resolved
runtime/oti/util_api.h Outdated Show resolved Hide resolved
runtime/oti/util_api.h Outdated Show resolved Hide resolved
@babsingh
Copy link
Contributor

@fengxue-IS Can you please also review the MethodHandleNatives and associated changes?

@babsingh babsingh requested a review from fengxue-IS July 27, 2023 20:18
@jdmpapin
Copy link
Contributor Author

Pushed changes to address review comments

@0xdaryl
Copy link
Contributor

0xdaryl commented Jul 29, 2023

JIT changes look ok after my first pass through.

Copy link
Contributor

@babsingh babsingh left a comment

Choose a reason for hiding this comment

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

LGTM.

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.

JITServer related changes look good.

@gacholio
Copy link
Contributor

gacholio commented Aug 2, 2023

jenkins compile win jdk8,jdk21

@gacholio
Copy link
Contributor

gacholio commented Aug 2, 2023

jenkins test sanity.functional,extended.functional,sanity.system,sanity.openjdk,extended.openjdk alinux64 jdk17,jdk21

@jdmpapin
Copy link
Contributor Author

jdmpapin commented Aug 2, 2023

Taking a look at what's going on with this on AArch64

@jdmpapin
Copy link
Contributor Author

jdmpapin commented Aug 2, 2023

Corrected the number of parameters for jitLookupDynamicPublicInterfaceMethod in *nathelp.m4. I looked for changes specific to AArch64, and the only such change was in arm64nathelp.m4, where I noticed that the parameter count was wrong. Since it was that way on every platform, I'm surprised it didn't cause more widespread failures, but I'm hoping anyway that it was the cause of the AArch64 failures in the PR build

@jdmpapin
Copy link
Contributor Author

jdmpapin commented Aug 2, 2023

Oh, I missed that tests in the PR builds had been running only on AArch64 to begin with

@jdmpapin jdmpapin marked this pull request as draft August 2, 2023 19:34
@jdmpapin
Copy link
Contributor Author

jdmpapin commented Aug 2, 2023

I'm doing some additional testing. Converted to draft in the meantime

@jdmpapin
Copy link
Contributor Author

jdmpapin commented Aug 3, 2023

OK, sorry for the confusion here. Because there had been so many failures, all on AArch64, and because I hadn't realized it was running only on AArch64 to begin with, I assumed that I had caused the failures, but after looking through them now I think they're unrelated to my changes.

We have these two known issues:

All of the remaining failures were in DatagramChannel, which I think is due to some kind of machine/network problem. Not everything has already been captured verbatim in an issue, but I've done my best to link to similar failures where possible. It seems to me that we don't run extended.openjdk very often.

Additionally, there were no crashes, but I expect that any failures caused by this PR would likely be crashes.

@jdmpapin jdmpapin marked this pull request as ready for review August 3, 2023 17:59
@gacholio
Copy link
Contributor

gacholio commented Aug 3, 2023

jenkins test sanity.functional,extended.functional,sanity.system,sanity.openjdk,extended.openjdk zlinux jdk17,jdk21

@gacholio
Copy link
Contributor

gacholio commented Aug 3, 2023

The test failures look like a GIT issue. I don't know how to restart the jobs without relaunching.

@pshipton
Copy link
Member

pshipton commented Aug 3, 2023

You look at https://openj9-jenkins.osuosl.org/job/Pipeline_Build_Test_JDK17_s390x_linux/1702/console and there are "Restart or Abort" links. I've restarted them.

@jdmpapin
Copy link
Contributor Author

jdmpapin commented Aug 4, 2023

Test_openjdk21_j9_sanity.functional_s390x_linux_Personal

  • testList_0 passed
  • testList_1 failed to fetch origin/pr/17850/merge ("the remote end hung up unexpectedly")

Test_openjdk21_j9_extended.functional_s390x_linux_Personal

  • testList_0 passed
  • testList_1 failed to fetch again

Test_openjdk21_j9_sanity.openjdk_s390x_linux_Personal

  • failed to fetch

Test_openjdk17_j9_extended.openjdk_s390x_linux_Personal:

  • security/infra/java/security/cert/CertPathValidator/certification/AmazonCA.java.AmazonCA: certificate revoked (as before)
  • com/sun/jndi/dns/ConfigTests/Timeout.java.Timeout: DNS error [... No route to host]

Test_openjdk21_j9_extended.openjdk_s390x_linux_Personal

  • AmazonCA again
  • SSLSocketParametersTest: java.rmi.NoSuchObjectException: no such object in table (as before)

The Restart links that Peter mentioned don't seem to be working for me, maybe because the Pipeline_Build_Test_... jobs have finished? For the ones that hit network errors with git, I'll restart them here

@jdmpapin
Copy link
Contributor Author

jdmpapin commented Aug 4, 2023

Jenkins test sanity.functional,extended.functional,sanity.openjdk zlinux jdk21

@jdmpapin
Copy link
Contributor Author

jdmpapin commented Aug 9, 2023

In extended.functional, there was one failure. It's a timeout when testing -XX:+ExitOnOutOfMemoryError:

Testing: Verify -XX:+ExitOnOutOfMemoryError behaves as expected with OutOfMemoryError
Test start time: 2023/08/04 20:17:28 Coordinated Universal Time
Running command: "/home/jenkins/workspace/Test_openjdk21_j9_extended.functional_s390x_linux_Personal_testList_0/openjdkbinary/j2sdk-image/bin/java"   -Xdump -Xmx64m -XX:+ExitOnOutOfMemoryError -cp "/home/jenkins/workspace/Test_openjdk21_j9_extended.functional_s390x_linux_Personal_testList_0/aqa-tests/TKG/../../jvmtest/functional/cmdLineTests/cmdLineTest_J9tests/cmdLineTest_J9tests.jar" OnOutOfMemoryErrorTest
Time spent starting: 1 milliseconds
***[TEST INFO 2023/08/04 20:27:28] ProcessKiller detected a timeout after 600000 milliseconds!***

I believe this is #13722


In sanity.openjdk there was also just one failure, which was a crash in OOMEInAQS:

[2023-08-04T22:18:40.450Z] JVMDUMP013I Processed dump event "systhrow", detail "java/lang/OutOfMemoryError".
[2023-08-04T22:18:40.450Z] Exception in thread "Attach API wait loop" java/lang/OutOfMemoryError: Java heap space
[2023-08-04T22:18:40.450Z] 	at java/lang/Throwable.printStackTrace (java.base@21-internal/Throwable.java:554)
[2023-08-04T22:18:40.450Z] 	at java/lang/Throwable.printStackTraceHelper (java.base@21-internal/Throwable.java:338)
[2023-08-04T22:18:40.450Z] 	at java/lang/Throwable.printStackTrace (java.base@21-internal/Throwable.java:307)
[2023-08-04T22:18:40.450Z] 	at java/lang/Throwable.printStackTrace (java.base@21-internal/Throwable.java:250)
[2023-08-04T22:18:40.450Z] STATUS:Passed.
[2023-08-04T22:18:40.450Z] Unhandled exception
[2023-08-04T22:18:40.450Z] Type=Segmentation error vmState=0x00040000

This one looks to be #16659


The other two failing checks are just the extended.openjdk tests that I described previously, since I didn't restart those.

@jdmpapin
Copy link
Contributor Author

jdmpapin commented Aug 9, 2023

I believe that all of the failures have been accounted for

@gacholio
Copy link
Contributor

gacholio commented Aug 9, 2023

Are we waiting for @0xdaryl to review?

@jdmpapin
Copy link
Contributor Author

jdmpapin commented Aug 9, 2023

Ah, yes, I think so

@0xdaryl
Copy link
Contributor

0xdaryl commented Aug 14, 2023

Please fix merge conflicts. Otherwise, looks good to me.

This code was duplicated in multiple methods of J9::TransformUtil.
- Remove the direct- and non-interface virtual-dispatch cases from
  linkToInterface() in the VM. They used to be needed, but they've been
  dead since 425a1f1.

- Implement a recognized call transformation for linkToInterface().
  The generated IL need only handle actual itable-based dispatch, and it
  does not introduce any control flow in the IL. This avoids doing a J2I
  transition whenever the callee is compiled.

- Change jitLookupDynamicPublicInterfaceMethod (now used in the above-
  mentioned transformation) to take the MemberName instead of the
  interface class and iTable index. There's no need to generate IL to
  find them, since the helper can do that on its own. Cases where they
  are constant might get slightly slower, but the right way to improve
  those cases will be to refine and possibly inline linkToInterface().

- Remove the direct-dispatch case from linkToVirtual() in the VM and in
  the IL generated by recognized call transformer. That case used to be
  needed, but like the removed linkToInterface() cases, it has been dead
  since 425a1f1.

- Remove the interface-dispatch case from linkToVirtual() in the VM and
  in the IL generated by recognized call transformer. MemberName.vmindex
  is no longer a pointer to the J9JNIMethodID, but is now instead the
  vTable offset for invokevirtual, the iTable index for invokeinterface,
  and -1 for invokespecial and invokestatic. The interface dispatch case
  in linkToVirtual() used to occur whenever vmtarget was inherited from
  an interface. Now MemberName resolution/initialization detects that
  scenario and sets vmindex to the correct vTable offset for clazz so
  that linkToVirtual() can dispatch the call the same way as any other.
  Note that in combination with the previous point, this means that the
  linkToVirtual() recognized call transformation no longer introduces
  control flow into the IL.

- Refine linkToVirtual() calls in inliner and method handle transformer
  even when vmtarget has been inherited from an interface. Virtual calls
  to such methods can occur naturally in the bytecode, and the compiler
  is able to deal with them.

- Delete jitLookupDynamicInterfaceMethod, since it's no longer used.
@jdmpapin
Copy link
Contributor Author

Rebased to fix the merge conflict with CommunicationStream::MINOR_NUMBER

Range diff

@gacholio gacholio merged commit 1b26a8c into eclipse-openj9:master Aug 14, 2023
TR_ASSERT(haveAccess(), "jniMethodIdFromMemberName requires VM access");
return (J9JNIMethodID *)J9OBJECT_U64_LOAD(vmThread(), memberName, vmThread()->javaVM->vmindexOffset);
}
*out = {};
Copy link
Contributor

Choose a reason for hiding this comment

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

This doesn't compile on z/OS:

13:10:07  "/jenkins/workspace/Build_JDK17_s390x_zos_Personal/openj9/runtime/compiler/env/VMJ9.cpp", line 4764.11: CCN5063 (S) The text "{" is unexpected.
13:10:07  CCN0793(I) Compilation failed for file /jenkins/workspace/Build_JDK17_s390x_zos_Personal/openj9/runtime/compiler/env/VMJ9.cpp.  Object file not created.
13:10:07  runtime/compiler/CMakeFiles/j9jit.dir/build.make:960: recipe for target 'runtime/compiler/CMakeFiles/j9jit.dir/env/VMJ9.cpp.o' failed
13:10:07  make[6]: *** [runtime/compiler/CMakeFiles/j9jit.dir/env/VMJ9.cpp.o] Error 12

@jdmpapin Is there another way to say this that will be accepted by older compilers?

Copy link
Contributor

Choose a reason for hiding this comment

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

Should it be {0} perhaps?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The text "{" is unexpected.

suggests that we might get the same error from {0}. I think {} should work as an initializer though. I'll try this:

MemberNameMethodInfo zero = {};
*out = zero;

and of course check to make sure that it compiles on z/OS

Copy link
Contributor Author

@jdmpapin jdmpapin Sep 7, 2023

Choose a reason for hiding this comment

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

It looks like it should work to use

MemberNameMethodInfo zero = {0};

With {}, the build compiler complained that zero was potentially uninitialized

My personal z/OS build failed for a reason I don't understand. I think it's unrelated, but I've asked for some help confirming that my change builds. I'll open a PR as soon as I get confirmation

Copy link
Contributor Author

Choose a reason for hiding this comment

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

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.

9 participants