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

8342769: HotSpot Windows/gcc port is broken #21627

Open
wants to merge 27 commits into
base: master
Choose a base branch
from

Conversation

TheShermanTanker
Copy link
Contributor

@TheShermanTanker TheShermanTanker commented Oct 22, 2024

Several areas in HotSpot are broken in the gcc port. These, with the exception of 1 rather big oversight within SharedRuntime::frem and SharedRuntime::drem, are all minor correctness issues within the code. These mostly can be fixed with simple changes to the code. Note that I am not sure whether the SharedRuntime::frem and SharedRuntime::drem fix is correct. It may be that they can be removed entirely


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-8342769: HotSpot Windows/gcc port is broken (Bug - P4)

Reviewers

Reviewers without OpenJDK IDs

Reviewing

Using git

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

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

Using Skara CLI tools

Checkout this PR locally:
$ git pr checkout 21627

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

Using diff file

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

Using Webrev

Link to Webrev Comment

@bridgekeeper
Copy link

bridgekeeper bot commented Oct 22, 2024

👋 Welcome back jwaters! 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
Copy link

openjdk bot commented Oct 22, 2024

@TheShermanTanker 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:

8342769: HotSpot Windows/gcc port is broken

Reviewed-by: dholmes, aph

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 105 new commits pushed to the master branch:

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 changed the title 8342769 8342769: gcc port broken on HotSpot Oct 22, 2024
@openjdk openjdk bot added the rfr Pull request is ready for review label Oct 22, 2024
@openjdk
Copy link

openjdk bot commented Oct 22, 2024

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

  • hotspot

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 hotspot-dev@openjdk.org label Oct 22, 2024
@mlbridge
Copy link

mlbridge bot commented Oct 22, 2024

Copy link
Member

@dholmes-ora dholmes-ora left a comment

Choose a reason for hiding this comment

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

The sharedRuntime stuff is tricky and messy. Not sure about what is best/right/workable there. Maybe we even need to factor out like ./os/windows/sharedRuntimeRem.cpp?

st->print("%#11llx", reinterpret_cast<const unsigned long long>(mem_info.BaseAddress) - reinterpret_cast<const unsigned long long>(mem_info.AllocationBase));
st->print("%#11llx", reinterpret_cast<unsigned long long>(mem_info.BaseAddress) - reinterpret_cast<unsigned long long>(mem_info.AllocationBase));
Copy link
Member

Choose a reason for hiding this comment

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

What is the issue with const here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

More a correctness issue. The const is not required since the cast result is an rvalue unsigned long long. It's similar to something like a method's return type being marked as const int get(); where the const doesn't really mean anything since there is no possible way for it to be modified

Comment on lines 97 to 102
#ifdef _WIN64
const juint float_sign_mask = 0x7FFFFFFF;
const juint float_infinity = 0x7F800000;
const julong double_sign_mask = CONST64(0x7FFFFFFFFFFFFFFF);
const julong double_infinity = CONST64(0x7FF0000000000000);
#endif
Copy link
Member

Choose a reason for hiding this comment

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

Isn't all this better suited for sharedRuntime_x86_64.cpp?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You mean the entire custom frem and drem implementation unique to x64 Windows, or just this block of constants here? These constants are used by the custom Windows implementation, so they have to be in the same file. Moving the entire definition for Windows x64 to sharedRuntime_x86_64.cpp seems to be duplicating code even more, and I still don't know whether this is the right solution. It may be that this custom implementation may not be needed anymore and should be removed, which is why I left it in the sharedRuntime_x86.cpp file for the time being

Copy link
Member

Choose a reason for hiding this comment

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

I did mean the entire thing. I don't see any point in WIN64 code being in the x86 file when there is an x86_64 file. Of course I had forgotten about the Aarch64 Windows side, so maybe as I said this is really something for a os/windows file rather then cpu/<arch> ?

Copy link
Member

Choose a reason for hiding this comment

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

If it's needed on AArch64 too, this should move to something in os/windows as David said.

However, judging from the comment in

// This code is a copy of __ieee754_fmod() formerly from the JDK's libfdlibm and is
// used as a workaround for issues with the Windows x64 CRT implementation
// of fmod. Microsoft has acknowledged that this is an issue in Visual Studio
// 2012 and forward, but has not provided a time frame for a fix other than that
// it'll not be fixed in Visual Studio 2013 or 2015.
this workaround might not be needed anymore. The minimum version required for Windows-AArch64 is VS2017 (or even VS2019?), and for Windows-X64 apparently VS2022 is used (not sure what the minimum is):
windows_x64: "VS2022-17.6.5+1.0",

