struct ArtJvmTiEnv; class JvmtiEventAllocationListener; class JvmtiDdmChunkListener; class JvmtiGcPauseListener; class JvmtiMethodTraceListener; class JvmtiMonitorListener; class JvmtiParkListener;
// an enum for ArtEvents. This differs from the JVMTI events only in that we distinguish between // retransformation capable and incapable loading enumclass ArtJvmtiEvent : jint {
kMinEventTypeVal = JVMTI_MIN_EVENT_TYPE_VAL,
kVmInit = JVMTI_EVENT_VM_INIT,
kVmDeath = JVMTI_EVENT_VM_DEATH,
kThreadStart = JVMTI_EVENT_THREAD_START,
kThreadEnd = JVMTI_EVENT_THREAD_END,
kClassFileLoadHookNonRetransformable = JVMTI_EVENT_CLASS_FILE_LOAD_HOOK,
kClassLoad = JVMTI_EVENT_CLASS_LOAD,
kClassPrepare = JVMTI_EVENT_CLASS_PREPARE,
kVmStart = JVMTI_EVENT_VM_START,
kException = JVMTI_EVENT_EXCEPTION,
kExceptionCatch = JVMTI_EVENT_EXCEPTION_CATCH,
kSingleStep = JVMTI_EVENT_SINGLE_STEP,
kFramePop = JVMTI_EVENT_FRAME_POP,
kBreakpoint = JVMTI_EVENT_BREAKPOINT,
kFieldAccess = JVMTI_EVENT_FIELD_ACCESS,
kFieldModification = JVMTI_EVENT_FIELD_MODIFICATION,
kMethodEntry = JVMTI_EVENT_METHOD_ENTRY,
kMethodExit = JVMTI_EVENT_METHOD_EXIT,
kNativeMethodBind = JVMTI_EVENT_NATIVE_METHOD_BIND,
kCompiledMethodLoad = JVMTI_EVENT_COMPILED_METHOD_LOAD,
kCompiledMethodUnload = JVMTI_EVENT_COMPILED_METHOD_UNLOAD,
kDynamicCodeGenerated = JVMTI_EVENT_DYNAMIC_CODE_GENERATED,
kDataDumpRequest = JVMTI_EVENT_DATA_DUMP_REQUEST,
kMonitorWait = JVMTI_EVENT_MONITOR_WAIT,
kMonitorWaited = JVMTI_EVENT_MONITOR_WAITED,
kMonitorContendedEnter = JVMTI_EVENT_MONITOR_CONTENDED_ENTER,
kMonitorContendedEntered = JVMTI_EVENT_MONITOR_CONTENDED_ENTERED,
kResourceExhausted = JVMTI_EVENT_RESOURCE_EXHAUSTED,
kGarbageCollectionStart = JVMTI_EVENT_GARBAGE_COLLECTION_START,
kGarbageCollectionFinish = JVMTI_EVENT_GARBAGE_COLLECTION_FINISH,
kObjectFree = JVMTI_EVENT_OBJECT_FREE,
kVmObjectAlloc = JVMTI_EVENT_VM_OBJECT_ALLOC, // Internal event to mark a ClassFileLoadHook as one created with the can_retransform_classes // capability.
kClassFileLoadHookRetransformable = JVMTI_MAX_EVENT_TYPE_VAL + 1,
kDdmPublishChunk = JVMTI_MAX_EVENT_TYPE_VAL + 2,
kObsoleteObjectCreated = JVMTI_MAX_EVENT_TYPE_VAL + 3,
kStructuralDexFileLoadHook = JVMTI_MAX_EVENT_TYPE_VAL + 4,
kMaxNormalEventTypeVal = kStructuralDexFileLoadHook,
// All that follow are events used to implement internal JVMTI functions. They are not settable // directly by agents.
kMinInternalEventTypeVal = kMaxNormalEventTypeVal + 1,
// Internal event we use to implement the ForceEarlyReturn functions.
kForceEarlyReturnUpdateReturnValue = kMinInternalEventTypeVal,
kMaxInternalEventTypeVal = kForceEarlyReturnUpdateReturnValue,
// It is not enough to store a Thread pointer, as these may be reused. Use the pointer and the // thread id. // Note: We could just use the tid like tracing does. using UniqueThread = std::pair<art::Thread*, uint32_t>;
// Copies extension functions from other callback struct if it exists. There must not have been // any modifications to this struct when it is called. void CopyExtensionsFrom(const ArtJvmtiEventCallbacks* cb);
struct EventMasks { // The globally enabled events.
EventMask global_event_mask;
// The per-thread enabled events.
// TODO: Native thread objects are immovable, so we can use them as keys in an (unordered) map, // if necessary.
std::vector<std::pair<UniqueThread, EventMask>> thread_event_masks;
// A union of the per-thread events, for fast-pathing.
EventMask unioned_thread_event_mask;
EventMask& GetEventMask(art::Thread* thread);
EventMask* GetEventMaskOrNull(art::Thread* thread); // Circular dependencies mean we cannot see the definition of ArtJvmTiEnv so the mutex is simply // asserted in the function. // Note that the 'env' passed in must be the same env this EventMasks is associated with. void EnableEvent(ArtJvmTiEnv* env, art::Thread* thread, ArtJvmtiEvent event); // REQUIRES(env->event_info_mutex_); // Circular dependencies mean we cannot see the definition of ArtJvmTiEnv so the mutex is simply // asserted in the function. // Note that the 'env' passed in must be the same env this EventMasks is associated with. void DisableEvent(ArtJvmTiEnv* env, art::Thread* thread, ArtJvmtiEvent event); // REQUIRES(env->event_info_mutex_); bool IsEnabledAnywhere(ArtJvmtiEvent event); // Make any changes to event masks needed for the given capability changes. If caps_added is true // then caps is all the newly set capabilities of the jvmtiEnv. If it is false then caps is the // set of all capabilities that were removed from the jvmtiEnv. void HandleChangedCapabilities(const jvmtiCapabilities& caps, bool caps_added);
};
// Helper class for event handling. class EventHandler { public:
EventHandler();
~EventHandler();
// do cleanup for the event handler. void Shutdown();
// Register an env. It is assumed that this happens on env creation, that is, no events are // enabled, yet. void RegisterArtJvmTiEnv(ArtJvmTiEnv* env) REQUIRES(!envs_lock_);
// Remove an env. void RemoveArtJvmTiEnv(ArtJvmTiEnv* env) REQUIRES(!envs_lock_);
// Sets an internal event. Unlike normal JVMTI events internal events are not associated with any // particular jvmtiEnv and are refcounted. This refcounting is done to allow us to easily enable // events during functions and disable them during the requested event callback. Since these are // used to implement various JVMTI functions these events always have a single target thread. If // target is null the current thread is used.
jvmtiError SetInternalEvent(jthread target,
ArtJvmtiEvent event,
jvmtiEventMode mode)
REQUIRES(!envs_lock_, !art::Locks::mutator_lock_);
// Dispatch event to all registered environments. Since this one doesn't have a JNIEnv* it doesn't // matter if it has the mutator_lock. template <ArtJvmtiEvent kEvent, typename ...Args>
ALWAYS_INLINE inlinevoid DispatchEvent(art::Thread* thread, Args... args) const
REQUIRES(!envs_lock_);
// Dispatch event to all registered environments stashing exceptions as needed. This works since // JNIEnv* is always the second argument if it is passed to an event. Needed since C++ does not // allow partial template function specialization. // // We need both of these since we want to make sure to push a stack frame when it is possible for // the event to allocate local references. template <ArtJvmtiEvent kEvent, typename ...Args>
ALWAYS_INLINE inlinevoid DispatchEvent(art::Thread* thread, JNIEnv* jnienv, Args... args) const
REQUIRES(!envs_lock_);
// Tell the event handler capabilities were added/lost so it can adjust the sent events.If // caps_added is true then caps is all the newly set capabilities of the jvmtiEnv. If it is false // then caps is the set of all capabilities that were removed from the jvmtiEnv.
ALWAYS_INLINE inlinevoid HandleChangedCapabilities(ArtJvmTiEnv* env, const jvmtiCapabilities& caps, bool added)
REQUIRES(!envs_lock_);
// Dispatch event to the given environment, only. template <ArtJvmtiEvent kEvent, typename ...Args>
ALWAYS_INLINE inlinevoid DispatchEventOnEnv(ArtJvmTiEnv* env,
art::Thread* thread,
JNIEnv* jnienv,
Args... args) const
REQUIRES(!envs_lock_);
// Dispatch event to the given environment, only. template <ArtJvmtiEvent kEvent, typename ...Args>
ALWAYS_INLINE inlinevoid DispatchEventOnEnv(ArtJvmTiEnv* env, art::Thread* thread, Args... args) const
REQUIRES(!envs_lock_);
// Recalculates the event mask for the given event.
ALWAYS_INLINE inlinevoid RecalculateGlobalEventMask(ArtJvmtiEvent event) REQUIRES(!envs_lock_);
ALWAYS_INLINE inlinevoid RecalculateGlobalEventMaskLocked(ArtJvmtiEvent event) REQUIRES_SHARED(envs_lock_);
// Returns whether there are any active requests for the given event on the given thread. This // should only be used while modifying the events for a thread. bool GetThreadEventState(ArtJvmtiEvent event, art::Thread* thread)
REQUIRES(envs_lock_, art::Locks::thread_list_lock_);
// Sets up the global state needed for the first/last enable of an event across all threads void HandleEventType(ArtJvmtiEvent event, bool enable); // Perform deopts required for enabling the event on the given thread. Null thread indicates // global event enabled.
jvmtiError HandleEventDeopt(ArtJvmtiEvent event, jthread thread, bool enable); void HandleLocalAccessCapabilityAdded(); void HandleBreakpointEventsChanged(bool enable);
int32_t GetInternalEventRefcount(ArtJvmtiEvent event) const REQUIRES(envs_lock_); // Increment internal event refcount for the given event and return the new count.
int32_t IncrInternalEventRefcount(ArtJvmtiEvent event) REQUIRES(envs_lock_); // Decrement internal event refcount for the given event and return the new count.
int32_t DecrInternalEventRefcount(ArtJvmtiEvent event) REQUIRES(envs_lock_);
int32_t& GetInternalEventThreadRefcount(ArtJvmtiEvent event, art::Thread* target)
REQUIRES(envs_lock_, art::Locks::thread_list_lock_); // Increment internal event refcount for the given event and return the new count.
int32_t IncrInternalEventThreadRefcount(ArtJvmtiEvent event, art::Thread* target)
REQUIRES(envs_lock_, art::Locks::thread_list_lock_); // Decrement internal event refcount for the given event and return the new count.
int32_t DecrInternalEventThreadRefcount(ArtJvmtiEvent event, art::Thread* target)
REQUIRES(envs_lock_, art::Locks::thread_list_lock_);
// List of all JvmTiEnv objects that have been created, in their creation order. It is a std::list // since we mostly access it by iterating over the entire thing, only ever append to the end, and // need to be able to remove arbitrary elements from it.
std::list<ArtJvmTiEnv*> envs GUARDED_BY(envs_lock_);
// Close to top level lock. Nothing should be held when we lock this (except for mutator_lock_ // which is needed when setting new events). mutable art::ReaderWriterMutex envs_lock_ ACQUIRED_AFTER(art::Locks::mutator_lock_);
// A union of all enabled events, anywhere.
EventMask global_mask;
// True if frame pop has ever been enabled. Since we store pointers to stack frames we need to // continue to listen to this event even if it has been disabled. // TODO We could remove the listeners once all jvmtiEnvs have drained their shadow-frame vectors. bool frame_pop_enabled;
// The overall refcount for each internal event across all threads.
std::array<int32_t, kInternalEventCount> internal_event_refcount_ GUARDED_BY(envs_lock_); // The refcount for each thread for each internal event. // TODO We should clean both this and the normal EventMask lists up when threads end.
std::array<std::unordered_map<UniqueThread, int32_t, UniqueThreadHasher>, kInternalEventCount>
internal_event_thread_refcount_
GUARDED_BY(envs_lock_) GUARDED_BY(art::Locks::thread_list_lock_);
friendclass JvmtiMethodTraceListener;
};
} // namespace openjdkjvmti
#endif// ART_OPENJDKJVMTI_EVENTS_H_
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.13 Sekunden
(vorverarbeitet am 2026-06-29)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.