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

8255550: x86: Assembler::cmpq(Address dst, Register src) encoding is incorrect #910

Closed
wants to merge 2 commits into from

Conversation

shipilev
Copy link
Member

@shipilev shipilev commented Oct 28, 2020

Compare:

void Assembler::cmpq(Address dst, Register src) {
  InstructionMark im(this);
  emit_int16(get_prefixq(dst, src), 0x3B);
  emit_operand(src, dst);
}

void Assembler::cmpq(Register dst, Address src) {
  InstructionMark im(this);
  emit_int16(get_prefixq(src, dst), 0x3B);
  emit_operand(dst, src);
}

They use the same opcode -- 0x3B, which is for CMP r, r/m. While cmpq(Address,Register) actually should be using 0x39 for CMP r/m, r. I also suspect they emit basically the same instruction, because the get_prefixq and emit_operand argument order is irrelevant.

AFAIU, it does not break horribly, because the cmpq(Address,Register) is not used anywhere except the new code in MacroAssembler::safepoint_poll, added by JDK-8253180. This was found by Zhengyu, when he tried to enable that new code on x86_32 by inverting cmpq(addr, reg); jcc(above, slow_path) to cmpptr(reg, addr); jcc(belowEquals, slow_path). Then, everything blew up, because the semantics of cmpq(addr,reg) was wrong, and this inversion was subtly broken.

Current candidate patch encodes this cmpq properly. Since that changes the semantics, I had to flip the condition code in its only use. I opted to do this, because maybe some code in downstream projects want to use this odd cmpq. Although even if so, the uses could be trivially rewritten.

Alternatives:

  • I considered removing cmpq(Address,Register) altogether, but it would require more work to untangle cmpptr(Address,Register) and cmpptr(Address,AddressLiteral) for x86_32.
  • We can also split out MacroAssembler::safepoint_poll change to use cmpq(Register,Address) to begin with, but current shape gives us a way to test the encoding.

