-
Notifications
You must be signed in to change notification settings - Fork 5.8k
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
8340824: C2: Memory for TypeInterfaces not reclaimed by hashcons() #21163
Conversation
👋 Welcome back roland! A progress list of the required criteria for merging this PR into |
@rwestrel 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:
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 14 new commits pushed to the
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 |
Webrevs
|
Converted back to draft while I investigate gtest failures. |
This reverts commit 3598dc0.
/label remove hotspot |
@rwestrel |
@rwestrel |
src/hotspot/share/opto/type.cpp
Outdated
const TypeInterfaces* TypeInterfaces::make(GrowableArray<ciInstanceKlass*>* interfaces) { | ||
TypeInterfaces* result = (interfaces == nullptr) ? new TypeInterfaces() : new TypeInterfaces(interfaces); | ||
return (const TypeInterfaces*)result->hashcons(); | ||
const TypeInterfaces* TypeInterfaces::make(const GrowableArray<ciInstanceKlass*>* interfaces) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you can make _interface
a ciInstanceKlass**
and do this:
void* ptr = Type::operator new(sizeof(TypeInterfaces) + sizeof(ciInstanceKlass*) * interfaces->length())
Then delete ptr
should drop the whole thing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A GrowableArrayFromArray
would be mostly compatible with the interface of GrowableArray
, too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah! nice. I wasn't aware of GrowableArrayFromArray
. Updated change follows your suggestion.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good.
It feels a bit weird to see GrowableArray
used to represent a read-only data structure, but I understand that you still benefit from some helper methods it provides.
@iwanowww @merykitty thanks for the reviews |
/integrate |
Going to push as commit 90c944f.
Your commit was automatically rebased without conflicts. |
/backport jdk21u-dev |
@rwestrel the backport was successfully created on the branch backport-rwestrel-90c944fe-master in my personal fork of openjdk/jdk21u-dev. To create a pull request with this backport targeting openjdk/jdk21u-dev:master, just click the following link: The title of the pull request is automatically filled in correctly and below you find a suggestion for the pull request body:
If you need to update the source branch of the pull then run the following commands in a local clone of your personal fork of openjdk/jdk21u-dev:
|
The list of interfaces for a
TypeInterfaces
is contained in aGrowableArray
that's allocated in the type arena. Whenhashcons()
deletes aTypeInterfaces
object because an identical one exists, it can't reclaim memory for the object because it can only free the last thing that was allocated and that's the backing store for theGrowableArray
, not theTypeInterfaces
object.This patch changes the array of interfaces stored in
TypeInterfaces
into a pointer to aGrowableArray
.TypeInterfaces::make
callshashcons
with a temporary copy of the array of interfaces allocated in the current thread's resource area. This way ifhascons
deletes theTypeInterfaces
, it is the last thing allocated in the type arena and memory can be reclaimed. Memory for theGrowableArray
is freed as well on return fromTypeInterfaces::make
. If the newly allocatedTypeInterfaces
surviveshashcons
then a permanent array of interfaces is allocated in the type arena and linked from theTypeInterfaces
object.I ran into this issue while working on a fix for a separate issue that causes more Type objects to be created. With that prototype fix, TestScalarReplacementMaxLiveNodes uses 1.4GB of memory at peak. With the patch I propose here on top, memory usage goes down to 150-200 MB which is in line with the peak memory usage for TestScalarReplacementMaxLiveNodes when run with current master.
When I opened the PR initially, the fix I proposed was to let
GrowableArray
try to reclaim memory from an arena when destroyed. With that patch, some gtests failed when aGrowableArray
is created by a copy constructor and the backing store for the array is shared. As a consequence, I reconsidered the fix and thought it was safer to go with a fix that only affectsTypeInterfaces
.Progress
Issue
Reviewers
Reviewing
Using
git
Checkout this PR locally:
$ git fetch https://git.openjdk.org/jdk.git pull/21163/head:pull/21163
$ git checkout pull/21163
Update a local copy of the PR:
$ git checkout pull/21163
$ git pull https://git.openjdk.org/jdk.git pull/21163/head
Using Skara CLI tools
Checkout this PR locally:
$ git pr checkout 21163
View PR using the GUI difftool:
$ git pr show -t 21163
Using diff file
Download this PR as a diff file:
https://git.openjdk.org/jdk/pull/21163.diff
Webrev
Link to Webrev Comment