-
Notifications
You must be signed in to change notification settings - Fork 5.7k
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
8344232: [PPC64] secondary_super_cache does not scale well: C1 and interpreter #22881
8344232: [PPC64] secondary_super_cache does not scale well: C1 and interpreter #22881
Conversation
👋 Welcome back mdoerr! A progress list of the required criteria for merging this PR into |
@TheRealMDoerr 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 303 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 |
@TheRealMDoerr The following label will be automatically applied to this pull request:
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. |
Webrevs
|
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. Maybe update copyright header year.
Thanks for the review! |
I have seen header getting updated for some PRs like this one: #22246 So I think we are expected to update, I haven’t seen any such rule though? |
Some people use a script, but it's unclear if it does the right thing: #22890 (comment) |
|
__ check_klass_subtype_slow_path(sub_klass, super_klass, temp1_reg, temp2_reg); // returns with CR0.eq if successful | ||
__ crandc(CCR0, Assembler::equal, CCR0, Assembler::equal); // failed: CR0.ne | ||
temp1_reg = R6; | ||
__ check_klass_subtype_slow_path(sub_klass, super_klass, temp1_reg, noreg); // may return with CR0.eq if successful |
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.
The comment is unclear to me. Where is the result of the subtype check? Can it also return with CR0.ne if successful?
I noticed you added the crandc
to check_klass_subtype_slow_path_linear()
but if we reach there calling from this location then the crandc
is not emitted because L_success == nullptr
. Is this ok?
I'd appreciate comments on the masm methods explaining how the result of the subtype check is conveyed.
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.
The correct result is always in CR0 with this PR (unless a label or result GP reg is provided).
"return" means "blr", here. That can optionally be used in case of success. In this case, CR0 is always "eq".
I've moved the crandc
instruction into check_klass_subtype_slow_path_linear
which contains such a "blr" for a success case. This way, the linear version works exactly as before.
The new code check_klass_subtype_slow_path_table
doesn't use "blr". That's why I added "may" to the comment.
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.
This is extremely hard to see.
L2154 with the "blr" in check_klass_subtype_slow_path_linear
looks redundant to me. It should be removed if you agree.
The comment here should be adapted then too.
Also the comment at macroAssembler_ppc.cpp:2258 needs to be adapted because fallthrough from check_klass_subtype_slow_path
does not mean "not successful". L_failure
could be renamed to L_fast_path_failure
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 L_failure
is correct. And it's used the same way on all platforms.
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, I see. I missed that L_failure
is passed by reference
jdk/src/hotspot/cpu/ppc/macroAssembler_ppc.cpp
Lines 2159 to 2168 in c00557f
void MacroAssembler::check_klass_subtype(Register sub_klass, | |
Register super_klass, | |
Register temp1_reg, | |
Register temp2_reg, | |
Label& L_success) { | |
Label L_failure; | |
check_klass_subtype_fast_path(sub_klass, super_klass, temp1_reg, temp2_reg, &L_success, &L_failure); | |
check_klass_subtype_slow_path(sub_klass, super_klass, temp1_reg, temp2_reg, &L_success); | |
bind(L_failure); // Fallthru if not successful. | |
} |
Therefore it's never null and
L_failure
is reached if, and only if the result of the type check is negative.
@@ -2154,6 +2154,96 @@ void MacroAssembler::check_klass_subtype_slow_path(Register sub_klass, | |||
else if (result_reg == noreg) { blr(); } // return with CR0.eq if neither label nor result reg provided | |||
|
|||
bind(fallthru); | |||
if (L_success != nullptr && result_reg == noreg) { |
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.
Is there a problem if L_success == nullptr && result_reg == noreg
and there aren't any secondary supers?
In that case we would reach here with CR0.eq from L2134 and we would fallthrough with CR0.eq. Due to the change in C1StubId::slow_subtype_check_id
we would return there with CR0.eq.
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.
This is a reproducer:
public class InstanceOfTest {
public static interface TestInterfaceI {
}
public static class TestClassNegative {
}
public static void main(String[] args) {
Object obj = new TestClassNegative();
for (int i = 100_000; i > 0; i--) {
dontinline_testMethod(obj);
}
boolean result = dontinline_testMethod(obj);
System.out.println("result: " + result);
}
static boolean dontinline_testMethod(Object obj) {
return obj instanceof TestInterfaceI;
}
}
./jdk/bin/java -XX:TieredStopAtLevel=1 -XX:-UseSecondarySupersTable InstanceOfTest
result: true
Thanks for looking at this! The condition was wrong. I have improved the design of |
li(result_reg, 1); // load non-zero result (indicates a miss) | ||
} else if (L_success == nullptr) { | ||
crandc(CCR0, Assembler::equal, CCR0, Assembler::equal); // miss indicated by CR0.ne | ||
} | ||
b(fallthru); | ||
|
||
bind(hit); | ||
std(super_klass, target_offset, sub_klass); // save result to cache | ||
if (result_reg != noreg) { li(result_reg, 0); } // load zero result (indicates a hit) | ||
if (L_success != nullptr) { b(*L_success); } |
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.
Handling L_success != nullptr
should be put on the else-branch of the previous if-statement.
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.
Doesn't make a real difference, but I've cleaned it up.
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.
Thanks. It matches the assertion you've added. I like consistency. It helps understanding stuff.
I've run most of the tier 1 tests with JTREG="VM_OPTIONS=-XX:-UseSecondarySupersTable" and didn't see new failures. I'll rerun tests. Note that Oracle Copyright years are already updated in head, but I don't want to merge because the PPC64le build is currently broken. |
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.
Thanks for doing the port 👍
Cheers, Richard.
Thanks for the review and for finding the bug! |
Tier 1-4 have passed with and without UseSecondarySupersTable on both, linux ppc64le and AIX. |
Going to push as commit 4a375e5.
Your commit was automatically rebased without conflicts. |
@TheRealMDoerr Pushed as commit 4a375e5. 💡 You may see a message that your pull request was closed with unmerged commits. This can be safely ignored. |
PPC64 implementation of ead0116. I have implemented a couple of rotate instructions.
The first commit only implements
lookup_secondary_supers_table_var
and uses it in C2. The second commit makes the changes to use it in the interpreter, runtime and C1.C1 part is refactored such that the same code as before this patch is generated when
UseSecondarySupersTable
is disabled. Some stubs are modified to provide one more temp register.Performance difference can be observed when C2 is disabled (measured on Power10):
SecondarySuperCacheHits
seems to be slightly slower, butSecondarySuperCacheInterContention
andSecondarySuperCacheIntraContention
are much faster (when C2 is disabled).Progress
Issue
Reviewers
Reviewing
Using
git
Checkout this PR locally:
$ git fetch https://git.openjdk.org/jdk.git pull/22881/head:pull/22881
$ git checkout pull/22881
Update a local copy of the PR:
$ git checkout pull/22881
$ git pull https://git.openjdk.org/jdk.git pull/22881/head
Using Skara CLI tools
Checkout this PR locally:
$ git pr checkout 22881
View PR using the GUI difftool:
$ git pr show -t 22881
Using diff file
Download this PR as a diff file:
https://git.openjdk.org/jdk/pull/22881.diff
Using Webrev
Link to Webrev Comment