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

8266015: Implement AdapterHandlerLibrary lookup fast-path for common adapters #3706

Closed
wants to merge 11 commits into from

Conversation

@cl4es
Copy link
Member

@cl4es cl4es commented Apr 27, 2021

This patch refactors AdapterHandlerLibrary initialization so that we can initialize a handful of commonly used adapters early during bootstrap, and avoid taking the AdapterHandlerLibrary_lock when looking up these adapters.

Since the 5 most common adapters plus the abstract adapter constitutes roughly 60% of the method shapes loaded and linked on a Hello World, this means a relatively significant startup optimization (~2M insns on Hello World); most of the win is in lookup code that will be a significant part of the cost of class loading even when no adapters need to be generated.

This enhancement partially recuperates the regression reported in https://bugs.openjdk.java.net/browse/JDK-8265523


Progress

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

Issue

  • JDK-8266015: Implement AdapterHandlerLibrary lookup fast-path for common adapters

Reviewers

Reviewing

Using git

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

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

Using Skara CLI tools

Checkout this PR locally:
$ git pr checkout 3706

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

Using diff file

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

@bridgekeeper
Copy link

@bridgekeeper bridgekeeper bot commented Apr 27, 2021

👋 Welcome back redestad! 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
Copy link

@openjdk openjdk bot commented Apr 27, 2021

@cl4es 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 Apr 27, 2021
@cl4es
Copy link
Member Author

@cl4es cl4es commented Apr 28, 2021

/label remove hotspot
/label add hotspot-runtime

Loading

@openjdk openjdk bot removed the hotspot label Apr 28, 2021
@openjdk
Copy link

@openjdk openjdk bot commented Apr 28, 2021

@cl4es
The hotspot label was successfully removed.

Loading

@openjdk
Copy link

@openjdk openjdk bot commented Apr 28, 2021

@cl4es
The hotspot-runtime label was successfully added.

Loading

@cl4es
Copy link
Member Author

@cl4es cl4es commented Apr 28, 2021

To avoid making this code more complex, and enable splitting apart get_adapter, this patch simplifies the output for the develop flag PrintAdapterHandlers somewhat. Before this would arbitrarily print the signature of the method that happen to cause the adapter to be generated. Since adapters for methods with the same basic type arguments are shared it makes more sense to distill to BasicType strings.

Before:

AHE@0x00007efc503007a0: 0xbaabbaa0 i2c: 0x00007efc399484e0 c2i: 0x00007efc399485e2 c2iUV: 0x00007efc399485a8 c2iNCI: 0x00007efc3994861f
i2c argument handler #246 for: static ([Ljava/lang/Object;IILjava/util/Comparator;[Ljava/lang/Object;II)V 0xbaabbaa0 (614 bytes generated)
c2i argument handler starts at 0x7efc399485e2

After:

AHE@0x00007fc28c2f6850: 0x0baabbaa i2c: 0x00007fc27570d460 c2i: 0x00007fc27570d562 c2iUV: 0x00007fc27570d528 c2iNCI: 0x00007fc27570d59f
i2c argument handler #244 for: LIILLII 0x0baabbaa (614 bytes generated)
c2i argument handler starts at 0x7fc27570d562

Loading

@cl4es cl4es marked this pull request as ready for review Apr 28, 2021
@openjdk openjdk bot added the rfr label Apr 28, 2021
@mlbridge
Copy link

@mlbridge mlbridge bot commented Apr 28, 2021

Loading

Copy link
Member

@iklam iklam left a comment

Looks good overall, but I think we should avoid changing the return NULL to fatal().

Also note to other reviewers: when looking at the "Files changed", add &w=1 to the URL so GitHub will ignore whitespace changes.

Loading

