On Fri, 14 Apr 2023 09:20:18 GMT, Markus Grönlund <mgron...@openjdk.org> wrote:

>> src/hotspot/share/prims/jvmtiExport.cpp line 717:
>> 
>>> 715:       jvmtiEventVMInit callback = env->callbacks()->VMInit;
>>> 716:       if (callback != nullptr) {
>>> 717:         JvmtiAgent* const agent = lookup_uninitialized_agent(env, 
>>> reinterpret_cast<void*>(callback));
>> 
>> It was a surprise to me to discover this code in your changes.
>> How can it be possible that some agents are left uninitialized at the time 
>> of VMInit event?
>> Have you really observed this?
>> If so, then can you add a comment explaining the need of this initialization?
>> Is it needed for JFR purposes only?
>
> Ok. the terminology here might be confusing. The concept of an agent being 
> "initialized" is introduced and reported by JFR. For example, here is the JFR 
> event type definition for a NativeAgent:
> ``` 
>   <Event name="NativeAgent" category="Java Virtual Machine, Diagnostics" 
> label="Native Agent" description="A native programming language agent making 
> use of the JVMTI interface used by development, profiling and monitoring 
> tools"
>     thread="false" startTime="false" period="endChunk" stackTrace="false">
>     <Field type="string" name="name" label="Name" />
>     <Field type="string" name="options" label="Options" />
>     <Field type="boolean" name="dynamic" label="Dynamic" description="If the 
> library attached to the JVM dynamically during runtime, i.e. not at startup" 
> />
>     <Field type="Ticks" name="initializationTime" label="Initialization Time" 
> description="The time the JVM initialized the agent" />
>     <Field type="Tickspan" name="initializationDuration" 
> label="Initialization Duration" description="The duration of executing the 
> JVMTI VMInit event callback. If no VMInit callback is specified, the duration 
> is 0. For a dynamically loaded agent, it is the duration of executing the 
> call to Agent_OnAttach." />
>     <Field type="string" name="path" label="Path" description="The path of 
> the library" />
>   </Event>
> 
> As you can see, there are two fields: initializationTime and 
> IntializationDuration.
> 
> We report these to let users understand when an agent was initialized (VMInit 
> or Agent_OnAttach), together with the duration it took to execute either. For 
> JavaAgents, it measures the invocation and duration of the premain or 
> agentmain methods.
> 
> "Initialized" does not mean "loaded" (at this point, all agents are loaded), 
> but rather it means the agent has received a timestamp set as a function of 
> VMInit. This timestamp and duration are what we will report in JFR as part of 
> the event.
> 
> An "uninitialized" agent is an agent who has not yet been timestamped, as 
> part of VMInit, for example. Since an agent can create multiple JvmtiEnvs, 
> the function is called lookup_uninitialized_agent() because we can only have 
> a single timestamp for an agent, but it can, in turn, have multiple 
> JvmtiEnvs. When looking up an agent again, using a second JvmtiEnv created by 
> it, the agent is already "initialized", so no agent is returned.
> 
> We cannot have the timestamping logic as part of the call out to 
> Agent_OnLoad, because that call happens very early during VM bootstrap, so 
> the Ticks support structures are not yet in place. But, timing the 
> Agent_OnLoad call would be rather meaningless because the agent cannot do 
> much except construct a JvmtiEnv and setting capabilities and callbacks.
> 
> VMInit is where most of the invocation logic, at least for JavaAgents 
> happens, so the measurements are placed there.

Thank you for explaining it.
Could you, please, add small comment explaining that it is for JFR purposes?

-------------

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

Reply via email to