So maybe this can be removed altogether? Someone needs to check if this assumption is still true today.

Alas I don't have a Windows setup anymore. @karianna who is the local HotSpot Windows expert these days who could have a look at this? 🙂

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't think this workaround was intended for ARM64 in the first place, it explicitly mentions that it was written for x64, and the ifdef mess that resulted in this bug ended up bringing it over to ARM64

Copy link
Contributor

Choose a reason for hiding this comment

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

The minimum Visual Studio version required to build the Windows AArch64 port is VS 2022 via the DevKit - https://wiki.openjdk.org/display/Build/Supported+Build+Platforms

I'm now verifying whether this workaround is still needed.

Copy link
Contributor

Choose a reason for hiding this comment

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

@TheShermanTanker - this workaround is still needed on Windows AArch64. I haved filed https://developercommunity.visualstudio.com/t/fmod-incorrectly-returns-NaN-on-certain-/10793176 to track a fix for the underlying fmod bug.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm astounded by how this happy accident looped all the way back around to being needed for ARM64, truly one of the funniest coincidences of all time

Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think this workaround was intended for ARM64 in the first place, it explicitly mentions that it was written for x64, and the ifdef mess that resulted in this bug ended up bringing it over to ARM64

So what? I'm sure it'll be fine on AArch64. Just use it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't think this workaround was intended for ARM64 in the first place, it explicitly mentions that it was written for x64, and the ifdef mess that resulted in this bug ended up bringing it over to ARM64

So what? I'm sure it'll be fine on AArch64. Just use it.

This comment was made before Saint Wesonga confirmed that Windows/ARM64 now needed the workaround

@TheShermanTanker
Copy link
Contributor Author

The sharedRuntime stuff is tricky and messy. Not sure about what is best/right/workable there. Maybe we even need to factor out like ./os/windows/sharedRuntimeRem.cpp?

I'm not sure what is best too. I think we might need more people looking at this, in particular Windows ARM64 maintainers, because they might be the only platform that this change will affect. Some in the mailing lists mentioned that fmod_winx64 might not be needed anymore and could be removed entirely

@TheShermanTanker TheShermanTanker changed the title 8342769: gcc port broken on HotSpot 8342769: HotSpot Windows/gcc port is broken Oct 30, 2024
@TheShermanTanker
Copy link
Contributor Author

Bumping, please advise how to proceed on the sharedRuntime issue. It potentially affects Windows/ARM64 in an unknown way

@dholmes-ora
Copy link
Member

