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

8272563: assert(is_double_stack() && !is_virtual()) failed: type check #5164

Closed
wants to merge 4 commits into from

Conversation

@fmatte1
Copy link

@fmatte1 fmatte1 commented Aug 18, 2021

This patch is proposed by the submitter of the bug - ugawa@ci.i.u-tokyo.ac.jp

The method CardTableBarrierSetC1::post_barrier generates a move LIR when TwoOperandLIRForm flag is true to move the address to be marked in the card table to a temporary register.

__ move(addr, tmp);
However, this code only guarantees that addr is a valid register for LIR, which can be a virtual register. If the virtual register for addr is spilled to the stack by chance, the move(addr, tmp) is compiled to a memory-to-register which causes an assertion failure because a memory-to-register move requires their arguments to have the same size.
The fix is to check if it is is_oop() and call the mov appropriately.

No issues found in local testing and Mach5 tier1-3


Progress

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

Issue

  • JDK-8272563: assert(is_double_stack() && !is_virtual()) failed: type check

Reviewers

Reviewing

Using git

Checkout this PR locally:
$ git fetch https://git.openjdk.java.net/jdk pull/5164/head:pull/5164
$ git checkout pull/5164

Update a local copy of the PR:
$ git checkout pull/5164
$ git pull https://git.openjdk.java.net/jdk pull/5164/head

Using Skara CLI tools

Checkout this PR locally:
$ git pr checkout 5164

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

Using diff file

Download this PR as a diff file:
https://git.openjdk.java.net/jdk/pull/5164.diff

@bridgekeeper
Copy link

@bridgekeeper bridgekeeper bot commented Aug 18, 2021

👋 Welcome back fmatte! 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.

Loading

@openjdk openjdk bot added the rfr label Aug 18, 2021
@openjdk
Copy link

@openjdk openjdk bot commented Aug 18, 2021

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

Loading

@openjdk openjdk bot added the hotspot label Aug 18, 2021
@fmatte1
Copy link
Author

@fmatte1 fmatte1 commented Aug 18, 2021

/label hotspot-gc hotspot-compiler

Loading

@openjdk
Copy link

@openjdk openjdk bot commented Aug 18, 2021

@fmatte1
The hotspot-gc label was successfully added.

The hotspot-compiler label was successfully added.

Loading

@mlbridge
Copy link

@mlbridge mlbridge bot commented Aug 18, 2021

Loading

Copy link
Member

@TobiHartmann TobiHartmann left a comment

Using an additional register + move does not seem right to fix this.

The problem is that addr->type() is T_OBJECT and the type of the virtual register tmp is T_LONG, right?

What about this?

LIR_Opr tmp = gen->new_register(addr->type());

Could the reporter provide a reproducer?

Loading

@fmatte1
Copy link
Author

@fmatte1 fmatte1 commented Aug 26, 2021

Hi Tobias,
Thanks for looking into this thread. There is reproducer but it has lot of dependencies with dacapo-9.12-MR1-bach.jar and I am unable to isolate to smaller case.
I tried with your suggestion but could not resolve the issue.
Below is the original issue reproduced on fastdebug build (Updated the jbs bug)

A fatal error has been detected by the Java Runtime Environment:

Internal Error (/tank/fmatte/bugs/8272563/openjdk-reproduce-5164/src/hotspot/share/c1/c1_LIR.hpp:413), pid=28744, tid=28763

assert(is_double_stack() && !is_virtual()) failed: type check

JRE version: OpenJDK Runtime Environment (16.0.2) (fastdebug build 16.0.2-internal+0-adhoc.fmatte.openjdk-reproduce-5164)

Java VM: OpenJDK 64-Bit Server VM (fastdebug 16.0.2-internal+0-adhoc.fmatte.openjdk-reproduce-5164, compiled mode, tiered, compressed oops, compressed class ptrs, serial gc, linux-amd64)

Problematic frame:

