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

8314220: Configurable InlineCacheBuffer size #15271

Closed
wants to merge 4 commits into from

Conversation

kvergizova
Copy link
Contributor

@kvergizova kvergizova commented Aug 14, 2023

InlineCacheBuffer size is currently hardcoded to 10K.
This can lead to multiple ICBufferFull safepoints for InlineCacheBuffer cleanup and possible performance degradation.

Added experimental command line option InlineCacheBufferSize with the same default value, allowing it to be configured for performance experiments with ICBufferFull safepoints frequency.


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-8314220: Configurable InlineCacheBuffer size (Enhancement - P4)

Reviewers

Reviewing

Using git

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

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

Using Skara CLI tools

Checkout this PR locally:
$ git pr checkout 15271

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

Using diff file

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

Webrev

Link to Webrev Comment

@bridgekeeper
Copy link

bridgekeeper bot commented Aug 14, 2023

👋 Welcome back evergizova! 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 Aug 14, 2023
@openjdk
Copy link

openjdk bot commented Aug 14, 2023

@kvergizova 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 Aug 14, 2023
@mlbridge
Copy link

mlbridge bot commented Aug 14, 2023

Webrevs

@@ -295,6 +295,9 @@ const int ObjectAlignmentInBytes = 8;
product(bool, UseInlineCaches, true, \
"Use Inline Caches for virtual calls ") \
\
product(uintx, InlineCacheBufferSize, 10*K, EXPERIMENTAL, \
"InlineCacheBuffer size") \
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you make this type an int and add a range to it? Line 143 above will get -Wconversion warnings if we ever turned them on.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks, I changed type to int and added a range check constraint.

Copy link
Member

Choose a reason for hiding this comment

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

I'd rather have the type as size_t and change StubQueue accordingly.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks @dean-long.
I would like to keep this enhancement simple and minimal so that it can be backported to 17 and 11.
So I'd like to avoid changes to StubQueue. I can change the type of InlineCacheBufferSize to size_t and add checked_cast to StubQueue constructor in InlineCacheBuffer::initialize():
_buffer = new StubQueue(new ICStubInterface, checked_cast(InlineCacheBufferSize), InlineCacheBuffer_lock, "InlineCacheBuffer");

Because in any case InlineCacheBufferSize can't be greater than INT_MAX:
InlineCacheBufferSize < NonNMethodCodeHeapSize < ReservedCodeCacheSize < CODE_CACHE_DEFAULT_LIMIT = 2G:
https://github.com/openjdk/jdk/blob/master/src/hotspot/share/code/codeCache.cpp#L191
https://github.com/openjdk/jdk/blob/master/src/hotspot/share/compiler/compilerDefinitions.cpp#L492
https://github.com/openjdk/jdk/blob/master/src/hotspot/share/utilities/globalDefinitions.hpp#L589

Will that be OK?

Copy link
Member

Choose a reason for hiding this comment

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

OK.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

@dean-long
Copy link
Member

I like the idea of getting rid of this arbitrary limit, but it might be better to either:

  1. scale the default size value based on the code cache size (ergonomics)?
  2. grow the buffer as needed, no size flag needed
    I would prefer 2).

@kvergizova
Copy link
Contributor Author

I like the idea of getting rid of this arbitrary limit, but it might be better to either:

  1. scale the default size value based on the code cache size (ergonomics)?
  2. grow the buffer as needed, no size flag needed
    I would prefer 2).

@dean-long, good ideas, but they require some investigations and non-trivial changes.
Maybe it's better to integrate this simple approach, that can be useful for performance experiments and can possibly be backported to 17u/11u due to its simplicity, and then implement one of your ideas separately?
Since the suggested InlineCacheBufferSize option is experimental, it can be dropped later without any notice.

@kvergizova
Copy link
Contributor Author

Can someone please review this fix?
Pre-submit failures are unrelated.

return JVMFlag::VIOLATES_CONSTRAINT;
}

