Skip to content

8316186: RISC-V: Remove PlatformCmpxchg<4> #15715

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

Closed
wants to merge 3 commits into from

Conversation

robehn
Copy link
Contributor

@robehn robehn commented Sep 13, 2023

Hi, please consider.

I don't know the history behind the Cmpxhg<4>, but it is not needed anymore.
Using compiler as in 8 byte case is just fine.

Passes hotspot-tier (qemu, vf2 still running), some manual extra testing via gtest, looked at compiler: output, e.g. https://godbolt.org/z/a31Gdqn8q

If you know the history please share, and if you have a reason why we should keep it please speak up!


Progress

  • Change must be properly reviewed (1 review required, with at least 1 Reviewer)
  • Change must not contain extraneous whitespace
  • Commit message must refer to an issue

Issue

  • JDK-8316186: RISC-V: Remove PlatformCmpxchg<4> (Enhancement - P5)

Reviewers

Reviewing

Using git

Checkout this PR locally:
$ git fetch https://git.openjdk.org/jdk.git pull/15715/head:pull/15715
$ git checkout pull/15715

Update a local copy of the PR:
$ git checkout pull/15715
$ git pull https://git.openjdk.org/jdk.git pull/15715/head

Using Skara CLI tools

Checkout this PR locally:
$ git pr checkout 15715

View PR using the GUI difftool:
$ git pr show -t 15715

Using diff file

Download this PR as a diff file:
https://git.openjdk.org/jdk/pull/15715.diff

Webrev

Link to Webrev Comment

@bridgekeeper
Copy link

bridgekeeper bot commented Sep 13, 2023

👋 Welcome back rehn! A progress list of the required criteria for merging this PR into master will be added to the body of your pull request. There are additional pull request commands available for use with this pull request.

@openjdk openjdk bot added the rfr Pull request is ready for review label Sep 13, 2023
@openjdk
Copy link

openjdk bot commented Sep 13, 2023

@robehn The following label will be automatically applied to this pull request:

  • hotspot-runtime

When this pull request is ready to be reviewed, an "RFR" email will be sent to the corresponding mailing list. If you would like to change these labels, use the /label pull request command.

@openjdk openjdk bot added the hotspot-runtime hotspot-runtime-dev@openjdk.org label Sep 13, 2023
@mlbridge
Copy link

mlbridge bot commented Sep 13, 2023

Webrevs

@RealFYang
Copy link
Member

RealFYang commented Sep 13, 2023