? adapter_encoding(sig_bt[sig_index++])
: 0);
for (int byte = 0; sig_index < total_args_passed && byte < _basic_types_per_int; byte++) {
int bt = adapter_encoding(sig_bt[sig_index++]);
Copy link
Member

@iklam iklam Apr 29, 2021

Choose a reason for hiding this comment

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

Why is the above changed? Is it for performance? It seems unrelated to this PR.

Loading

Copy link
Member Author

@cl4es cl4es Apr 29, 2021

Choose a reason for hiding this comment

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

Performance (fingerprints are calculated on every lookup) but also for simplifying the fingerprint iterator in as_basic_args_string: Once we hit total_args_passed, the previous algorithm would keep shifting and adding zero bits until the int is "filled". Now I stop when the last argument has been processed, which meant that iterating becomes simpler. Since the hash function will xor the last value (which is the only one that can have zeros) as a last step, it should also improve how well trailing arguments shuffles low bits.

I'm adding some comments, and also fixed a bug in as_basic_args_string when > 8 arguments and changed as_string to not include leading zeroes of the last in (0xbbbbbabb0000000b -> 0xbbbbbabbb)

Loading

new_adapter = AdapterBlob::create(&buffer);
NOT_PRODUCT(int insts_size = buffer.insts_size());
if (new_adapter == NULL) {
fatal("No memory to create adapter");
Copy link
Member

@iklam iklam Apr 29, 2021

Choose a reason for hiding this comment

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

This used to be return NULL;, and the JVM is supposed to continue execution (but the linking of the current class will get a VirtualMachineError. I think we should keep the old behavior.

Loading

Copy link
Member Author

@cl4es cl4es Apr 29, 2021

Choose a reason for hiding this comment

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

Yes, an unintentional result of me breaking the code flow apart and then merging it back together.

Loading

@cl4es
Copy link
Member Author

@cl4es cl4es commented Apr 30, 2021

@iklam asked me offline to experiment using a concurrent hash table keyed on fingerprint to create a quick filter. I've done a few prototypes and verified that a concurrent hash table alone[1] does perform roughly as well as this patch on a few sampled applications, and that combining the current patch with a concurrent hash table comes out slightly ahead of both[2]. But this comes at a cost of an additional data structure that might grow to non-trivial size.

After analyzing the most significant part of the difference comes not from a reduction in Mutex overhead (~400k insts) but from a reduction in SignatureStream parsing (~1.2M insns). Using a SignatureIterator that takes the method fingerprint into account gets us ahead of the combined ConcurrentHashTable experiment, without needing to add another data structure.

For a follow-up to this it might make sense to re-implement AdapterHandlerLibrary::_adapters as a ConcurrentHashTable rather than a BasicHashtable.

[1] https://github.com/openjdk/jdk/compare/master...cl4es:adapter_cht_only?expand=1
[2] https://github.com/openjdk/jdk/compare/master...cl4es:adapter_cht_combined?expand=1

Loading

iklam
iklam approved these changes May 4, 2021
Copy link
Member

@iklam iklam left a comment

The latest version LGTM. Thanks for also testing out the alternative optimizations.

Loading

@openjdk
Copy link

@openjdk openjdk bot commented May 4, 2021

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

8266015: Implement AdapterHandlerLibrary lookup fast-path for common adapters

Reviewed-by: iklam, coleenp

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

  • 0790e60: 8196743: jstatd doesn't see new Java processes inside Docker container
  • c6aa8f1: 8232644: bugs in serialized-form.html
  • b5b3119: 8266589: (fs) Improve performance of Files.copy() on macOS using copyfile(3)
  • 947d69d: 8265042: javadoc HTML files not generated for types nested in records
  • 946b0fe: 8266645: javac should not check for sealed supertypes in intersection types
  • 74fecc0: 8266503: [UL] Make Decorations safely copy-able and reduce their size
  • 86b8dc9: 8265426: Update java.security to use instanceof pattern variable
  • 3fcdc50: 8266646: Add more diagnostic to java/lang/System/LoggerFinder/modules
  • 9a19a0c: 8264760: JVM crashes when two threads encounter the same resolution error
  • 14f0afe: 8214237: Join parallel phases post evacuation
  • ... and 197 more: https://git.openjdk.java.net/jdk/compare/0a4c33826d0422af7c4cfa5f479fe0b6b0f83d23...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.

➡️ To integrate this PR with the above commit message to the master branch, type /integrate in a new comment.

Loading

@openjdk openjdk bot added the ready label May 4, 2021
coleenp
coleenp approved these changes May 7, 2021
Copy link
Contributor

@coleenp coleenp left a comment

This looks good to me!

Loading

case T_FLOAT: st.print("F"); break;
case T_DOUBLE: st.print("D"); break;
case T_VOID: break;
default: ShouldNotReachHere();
Copy link
Contributor

@coleenp coleenp May 7, 2021

Choose a reason for hiding this comment

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

For some reason, I thought there'd be some mapping from T_INT to JVM_SIGNATURE_INT that you could do
st.print(signature_char(v)); and avoid this work.

Loading

@cl4es
Copy link
Member Author

@cl4es cl4es commented May 10, 2021

@iklam @coleenp - thank you for reviewing!

/integrate

Loading

@openjdk openjdk bot closed this May 10, 2021
@openjdk openjdk bot added integrated and removed ready rfr labels May 10, 2021
@openjdk
Copy link

@openjdk openjdk bot commented May 10, 2021

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

  • 69b96f9: 8266610: Method RandomAccessFile#length() returns 0 for block devices on linux.
  • 9b76955: 8266249: javax/swing/JPopupMenu/7156657/bug7156657.java fails on macOS
  • 3af4efd: 8265291: Error in Javadoc for doAccessibleAction API in AccessibleJSlider class
  • be4f25b: 8266369: (se) Add wepoll based Selector
  • ff77ca8: 8266675: Optimize IntHashTable for encapsulation and ease of use
  • 04fad70: 8266765: [BACKOUT] JDK-8255493 Support for pre-generated java.lang.invoke classes in CDS dynamic archive
  • 0790e60: 8196743: jstatd doesn't see new Java processes inside Docker container
  • c6aa8f1: 8232644: bugs in serialized-form.html
  • b5b3119: 8266589: (fs) Improve performance of Files.copy() on macOS using copyfile(3)
  • 947d69d: 8265042: javadoc HTML files not generated for types nested in records
  • ... and 203 more: https://git.openjdk.java.net/jdk/compare/0a4c33826d0422af7c4cfa5f479fe0b6b0f83d23...master

Your commit was automatically rebased without conflicts.

Pushed as commit 0f925d1.

💡 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