if ((value % CodeEntryAlignment) != 0) {
Copy link
Member

Choose a reason for hiding this comment

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

I don't understand why this is necessary.

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 is needed to avoid 'failed: _buffer_size not aligned' crashes on debug builds:
https://github.com/openjdk/jdk/blob/master/src/hotspot/share/code/stubs.cpp#L221

Copy link
Member

Choose a reason for hiding this comment

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

That sounds like a bug. We already align the code_begin(). I see no reason to align code_end() as well. It just wastes space.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

OK, can I remove these guarantees for _buffer_size and _buffer_limit in this PR? Or do I need to create a separate one?

Copy link
Member

Choose a reason for hiding this comment

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

I would like to see it cleaned up in this PR.

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 changed the InlineCacheBufferSize type to size_t and removed unnecessary guarantees for _buffer_size and _buffer_limit.
@dean-long could you please take a look?

@@ -439,3 +439,29 @@ JVMFlag::Error ControlIntrinsicConstraintFunc(ccstrlist value, bool verbose) {
return JVMFlag::SUCCESS;
}

JVMFlag::Error InlineCacheBufferSizeConstraintFunc(int value, bool verbose) {
if (value <= 0) {
Copy link
Member

Choose a reason for hiding this comment

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

Shouldn't be needed if the type is unsigned.

@bridgekeeper
Copy link

bridgekeeper bot commented Oct 20, 2023

@kvergizova This pull request has been inactive for more than 4 weeks and will be automatically closed if another 4 weeks passes without any activity. To avoid this, simply add a new comment to the pull request. Feel free to ask for assistance if you need help with progressing this pull request towards integration!

@dean-long
Copy link
Member

This looks good. There is still potentially over-alignment for the data header, but that's an existing problem:

65    // ICStub_from_destination_address looks up Stub* address from code entry address,
66    // which unfortunately means the stub head should be at the same alignment as the code.
67    static  int alignment()                        { return CodeEntryAlignment; }

I suggest you get another review before integrating.

@openjdk
Copy link

openjdk bot commented Nov 20, 2023

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

8314220: Configurable InlineCacheBuffer size

Reviewed-by: dlong, kvn

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

  • 4d50df6: 8320691: Timeout handler on Windows takes 2 hours to complete
  • 0c9a61c: 8319220: Pattern matching switch with a lot of cases is unduly slow
  • 26c3390: 8320383: refresh libraries cache on AIX in VMError::report
  • fc31474: 8318913: The module-infos for --release data do not contain pre-set versions
  • df1b896: 8320679: [JVMCI] invalid code in PushLocalFrame event message
  • c75c388: 8318776: Require supports_cx8 to always be true
  • 14557e7: 8314502: Change the comparator taking version of GrowableArray::find to be a template method
  • 2802643: 8314243: Make VM_Exit::wait_for_threads_in_native_to_block wait for user threads time configurable
  • 6f26311: 8318490: Increase timeout for JDK tests that are close to the limit when run with libgraal
  • cb95e39: 8224261: JProgressBar always with border painted around it
  • ... and 1330 more: https://git.openjdk.org/jdk/compare/ec0cc6300a02dd92b25d9072b8b3859dab583bbd...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 (@dean-long, @vnkozlov) 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).

@openjdk openjdk bot added the ready Pull request is ready to be integrated label Nov 20, 2023
Comment on lines -220 to -221
guarantee(_buffer_size % stub_alignment() == 0, "_buffer_size not aligned");
guarantee(_buffer_limit % stub_alignment() == 0, "_buffer_limit not aligned");
Copy link
Contributor

Choose a reason for hiding this comment

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

Why these were removed?

Copy link
Member

Choose a reason for hiding this comment

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

I suggested to remove it, because it shouldn't be necessary to align the end of the code. Only the data header and code start should need alignment.

Comment on lines 500 to 503
} else if (InlineCacheBufferSize >= NonNMethodCodeHeapSize) {
jio_fprintf(defaultStream::error_stream(),
"Invalid InlineCacheBufferSize=" SIZE_FORMAT "K. Must be less than NonNMethodCodeHeapSize=" SIZE_FORMAT "K.\n",
InlineCacheBufferSize/K, NonNMethodCodeHeapSize/K);
Copy link
Contributor

Choose a reason for hiding this comment

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

You need to check for alignment of the value. In StubQueue() it is aligned up by 2*BytesPerWord so the final value could be > InlineCacheBufferSize.

Copy link
Member

Choose a reason for hiding this comment

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

I think the align up to 2*BytesPerWord is not really need, because BufferBlob::create already does its own alignment which will make the final value > InlineCacheBufferSize. BufferBlob::create uses the size as a minimum, not a maximum.
I don't think the above check should need to know the details of BufferBlob::create and StubQueue() alignment adjustments. Having InlineCacheBufferSize near to NonNMethodCodeHeapSize is going the make the JVM fail in startup for other reasons, isn't it? Maybe the max for InlineCacheBufferSize should be NonNMethodCodeHeapSize/2?

Copy link
Contributor

Choose a reason for hiding this comment

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

Thank you for answering my questions, Dean.
Yes, non-nmethod section contains template Interpreter code, stubs and adapters. So it will fail immediately if no space left for it. NonNMethodCodeHeapSize/2 is reasonable limit.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks @dean-long and @vnkozlov, I updated InlineCacheBufferSize limit to NonNMethodCodeHeapSize/2.

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.

@kvergizova
Copy link
Contributor Author

/integrate

@openjdk openjdk bot added the sponsor Pull request is ready to be sponsored label Nov 24, 2023
@openjdk
Copy link

openjdk bot commented Nov 24, 2023

@kvergizova
Your change (at version 3ee22af) is now ready to be sponsored by a Committer.

@yan-too
Copy link

yan-too commented Nov 27, 2023

/sponsor

@openjdk
Copy link

openjdk bot commented Nov 27, 2023

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

  • 1272368: 8318113: CSS.BackgroundImage doesn't implement equals
  • 28d3762: 8320618: NPE: Cannot invoke "java.lang.constant.ClassDesc.isArray()" because "this.sym" is null
  • f6e5559: 8320601: ProblemList java/lang/invoke/lambda/LambdaFileEncodingSerialization.java on linux-all
  • bddcd08: 8304701: Request with timeout aborts later in-flight request on HTTP/1.1 cxn
  • 91279fc: 8319778: Remove unreachable code in ObjectSynchronizer::exit
  • 6aa1976: 8320363: ppc64 TypeEntries::type_unknown logic looks wrong, missed optimization opportunity
  • 4d50df6: 8320691: Timeout handler on Windows takes 2 hours to complete
  • 0c9a61c: 8319220: Pattern matching switch with a lot of cases is unduly slow
  • 26c3390: 8320383: refresh libraries cache on AIX in VMError::report
  • fc31474: 8318913: The module-infos for --release data do not contain pre-set versions
  • ... and 1336 more: https://git.openjdk.org/jdk/compare/ec0cc6300a02dd92b25d9072b8b3859dab583bbd...master

Your commit was automatically rebased without conflicts.

@openjdk openjdk bot added the integrated Pull request has been integrated label Nov 27, 2023
@openjdk openjdk bot closed this Nov 27, 2023
@openjdk openjdk bot removed the ready Pull request is ready to be integrated label Nov 27, 2023
@openjdk openjdk bot removed rfr Pull request is ready for review sponsor Pull request is ready to be sponsored labels Nov 27, 2023
@openjdk
Copy link

openjdk bot commented Nov 27, 2023

@yan-too @kvergizova Pushed as commit a40d8d9.

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

@kdnilsen
Copy link
Contributor

Thanks for integrating this patch. Generational Shenandoah has also observed problems with this issue. For a user who is not intimately familiar with the internal workings of the JIT compilers, is there any advice as to what value we should set this to?

I'm guessing the answer might relate to:

  1. How often do we experience ICBufferFull safepoints in the absence of concurrent GC. Does this tell us anything?
  2. What is the typical duration of a concurrent GC cycle?
  3. Is there a recommendation for safety buffer?

FWIW: We are aware of a service that consistently experiences roughly 30 ICBufferFull safepoints during the third concurrent GC following each restart (without your patch). Once we survive this startup storm, we do not experience any further problems.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
hotspot hotspot-dev@openjdk.org integrated Pull request has been integrated
6 participants