The first instruction of the inline asm in this function will make a difference here.
It sign-extend the 32-bit input compare_value into 64-bit because the bne instruction compares 64-bit values.
Please note that we don't have 32-bit compare-and-branch instructions for RISC-V 64.
As I remembered, we once witnessed test failures if we use the compiler version. We could be passed 32-bit non-sign-extended compare_value vaules in certain cases.

 __asm__ __volatile__ (
    "1:  sext.w    %1, %3      \n\t" // sign-extend compare_value
    "    lr.w      %0, %2      \n\t"
    "    bne       %0, %1, 2f  \n\t"

@robehn
Copy link
Contributor Author

robehn commented Sep 14, 2023

So we basically have some rubbish in top 32 bits, we clear them, right.
And lr.w automatically sign extends, so old_value is fine.

Checking for when/where the bug was/is in tool-chain.

@robehn
Copy link
Contributor Author

robehn commented Sep 15, 2023

I asked around, there is no known bug.
And if there was a bug it can't be the " __atomic_compare_exchange" it self I was told.
"As per ABI, 32-bit quantities in 64-bit container have to be sign-extended"

The compare value is passed as pointer, the normal generate code is:
"lw a3,0(a5)"
"LW instruction loads a 32-bit value from memory and sign-extends this to 64 bits"

gcc 8.2 seems to generate the same code as gcc 13/tip.

@RealFYang
Copy link
Member

Try this test: make test TEST="test/hotspot/jtreg/gc/shenandoah/compiler/TestReferenceCAS.java"
It fails with this change:

java.lang.RuntimeException: a (foo) != b (bar): success compareAndSet Object value
        at TestReferenceCAS.assertEquals(TestReferenceCAS.java:93)
        at TestReferenceCAS.testAccess(TestReferenceCAS.java:115)
        at TestReferenceCAS.main(TestReferenceCAS.java:100)
        at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
        at java.base/java.lang.reflect.Method.invoke(Method.java:580)
        at com.sun.javatest.regtest.agent.MainWrapper$MainTask.run(MainWrapper.java:138)
        at java.base/java.lang.Thread.run(Thread.java:1570)

@robehn
Copy link
Contributor Author

robehn commented Sep 15, 2023

Try this test: make test TEST="test/hotspot/jtreg/gc/shenandoah/compiler/TestReferenceCAS.java" It fails with this change:

java.lang.RuntimeException: a (foo) != b (bar): success compareAndSet Object value
        at TestReferenceCAS.assertEquals(TestReferenceCAS.java:93)
        at TestReferenceCAS.testAccess(TestReferenceCAS.java:115)
        at TestReferenceCAS.main(TestReferenceCAS.java:100)
        at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
        at java.base/java.lang.reflect.Method.invoke(Method.java:580)
        at com.sun.javatest.regtest.agent.MainWrapper$MainTask.run(MainWrapper.java:138)
        at java.base/java.lang.Thread.run(Thread.java:1570)

But that test should be using MacroAssembler::cmpxchg_ ?

Testing whats wrong....

@robehn
Copy link
Contributor Author

robehn commented Sep 18, 2023

GC barrier may use that Atomic::cmpxchg, depending on compiled or not, etc, so that test uses this cmpxchg

The case we are talking seems to be the narrow oop.

According to RV calling convention specs:

In RV64, 32-bit types, such as int, are stored in integer registers as proper sign extensions of their
32-bit values; that is, bits 63..31 are all equal. This restriction holds even for unsigned 32-bit types

This means any 4-bytes passed in integer register must be sign extended by caller.
Now this method will be inline, but above must still be true.

I added this 'assert':

+  if (byte_size == 4) {
+    T tmp;
+    __asm__ __volatile__ (
+    "    sext.w    %0, %1      \n\t" // sign-extend
+    "    beq       %0, %1, 1f  \n\t"
+    "    ld        x0,(x0)     \n\t"
+    "    1:                    \n\t"
+    "                          \n\t"
+    : /*%0*/"=&r" (tmp)
+    : /*%1*/"r" (compare_value)
+    : "memory" );
+  }

And tested gcc 12 and 13, in qemu and on VF2 (gcc 12) it do not fire, hence I cannot reproduce.
If there is a bug it is not with __atomic_compare_exchange, since the value must already be sign extended.

AFAICT this extra sign extension is actually hiding a deeper bug!

Are you building with normal upstream gcc (12/13)?

This made me realize that the call_VM with Register must always be manually check for proper sign extension.

@RealFYang
Copy link
Member

RealFYang commented Sep 18, 2023

I agree with your understanding about RISC-V C/C++ ABI calling conversion. I am suspecting that this might be related how narrow oop are loaded for template interpreter, C1 and C2. Normally we use lwu to do that which does zero-extension instead of sign-extension for the low 32-bits. An example for C2 is [1]. Sign-extension for 32-bit narrow oop doesn't make much sense to me at first glance. But that's just a guess.

BTW: I am using native GCC-11.4.0 shipped with Ubuntu 22.04.3 LTS on Unmatched board. I can try GCC-12 later.

[1] https://github.com/openjdk/jdk/blob/master/src/hotspot/cpu/riscv/riscv.ad#L4684

@RealFYang
Copy link
Member

RealFYang commented Sep 19, 2023

PS: I can reproduce the test failure with GCC version 10 and 11. But it does not trigger with GCC 12. (GCC 13 is not shipped with the distro)
Note that I am using openjdk release build. It won't trigger if I use openjdk slowdebug build built with GCC 11.

@robehn
Copy link
Contributor Author

robehn commented Sep 19, 2023

This look like the bug you are hitting:

EDIT: Ignore above, was never meant to send that.

PS: I can reproduce the test failure with GCC version 10 and 11. But it does not trigger with GCC 12. (GCC 13 is not shipped with the distro) Note that I am using openjdk release build. It won't trigger if I use openjdk slowdebug build built with GCC 11.

I can't reproduce with gcc 11.4.0-1ubuntu1~23.04 (testing with fastdebug).
Trying with another gcc....

Can you add 'assert' code above and check hs_err which case this is?

@RealFYang
Copy link
Member

I can't reproduce with gcc 11.4.0-1ubuntu1~23.04 (testing with fastdebug). Trying with another gcc....

You might want to try openjdk release build from GCC 10 or 11.

Can you add 'assert' code above and check hs_err which case this is?

Yeah, I have added code change from this pull request and your 'assert' code and doing a native release build with GCC 11.

@RealFYang
Copy link
Member

Can you add 'assert' code above and check hs_err which case this is?

Yeah, I have added code change from this pull request and your 'assert' code and doing a native release build with GCC 11.

Turns out that the issue won't reproduce if adding your 'assert' code.
That is to say, it only triggers with openjdk release build built with this PR and GCC version 10 or 11 on my side.

@robehn
Copy link
Contributor Author

robehn commented Sep 20, 2023

Can you add 'assert' code above and check hs_err which case this is?

Yeah, I have added code change from this pull request and your 'assert' code and doing a native release build with GCC 11.

Turns out that the issue won't reproduce if adding your 'assert' code. That is to say, it only triggers with openjdk release build built with this PR and GCC version 10 or 11 on my side.

I can now reproduce using gcc 11.3 + this branch with no changes.

https://bugs.openjdk.org/browse/JDK-8316566

@robehn
Copy link
Contributor Author

robehn commented Sep 26, 2023

Fix for the bug here:
#15917

@robehn
Copy link
Contributor Author

robehn commented Sep 28, 2023

Merge with master, retested the problematic tests, we are all green now.
Please consider :)