You need to contact the Windows-Aarch64 port maintainers and get them to tell you what the correct thing for Aarch64 is. Paging @mo-beck , @luhenry and @lewurm (https://openjdk.org/jeps/388)

@karianna
Copy link
Contributor

karianna commented Nov 2, 2024

Passing onto Microsoft's VM Engineering manager @brianjstafford - he'll find someone to take a look and advise.

@brianjstafford
Copy link
Contributor

@swesonga, can you please take a look at this?

@TheShermanTanker
Copy link
Contributor Author

Bumping

@swesonga
Copy link
Contributor

swesonga commented Nov 8, 2024

Bumping

Reviewing this change today. cc @brianjstafford

@TheShermanTanker
Copy link
Contributor Author

Bumping

@brianjstafford
Copy link
Contributor

@swesonga is out of office this week and will resume looking into this when he's back.

@TheShermanTanker
Copy link
Contributor Author

I've changed the check to instead define the constants when _M_ARM64 is defined. This is the cleanest approach I can come up with, and doesn't touch the workaround code in frem and drem either

@theRealAph
Copy link
Contributor

Wouldn't it be far easier to handle fmod ourselves in the AArch64b back end?

@TheShermanTanker
Copy link
Contributor Author

Wouldn't it be far easier to handle fmod ourselves in the AArch64b back end?

You mean like how x86 has its own custom fmod implementation in the assembler? That does sound pretty good to me, then we could get rid of this workaround entirely, but I don't know how to implement this on ARM64

@theRealAph
Copy link
Contributor

Wouldn't it be far easier to handle fmod ourselves in the AArch64b back end?

You mean like how x86 has its own custom fmod implementation in the assembler? That does sound pretty good to me, then we could get rid of this workaround entirely, but I don't know how to implement this on ARM64

Oh, OK. I'll have a look.

@theRealAph
Copy link
Contributor

Wouldn't it be far easier to handle fmod ourselves in the AArch64b back end?

You mean like how x86 has its own custom fmod implementation in the assembler? That does sound pretty good to me, then we could get rid of this workaround entirely, but I don't know how to implement this on ARM64

Oh, OK. I'll have a look.

I had a look at SharedRuntime::fmod_winx64. I'm sure it's fine for AArch64. Just put it in os_windows.

@TheShermanTanker
Copy link
Contributor Author

Bump

@TheShermanTanker
Copy link
Contributor Author

Bumping

@karianna
Copy link
Contributor

karianna commented Dec 3, 2024

@TheShermanTanker - Is there someone in particular you're waiting to approve this PR? I think you can re-request reviews.

@TheShermanTanker
Copy link
Contributor Author

@karianna I need 2 reviews with at least 1 of them being from a reviewer before this is marked by the automated systems as allowed for integration - Skara doesn't count swesonga's review because he's apparently not registered in the census (I think there might be a mistake there, either in the Skara tool or someone forgot to register him). I guess David or Andrew, or any one of the people from Microsoft who have seen this PR are the next best people to approve this. I had forgotten completely about the review request feature, thanks for reminding me :)

Copy link
Contributor

@theRealAph theRealAph 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.

@openjdk openjdk bot added the ready Pull request is ready to be integrated label Dec 3, 2024
Copy link
Member

@dholmes-ora dholmes-ora left a comment

Choose a reason for hiding this comment

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

So for the sharedRuntime changes, IIUC what was previously only needed for Windows x64 is now only needed for Windows Aarch64 - correct?

@@ -25,6 +25,7 @@
#include "precompiled.hpp"
#include "runtime/sharedRuntime.hpp"

#ifdef _M_ARM64
Copy link
Member

Choose a reason for hiding this comment

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

As this is ARM64 only now, the comment block at line 34 needs updating

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

@@ -284,7 +284,7 @@ JRT_LEAF(jlong, SharedRuntime::lrem(jlong y, jlong x))
JRT_END


#ifdef _WIN64
#ifdef _M_ARM64
Copy link
Member

Choose a reason for hiding this comment

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

If this is ARM64 only then the #if !defined(X86) at line 294 is not needed.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Wouldn't this cause a multiple definition error for frem and drem if the #if !defined(X86) was removed? The #if prevents those 2 methods from being defined when on x86 so it doesn't conflict with the x86 specific definitions, without it frem and drem would be defined twice on x86

Copy link
Member

Choose a reason for hiding this comment

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

But if we enter this block because _M_ARM64 is defined then X86 cannot be defined so line 294 is vacuously true.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm not sure I follow - The _M_ARM64 block is terminated by an endif before line 294, it is only there to define the global constants and does not guard the code below that line 294 does. Additionally, the code guarded by the if X86 seems to be for all non x86 platforms, not just ARM64

Copy link
Member

Choose a reason for hiding this comment

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

Apologies somehow the endif at line 292 was invisible

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm not really sure what you mean, if you mean why the _M_ARM64 ifdef doesn't guard the frem and drem implementations in sharedRuntime.cpp here, it's because the Windows/ARM64 implementation with the workaround in it and the implementation for the rest of the platforms (minus x86) are squashed right next to each other. Which implementation is compiled into HotSpot is then determined by the #ifdef _WIN64 check on line 296. If the _M_ARM64 ifdef covered the frem and drem implementation here then the implementation for all non Windows/ARM64 and non x86 platforms would not be defined, and HotSpot wouldn't link at all. Well, that's if I understood you correctly, at least

It might be possible to split the Windows/ARM64 implementation specifically into another file to reduce the confusion, but I feel like that is more trouble than it's worth, and may just cause more issues if not done right. I'd prefer not to do that to avoid all those problems

Copy link
Member

Choose a reason for hiding this comment

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

Sorry I'm doing a really bad job of pretending to be the preprocessor. :)

So the block at line 287 defines some constants for all ARM64, even though they are only needed on Windows.

The block at line 294 provides function definitions for all CPUs other the x86. Then within that we have one version for WIN64 (which really means Windows/Aarch64) and a regular version for all other non-x86 CPUS and non-Windows Aarch64.

So I guess what I'm suggesting is that it would be clearer to use if defined(_M_ARM64) && defined(WINDOWS) at lines 287, 294 and 321, to be clear the special code is only for Windows/Aarch64.

Second I think it would be clearer to just have two blocks: one for windows/aarch64 and the other for all other non-x86, rather than interleaving things the way they have been done.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ah, I see what you mean. There's just a small change I would make, which is to check whether defined(_WINDOWS) and defined(AARCH64) instead. Checking for both _M_ARM64 and _WINDOWS is redundant; _M_ARM64 is a Windows only define, so checking for _M_ARM64 == checking for AARCH64 && _WINDOWS. Would you be ok with that instead?

I think(?) I get what you mean by having 2 blocks, I'll try to do that

Sorry I'm doing a really bad job of pretending to be the preprocessor. :)

Haha, it happens

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah, I see what you mean. There's just a small change I would make, which is to check whether defined(_WINDOWS) and defined(AARCH64) instead. Checking for both _M_ARM64 and _WINDOWS is redundant; _M_ARM64 is a Windows only define, so checking for _M_ARM64 == checking for AARCH64 && _WINDOWS.

Checking for AARCH64 && _WINDOWS is much easier to understand.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Andrew and David, are the latest changes what you had in mind?

Comment on lines 41 to 42
double SharedRuntime::fmod_winx64(double x, double y)
double SharedRuntime::fmod_win64(double x, double y)
Copy link
Member

Choose a reason for hiding this comment

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

Wouldn't fmod_winAarch64 or fmod_winARM64 make more sense given this is now only used for Aarch64?

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 name was suggested by Andrew, I'll change it to fmod_winarm64 if you prefer

Copy link
Member

Choose a reason for hiding this comment

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

I thought at the time the name was because it was for both x64 and aarch64 - hence any win64 platform. But if it is only for Aarch64 then it makes sense to me that the function name conveys that.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Alright, I'll change it

@dholmes-ora
Copy link
Member

I had forgotten completely about the review request feature, thanks for reminding me :)

