Re: RFR: 8257967: JFR: Events for loaded agents [v10]

2023-03-31 Thread Serguei Spitsyn
On Wed, 22 Mar 2023 09:18:51 GMT, David Holmes  wrote:

>> src/hotspot/share/prims/jvmtiEnvBase.hpp line 166:
>> 
>>> 164: 
>>> 165:   const void* get_env_local_storage() { return _env_local_storage; }
>>> 166: 
>> 
>> Why was this change/move necessary? Do I miss anything?
>
> It is now public, not protected.

I see, thanks.

-

PR Review Comment: https://git.openjdk.org/jdk/pull/12923#discussion_r1155048753


Re: RFR: 8257967: JFR: Events for loaded agents [v10]

2023-03-30 Thread Markus Grönlund
On Tue, 14 Mar 2023 12:22:16 GMT, Markus Grönlund  wrote:

>> n.b. that also applies for accesses/updates to field _next.
>
> I wanted all accesses to use the iterator. The only access is given to the 
> iterator and AgentList by way of being friends. No need to expose more.

I updated all external access to use getters/setters.

-

PR Review Comment: https://git.openjdk.org/jdk/pull/12923#discussion_r1153703241


Re: RFR: 8257967: JFR: Events for loaded agents [v10]

2023-03-30 Thread Markus Grönlund
On Tue, 14 Mar 2023 12:26:16 GMT, Markus Grönlund  wrote:

> I've had a good look through now and have a better sense of the refactoring. 
> Seems good.
> 
> I'll wait for any tweaks before hitting the approve button though.
> 
> Thanks

Moving the loading logic to the agent.cpp module was a bit harder than I 
initially thought. It also exposed a bug in how statically linked libraries 
were loaded - now fixed. Sorry for the large update. Thanks again for having a 
look.

>> src/hotspot/share/prims/agentList.cpp line 542:
>> 
>>> 540: 
>>> 541:   // Invoke the Agent_OnAttach function
>>> 542:   JavaThread* THREAD = JavaThread::current(); // For exception macros.
>> 
>> Nit: just use `current` rather than `THREAD` and don't use the exception 
>> macros.
>
> Ported as is but good point, will update.

Updated - cheers.

-

PR Comment: https://git.openjdk.org/jdk/pull/12923#issuecomment-1490828465
PR Review Comment: https://git.openjdk.org/jdk/pull/12923#discussion_r1153703484


Re: RFR: 8257967: JFR: Events for loaded agents [v10]

2023-03-30 Thread Markus Grönlund
On Tue, 14 Mar 2023 12:23:08 GMT, Markus Grönlund  wrote:

