Skip to content

Conversation

@TheShermanTanker
Copy link
Contributor

@TheShermanTanker TheShermanTanker commented Jul 28, 2023

Fix several formatting errors on Windows


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-8313302: Fix formatting errors on Windows (Bug - P4)

Reviewing

Using git

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

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

Using Skara CLI tools

Checkout this PR locally:
$ git pr checkout 15063

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

Using diff file

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

Webrev

Link to Webrev Comment

@bridgekeeper
Copy link

bridgekeeper bot commented Jul 28, 2023

👋 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 openjdk bot changed the title 8313302 8313302: Fix formatting errors on Windows Jul 28, 2023
@openjdk openjdk bot added the rfr Pull request is ready for review label Jul 28, 2023
@openjdk
Copy link

openjdk bot commented Jul 28, 2023

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

  • graal
  • hotspot

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

@openjdk openjdk bot added graal graal-dev@openjdk.org hotspot hotspot-dev@openjdk.org labels Jul 28, 2023
@mlbridge
Copy link

mlbridge bot commented Jul 28, 2023

Webrevs

Copy link
Member

@tstuefe tstuefe left a comment

Choose a reason for hiding this comment

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

Hi Julian,

I'm sorry, but I object to this change.

It is another heap of aesthetic changes, with very very few changes actually needed (see inline remarks). Contrary to the title, it also touches shared code, and there are (almost) no errors to fix. And the one arguably incorrect place, in code heap, is not a "formatting error on windows".

Please consider that your aesthetic taste is not shared by everyone, but changes like these cause a lot of work for others.

Cheers, Thomas

