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

8257692: Using both heap and native segments can degrade performance #413

Conversation

mcimadamore
Copy link
Collaborator

@mcimadamore mcimadamore commented Dec 11, 2020

This patch fixes a problem with type profile pollution when segments of different kinds are used on the same memory access var handle, or on the same MemoryAccess static method.

In principle, argument profiling should kick in for VarHandles and MethodHandles, and that should be enough at least to avoid pollution when using var handles directly. In reality, this is not the case; as Vlad discovered after relatively intense debugging session (thanks!), the VarHandle implementation code has to cast the incoming segment to the MemorySegmentProxy internal interface. This creates problems for C2, as concrete segment implementations have two interface types: MemorySegment and the internal MemorySegmentProxy class. Side casts from one to the other are not supported well, and can cause loss of type profiling infomation.

To solve this problem we realized, in hindisght, that MemorySegmentProxy didn't really needed to be an interface and that it could easily be converted to an abstract class. Alone this solves 50% of the issues, since that makes direct var handle access robust to pollution issues. The remaining problems (using accessors in MemoryAccess class) can be addressed the usual way, by adding argument type profiling for the methods in that class (similarly to what we've done for ScopedMemoryAccess).

Here are some numbers before the patch:

Benchmark                                            Mode  Cnt   Score   Error  Units
LoopOverPollutedSegments.heap_segment_floats_VH      avgt   30  11.535 ? 0.039  ms/op
LoopOverPollutedSegments.heap_segment_floats_static  avgt   30  10.860 ? 0.162  ms/op
LoopOverPollutedSegments.heap_segment_ints_VH        avgt   30  11.479 ? 0.202  ms/op
LoopOverPollutedSegments.heap_segment_ints_static    avgt   30  10.562 ? 0.027  ms/op
LoopOverPollutedSegments.heap_unsafe                 avgt   30   0.240 ? 0.003  ms/op
LoopOverPollutedSegments.native_segment_VH           avgt   30  11.603 ? 0.154  ms/op
LoopOverPollutedSegments.native_segment_static       avgt   30  10.613 ? 0.128  ms/op
LoopOverPollutedSegments.native_unsafe               avgt   30   0.243 ? 0.003  ms/op

As you can see there is quite a big difference between unsafe access and all the other modes. Here are the results after the patch:

Benchmark                                            Mode  Cnt  Score   Error  Units
LoopOverPollutedSegments.heap_segment_floats_VH      avgt   30  0.244 ? 0.002  ms/op
LoopOverPollutedSegments.heap_segment_floats_static  avgt   30  0.301 ? 0.001  ms/op
LoopOverPollutedSegments.heap_segment_ints_VH        avgt   30  0.245 ? 0.003  ms/op
LoopOverPollutedSegments.heap_segment_ints_static    avgt   30  0.302 ? 0.004  ms/op
LoopOverPollutedSegments.heap_unsafe                 avgt   30  0.242 ? 0.003  ms/op
LoopOverPollutedSegments.native_segment_VH           avgt   30  0.246 ? 0.004  ms/op
LoopOverPollutedSegments.native_segment_static       avgt   30  0.295 ? 0.006  ms/op
LoopOverPollutedSegments.native_unsafe               avgt   30  0.245 ? 0.003  ms/op

That is, the situation is back to normal. Thanks to @JornVernee and @iwanowww for the help!


Progress

  • Change must not contain extraneous whitespace
  • Change must be properly reviewed

Issue

  • JDK-8257692: Using both heap and native segments can degrade performance

Reviewers

Download

$ git fetch https://git.openjdk.java.net/panama-foreign pull/413/head:pull/413
$ git checkout pull/413

@bridgekeeper
Copy link

bridgekeeper bot commented Dec 11, 2020

👋 Welcome back mcimadamore! A progress list of the required criteria for merging this PR into foreign-memaccess+abi 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 Ready for review label Dec 11, 2020
@mlbridge
Copy link

mlbridge bot commented Dec 11, 2020

Webrevs

@openjdk
Copy link

openjdk bot commented Dec 11, 2020

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

8257692: Using both heap and native segments can degrade performance

Reviewed-by: jvernee, psandoz, vlivanov

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 no new commits pushed to the foreign-memaccess+abi branch. If another commit should be pushed before you perform the /integrate command, your PR will be automatically rebased. If you prefer to avoid any potential automatic rebasing, please check the documentation for the /integrate command for further details.

➡️ To integrate this PR with the above commit message to the foreign-memaccess+abi branch, type /integrate in a new comment.

@openjdk openjdk bot added the ready Ready to be integrated label Dec 11, 2020
Copy link
Member

@PaulSandoz PaulSandoz left a comment

Choose a reason for hiding this comment

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

Glad you all managed to resolve this.

It would be nice to mark the classes that have special profiling characteristics, otherwise it's easy to forgot or be unaware of the implications. Perhaps comments on each are sufficient. An annotation would be nice but is more work.

@JornVernee
Copy link
Member

JornVernee commented Dec 11, 2020

@PaulSandoz FWIW, I also looked into using an annotation to drive the profiling, instead of the special casing based on the name, but the problem is that we can't see the annotations of an unresolved method, so would have to resolve everything in the interpreter just to check for annotations. The current mechanism is solely based on the symbolic reference found in the caller's bytecode.

Copy link
Collaborator

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

@mcimadamore
Copy link
Collaborator Author

/integrate

@openjdk openjdk bot closed this Dec 11, 2020
@openjdk openjdk bot added integrated Pull request has been integrated and removed ready Ready to be integrated rfr Ready for review labels Dec 11, 2020
@openjdk
Copy link

openjdk bot commented Dec 11, 2020

@mcimadamore Pushed as commit e367491.

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
integrated Pull request has been integrated
4 participants