>> src/hotspot/share/prims/agentList.cpp line 419:
>> 
>>> 417: const jint err = (*on_load_entry)(_vm, 
>>> const_cast(agent->options()), NULL);
>>> 418: if (err != JNI_OK) {
>>> 419:   vm_exit_during_initialization("-Xrun library failed to init", 
>>> agent->name());
>> 
>> Do you need to be back in `_thread_in_vm` before exiting?
>
> Hmm. This was ported as is. I will double-check.

Looks like there is no requirement to be in _thread_in_vm before invoking 
vm_exit_during_initialization().

vm_perform_shutdown_actions() will forcibly set the thread state to 
_thread_in_native (no transition).

-

PR Review Comment: https://git.openjdk.org/jdk/pull/12923#discussion_r1153243069


Re: RFR: 8257967: JFR: Events for loaded agents [v10]

2023-03-22 Thread David Holmes
On Tue, 21 Mar 2023 00:53:31 GMT, Serguei Spitsyn  wrote:

>> Markus Grönlund has updated the pull request incrementally with one 
>> additional commit since the last revision:
>> 
>>   more cleanup
>
> src/hotspot/share/prims/jvmtiEnvBase.hpp line 166:
> 
>> 164: 
>> 165:   const void* get_env_local_storage() { return _env_local_storage; }
>> 166: 
> 
> Why was this change/move necessary? Do I miss anything?

It is now public, not protected.

-

PR Review Comment: https://git.openjdk.org/jdk/pull/12923#discussion_r1144458026


Re: RFR: 8257967: JFR: Events for loaded agents [v10]

2023-03-20 Thread Serguei Spitsyn
On Fri, 10 Mar 2023 10:43:23 GMT, Markus Grönlund  wrote:

>> Greetings,
>> 
>> We are adding support to let JFR report on Agents.
>> 
>>  Design
>> 
>> An Agent is a library that uses any instrumentation or profiling APIs. Most 
>> agents are started and initialized on the command line, but agents can also 
>> be loaded dynamically during runtime. Because command line agents initialize 
>> during the VM startup sequence, they add to the overall startup time latency 
>> in getting the VM ready. The events will report on the time the agent took 
>> to initialize.
>> 
>> A JavaAgent is an agent written in the Java programming language, using the 
>> APIs in the package 
>> [java.lang.instrument](https://docs.oracle.com/en/java/javase/19/docs/api/java.instrument/java/lang/instrument/package-summary.html)
>> 
>> A JavaAgent is sometimes called a JPLIS agent, where the acronym JPLIS 
>> stands for Java Programming Language Instrumentation Services.
>> 
>> To report on JavaAgents, JFR will add the new event type jdk.JavaAgent and 
>> events will look similar to these two examples:
>> 
>> // Command line
>> jdk.JavaAgent {
>>   startTime = 12:31:19.789 (2023-03-08)
>>   name = "JavaAgent.jar"
>>   options = "foo=bar"
>>   dynamic = false
>>   initialization = 12:31:15.574 (2023-03-08)
>>   initializationTime = 172 ms
>> }
>> 
>> // Dynamic load
>> jdk.JavaAgent {
>>   startTime = 12:31:31.158 (2023-03-08)
>>   name = "JavaAgent.jar"
>>   options = "bar=baz"
>>   dynamic = true
>>   initialization = 12:31:31.037 (2023-03-08)
>>   initializationTime = 64,1 ms
>> }
>> 
>> The jdk.JavaAgent event type is a JFR periodic event that iterates over 
>> running Java agents.
>> 
>> For a JavaAgent event, the agent's name will be the specific .jar file 
>> containing the instrumentation code. The options will be the specific 
>> options passed to the .jar file as part of launching the agent, for example, 
>> on the command line: -javaagent: JavaAgent.jar=foo=bar.
>> 
>> The "dynamic" field denotes if the agent was loaded via the command line 
>> (dynamic = false) or dynamically (dynamic = true)
>> 
>> "initialization" is the timestamp the JVM invoked the initialization method, 
>> and "initializationTime" is the duration of executing the initialization 
>> method.
>> 
>> "startTime" represents the time the JFR framework issued the periodic event; 
>> hence "initialization" will be earlier than "startTime".
>> 
>> An agent can also be written in a native programming language using the [JVM 
>> Tools Interface 
>> (JVMTI)](https://docs.oracle.com/en/java/javase/19/docs/specs/jvmti.html). 
>> This kind of agent, sometimes called a native agent, is a platform-specific 
>> binary, sometimes referred to as a library, but here it means a .so or .dll 
>> file.
>> 
>> To report on native agents, JFR will add the new event type jdk.NativeAgent 
>> and events will look similar to this example:
>> 
>> jdk.NativeAgent {
>>   startTime = 12:31:40.398 (2023-03-08)
>>   name = "jdwp"
>>   options = "transport=dt_socket,server=y,address=any,onjcmd=y"
>>   dynamic = false
>>   initialization = 12:31:36.142 (2023-03-08)
>>   initializationTime = 0,00184 ms
>>   path = 
>> "c:\ade\github\openjdk\jdk\build\windows-x86_64-server-slowdebug\jdk\bin\jdwp.dll"
>> }
>> 
>> The layout of the event type is very similar to the jdk.JavaAgent event, but 
>> here the path to the native library is reported.
>> 
>> The initialization of a native agent is performed by invoking an 
>> agent-specified callback routine. The "initialization" is when the JVM sent 
>> or would have sent the JVMTI VMInit event to a specified callback. 
>> "initializationTime" is the duration to execute that specific callback. If 
>> no callback is specified for the JVMTI VMInit event, the 
>> "initializationTime" will be 0.
>> 
>>  Implementation
>> 
>> There has not existed a reification of a JavaAgent directly in the JVM, as 
>> these are built on top of the JDK native library, "instrument", using a 
>> many-to-one mapping. At the level of the JVM, the only representation of 
>> agents after startup is through JvmtiEnv's, which agents request from the 
>> JVM during startup and initialization — as such, mapping which JvmtiEnv 
>> belongs to what JavaAgent was not possible before.
>> 
>> Using implementation details of how the JDK native library "instrument" 
>> interacts with the JVM, we can build this mapping to track what JvmtiEnv's 
>> "belong" to what JavaAgent. This mapping now lets us report the 
>> Java-relevant context (name, options) and measure the time it takes for the 
>> JavaAgent to initialize.
>> 
>> When implementing this capability, it was necessary to refactor the code 
>> used to represent agents, AgentLibrary. The previous implementation was 
>> located primarily in arguments.cpp, and threads.cpp but also jvmtiExport.cpp.
>> 
>> The refactoring isolates the relevant logic into two new modules, 
>> prims/agent.hpp and prims/agentList.hpp. Breaking out 

Re: RFR: 8257967: JFR: Events for loaded agents [v10]

2023-03-15 Thread Serguei Spitsyn
On Tue, 14 Mar 2023 12:26:16 GMT, Markus Grönlund  wrote:

>> I've had a good look through now and have a better sense of the refactoring. 
>> Seems good.
>> 
>> I'll wait for any tweaks before hitting the approve button though.
>> 
>> Thanks
>
>> I've had a good look through now and have a better sense of the refactoring. 
>> Seems good.
>> 
>> 
>> 
>> I'll wait for any tweaks before hitting the approve button though.
>> 
>> 
>> 
>> Thanks
> 
> Thanks so much for taking a look. I realized that implementation details of 
> loading should probably reside in agent.cpp, not agentList.cpp.
> 
> I am currently off on vacation and will update when back. Thanks also to 
> Andrew Dinn for comments.

@mgronlun I'm looking at the fixes but it will take some time.

-

PR: https://git.openjdk.org/jdk/pull/12923


Re: RFR: 8257967: JFR: Events for loaded agents [v10]

2023-03-14 Thread Markus Grönlund
On Mon, 13 Mar 2023 09:46:04 GMT, Andrew Dinn  wrote:

>> Markus Grönlund has updated the pull request incrementally with one 
>> additional commit since the last revision:
>> 
>>   more cleanup
>
> src/hotspot/share/jfr/metadata/metadata.xml line 1182:
> 
>> 1180: > description="The time the JVM initialized the agent" />
>> 1181: > label="Initialization Time" description="The duration of executing the 
>> initialization method exported by the agent" />
>> 1182:   
> 
> @mgronlun A somewhat drive-by comment. It might be clearer if you renamed 
> these event fields and accessors, plus also the corresponding fields and 
> accessors in class Agent, as `initializationTime` and 
> `initializationDuration`.

Makes sense.

-

PR: https://git.openjdk.org/jdk/pull/12923


Re: RFR: 8257967: JFR: Events for loaded agents [v10]

2023-03-14 Thread Markus Grönlund
On Tue, 14 Mar 2023 06:01:05 GMT, David Holmes  wrote:

> I've had a good look through now and have a better sense of the refactoring. 
> Seems good.
> 
> 
> 
> I'll wait for any tweaks before hitting the approve button though.
> 
> 
> 
> Thanks

Thanks so much for taking a look. I realized that implementation details of 
loading should probably reside in agent.cpp, not agentList.cpp.

I am currently off on vacation and will update when back. Thanks also to Andrew 
Dinn for comments.

-

PR: https://git.openjdk.org/jdk/pull/12923


Re: RFR: 8257967: JFR: Events for loaded agents [v10]

2023-03-14 Thread Markus Grönlund
On Mon, 13 Mar 2023 09:49:39 GMT, Andrew Dinn  wrote:

>> src/hotspot/share/prims/agentList.cpp line 64:
>> 
>>> 62: void AgentList::add_xrun(const char* name, char* options, bool 
>>> absolute_path) {
>>> 63:   Agent* agent = new Agent(name, options, absolute_path);
>>> 64:   agent->_is_xrun = true;
>> 
>> Why direct access of private field instead of having a setter like other 
>> parts of the Agent API?
>
> n.b. that also applies for accesses/updates to field _next.

I wanted all accesses to use the iterator. The only access is given to the 
iterator and AgentList by way of being friends. No need to expose more.

-

PR: https://git.openjdk.org/jdk/pull/12923


Re: RFR: 8257967: JFR: Events for loaded agents [v10]

2023-03-14 Thread Markus Grönlund
On Mon, 13 Mar 2023 06:22:21 GMT, David Holmes  wrote:

>> Markus Grönlund has updated the pull request incrementally with one 
>> additional commit since the last revision:
>> 
>>   more cleanup
>
> src/hotspot/share/prims/agent.cpp line 34:
> 
>> 32: }
>> 33: 
>> 34: static const char* allocate_copy(const char* str) {
> 
> Why not just use `os::strdup`?

Better alternative, thanks David.

> src/hotspot/share/prims/agentList.cpp line 227:
> 
>> 225:  * store data in their JvmtiEnv local storage.
>> 226:  *
>> 227:  * Please see JPLISAgent.c in module java.instrument, see JPLISAgent.h 
>> and JPLISAgent.c.
> 
> No need to mention the .c file twice.

Good point.

> src/hotspot/share/prims/agentList.cpp line 419:
> 
>> 417: const jint err = (*on_load_entry)(_vm, 
>> const_cast(agent->options()), NULL);
>> 418: if (err != JNI_OK) {
>> 419:   vm_exit_during_initialization("-Xrun library failed to init", 
>> agent->name());
> 
> Do you need to be back in `_thread_in_vm` before exiting?

Hmm. This was ported as is. I will double-check.

> src/hotspot/share/prims/agentList.cpp line 542:
> 
>> 540: 
>> 541:   // Invoke the Agent_OnAttach function
>> 542:   JavaThread* THREAD = JavaThread::current(); // For exception macros.
> 
> Nit: just use `current` rather than `THREAD` and don't use the exception 
> macros.

Ported as is but good point, will update.

-

PR: https://git.openjdk.org/jdk/pull/12923


Re: RFR: 8257967: JFR: Events for loaded agents [v10]

2023-03-14 Thread David Holmes
On Fri, 10 Mar 2023 10:43:23 GMT, Markus Grönlund  wrote:

>> Greetings,
>> 
>> We are adding support to let JFR report on Agents.
>> 
>>  Design
>> 
>> An Agent is a library that uses any instrumentation or profiling APIs. Most 
>> agents are started and initialized on the command line, but agents can also 
>> be loaded dynamically during runtime. Because command line agents initialize 
>> during the VM startup sequence, they add to the overall startup time latency 
>> in getting the VM ready. The events will report on the time the agent took 
>> to initialize.
>> 
>> A JavaAgent is an agent written in the Java programming language, using the 
>> APIs in the package 
>> [java.lang.instrument](https://docs.oracle.com/en/java/javase/19/docs/api/java.instrument/java/lang/instrument/package-summary.html)
>> 
>> A JavaAgent is sometimes called a JPLIS agent, where the acronym JPLIS 
>> stands for Java Programming Language Instrumentation Services.
>> 
>> To report on JavaAgents, JFR will add the new event type jdk.JavaAgent and 
>> events will look similar to these two examples:
>> 
>> // Command line
>> jdk.JavaAgent {
>>   startTime = 12:31:19.789 (2023-03-08)
>>   name = "JavaAgent.jar"
>>   options = "foo=bar"
>>   dynamic = false
>>   initialization = 12:31:15.574 (2023-03-08)
>>   initializationTime = 172 ms
>> }
>> 
>> // Dynamic load
>> jdk.JavaAgent {
>>   startTime = 12:31:31.158 (2023-03-08)
>>   name = "JavaAgent.jar"
>>   options = "bar=baz"
>>   dynamic = true
>>   initialization = 12:31:31.037 (2023-03-08)
>>   initializationTime = 64,1 ms
>> }
>> 
>> The jdk.JavaAgent event type is a JFR periodic event that iterates over 
>> running Java agents.
>> 
>> For a JavaAgent event, the agent's name will be the specific .jar file 
>> containing the instrumentation code. The options will be the specific 
>> options passed to the .jar file as part of launching the agent, for example, 
>> on the command line: -javaagent: JavaAgent.jar=foo=bar.
>> 
>> The "dynamic" field denotes if the agent was loaded via the command line 
>> (dynamic = false) or dynamically (dynamic = true)
>> 
>> "initialization" is the timestamp the JVM invoked the initialization method, 
>> and "initializationTime" is the duration of executing the initialization 
>> method.
>> 
>> "startTime" represents the time the JFR framework issued the periodic event; 
>> hence "initialization" will be earlier than "startTime".
>> 
>> An agent can also be written in a native programming language using the [JVM 
>> Tools Interface 
>> (JVMTI)](https://docs.oracle.com/en/java/javase/19/docs/specs/jvmti.html). 
>> This kind of agent, sometimes called a native agent, is a platform-specific 
>> binary, sometimes referred to as a library, but here it means a .so or .dll 
>> file.
>> 
>> To report on native agents, JFR will add the new event type jdk.NativeAgent 
>> and events will look similar to this example:
>> 
>> jdk.NativeAgent {
>>   startTime = 12:31:40.398 (2023-03-08)
>>   name = "jdwp"
>>   options = "transport=dt_socket,server=y,address=any,onjcmd=y"
>>   dynamic = false
>>   initialization = 12:31:36.142 (2023-03-08)
>>   initializationTime = 0,00184 ms
>>   path = 
>> "c:\ade\github\openjdk\jdk\build\windows-x86_64-server-slowdebug\jdk\bin\jdwp.dll"
>> }
>> 
>> The layout of the event type is very similar to the jdk.JavaAgent event, but 
>> here the path to the native library is reported.
>> 
>> The initialization of a native agent is performed by invoking an 
>> agent-specified callback routine. The "initialization" is when the JVM sent 
>> or would have sent the JVMTI VMInit event to a specified callback. 
>> "initializationTime" is the duration to execute that specific callback. If 
>> no callback is specified for the JVMTI VMInit event, the 
>> "initializationTime" will be 0.
>> 
>>  Implementation
>> 
>> There has not existed a reification of a JavaAgent directly in the JVM, as 
>> these are built on top of the JDK native library, "instrument", using a 
>> many-to-one mapping. At the level of the JVM, the only representation of 
>> agents after startup is through JvmtiEnv's, which agents request from the 
>> JVM during startup and initialization — as such, mapping which JvmtiEnv 
>> belongs to what JavaAgent was not possible before.
>> 
>> Using implementation details of how the JDK native library "instrument" 
>> interacts with the JVM, we can build this mapping to track what JvmtiEnv's 
>> "belong" to what JavaAgent. This mapping now lets us report the 
>> Java-relevant context (name, options) and measure the time it takes for the 
>> JavaAgent to initialize.
>> 
>> When implementing this capability, it was necessary to refactor the code 
>> used to represent agents, AgentLibrary. The previous implementation was 
>> located primarily in arguments.cpp, and threads.cpp but also jvmtiExport.cpp.
>> 
>> The refactoring isolates the relevant logic into two new modules, 
>> prims/agent.hpp and prims/agentList.hpp. Breaking out 

Re: RFR: 8257967: JFR: Events for loaded agents [v10]

2023-03-13 Thread David Holmes
On Thu, 9 Mar 2023 09:29:41 GMT, Markus Grönlund  wrote:

>> src/hotspot/share/runtime/threads.cpp line 338:
>> 
>>> 336:   if (EagerXrunInit && Arguments::init_libraries_at_startup()) {
>>> 337: create_vm_init_libraries();
>>> 338:   }
>> 
>> Not obvious where this went. Changes to the initialization order can be very 
>> problematic.
>
> Thanks, David. Two calls to launch XRun agents are invoked during startup, 
> and they depend on the EagerXrunInit option. The !EagerXrunInit case is 
> already located in create_vm(), but the EagerXrunInit was located as the 
> first entry in initialize_java_lang_classes(), which I thought was tucked 
> away a bit unnecessarily.
> 
> I hoisted the EagerXrunInit case from initialize_java_lang_classes() up to 
> create_vm(). It's now the call just before initialize_java_lang_classes().
> 
> This made it clearer, i.e. to have both calls located directly in create_vm().

Thanks for clarifying. That makes sense.

-

PR: https://git.openjdk.org/jdk/pull/12923


Re: RFR: 8257967: JFR: Events for loaded agents [v10]

2023-03-13 Thread Andrew Dinn
On Mon, 13 Mar 2023 06:29:11 GMT, David Holmes  wrote:

>> Markus Grönlund has updated the pull request incrementally with one 
>> additional commit since the last revision:
>> 
>>   more cleanup
>
> src/hotspot/share/prims/agentList.cpp line 64:
> 
>> 62: void AgentList::add_xrun(const char* name, char* options, bool 
>> absolute_path) {
>> 63:   Agent* agent = new Agent(name, options, absolute_path);
>> 64:   agent->_is_xrun = true;
> 
> Why direct access of private field instead of having a setter like other 
> parts of the Agent API?

n.b. that also applies for accesses/updates to field _next.

-

PR: https://git.openjdk.org/jdk/pull/12923


Re: RFR: 8257967: JFR: Events for loaded agents [v10]

2023-03-13 Thread Andrew Dinn
On Fri, 10 Mar 2023 10:43:23 GMT, Markus Grönlund  wrote:

>> Greetings,
>> 
>> We are adding support to let JFR report on Agents.
>> 
>>  Design
>> 
>> An Agent is a library that uses any instrumentation or profiling APIs. Most 
>> agents are started and initialized on the command line, but agents can also 
>> be loaded dynamically during runtime. Because command line agents initialize 
>> during the VM startup sequence, they add to the overall startup time latency 
>> in getting the VM ready. The events will report on the time the agent took 
>> to initialize.
>> 
>> A JavaAgent is an agent written in the Java programming language, using the 
>> APIs in the package 
>> [java.lang.instrument](https://docs.oracle.com/en/java/javase/19/docs/api/java.instrument/java/lang/instrument/package-summary.html)
>> 
>> A JavaAgent is sometimes called a JPLIS agent, where the acronym JPLIS 
>> stands for Java Programming Language Instrumentation Services.
>> 
>> To report on JavaAgents, JFR will add the new event type jdk.JavaAgent and 
>> events will look similar to these two examples:
>> 
>> // Command line
>> jdk.JavaAgent {
>>   startTime = 12:31:19.789 (2023-03-08)
>>   name = "JavaAgent.jar"
>>   options = "foo=bar"
>>   dynamic = false
>>   initialization = 12:31:15.574 (2023-03-08)
>>   initializationTime = 172 ms
>> }
>> 
>> // Dynamic load
>> jdk.JavaAgent {
>>   startTime = 12:31:31.158 (2023-03-08)
>>   name = "JavaAgent.jar"
>>   options = "bar=baz"
>>   dynamic = true
>>   initialization = 12:31:31.037 (2023-03-08)
>>   initializationTime = 64,1 ms
>> }
>> 
>> The jdk.JavaAgent event type is a JFR periodic event that iterates over 
>> running Java agents.
>> 
>> For a JavaAgent event, the agent's name will be the specific .jar file 
>> containing the instrumentation code. The options will be the specific 
>> options passed to the .jar file as part of launching the agent, for example, 
>> on the command line: -javaagent: JavaAgent.jar=foo=bar.
>> 
>> The "dynamic" field denotes if the agent was loaded via the command line 
>> (dynamic = false) or dynamically (dynamic = true)
>> 
>> "initialization" is the timestamp the JVM invoked the initialization method, 
>> and "initializationTime" is the duration of executing the initialization 
>> method.
>> 
>> "startTime" represents the time the JFR framework issued the periodic event; 
>> hence "initialization" will be earlier than "startTime".
>> 
>> An agent can also be written in a native programming language using the [JVM 
>> Tools Interface 
>> (JVMTI)](https://docs.oracle.com/en/java/javase/19/docs/specs/jvmti.html). 
>> This kind of agent, sometimes called a native agent, is a platform-specific 
>> binary, sometimes referred to as a library, but here it means a .so or .dll 
>> file.
>> 
>> To report on native agents, JFR will add the new event type jdk.NativeAgent 
>> and events will look similar to this example:
>> 
>> jdk.NativeAgent {
>>   startTime = 12:31:40.398 (2023-03-08)
>>   name = "jdwp"
>>   options = "transport=dt_socket,server=y,address=any,onjcmd=y"
>>   dynamic = false
>>   initialization = 12:31:36.142 (2023-03-08)
>>   initializationTime = 0,00184 ms
>>   path = 
>> "c:\ade\github\openjdk\jdk\build\windows-x86_64-server-slowdebug\jdk\bin\jdwp.dll"
>> }
>> 
>> The layout of the event type is very similar to the jdk.JavaAgent event, but 
>> here the path to the native library is reported.
>> 
>> The initialization of a native agent is performed by invoking an 
>> agent-specified callback routine. The "initialization" is when the JVM sent 
>> or would have sent the JVMTI VMInit event to a specified callback. 
>> "initializationTime" is the duration to execute that specific callback. If 
>> no callback is specified for the JVMTI VMInit event, the 
>> "initializationTime" will be 0.
>> 
>>  Implementation
>> 
>> There has not existed a reification of a JavaAgent directly in the JVM, as 
>> these are built on top of the JDK native library, "instrument", using a 
>> many-to-one mapping. At the level of the JVM, the only representation of 
>> agents after startup is through JvmtiEnv's, which agents request from the 
>> JVM during startup and initialization — as such, mapping which JvmtiEnv 
>> belongs to what JavaAgent was not possible before.
>> 
>> Using implementation details of how the JDK native library "instrument" 
>> interacts with the JVM, we can build this mapping to track what JvmtiEnv's 
>> "belong" to what JavaAgent. This mapping now lets us report the 
>> Java-relevant context (name, options) and measure the time it takes for the 
>> JavaAgent to initialize.
>> 
>> When implementing this capability, it was necessary to refactor the code 
>> used to represent agents, AgentLibrary. The previous implementation was 
>> located primarily in arguments.cpp, and threads.cpp but also jvmtiExport.cpp.
>> 
>> The refactoring isolates the relevant logic into two new modules, 
>> prims/agent.hpp and prims/agentList.hpp. Breaking out 

Re: RFR: 8257967: JFR: Events for loaded agents [v10]

2023-03-13 Thread David Holmes
On Fri, 10 Mar 2023 10:43:23 GMT, Markus Grönlund  wrote:

>> Greetings,
>> 
>> We are adding support to let JFR report on Agents.
>> 
>>  Design
>> 
>> An Agent is a library that uses any instrumentation or profiling APIs. Most 
>> agents are started and initialized on the command line, but agents can also 
>> be loaded dynamically during runtime. Because command line agents initialize 
>> during the VM startup sequence, they add to the overall startup time latency 
>> in getting the VM ready. The events will report on the time the agent took 
>> to initialize.
>> 
>> A JavaAgent is an agent written in the Java programming language, using the 
>> APIs in the package 
>> [java.lang.instrument](https://docs.oracle.com/en/java/javase/19/docs/api/java.instrument/java/lang/instrument/package-summary.html)
>> 
>> A JavaAgent is sometimes called a JPLIS agent, where the acronym JPLIS 
>> stands for Java Programming Language Instrumentation Services.
>> 
>> To report on JavaAgents, JFR will add the new event type jdk.JavaAgent and 
>> events will look similar to these two examples:
>> 
>> // Command line
>> jdk.JavaAgent {
>>   startTime = 12:31:19.789 (2023-03-08)
>>   name = "JavaAgent.jar"
>>   options = "foo=bar"
>>   dynamic = false
>>   initialization = 12:31:15.574 (2023-03-08)
>>   initializationTime = 172 ms
>> }
>> 
>> // Dynamic load
>> jdk.JavaAgent {
>>   startTime = 12:31:31.158 (2023-03-08)
>>   name = "JavaAgent.jar"
>>   options = "bar=baz"
>>   dynamic = true
>>   initialization = 12:31:31.037 (2023-03-08)
>>   initializationTime = 64,1 ms
>> }
>> 
>> The jdk.JavaAgent event type is a JFR periodic event that iterates over 
>> running Java agents.
>> 
>> For a JavaAgent event, the agent's name will be the specific .jar file 
>> containing the instrumentation code. The options will be the specific 
>> options passed to the .jar file as part of launching the agent, for example, 
>> on the command line: -javaagent: JavaAgent.jar=foo=bar.
>> 
>> The "dynamic" field denotes if the agent was loaded via the command line 
>> (dynamic = false) or dynamically (dynamic = true)
>> 
>> "initialization" is the timestamp the JVM invoked the initialization method, 
>> and "initializationTime" is the duration of executing the initialization 
>> method.
>> 
>> "startTime" represents the time the JFR framework issued the periodic event; 
>> hence "initialization" will be earlier than "startTime".
>> 
>> An agent can also be written in a native programming language using the [JVM 
>> Tools Interface 
>> (JVMTI)](https://docs.oracle.com/en/java/javase/19/docs/specs/jvmti.html). 
>> This kind of agent, sometimes called a native agent, is a platform-specific 
>> binary, sometimes referred to as a library, but here it means a .so or .dll 
>> file.
>> 
>> To report on native agents, JFR will add the new event type jdk.NativeAgent 
>> and events will look similar to this example:
>> 
>> jdk.NativeAgent {
>>   startTime = 12:31:40.398 (2023-03-08)
>>   name = "jdwp"
>>   options = "transport=dt_socket,server=y,address=any,onjcmd=y"
>>   dynamic = false
>>   initialization = 12:31:36.142 (2023-03-08)
>>   initializationTime = 0,00184 ms
>>   path = 
>> "c:\ade\github\openjdk\jdk\build\windows-x86_64-server-slowdebug\jdk\bin\jdwp.dll"
>> }
>> 
>> The layout of the event type is very similar to the jdk.JavaAgent event, but 
>> here the path to the native library is reported.
>> 
>> The initialization of a native agent is performed by invoking an 
>> agent-specified callback routine. The "initialization" is when the JVM sent 
>> or would have sent the JVMTI VMInit event to a specified callback. 
>> "initializationTime" is the duration to execute that specific callback. If 
>> no callback is specified for the JVMTI VMInit event, the 
>> "initializationTime" will be 0.
>> 
>>  Implementation
>> 
>> There has not existed a reification of a JavaAgent directly in the JVM, as 
>> these are built on top of the JDK native library, "instrument", using a 
>> many-to-one mapping. At the level of the JVM, the only representation of 
>> agents after startup is through JvmtiEnv's, which agents request from the 
>> JVM during startup and initialization — as such, mapping which JvmtiEnv 
>> belongs to what JavaAgent was not possible before.
>> 
>> Using implementation details of how the JDK native library "instrument" 
>> interacts with the JVM, we can build this mapping to track what JvmtiEnv's 
>> "belong" to what JavaAgent. This mapping now lets us report the 
>> Java-relevant context (name, options) and measure the time it takes for the 
>> JavaAgent to initialize.
>> 
>> When implementing this capability, it was necessary to refactor the code 
>> used to represent agents, AgentLibrary. The previous implementation was 
>> located primarily in arguments.cpp, and threads.cpp but also jvmtiExport.cpp.
>> 
>> The refactoring isolates the relevant logic into two new modules, 
>> prims/agent.hpp and prims/agentList.hpp. Breaking out 

Re: RFR: 8257967: JFR: Events for loaded agents [v10]

2023-03-10 Thread Markus Grönlund
> Greetings,
> 
> We are adding support to let JFR report on Agents.
> 
>  Design
> 
> An Agent is a library that uses any instrumentation or profiling APIs. Most 
> agents are started and initialized on the command line, but agents can also 
> be loaded dynamically during runtime. Because command line agents initialize 
> during the VM startup sequence, they add to the overall startup time latency 
> in getting the VM ready. The events will report on the time the agent took to 
> initialize.
> 
> A JavaAgent is an agent written in the Java programming language, using the 
> APIs in the package 
> [java.lang.instrument](https://docs.oracle.com/en/java/javase/19/docs/api/java.instrument/java/lang/instrument/package-summary.html)
> 
> A JavaAgent is sometimes called a JPLIS agent, where the acronym JPLIS stands 
> for Java Programming Language Instrumentation Services.
> 
> To report on JavaAgents, JFR will add the new event type jdk.JavaAgent and 
> events will look similar to these two examples:
> 
> // Command line
> jdk.JavaAgent {
>   startTime = 12:31:19.789 (2023-03-08)
>   name = "JavaAgent.jar"
>   options = "foo=bar"
>   dynamic = false
>   initialization = 12:31:15.574 (2023-03-08)
>   initializationTime = 172 ms
> }
> 
> // Dynamic load
> jdk.JavaAgent {
>   startTime = 12:31:31.158 (2023-03-08)
>   name = "JavaAgent.jar"
>   options = "bar=baz"
>   dynamic = true
>   initialization = 12:31:31.037 (2023-03-08)
>   initializationTime = 64,1 ms
> }
> 
> The jdk.JavaAgent event type is a JFR periodic event that iterates over 
> running Java agents.
> 
> For a JavaAgent event, the agent's name will be the specific .jar file 
> containing the instrumentation code. The options will be the specific options 
> passed to the .jar file as part of launching the agent, for example, on the 
> command line: -javaagent: JavaAgent.jar=foo=bar.
> 
> The "dynamic" field denotes if the agent was loaded via the command line 
> (dynamic = false) or dynamically (dynamic = true)
> 
> "initialization" is the timestamp the JVM invoked the initialization method, 
> and "initializationTime" is the duration of executing the initialization 
> method.
> 
> "startTime" represents the time the JFR framework issued the periodic event; 
> hence "initialization" will be earlier than "startTime".
> 
> An agent can also be written in a native programming language using the [JVM 
> Tools Interface 
> (JVMTI)](https://docs.oracle.com/en/java/javase/19/docs/specs/jvmti.html). 
> This kind of agent, sometimes called a native agent, is a platform-specific 
> binary, sometimes referred to as a library, but here it means a .so or .dll 
> file.
> 
> To report on native agents, JFR will add the new event type jdk.NativeAgent 
> and events will look similar to this example:
> 
> jdk.NativeAgent {
>   startTime = 12:31:40.398 (2023-03-08)
>   name = "jdwp"
>   options = "transport=dt_socket,server=y,address=any,onjcmd=y"
>   dynamic = false
>   initialization = 12:31:36.142 (2023-03-08)
>   initializationTime = 0,00184 ms
>   path = 
> "c:\ade\github\openjdk\jdk\build\windows-x86_64-server-slowdebug\jdk\bin\jdwp.dll"
> }
> 
> The layout of the event type is very similar to the jdk.JavaAgent event, but 
> here the path to the native library is reported.
> 
> The initialization of a native agent is performed by invoking an 
> agent-specified callback routine. The "initialization" is when the JVM sent 
> or would have sent the JVMTI VMInit event to a specified callback. 
> "initializationTime" is the duration to execute that specific callback. If no 
> callback is specified for the JVMTI VMInit event, the "initializationTime" 
> will be 0.
> 
>  Implementation
> 
> There has not existed a reification of a JavaAgent directly in the JVM, as 
> these are built on top of the JDK native library, "instrument", using a 
> many-to-one mapping. At the level of the JVM, the only representation of 
> agents after startup is through JvmtiEnv's, which agents request from the JVM 
> during startup and initialization — as such, mapping which JvmtiEnv belongs 
> to what JavaAgent was not possible before.
> 
> Using implementation details of how the JDK native library "instrument" 
> interacts with the JVM, we can build this mapping to track what JvmtiEnv's 
> "belong" to what JavaAgent. This mapping now lets us report the Java-relevant 
> context (name, options) and measure the time it takes for the JavaAgent to 
> initialize.
> 
> When implementing this capability, it was necessary to refactor the code used 
> to represent agents, AgentLibrary. The previous implementation was located 
> primarily in arguments.cpp, and threads.cpp but also jvmtiExport.cpp.
> 
> The refactoring isolates the relevant logic into two new modules, 
> prims/agent.hpp and prims/agentList.hpp. Breaking out this code from their 
> older places will help reduce the sizes of oversized arguments.cpp and 
> threads.cpp.
> 
> The previous two lists that maintained "agents" (JVMTI)