-
Notifications
You must be signed in to change notification settings - Fork 1.8k
[GR-41851] Support thread sleep as a mirror event in JDK 19 #5214
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
[GR-41851] Support thread sleep as a mirror event in JDK 19 #5214
Conversation
|
@roberttoyonaga do you know why this event was removed in JDK19? Does the event cause issues for virtual threads? |
christianhaeubl
left a 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.
Thanks for working on that, I stumbled across the same issue today in a slightly different context.
| public class ThreadSleepEvent { | ||
| @Category("Java Application") | ||
| @Label("Java Thread Sleep") | ||
| @Name("jdk.ThreadSleep") |
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.
Does that really work reliably? If I understand everything correctly, then the following is happening:
- HotSpot uses
jdk.jfr.events.ThreadSleepEventas the mirror event. - HotSpot registers
jdk.internal.event.ThreadSleepEventas the thread sleep event. This creates aPlatformEventTypeobject at build time that ends up in the image heap (instance A). - You create a new
PlatformEventTypeobject for the SVM-internal classcom.oracle.svm.core.jfr.events.ThreadSleepEventat build time (instance B). This new object reuses the event id of instance A but otherwise behaves like a VM-internal event (e.g.,SubstrateJVM.eventSettingsis used to determine if the event is enabled or disabled). - You unconditionally enable the thread sleep event at build time (
SubstrateJVM.handleMirrorEvents()).
I see the following issues:
- What if the event should not be enabled by default?
- What if the event is enabled at runtime via
jdk.internal.event.ThreadSleepEvent? I don't think that the updated value will be used because JDK events directly store in theirPlatformEventTypeobject if the event is enabled. However, we would accessSubstrateJVM.eventSettingsto determine if the event is enabled.
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.
Thank you for the review Christian! Yes that is what I was doing. I was under the impression that built in events were enabled by default. I have removed that unconditional enablement and instead substituted PlatformEventType.setEnabled(boolean). This way changes can be propagated to the SubstrateJVM.eventSettings if the event happens to be one of the supported mirror event types. Please let me know if this is an acceptable solution.
I think the thread sleep event was moved from hotspot native code to java code to be able to emit the events for virtual threads as well.
|
I spent some more time on this topic and I think that we need a different approach. The So, I implemented a prototype where the thread sleep event is emitted in the same way as it is done by the JDK code. This seems to work but I need to do a few more cleanups and some more testing before I open a PR. |
Hi @christianhaeubl is there any update on this? Thanks! |
|
@roberttoyonaga I created #5528 |
Summary of bug:
Currently a null pointer exception is thrown at runtime if the thread sleep event is emitted (with JDK19). This is because jdk.ThreadSleep is only added as an event if the JDK version is <17. This is a recent change in SVM that was done because in JDK19, ThreadSleep is now a mirror event and is not longer in metadata.xml. This means it doesn't get added to
JfrMetadataTypeLibrary, and so an NPE is eventually thrown when we try to emit the event in uninterruptible code. A solution to this could be to not attempt to emit thread sleep events if jdk version is over 17. This PR instead tries to add support for thread sleep as a mirror event.This is the error:
Exception in thread "Thread-2" java.lang.NullPointerException: [no exception stack trace available because exception is thrown from code that must be allocation free]To reproduce:
mx native-image --no-fallback -H:+AllowVMInspection -cp /jfr-tests/target/classes com.redhat.jfr.tests.event.TestJavaMonitorWaitEvents./com.redhat.jfr.tests.event.testjavamonitorwaitevents -XX:+FlightRecorder -XX:StartFlightRecording=filename=testjavamonitorwaitevents.jfrSummary of changes
To solve this, special handling of jdk.ThreadSleep as a mirror event is added (only if jdk version is 19). In the future, support for new mirror events could possibly be done in a similar way.