Only works if you have Github notifications enabled (I don't) else you have to return to the PR to see it.

@TheShermanTanker
Copy link
Contributor Author

So for the sharedRuntime changes, IIUC what was previously only needed for Windows x64 is now only needed for Windows Aarch64 - correct?

Yes, that seems to be the case

@openjdk openjdk bot removed the ready Pull request is ready to be integrated label Dec 4, 2024
Copy link
Member

@dholmes-ora dholmes-ora left a comment

Choose a reason for hiding this comment

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

That seems a lot clearer to me now - thanks.

Just one query below.

@@ -25,7 +25,7 @@
#include "precompiled.hpp"
#include "runtime/sharedRuntime.hpp"

#ifdef _M_ARM64
#ifdef AARCH64
Copy link
Member

Choose a reason for hiding this comment

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

Shouldn't this also be

#if defined(_WINDOWS) && defined(AARCH64)

?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

sharedRuntimeRem.cpp is a Windows only file - Checking for _WINDOWS for a file under os/windows is somewhat redundant

Copy link
Member

Choose a reason for hiding this comment

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

Sorry, missed that. Please ignore.

@@ -25,7 +25,7 @@
#include "precompiled.hpp"
#include "runtime/sharedRuntime.hpp"

#ifdef _M_ARM64
#ifdef AARCH64
Copy link
Member

Choose a reason for hiding this comment

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

Sorry, missed that. Please ignore.

@openjdk openjdk bot added the ready Pull request is ready to be integrated label Dec 10, 2024
@bridgekeeper
Copy link

bridgekeeper bot commented Jan 7, 2025

@TheShermanTanker This pull request has been inactive for more than 4 weeks and will be automatically closed if another 4 weeks passes without any activity. To avoid this, simply add a new comment to the pull request. Feel free to ask for assistance if you need help with progressing this pull request towards integration!

@TheShermanTanker
Copy link
Contributor Author

Keep open please

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
hotspot hotspot-dev@openjdk.org ready Pull request is ready to be integrated rfr Pull request is ready for review
Development

Successfully merging this pull request may close these issues.

7 participants