const uintptr_t addr = map_view_no_placeholder(file_handle, file_offset, size);
if (addr == 0) {
log_error(gc)("Failed to map view of paging file mapping (%d)", GetLastError());
log_error(gc)("Failed to map view of paging file mapping (%ld)", GetLastError());
Copy link
Member

Choose a reason for hiding this comment

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

Here, and in many other places:

All these %d -> %ld changes are questionable. Why do you think l is more correct?

Strictly spoken both existing and your versions are incorrect since GetLastError returns a DWORD, which is an unsigned 32-bit integer.

Were I to change anything, I would print an unsigned integer. But I would not change anything, since all documented error codes are well below 0x8000_0000. I think we are good here.

Copy link
Contributor Author

@TheShermanTanker TheShermanTanker Jul 28, 2023

Choose a reason for hiding this comment

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

DWORD is defined as an unsigned long on all Windows compilers, which more accurately maps to %ld under C++ rules. This was more for correctness, but may not be strictly needed. Under JDK-8288293 however this is diagnosed as a formatting error, when compilerWarnings_gcc.hpp's format checking is enabled. I thus thought this was a fix that could be sent upstream


if (!res) {
fatal("Failed to unreserve memory: " PTR_FORMAT " " SIZE_FORMAT "M (%d)",
fatal("Failed to unreserve memory: " INTPTR_FORMAT " " SIZE_FORMAT "M (%ld)",
Copy link
Member

@tstuefe tstuefe Jul 28, 2023

Choose a reason for hiding this comment

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

Here, and in many other places:

PTR_FORMAT -> INTPTR_FORMAT both macros are the same.

We use PTR_FORMAT in many many places to print pointers. I prefer it to INTPTR_FORMAT, since it does not convey the assumption of a type. After all, the type does not matter: we just print the pointer as a raw hex value. Also, INTPTR suggests intptr_t which suggests signedness, which has no place here.

If we want to change this, we should first agree on the INTPTR_FORMAT vs PTR_FORMAT difference. And why we use intptr_t in many places that actually call for an uintptr_t.

But I would not change it. There is no need.

Copy link
Member

Choose a reason for hiding this comment

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

Yes. Please keep using PTR_FORMAT to print what's semantically a pointer in ZGC.


if (!res) {
fatal_error("Failed to split placeholder", addr, size);
fatal_error("Failed to split placeholder", untype(addr), size);
Copy link
Member

Choose a reason for hiding this comment

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

Please don't.

untype does an assertion check. We don't want that here, when constructing arguments for a fatal error message.

typedef void* HANDLE;
public:
typedef unsigned long thread_id_t;
typedef unsigned int thread_id_t;
Copy link
Member

Choose a reason for hiding this comment

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

Since Windows is LLP64, this has no effect, even though beginthreadex returns an unsigned int.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's also another formatting change, as this is printed as %d in shared code. This also matches the definition of int on other platforms. This should functionally be harmless, because ints are promoted to longs (DWORD) whenever thread_id_t is passed to a callee that expects a DWORD, and since longs are the same size as ints this is effectively an implicit cast with no effect in those cases

Copy link
Member

Choose a reason for hiding this comment

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

I can live with this change. Its also small and isolated.

if (Verbose && PrintMiscellaneous) {
reserveTimer.stop();
tty->print_cr("reserve_memory of %Ix bytes took " JLONG_FORMAT " ms (" JLONG_FORMAT " ticks)", bytes,
tty->print_cr("reserve_memory of %zx bytes took " JLONG_FORMAT " ms (" JLONG_FORMAT " ticks)", bytes,
Copy link
Member

@tstuefe tstuefe Jul 28, 2023

Choose a reason for hiding this comment

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

SIZE_FORMAT.

Choose a reason for hiding this comment

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

Regarding SIZE_FORMAT - https://bugs.openjdk.org/browse/JDK-8256379. Some people have been replacing
uses of SIZE_FORMAT when touching the relevant code for other reasons.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes, I think it might be best if people started using %zd rather than adding new SIZE_FORMAT to the code. I haven't figured out the best way to change the rest. If using %zx, I suggest adding 0x%zx.

if (PrintMiscellaneous && Verbose) {
warning("%s is not a directory, file attributes = "
INTPTR_FORMAT "\n", path, fa);
"0x%08lx\n", path, fa);
Copy link
Member

Choose a reason for hiding this comment

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

UINT32_FORMAT

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Noted, if this is accepted

st->print( "RAX=0x%016llx", uc->Rax);
st->print(", RBX=0x%016llx", uc->Rbx);
st->print(", RCX=0x%016llx", uc->Rcx);
st->print(", RDX=0x%016llx", uc->Rdx);
Copy link
Member

Choose a reason for hiding this comment

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

Why?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

All of these are either DWORD64 or DWORD, none are actually intptr_t's or uintptr_t's

Copy link
Member

Choose a reason for hiding this comment

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

In that case UINT64_FORMAT_X would be more correct. But again, unless there is an important reason to do so, I would leave changing this to when someone changes/moves around the code.

if (SizeDistributionArray != nullptr) {
unsigned long total_count = 0;
unsigned long total_size = 0;
uint64_t total_size = 0;
Copy link
Member

@tstuefe tstuefe Jul 28, 2023

Choose a reason for hiding this comment

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

This is a functional change (actually the only one I could spot), and it increases the size of this type to 64-bit on Windows.

It may also be incorrect, since on 32-bit platforms you probably don't want 64-bit here. The correct type to use would be size_t.

Since this change is hidden in a deluge of unnecessary cosmetic changes, if we feel this is needed, this should be addressed in a separate RFE.

But then again, probably not: code cache size is limited to 32-bit, and I bet we have a lot more places to change if we wanted to change that.

Also way out of scope for the RFE description.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

For this one (and the one below) I couldn't figure out whether the intention was for a 32 or 64 bit number in this case. This would be 64 bit on every platform but on Windows, which is 32 bit, and the code directly below this also faces the same issue too, is this intentional?

Copy link
Member

Choose a reason for hiding this comment

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

long is 32-bit on Linux x86 and arm32 too.

Choose a reason for hiding this comment

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

[not a review, just a drive-by comment]
The type long really shouldn't be used in shared code. There have been discussions and maybe some efforts
to nuke uses, but having just done the grep, there are still quite a few. The one in question might actually be an
appropriate place to use uintx.

" occupied space) is used by the blocks in the given size range.\n"
" %ld characters are printed per percentage point.\n", pctFactor/100);
ast->print_cr("total size of all blocks: %7ldM", (total_size<<log2_seg_size)/M);
ast->print_cr("total size of all blocks: " INT64_FORMAT_W(7) "M", (total_size<<log2_seg_size)/M);
Copy link
Member

Choose a reason for hiding this comment

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

Wrong for 32-bit platforms.

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 quite know what to do here, since on platforms where long < size_t (which in practice is probably just 32 bit or Windows) this division will promote to the type of size_t, which is likely 64 bits in size, but unfortunately %zd cannot be used here since the promotion only happens on said platforms where long < size_t, which will trip a compilation breaking warning on platforms where sizeof long is sizeof size_t, which is probably just 64 bit platforms that are not Windows

Copy link
Member

Choose a reason for hiding this comment

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

If we defer the issue of what type total_size should be and just keep it as unsigned long then the simple and correct fix would be to use %7lu would it not?

Choose a reason for hiding this comment

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

We shouldn't defer the issue of what type total_size should be. That's the underlying source of the problem. Don't use long types in shared code! I agree with @tstuefe - these should be size_t.

} else {
st->print("initialized successfully");
st->print(" - sym options: 0x%X", WindowsDbgHelp::symGetOptions());
st->print(" - sym options: 0x%lX", WindowsDbgHelp::symGetOptions());
Copy link
Member

Choose a reason for hiding this comment

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

No. SymGetOptions returns a DWORD, X is correct here.

@TheShermanTanker
Copy link
Contributor Author

TheShermanTanker commented Jul 28, 2023

Hi Julian,

I'm sorry, but I object to this change.

It is another heap of aesthetic changes, with very very few changes actually needed (see inline remarks). Contrary to the title, it also touches shared code, and there are (almost) no errors to fix. And the one arguably incorrect place, in code heap, is not a "formatting error on windows".

Please consider that your aesthetic taste is not shared by everyone, but changes like these cause a lot of work for others.

Cheers, Thomas

Hi Thomas,

Sigh, I was afraid of that. I've not been putting out good quality changes lately :(
I will mention that these are not merely aesthetic changes however, but actually is an effort spawned out of JDK-8288293, since all of these are flagged as formatting errors. It may be the case that I'm putting a bit too much faith in gcc's format checking, and I believe I won't be committing this in the end, but I do want to discuss a few things in the review comments since it is a bit easier

@tstuefe
Copy link
Member

tstuefe commented Jul 28, 2023

Hi Julian,
I'm sorry, but I object to this change.
It is another heap of aesthetic changes, with very very few changes actually needed (see inline remarks). Contrary to the title, it also touches shared code, and there are (almost) no errors to fix. And the one arguably incorrect place, in code heap, is not a "formatting error on windows".
Please consider that your aesthetic taste is not shared by everyone, but changes like these cause a lot of work for others.
Cheers, Thomas

Hi Thomas,

Sigh, I was afraid of that. I've not been putting out good quality changes lately :( I will mention that these are not merely aesthetic changes however, but actually is an effort spawned out of JDK-8288293, since all of these are flagged as formatting errors. It may be the case that I'm putting a bit too much faith in gcc's format checking, but I do want to discuss the rest in the review comments since it is a bit easier

So the point of this change is to satisfy gcc on Windows? Accomodating a new build platform, making (and keeping!) it warning-free is a considerable effort. Even if you do it, it has a lot of side effects on others: reviewer churn, accidental bugs, makes backports more difficult...

For smallish things its okay, but if it keeps causing massive changes like this one we should discuss this first. In my eyes, this is similar to adding a new platform, for which the bar is very (it is technically less complex than a new platform, but OTOH it is also less isolated).

As a side note, I think I mentioned this before, but it would be very helpful if you would put more love into your JBS issue descriptions and - texts.

Cheers, Thomas

@TheShermanTanker
Copy link
Contributor Author

TheShermanTanker commented Jul 28, 2023

Hi Thomas,

So the point of this change is to satisfy gcc on Windows? Accomodating a new build platform, making (and keeping!) it warning-free is a considerable effort. Even if you do it, it has a lot of side effects on others: reviewer churn, accidental bugs, makes backports more difficult...

Not really, I was perfectly capable of solving these issues by silencing the error checker in compilerWarnings_gcc.hpp (see ATTRIBUTE_PRINTF and ATTRIBUTE_SCANF), I decided not to do so since I believed these were reasonable changes as the time to fix the formatting on Windows, I was not aware of the actual scale the finished change would be on. I can retract this change if need be, it's not critical to the Project

For smallish things its okay, but if it keeps causing massive changes like this one we should discuss this first. In my eyes, this is similar to adding a new platform, for which the bar is very high (it is technically less complex than a new platform, but OTOH it is also less isolated).

Where would changes like these be discussed? As far as I know, I'm really the only one working on a Project like this. As a side note, the actual changes to HotSpot to get it compiling on gcc are actually minimal, this is technically not one of those changes, and a good chunk of them have already been integrated into mainline

Should I take the rest of this to build-dev?

Thanks for your time,
Julian

@tstuefe
Copy link
Member

tstuefe commented Jul 28, 2023

Hi Thomas,

So the point of this change is to satisfy gcc on Windows? Accomodating a new build platform, making (and keeping!) it warning-free is a considerable effort. Even if you do it, it has a lot of side effects on others: reviewer churn, accidental bugs, makes backports more difficult...

Not really, I was perfectly capable of solving these issues by silencing the error checker in compilerWarnings_gcc.hpp (see ATTRIBUTE_PRINTF and ATTRIBUTE_SCANF), I decided not to do so since I believed these were reasonable changes as the time to fix the formatting on Windows, I was not aware of the actual scale the finished change would be on. I can retract this change if need be, it's not critical to the Project

For smallish things its okay, but if it keeps causing massive changes like this one we should discuss this first. In my eyes, this is similar to adding a new platform, for which the bar is very high (it is technically less complex than a new platform, but OTOH it is also less isolated).

Where would changes like these be discussed? As far as I know, I'm really the only one working on a Project like this. As a side note, the actual changes to HotSpot to get it compiling on gcc are actually minimal, this is technically not one of those changes, and a good chunk of them have already been integrated into mainline

Should I take the rest of this to build-dev?

For discussing things that relate to hotspot coding, e.g. INTPTR_FORMAT, hotspot-dev would be better.

Thanks for your time, Julian

No problem.

@TheShermanTanker
Copy link
Contributor Author

Will close and address the issues discovered in this change individually

@TheShermanTanker TheShermanTanker deleted the format branch July 29, 2023 04:57
@TheShermanTanker TheShermanTanker restored the format branch August 1, 2023 05:56
@TheShermanTanker
Copy link
Contributor Author

Reopening - To fix the errors that were deemed as needing a fix

Copy link

@kimbarrett kimbarrett left a comment

Choose a reason for hiding this comment

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

Most/all of the PTR_FORMAT => INTPTR_FORMAT changes should not be made.
Especially those where the argument is the result of a call to p2i.
The p2i thing plus the definition of PTR_FORMAT are a bit of a kludge
to work around the variations in the implementations of "%p", which is
what one might wish PTR_FORMAT was using.

I've not looked at the rest yet. It would be easier to do so once the
PTR_FORMAT => INTPTR_FORMAT changes were removed.

@mlbridge
Copy link

mlbridge bot commented Aug 1, 2023

Mailing list message from Thomas Stüfe on graal-dev:

On Tue 1. Aug 2023 at 18:32, Coleen Phillimore <coleenp at openjdk.org> wrote:

On Tue, 1 Aug 2023 13:16:17 GMT, Kim Barrett <kbarrett at openjdk.org> wrote:

src/hotspot/os/windows/os_windows.cpp line 3382:

3380: if (Verbose && PrintMiscellaneous) {
3381: reserveTimer.stop();
3382: tty->print_cr("reserve_memory of %zx bytes took "
JLONG_FORMAT " ms (" JLONG_FORMAT " ticks)", bytes,

SIZE_FORMAT.

Regarding SIZE_FORMAT - https://bugs.openjdk.org/browse/JDK-8256379.
Some people have been replacing
uses of SIZE_FORMAT when touching the relevant code for other reasons.

Yes, I think it might be best if people started using %zd rather than
adding new SIZE_FORMAT to the code. I haven't figured out the best way to
change the rest. If using %zx, I suggest adding 0x%zx.

Pity, I liked those macros. We also lose the ability to compile with older
compilers, e.g. vs2013.

But I really dislike wholesale replacements of X with X prime (newer,
shinier) for aesthetic reasons. I much rather have those replacements we
agree upon be done when code is touched for other reasons. That causes
much less overhead for update maintainers.

-------------
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/graal-dev/attachments/20230801/c0ddd12f/attachment.htm>

@TheShermanTanker
Copy link
Contributor Author

Most/all of the PTR_FORMAT => INTPTR_FORMAT changes should not be made. Especially those where the argument is the result of a call to p2i. The p2i thing plus the definition of PTR_FORMAT are a bit of a kludge to work around the variations in the implementations of "%p", which is what one might wish PTR_FORMAT was using.

I've not looked at the rest yet. It would be easier to do so once the PTR_FORMAT => INTPTR_FORMAT changes were removed.

Understood, will revert them as soon as I can


if (!res) {
fatal_error("Failed to split placeholder", addr, size);
fatal_error("Failed to split placeholder", static_cast<uintptr_t>(addr), size);
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
fatal_error("Failed to split placeholder", static_cast<uintptr_t>(addr), size);
fatal_error("Failed to split placeholder", untype(addr), size);

Copy link
Contributor Author

Choose a reason for hiding this comment

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

won't these trigger assertions inside fatal error reporting code as Thomas mentioned earlier?

Copy link
Member

Choose a reason for hiding this comment

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

No. See:

inline uintptr_t untype(zaddress_unsafe addr) {
  return static_cast<uintptr_t>(addr);
}

I wonder if Thomas were thinking about the opposite operation, which converts an uintptr_t to a zaddress_unsafe:

inline zaddress_unsafe to_zaddress_unsafe(uintptr_t value) {
  const zaddress_unsafe addr = zaddress_unsafe(value);
  assert_is_valid(addr);
  return addr;
}

fatal("Failed to unmap view " PTR_FORMAT " " SIZE_FORMAT "M (%d)",
addr, size / M, GetLastError());
fatal("Failed to unmap view " PTR_FORMAT " " SIZE_FORMAT "M (%ld)",
static_cast<uintptr_t>(addr), size / M, GetLastError());
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
static_cast<uintptr_t>(addr), size / M, GetLastError());
untype(addr), size / M, GetLastError());

Copy link
Member

Choose a reason for hiding this comment

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

This suggestion is still valid.

@openjdk
Copy link

openjdk bot commented Aug 17, 2023

@TheShermanTanker this pull request can not be integrated into master due to one or more merge conflicts. To resolve these merge conflicts and update this pull request you can run the following commands in the local repository for your personal fork:

git checkout format
git fetch https://git.openjdk.org/jdk.git master
git merge FETCH_HEAD
# resolve conflicts and follow the instructions given by git merge
git commit -m "Merge master"
git push

@openjdk openjdk bot added the merge-conflict Pull request has merge conflict with target branch label Aug 17, 2023

if (!res) {
fatal_error("Failed to split placeholder", addr, size);
fatal_error("Failed to split placeholder", static_cast<uintptr_t>(addr), size);
Copy link
Member

Choose a reason for hiding this comment

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

No. See:

inline uintptr_t untype(zaddress_unsafe addr) {
  return static_cast<uintptr_t>(addr);
}

I wonder if Thomas were thinking about the opposite operation, which converts an uintptr_t to a zaddress_unsafe:

inline zaddress_unsafe to_zaddress_unsafe(uintptr_t value) {
  const zaddress_unsafe addr = zaddress_unsafe(value);
  assert_is_valid(addr);
  return addr;
}

fatal("Failed to unmap view " PTR_FORMAT " " SIZE_FORMAT "M (%d)",
addr, size / M, GetLastError());
fatal("Failed to unmap view " PTR_FORMAT " " SIZE_FORMAT "M (%ld)",
static_cast<uintptr_t>(addr), size / M, GetLastError());
Copy link
Member

Choose a reason for hiding this comment

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

This suggestion is still valid.

@TheShermanTanker
Copy link
Contributor Author

Closed due to merge conflicts

@TheShermanTanker TheShermanTanker deleted the format branch August 17, 2023 08:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

graal graal-dev@openjdk.org hotspot hotspot-dev@openjdk.org merge-conflict Pull request has merge conflict with target branch rfr Pull request is ready for review

Development

Successfully merging this pull request may close these issues.

6 participants