V [libjvm.so+0x7202f3] LIR_OprDesc::double_stack_ix() const+0x43

Core dump will be written. Default location: Core dumps may be processed with "/usr/share/apport/apport %p %s %c %d %P %E" (or dumping to /tank/fmatte/bugs/8272563/openjdk-reproduce-5164/core.28744)

An error report file with more information is saved as:

error.log

Compiler replay data is saved as:

/tank/fmatte/bugs/8272563/openjdk-reproduce-5164/replay_pid28744.log

If you would like to submit a bug report, please visit:

https://bugreport.java.com/bugreport/crash.jsp

Loading

@veresov
Copy link
Contributor

@veresov veresov commented Aug 27, 2021

I think we have to somehow tell the register allocator not to spill arguments of type converting moves. We already have some logic there to prevent spills in logic and arithmetic involving T_OBJECT:

} else if (opr_type != T_LONG LP64_ONLY(&& opr_type != T_OBJECT)) {

Perhaps we should also detect the conversion case when ( src and dst ) are of different types and force both to be in registers? Basically insert some logic here (reg-reg move):
} else if (move->in_opr()->is_register() && move->result_opr()->is_register()) {

Check the types, and if it's the T_OBJECT->T_LONG situation return mustHaveRegister ?

May be there is better solution, but that's the first thing that came to mind.

Loading

@fmatte1
Copy link
Author

@fmatte1 fmatte1 commented Aug 30, 2021

Hi Igor,

Thanks for looking into this and thanks for the pointers to handle the spills in logic involved in T_OBJECT to T_LONG mov's and Also to check the src and dst must have the registers.
These conditions can be handled using asserts/guarantee's (as the function doesn't return).
But as original patch suggests we can have solution by copying over extra temp register.