Additional testing:

  • tier1 with Shenandoah (a few failures are pre-existing)
  • tier1 with Z (AFAICS, all failing tests are OOME'ing or break SA, and probably are problem-listed)

Progress

  • Change must not contain extraneous whitespace
  • Commit message must refer to an issue
  • Change must be properly reviewed

Testing

Linux x64 Linux x86 Windows x64 macOS x64
Build ✔️ (5/5 passed) ✔️ (2/2 passed) ✔️ (2/2 passed) ✔️ (2/2 passed)
Test (tier1) ✔️ (9/9 passed) ✔️ (9/9 passed) ⏳ (3/9 running) ✔️ (9/9 passed)

Issue

  • JDK-8255550: x86: Assembler::cmpq(Address dst, Register src) encoding is incorrect

Reviewers

Download

$ git fetch https://git.openjdk.java.net/jdk pull/910/head:pull/910
$ git checkout pull/910

@bridgekeeper
Copy link

bridgekeeper bot commented Oct 28, 2020

👋 Welcome back shade! 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 Oct 28, 2020
@openjdk
Copy link

openjdk bot commented Oct 28, 2020

@shipilev 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 28, 2020
@mlbridge
Copy link

mlbridge bot commented Oct 28, 2020

Webrevs

@sviswa7
Copy link

sviswa7 commented Oct 28, 2020

The fix looks good to me. cmpq(Address,Register) should be using 0x39 as the opcode.

Copy link
Contributor

@vnkozlov vnkozlov left a comment

Choose a reason for hiding this comment

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

Good.

@openjdk
Copy link

openjdk bot commented Oct 28, 2020

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

8255550: x86: Assembler::cmpq(Address dst, Register src) encoding is incorrect

Reviewed-by: kvn, eosterlund

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

  • faf23de: 8255534: Shenandoah: Fix CmpP optimization wrt native-LRB
  • 579e50b: 8255564: InterpreterMacroAssembler::remove_activation() needs to restore thread right after VM call on x86_32

Please see this link for an up-to-date comparison between the source branch of this pull request and 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 added the ready Pull request is ready to be integrated label Oct 28, 2020
@shipilev
Copy link
Member Author

Thanks for review @vnkozlov and @sviswa7!

@fisk, does the changed code in safepoint_poll still looks good for you?

Copy link
Contributor

@fisk fisk left a comment

Choose a reason for hiding this comment

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

Thanks for poking me. I would prefer to change to the cmpq instruction that has the opposite order in the stack watermark barrier instead. Everywhere in the code I talk about the condition being sp being "above" watermark. Changing it to less makes me twist my head in ways that heads should not twist.

@shipilev
Copy link
Member Author

Thanks for poking me. I would prefer to change to the cmpq instruction that has the opposite order in the stack watermark barrier instead. Everywhere in the code I talk about the condition being sp being "above" watermark. Changing it to less makes me twist my head in ways that heads should not twist.

Ok, so let's do this: can you change the parameter order in cmpq instruction in safepoint_poll, run the tests you probably know are sensitive to this, and I'll drop the safepoint_poll hunk from here after that change lands?

@shipilev
Copy link
Member Author

Thanks for poking me. I would prefer to change to the cmpq instruction that has the opposite order in the stack watermark barrier instead. Everywhere in the code I talk about the condition being sp being "above" watermark. Changing it to less makes me twist my head in ways that heads should not twist.

Ok, so let's do this: can you change the parameter order in cmpq instruction in safepoint_poll, run the tests you probably know are sensitive to this, and I'll drop the safepoint_poll hunk from here after that change lands?

What I meant was "in a separate PR", not to mess up with the change here. I think it amounts to:

diff --git a/src/hotspot/cpu/x86/macroAssembler_x86.cpp b/src/hotspot/cpu/x86/macroAssembler_x86.cpp
index a8da3aa17b8..81303ea76c4 100644
--- a/src/hotspot/cpu/x86/macroAssembler_x86.cpp
+++ b/src/hotspot/cpu/x86/macroAssembler_x86.cpp
@@ -2765,7 +2765,7 @@ void MacroAssembler::safepoint_poll(Label& slow_path, Register thread_reg, bool
   if (at_return) {
     // Note that when in_nmethod is set, the stack pointer is incremented before the poll. Therefore,
     // we may safely use rsp instead to perform the stack watermark check.
-    cmpq(Address(thread_reg, Thread::polling_word_offset()), in_nmethod ? rsp : rbp);
+    cmpq(in_nmethod ? rsp : rbp, Address(thread_reg, Thread::polling_word_offset()));
     jcc(Assembler::above, slow_path);
     return;
   }

I can do that, if you want, and if you trust tier1 is enough.

@shipilev
Copy link
Member Author

Forked safepoint_poll change to JDK-8255579, #924

@shipilev
Copy link
Member Author

Dropped the safepoint_poll hunk after #924 integration. @fisk, this must be fine with you then?

@openjdk openjdk bot added hotspot-compiler hotspot-compiler-dev@openjdk.org and removed hotspot hotspot-dev@openjdk.org labels Oct 29, 2020
Copy link
Contributor

@fisk fisk left a comment

Choose a reason for hiding this comment

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

Yep, looks all good to me.

@shipilev
Copy link
Member Author

/integrate

@openjdk openjdk bot closed this Oct 29, 2020
@openjdk openjdk bot added integrated Pull request has been integrated and removed ready Pull request is ready to be integrated rfr Pull request is ready for review labels Oct 29, 2020
@openjdk
Copy link

openjdk bot commented Oct 29, 2020

@shipilev Since your change was applied there have been 3 commits pushed to the master branch:

  • 5b18558: 8255243: Reinforce escape barrier interactions with ZGC conc stack processing
  • faf23de: 8255534: Shenandoah: Fix CmpP optimization wrt native-LRB
  • 579e50b: 8255564: InterpreterMacroAssembler::remove_activation() needs to restore thread right after VM call on x86_32

Your commit was automatically rebased without conflicts.

Pushed as commit 9e5bbff.

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

@shipilev shipilev deleted the JDK-8255550-cmpq-incorrect branch November 2, 2020 09:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
hotspot-compiler hotspot-compiler-dev@openjdk.org integrated Pull request has been integrated
4 participants