Skip to content

8379667: C2: Deep recursion with cmovP_regNode::bottom_type#30765

Open
merykitty wants to merge 1 commit intoopenjdk:masterfrom
merykitty:machtypenode
Open

8379667: C2: Deep recursion with cmovP_regNode::bottom_type#30765
merykitty wants to merge 1 commit intoopenjdk:masterfrom
merykitty:machtypenode

Conversation

@merykitty
Copy link
Copy Markdown
Member

@merykitty merykitty commented Apr 16, 2026

Hi,

The issue that leads to the failure is in the implementation of cmoveP_regNode::bottom_type, which recursively invokes Node::bottom_type on its inputs:

const Type            *bottom_type() const { const Type *t = in(oper_input_base()+1)->bottom_type(); return (req() <= oper_input_base()+2) ? t : t->meet(in(oper_input_base()+2)->bottom_type()); } // CMoveP

This deep recursion results in the number of Type::meet being called being a quadratic function of the number of cmovP_regNode in the chain. Type::meet eventually calls TypeInterfaces::intersection_with, each time that method is called, it allocates a GrowableArray to store the _interfaces of the result, this allocation is not guarded with a ResourceMark, which results in the resource area being overloaded, hitting the MemLimit.

Simply adding a ResourceMark to TypeInterfaces::intersection_with does not work, the recursion is still expensive, and the compilation won't terminate in a reasonable amount of time. As a result, I go with a more comprehensive solution, that is to keep the bottom_type of all MachNode.

It also helps alleviate a potential issue. The type of a pointer needs to be correctly recorded for scheduling and builing of oop maps at safepoints. For this, we have a pretty ad-hoc list of MachTypeNode that store their bottom_type inside their instances. By making all MachNode keeping their bottom_type, we can remove this ad-hoc list.

Testing:

  • tier1-4,hs-comp-stress
  • tier5-7
  • tier8,9 - Linux-x64-fastdebug

Please take a look and leave your reviews, thanks a lot.



Progress

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

Issue

  • JDK-8379667: C2: Deep recursion with cmovP_regNode::bottom_type (Bug - P2)

Reviewers

Reviewing

Using git

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

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

Using Skara CLI tools

Checkout this PR locally:
$ git pr checkout 30765

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

Using diff file

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

Using Webrev

Link to Webrev Comment

@bridgekeeper
Copy link
Copy Markdown

bridgekeeper Bot commented Apr 16, 2026

👋 Welcome back qamai! 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
Copy Markdown

openjdk Bot commented Apr 16, 2026

❗ This change is not yet ready to be integrated.
See the Progress checklist in the description for automated requirements.

@openjdk openjdk Bot added the hotspot-compiler hotspot-compiler-dev@openjdk.org label Apr 16, 2026
@openjdk
Copy link
Copy Markdown

openjdk Bot commented Apr 16, 2026

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

  • hotspot-compiler

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 rfr Pull request is ready for review label Apr 16, 2026
@mlbridge
Copy link
Copy Markdown

mlbridge Bot commented Apr 16, 2026

Webrevs

@openjdk
Copy link
Copy Markdown

openjdk Bot commented Apr 16, 2026

The total number of required reviews for this PR has been set to 2 based on the presence of this label: hotspot-compiler. This can be overridden with the /reviewers command.

@anton-seoane
Copy link
Copy Markdown
Contributor

This looks nice @merykitty! It's great to see such a cleanup too :)
I just have a couple questions:

Comment on lines +3964 to +3965
// Special case, with AllocatePrefetchStyle == 3, this should be Type::MEMORY, but the graph
// seems unsound, needs further investigation
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

What do you mean by "unsound" here? Can you create a follow-up to track this?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Currently, in the ideal graph, a PrefetchAllocationNode is a Type::ABIO or Type::MEMORY. As a result, they are connected to previous and subsequent abio and memory nodes, respectively. However, when lowered to MachNodes, since the rule are declared match(PrefetchAllocation mem), they become Type::BOTTOM, but their inputs and outputs are still abio or memory nodes, hence the unsoundness.

With the PR, at least when AllocatePrefetchStyle != 3, they preserve their correct type after matching. For AllocatePrefetchStyle == 3, it is more difficult, because memory nodes participate in anti-dependency computations, so we need to make further modifications to ensure that a PrefetchAllocationNode has a control input, and they act as a full store (its anti-dependencies do not need computing).

I filed JDK-8382547.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I see, thanks!

if (_bottom_type != nullptr) {
_bottom_type->dump_on(st);
} else {
st->print(" null");
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Your change seems to leave out this printout we would get before. I'm unsure about if keeping it makes easier to read/parse the dump spec or more cluttered, though...

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

You mean the st->print(" null")? Since most nodes have bottom_type set, and the one that does not is either MachTemp, or something that is not a pointer (guaranteed by MachNode::bottom_type()), I think it is a little unnecessary.

Copy link
Copy Markdown
Contributor

@anton-seoane anton-seoane 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. Thanks!

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 rfr Pull request is ready for review

Development

Successfully merging this pull request may close these issues.

2 participants