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

8275729: Qualified method names in CodeHeap Analytics #6200

Closed
wants to merge 1 commit into from

Conversation

eastig
Copy link
Contributor

@eastig eastig commented Nov 1, 2021

This PR changes nmethods names in METHOD NAMES for CodeHeap section to be qualified.
Testing:

  • make test TEST="gtest": Passed
  • make run-test TEST="tier1": Passed
  • make run-test TEST="tier2": Passed
  • make run-test TEST=serviceability/dcmd/compiler/CodeHeapAnalyticsMethodNames.java: Passed

Progress

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

Issue

  • JDK-8275729: Qualified method names in CodeHeap Analytics

Reviewers

Reviewing

Using git

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

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

Using Skara CLI tools

Checkout this PR locally:
$ git pr checkout 6200

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

Using diff file

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

@bridgekeeper
Copy link

@bridgekeeper bridgekeeper bot commented Nov 1, 2021

👋 Welcome back eastig! 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 label Nov 1, 2021
@openjdk
Copy link

@openjdk openjdk bot commented Nov 1, 2021

@eastig The following labels will be automatically applied to this pull request:

  • hotspot-compiler
  • serviceability

When this pull request is ready to be reviewed, an "RFR" email will be sent to the corresponding mailing lists. If you would like to change these labels, use the /label pull request command.

@openjdk openjdk bot added serviceability hotspot-compiler labels Nov 1, 2021
@mlbridge
Copy link

@mlbridge mlbridge bot commented Nov 1, 2021

Webrevs

Copy link
Member

@kelthuzadx kelthuzadx left a comment

This looks good now. Old output can not tell us which class the method belongs to.

Old:
0x00007f6e91063010 (+0x00000010) 0x000000a0(   0K)  none   0    480 nMethod (deopt)     nmethod
0x00007f6e91063310 (+0x00000310) 0x000000f8(   0K)  none   0    480 nMethod (active)    name()Ljava/lang/String;
0x00007f6e91063610 (+0x00000610) 0x000000f8(   0K)  none   0    480 nMethod (active)    descriptor()Ljava/lang/module/ModuleDescriptor;
0x00007f6e91063910 (+0x00000910) 0x00000000(   0K)  none   0    480 nMethod (active)    getReferenceVolatile(Ljava/lang/Object;J)Ljava/lang/Object;
0x00007f6e91063d90 (+0x00000d90) 0x00000000(   0K)  none   0    480 nMethod (active)    hashCode()I
0x00007f6e91064190 (+0x00001190) 0x000000f8(   0K)    c1   1    480 nMethod (active)    name()Ljava/lang/String;
0x00007f6e91064490 (+0x00001490) 0x000000f8(   0K)    c1   1    480 nMethod (active)    modifiers()Ljava/util/Set;
0x00007f6e91064790 (+0x00001790) 0x000000f8(   0K)    c1   1    480 nMethod (active)    targets()Ljava/util/Set;
0x00007f6e91064a90 (+0x00001a90) 0x000000f8(   0K)    c1   1    480 nMethod (active)    source()Ljava/lang/String;
0x00007f6e91064d90 (+0x00001d90) 0x000000f8(   0K)    c1   1    480 nMethod (active)    isEmpty()Z
New:

