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