In

} else if (opr_type != T_LONG LP64_ONLY(&& opr_type != T_OBJECT)) {
It was not handled and enfornced we must have both registers. So I am not sure if we also can handle this scenario or it can be prevented as done in c1_LinearScan.cpp file.

Thanks,

Loading

@veresov
Copy link
Contributor

@veresov veresov commented Aug 30, 2021

Well, an extra temp register won't solve it, right? You're just getting lucky that tmp2 is not getting spilled. If that happens you get exactly the same situation as before, don't you?

Loading

@fmatte1
Copy link
Author

@fmatte1 fmatte1 commented Aug 31, 2021

yes that's being the case.
I got your point, will try to add guarantees to handle this scenario and propose the solution after testing

Loading

@veresov
Copy link
Contributor

@veresov veresov commented Aug 31, 2021

Oh, hey! Another much easier idea. Do it with a lea.

LIR_Address* addr_addr = new LIR_Address(addr, addr->type());
__ leal(addr_addr, tmp);

It will force addr into a register. And no need to mess with the register allocator.

Loading

@fmatte1
Copy link
Author

@fmatte1 fmatte1 commented Aug 31, 2021

Hi Igor,

Possibly you mean this,
LIR_Opr addr_opr = LIR_OprFact::address(new LIR_Address(addr, addr->type())); __ leal(addr_opr, tmp);
I have updated the patch with this fix and there is no issue in hs-tier1 to hs-tier3

Loading

@veresov
Copy link
Contributor

@veresov veresov commented Aug 31, 2021

Good. You don't actually need to check if it's an oop or not. You can just do leal for all the types.

Loading

@fmatte1
Copy link
Author

@fmatte1 fmatte1 commented Sep 1, 2021

Thanks, updated the patch.

Loading

@veresov
Copy link
Contributor

@veresov veresov commented Sep 1, 2021

Looks good!

Loading

veresov
veresov approved these changes Sep 1, 2021
@fmatte1 fmatte1 changed the title 8272563: Possible assertion failure in CardTableBarrierSetC1 8272563: assert(is_double_stack() && !is_virtual()) failed: type check Sep 1, 2021
@openjdk
Copy link

@openjdk openjdk bot commented Sep 1, 2021

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

8272563: assert(is_double_stack() && !is_virtual()) failed: type check

Reviewed-by: thartmann, iveresov

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

  • 0e14bf7: 8273176: handle latest VS2019 in abstract_vm_version
  • f1c5e26: 8273206: jdk/jfr/event/gc/collection/TestG1ParallelPhases.java fails after JDK-8159979
  • e600fe1: 8272618: Unnecessary Attr.visitIdent.noOuterThisPath
  • 2fce7cb: 8272963: Update the java manpage markdown source
  • 18a731a: 8269770: nsk tests should start IOPipe channel before launch debuggee - Debugee.prepareDebugee
  • 9c392d0: 8273197: ProblemList 2 jtools tests due to JDK-8273187
  • 3d657eb: 8262186: Call X509KeyManager.chooseClientAlias once for all key types
  • c1e0aac: 8273186: Remove leftover comment about sparse remembered set in G1 HeapRegionRemSet
  • 683e30d: 8273169: java/util/regex/NegativeArraySize.java failed after JDK-8271302
  • 1996f64: 8273092: Sort classlist in JDK image
  • ... and 112 more: https://git.openjdk.java.net/jdk/compare/30b0f820cec12b6da62229fe78a528ab3ad0d134...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.

As you do not have Committer status in this project an existing Committer must agree to sponsor your change. Possible candidates are the reviewers of this PR (@TobiHartmann, @veresov) but any other Committer may sponsor as well.

➡️ To flag this PR as ready for integration with the above commit message, type /integrate in a new comment. (Afterwards, your sponsor types /sponsor in a new comment to perform the integration).

Loading

@openjdk openjdk bot added the ready label Sep 1, 2021
@fmatte1
Copy link
Author

@fmatte1 fmatte1 commented Sep 1, 2021

/integrate

Loading

@openjdk openjdk bot added the sponsor label Sep 1, 2021
@openjdk
Copy link

@openjdk openjdk bot commented Sep 1, 2021

@fmatte1
Your change (at version 359cbf3) is now ready to be sponsored by a Committer.

Loading

Copy link
Member

@TobiHartmann TobiHartmann left a comment

Looks good to me too!

Loading

@TobiHartmann
Copy link
Member

@TobiHartmann TobiHartmann commented Sep 1, 2021

/sponsor

Loading

@openjdk
Copy link

@openjdk openjdk bot commented Sep 1, 2021

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

  • 0e14bf7: 8273176: handle latest VS2019 in abstract_vm_version
  • f1c5e26: 8273206: jdk/jfr/event/gc/collection/TestG1ParallelPhases.java fails after JDK-8159979
  • e600fe1: 8272618: Unnecessary Attr.visitIdent.noOuterThisPath
  • 2fce7cb: 8272963: Update the java manpage markdown source
  • 18a731a: 8269770: nsk tests should start IOPipe channel before launch debuggee - Debugee.prepareDebugee
  • 9c392d0: 8273197: ProblemList 2 jtools tests due to JDK-8273187
  • 3d657eb: 8262186: Call X509KeyManager.chooseClientAlias once for all key types
  • c1e0aac: 8273186: Remove leftover comment about sparse remembered set in G1 HeapRegionRemSet
  • 683e30d: 8273169: java/util/regex/NegativeArraySize.java failed after JDK-8271302
  • 1996f64: 8273092: Sort classlist in JDK image
  • ... and 112 more: https://git.openjdk.java.net/jdk/compare/30b0f820cec12b6da62229fe78a528ab3ad0d134...master

Your commit was automatically rebased without conflicts.

Loading

@openjdk openjdk bot closed this Sep 1, 2021
@openjdk
Copy link

@openjdk openjdk bot commented Sep 1, 2021

@TobiHartmann @fmatte1 Pushed as commit a58cf16.

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

Loading

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
3 participants