-
Notifications
You must be signed in to change notification settings - Fork 5.6k
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
8212879: Make JVMTI TagMap table concurrent #967
Conversation
👋 Welcome back coleenp! A progress list of the required criteria for merging this PR into |
@coleenp The following labels 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 lists. 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.
Build changes look ok.
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.
Commented on nits, and reviewed GC code and tag map code. Didn't look closely on the hashmap changes.
test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/capability/CM02/cm02t001/cm02t001.cpp
Outdated
Show resolved
Hide resolved
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.
Build changes look good. Not reviewed hotspot changes.
@coleenp 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 10 new commits pushed to the
Please see this link for an up-to-date comparison between the source branch of this pull request and the ➡️ To integrate this PR with the above commit message to the |
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 I addressed your comments, retesting now. Thank you!
test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/capability/CM02/cm02t001/cm02t001.cpp
Outdated
Show resolved
Hide resolved
@coleenp this pull request can not be integrated into git checkout jvmti-table
git fetch https://git.openjdk.java.net/jdk master
git merge FETCH_HEAD
# resolve conflicts and follow the instructions given by git merge
git commit -m "Merge master"
git push |
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.
Shenandoah part looks good.
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 great in general. Great work Coleen, and thanks again for fixing this. I like all the red lines in the GC code. I added a few nits/questions.
test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/capability/CM02/cm02t001/cm02t001.cpp
Outdated
Show resolved
Hide resolved
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.
Some more nit-picking to make the code more consistent.
I've added two commits from @kimbarrett that defer the ObjectFree posting to the service thread or to a place where it could be removed before posting. |
@coleenp Unknown command |
/contributor add @kimbarrett |
@coleenp |
@coleenp |
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.
Hi Coleen,
It looks good to me.
Just a couple of nits below.
src/hotspot/share/prims/jvmtiTagMap.cpp:
There is a double-check for _needs_cleaning, so the one at line 136 can be removed:
136 if (_needs_cleaning &&
137 post_events &&
138 env()->is_enabled(JVMTI_EVENT_OBJECT_FREE)) {
139 remove_dead_entries(true /* post_object_free */);
1158 void JvmtiTagMap::remove_dead_entries(bool post_object_free) {
1159 assert(is_locked(), "precondition");
1160 if (_needs_cleaning) {
1161 log_info(jvmti, table)("TagMap table needs cleaning%s",
1162 (post_object_free ? " and posting" : ""));
1163 hashmap()->remove_dead_entries(env(), post_object_free);
1164 _needs_cleaning = false;
1165 }
1166 }
test/hotspot/jtreg/vmTestbase/nsk/jvmti/AttachOnDemand/attach021/attach021Agent00.cpp:
The change below is not needed as the call to nsk_jvmti_aod_disableEventAndFinish() does exactly the same:
- nsk_jvmti_aod_disableEventAndFinish(agentName, JVMTI_EVENT_OBJECT_FREE, success, jvmti, jni);
+
+ /* Flush any pending ObjectFree events, which may set success to 1 */
+ if (jvmti->SetEventNotificationMode(JVMTI_DISABLE,
+ JVMTI_EVENT_OBJECT_FREE,
+ NULL) != JVMTI_ERROR_NONE) {
+ success = 0;
+ }
+
+ nsk_aod_agentFinished(jni, agentName, success);
}
@@ -69,7 +69,15 @@ Java_nsk_jvmti_AttachOnDemand_attach021_attach021Target_setTagFor(JNIEnv * jni, | |||
JNIEXPORT void JNICALL | |||
Java_nsk_jvmti_AttachOnDemand_attach021_attach021Target_shutdownAgent(JNIEnv * jni, | |||
jclass klass) { | |||
nsk_jvmti_aod_disableEventAndFinish(agentName, JVMTI_EVENT_OBJECT_FREE, success, jvmti, jni); |
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.
@kimbarrett ? I'm not sure why you made this change. See Serguei's comment. It does look the same.
I want to leave _needs_cleaning at 136 because even though the boolean is checked twice, it doesn't hurt performance and it has a nice symmetry in that function. I asked Kim about the other change. Thank you for reviewing, Serguei! |
This change really is needed. The success variable in the test is a global, initially 0, set to 1 by the In the old code, if the ObjectFree event hasn't been posted yet, we pass the The split in the change causes the updated post-ObjectFree event success That required some head scratching to find at the time. That's the point of |
@kimbarrett |
So should nsk_jvmti_aod_disableEventAndFinish pass the address of success instead? Why didn't it fail before this change? |
How about this? The word 'global' helps me. |
With remerging into shenandoah, all the jdi tests pass with shenandoah also. |
Thank you to all the reviewers. |
@coleenp Since your change was applied there have been 10 commits pushed to the
Your commit was automatically rebased without conflicts. Pushed as commit ba721f5. 💡 You may see a message that your pull request was closed with unmerged commits. This can be safely ignored. |
Co-authored-by: Kim Barrett <kbarrett@openjdk.org> Co-authored-by: Coleen Phillimore <coleenp@openjdk.org> Reviewed-by: stefank, ihse, zgu, eosterlund, sspitsyn, kbarrett
This change turns the HashTable that JVMTI uses for object tagging into a regular Hotspot hashtable - the one in hashtable.hpp with resizing and rehashing. Instead of pointing directly to oops so that GC has to walk the table to follow oops and then to rehash the table, this table points to WeakHandle. GC walks the backing OopStorages concurrently.
The hash function for the table is a hash of the lower 32 bits of the address. A flag is set during GC (gc_notification if in a safepoint, and through a call to JvmtiTagMap::needs_processing()) so that the table is rehashed at the next use.
The gc_notification mechanism of weak oop processing is used to notify Jvmti to post ObjectFree events. In concurrent GCs there can be a window of time between weak oop marking where the oop is unmarked, so dead (the phantom load in peek returns NULL) but the gc_notification hasn't been done yet. In this window, a heap walk or GetObjectsWithTags call would not find an object before the ObjectFree event is posted. This is dealt with in two ways:
Event posting cannot be done in a JavaThread because the posting needs to be done while holding the table lock, so that the JvmtiEnv state doesn't change before posting is done. ObjectFree callbacks are limited in what they can do as per the JVMTI Specification. The allowed callbacks to the VM already have code to allow NonJava threads.
To avoid rehashing, I also tried to use object->identity_hash() but this breaks because entries can be added to the table during heapwalk, where the objects use marking. The starting markWord is saved and restored. Adding a hashcode during this operation makes restoring the former markWord (locked, inflated, etc) too complicated. Plus we don't want all these objects to have hashcodes because locking operations after tagging would have to always use inflated locks.
Much of this change is to remove serial weak oop processing for the weakProcessor, ZGC and Shenandoah. The GCs have been stress tested with jvmti code.
It has also been tested with tier1-6.
Thank you to Stefan, Erik and Kim for their help with this change.
Progress
Testing
Issue
Reviewers
Contributors
<kbarrett@openjdk.org>
<coleenp@openjdk.org>
Download
$ git fetch https://git.openjdk.java.net/jdk pull/967/head:pull/967
$ git checkout pull/967