On Fri, 14 Apr 2023 09:20:18 GMT, Markus Grönlund <[email protected]> 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