Copy link
Member

@RealFYang RealFYang 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. So far my local regression tests with release build from GCC-11 are fine.

PS: Tier1-3 and hotspot:tier4 test good on hifive unmatched.

@openjdk
Copy link

openjdk bot commented Sep 28, 2023

@robehn This change now passes all automated pre-integration checks.

ℹ️ This project also has non-automated pre-integration requirements. Please see the file CONTRIBUTING.md for details.

After integration, the commit message for the final commit will be:

8316186: RISC-V: Remove PlatformCmpxchg<4>

Reviewed-by: fyang, mli

You can use pull request commands such as /summary, /contributor and /issue to adjust it as needed.

At the time when this comment was updated there had been 30 new commits pushed to the master branch:

  • 009f5e1: 8317141: Remove unused validIndex method from URLClassPath$JarLoader
  • 47569a2: 8295919: java.security.MessageDigest.isEqual does not adhere to @implNote
  • 5a6aa56: 8303959: tools/jpackage/share/RuntimePackageTest.java fails with java.lang.AssertionError missing files
  • 014c95a: 8317126: Redundant entries in Windows tzmappings file
  • fa0697a: 8316998: Remove redundant type arguments in the java.util.stream package
  • 49376e4: 8316000: File.setExecutable silently fails if file does not exist
  • a185be0: 8317139: [JVMCI] oop handles clearing message pollutes event log
  • 179792b: 8317283: jpackage tests run osx-specific checks on windows and linux
  • bd918f4: 8316401: sun/tools/jhsdb/JStackStressTest.java failed with "InternalError: We should have found a thread that owns the anonymous lock"
  • c45308a: 8301327: convert assert to guarantee in Handle_IDiv_Exception
  • ... and 20 more: https://git.openjdk.org/jdk/compare/798125152ba40ff2d093711629f275b5d74f0bcb...master

As there are no conflicts, your changes will automatically be rebased on top of these commits when integrating. If you prefer to avoid this automatic rebasing, please check the documentation for the /integrate command for further details.

➡️ To integrate this PR with the above commit message to the master branch, type /integrate in a new comment.

@openjdk openjdk bot added the ready Pull request is ready to be integrated label Sep 28, 2023
@robehn
Copy link
Contributor Author

robehn commented Sep 28, 2023

Looks good. So far my local regression tests with release build from GCC-11 are fine.

Thanks you, and extra thanks for testing!

@robehn
Copy link
Contributor Author

robehn commented Oct 1, 2023

@Hamlin-Li thanks!

/integrate

@openjdk
Copy link

openjdk bot commented Oct 1, 2023

Going to push as commit b8fa6c2.
Since your change was applied there have been 31 commits pushed to the master branch:

  • fb055e7: 8316645: RISC-V: Remove dependency on libatomic by adding cmpxchg 1b
  • 009f5e1: 8317141: Remove unused validIndex method from URLClassPath$JarLoader
  • 47569a2: 8295919: java.security.MessageDigest.isEqual does not adhere to @implNote
  • 5a6aa56: 8303959: tools/jpackage/share/RuntimePackageTest.java fails with java.lang.AssertionError missing files
  • 014c95a: 8317126: Redundant entries in Windows tzmappings file
  • fa0697a: 8316998: Remove redundant type arguments in the java.util.stream package
  • 49376e4: 8316000: File.setExecutable silently fails if file does not exist
  • a185be0: 8317139: [JVMCI] oop handles clearing message pollutes event log
  • 179792b: 8317283: jpackage tests run osx-specific checks on windows and linux
  • bd918f4: 8316401: sun/tools/jhsdb/JStackStressTest.java failed with "InternalError: We should have found a thread that owns the anonymous lock"
  • ... and 21 more: https://git.openjdk.org/jdk/compare/798125152ba40ff2d093711629f275b5d74f0bcb...master

Your commit was automatically rebased without conflicts.

@openjdk openjdk bot added the integrated Pull request has been integrated label Oct 1, 2023
@openjdk openjdk bot closed this Oct 1, 2023
@openjdk openjdk bot removed ready Pull request is ready to be integrated rfr Pull request is ready for review labels Oct 1, 2023
@openjdk
Copy link

openjdk bot commented Oct 1, 2023

@robehn Pushed as commit b8fa6c2.

💡 You may see a message that your pull request was closed with unmerged commits. This can be safely ignored.

@robehn robehn deleted the 8316186-4cmpxchg branch October 9, 2023 05:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
hotspot-runtime hotspot-runtime-dev@openjdk.org integrated Pull request has been integrated
Development

Successfully merging this pull request may close these issues.

3 participants