0x00007f08adc94010 (+0x00000010) 0x00000150(   0K)    c1   3    480 nMethod (deopt)     nmethod
0x00007f08adc94390 (+0x00000390) 0x000001b0(   0K)    c1   3    480 nMethod (active)    java.lang.String.isLatin1()Z
0x00007f08adc94710 (+0x00000710) 0x00000258(   0K)    c1   3    480 nMethod (active)    jdk.internal.util.Preconditions.checkIndex(IILjava/util/function/BiFunction;)I
0x00007f08adc94b90 (+0x00000b90) 0x000004e8(   1K)    c1   3    480 nMethod (deopt)     nmethod
0x00007f08adc95310 (+0x00001310) 0x00000298(   0K)    c1   3    480 nMethod (active)    java.lang.StringLatin1.charAt([BI)C
0x00007f08adc95790 (+0x00001790) 0x000001a0(   0K)    c1   3    480 nMethod (active)    java.lang.String.checkIndex(II)V
0x00007f08adc95b10 (+0x00001b10) 0x00000170(   0K)    c1   3    480 nMethod (active)    java.lang.String.coder()B
0x00007f08adc95e90 (+0x00001e90) 0x000003e8(   0K)    c1   3    480 nMethod (active)    java.lang.String.hashCode()I
0x00007f08adc96490 (+0x00002490) 0x00000130(   0K)    c1   3    480 nMethod (deopt)     nmethod
0x00007f08adc96790 (+0x00002790) 0x00000210(   0K)    c1   3    480 nMethod (active)    java.lang.String.length()I

Copy link
Member

@TobiHartmann TobiHartmann left a comment

Looks good to me.

@openjdk
Copy link

@openjdk openjdk bot commented Nov 2, 2021

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

8275729: Qualified method names in CodeHeap Analytics

Reviewed-by: yyang, thartmann

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

  • 8630f55: 8275406: Add copy-to-clipboard feature to snippet UI
  • 9971a2c: 8275735: [linux] Remove deprecated Metrics api (kernel memory limit)
  • b7a06be: 8252990: Intrinsify Unsafe.storeStoreFence
  • 92be9d8: 8276236: Table headers missing in Formatter api docs
  • 9bf3165: 8276164: RandomAccessFile#write method could throw IndexOutOfBoundsException that is not described in javadoc
  • 0488ebd: 8276105: C2: Conv(D|F)2(I|L)Nodes::Ideal should handle rounding correctly
  • acceffc: 8273704: DrawStringWithInfiniteXform.java failed : drawString with InfiniteXform transform takes long time
  • 2eafa03: 8276234: Trivially clean up locale-related code
  • 47e7a42: 8262945: [macos] Regression Manual Test for Key Events Fails
  • 99b7b95: 8276205: Shenandoah: CodeCache_lock should always be held for initializing code cache iteration
  • ... and 91 more: https://git.openjdk.java.net/jdk/compare/0bcc1749eaea20cb983a983073ad33d305681879...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 (@kelthuzadx, @TobiHartmann) 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 label Nov 2, 2021
@eastig
Copy link
Contributor Author

@eastig eastig commented Nov 2, 2021

/integrate

@openjdk openjdk bot added the sponsor label Nov 2, 2021
@openjdk
Copy link

@openjdk openjdk bot commented Nov 2, 2021

@eastig
Your change (at version bba8ae3) is now ready to be sponsored by a Committer.

@phohensee
Copy link
Member

@phohensee phohensee commented Nov 2, 2021

/sponsor

@openjdk
Copy link

@openjdk openjdk bot commented Nov 2, 2021

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

  • fa4ce82: 8276260: (se) Remove java/nio/channels/Selector/Wakeup.java from ProblemList (win)
  • 495c828: 8276188: Clarify "default charset" descriptions in String class
  • cd778f5: 8202667: java/awt/Debug/DumpOnKey/DumpOnKey.java times out on Windows
  • b889f2a: 8276175: codestrings.validate_vm gtest still broken on ppc64 after JDK-8276046
  • 5b4e398: 8275766: (tz) Update Timezone Data to 2021e
  • 8630f55: 8275406: Add copy-to-clipboard feature to snippet UI
  • 9971a2c: 8275735: [linux] Remove deprecated Metrics api (kernel memory limit)
  • b7a06be: 8252990: Intrinsify Unsafe.storeStoreFence
  • 92be9d8: 8276236: Table headers missing in Formatter api docs
  • 9bf3165: 8276164: RandomAccessFile#write method could throw IndexOutOfBoundsException that is not described in javadoc
  • ... and 96 more: https://git.openjdk.java.net/jdk/compare/0bcc1749eaea20cb983a983073ad33d305681879...master

Your commit was automatically rebased without conflicts.

@openjdk openjdk bot closed this Nov 2, 2021
@openjdk openjdk bot added integrated and removed ready rfr sponsor labels Nov 2, 2021
@openjdk
Copy link

@openjdk openjdk bot commented Nov 2, 2021

@phohensee @eastig Pushed as commit 8fc16f1.

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

@@ -2334,6 +2335,11 @@ void CodeHeapState::print_names(outputStream* out, CodeHeap* heap) {
Symbol* methSig = method->signature();
const char* methSigS = (methSig == NULL) ? NULL : methSig->as_C_string();
methSigS = (methSigS == NULL) ? "<method signature unavailable>" : methSigS;

Klass* klass = method->method_holder();
assert(klass->is_loader_alive(), "must be alive");
Copy link
Member

@simonis simonis Nov 2, 2021

Choose a reason for hiding this comment

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

Are you sure klass is always valid here and that its class loader has to be alive (i.e. the corresponding class hasn't been unloaded in the meantime)?

In https://bugs.openjdk.java.net/browse/JDK-8275729 you say that the Top50 list already has qualified names but as far as I know, that information is already collected in the aggregation step where it is safe. You now query this information in the reporting step.

I know we had problems due to access to dead methods before (see JDK-8219586: CodeHeap State Analytics processes dead nmethods and I just want to make sure we don't re-introduce such problems.

Maybe @RealLucy or @fisk can have an additional look?

Copy link
Contributor Author

@eastig eastig Nov 2, 2021

Choose a reason for hiding this comment

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

@simonis
The code is guarded by checks:

        // access nmethod and Method fields only if we own the CodeCache_lock.
        // This fact is implicitly transported via nm != NULL.
        if (nmethod_access_is_safe(nm)) {
        ...
          bool         get_name   = (cbType == nMethod_inuse) || (cbType == nMethod_notused);
        ...
          if (get_name) {

I was thinking whether I should use if (klass->is_loader_alive()) or assert(klass->is_loader_alive()). I chose the assert because if it is safe to access Method than its holder Klass must be alive.

Copy link
Contributor

@RealLucy RealLucy Nov 2, 2021

Choose a reason for hiding this comment

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

Hi,
the code is safe. Not because of the checks cited by @eastig but because print_names() is only called if the required locks (Compile_lock and CodeCache_lock) have been continuously held since the aggregation step. See src/hotspot/share/compiler/compileBroker.cpp. A lot of effort has been spent to be less restrictive on print_names(), with no success.
Thanks for the enhancement.

@phohensee
Copy link
Member

@phohensee phohensee commented Nov 2, 2021

Volker, I sponsored this before you posted your review. Evgeny, if it's a problem, please file a bug.

@simonis
Copy link
Member

@simonis simonis commented Nov 2, 2021

No problem, I know I was late :)
But I also know that this is a sensitive area, so better double check...

@eastig
Copy link
Contributor Author

@eastig eastig commented Nov 2, 2021

Thanks for reviewing @kelthuzadx and @TobiHartmann.

Copy link
Contributor

@RealLucy RealLucy left a comment

To me, the change looks good.

@@ -2334,6 +2335,11 @@ void CodeHeapState::print_names(outputStream* out, CodeHeap* heap) {
Symbol* methSig = method->signature();
const char* methSigS = (methSig == NULL) ? NULL : methSig->as_C_string();
methSigS = (methSigS == NULL) ? "<method signature unavailable>" : methSigS;

Klass* klass = method->method_holder();
assert(klass->is_loader_alive(), "must be alive");
Copy link
Contributor

@RealLucy RealLucy Nov 2, 2021

Choose a reason for hiding this comment

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

Hi,
the code is safe. Not because of the checks cited by @eastig but because print_names() is only called if the required locks (Compile_lock and CodeCache_lock) have been continuously held since the aggregation step. See src/hotspot/share/compiler/compileBroker.cpp. A lot of effort has been spent to be less restrictive on print_names(), with no success.
Thanks for the enhancement.

@vnkozlov
Copy link
Contributor

@vnkozlov vnkozlov commented Nov 2, 2021

The change caused failure in our testing: https://bugs.openjdk.java.net/browse/JDK-8276429

@vnkozlov
Copy link
Contributor

@vnkozlov vnkozlov commented Nov 2, 2021

I don't think we need this assert just to print klass's name.
May be follow the code pattern for method's name and signature.

@eastig
Copy link
Contributor Author

@eastig eastig commented Nov 2, 2021

I don't think we need this assert just to print klass's name. May be follow the code pattern for method's name and signature.

Agree. I'll submit PR with the code:

Symbol* className = klass->name();
const char*   classNameS = (className == nullptr) ? nullptr : className->external_name();
classNameS = (classNameS == nullptr) ? "<class name unavailable>" : classNameS;
ast->print("%s.", classNameS);

@vnkozlov
Copy link
Contributor

@vnkozlov vnkozlov commented Nov 2, 2021

Yes, I am currently testing similar fix:

-            Klass* klass = method->method_holder();
-            assert(klass->is_loader_alive(), "must be alive");
+            Klass* methHolder = method->method_holder();
+            const char*    methHolderS  = (methHolder  == NULL) ? NULL : methHolder->external_name();
+            methHolderS = (methHolderS  == NULL) ? "<method holder name unavailable>" : methHolderS;
 
-            ast->print("%s.", klass->external_name());
+            ast->print("%s.", methHolderS);

Note, failed test is closed so I have to run testing.

@eastig
Copy link
Contributor Author

@eastig eastig commented Nov 2, 2021

Yes, I am currently testing similar fix:

-            Klass* klass = method->method_holder();
-            assert(klass->is_loader_alive(), "must be alive");
+            Klass* methHolder = method->method_holder();
+            const char*    methHolderS  = (methHolder  == NULL) ? NULL : methHolder->external_name();
+            methHolderS = (methHolderS  == NULL) ? "<method holder name unavailable>" : methHolderS;
 
-            ast->print("%s.", klass->external_name());
+            ast->print("%s.", methHolderS);

Note, failed test is closed so I have to run testing.

Is NULL method holder an acceptable situation? Could it be a sign of a bug?
BTW, Klass::external_name() returns <unknown> if Klass::name() is NULL.

@vnkozlov
Copy link
Contributor

@vnkozlov vnkozlov commented Nov 2, 2021

Is NULL method holder an acceptable situation? Could it be a sign of a bug?

You are right, all methods should have class holders. I just followed code pattern.

BTW, Klass::external_name() returns <unknown> if Klass::name() is NULL.

I see, you want to have the same string instead of <unknown>. Reasonable.

I will test your changes too. File PR and I will review and post testing results.

@vnkozlov
Copy link
Contributor

@vnkozlov vnkozlov commented Nov 2, 2021

BTW, you need to update Copyright year in file.

@eastig
Copy link
Contributor Author

@eastig eastig commented Nov 3, 2021

@vnkozlov Created PR #6234

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
hotspot-compiler integrated serviceability
7 participants