Refactor jvmtiEvent so we can add to it.
Change all code over to using ArtJvmtiEvent from jvmtiEvent so that we
have a way to add additional internal events if the need arises.
Bug: 32369913
Bug: 31684920
Test: mma -j40 test-art-host
Change-Id: I555475048d2e753db8adf317dc1f66d81533cde0
diff --git a/runtime/openjdkjvmti/OpenjdkJvmTi.cc b/runtime/openjdkjvmti/OpenjdkJvmTi.cc
index d9aea01..966bd57 100644
--- a/runtime/openjdkjvmti/OpenjdkJvmTi.cc
+++ b/runtime/openjdkjvmti/OpenjdkJvmTi.cc
@@ -856,7 +856,8 @@
}
}
- return gEventHandler.SetEvent(ArtJvmTiEnv::AsArtJvmTiEnv(env), art_thread, event_type, mode);
+ ArtJvmTiEnv* art_env = ArtJvmTiEnv::AsArtJvmTiEnv(env);
+ return gEventHandler.SetEvent(art_env, art_thread, GetArtJvmtiEvent(art_env, event_type), mode);
}
static jvmtiError GenerateEvents(jvmtiEnv* env, jvmtiEvent event_type) {
diff --git a/runtime/openjdkjvmti/events-inl.h b/runtime/openjdkjvmti/events-inl.h
index d027201..fb39db5 100644
--- a/runtime/openjdkjvmti/events-inl.h
+++ b/runtime/openjdkjvmti/events-inl.h
@@ -23,8 +23,13 @@
namespace openjdkjvmti {
+static inline ArtJvmtiEvent GetArtJvmtiEvent(ArtJvmTiEnv* env ATTRIBUTE_UNUSED,
+ jvmtiEvent e) {
+ return static_cast<ArtJvmtiEvent>(e);
+}
+
template <typename FnType>
-ALWAYS_INLINE static inline FnType* GetCallback(ArtJvmTiEnv* env, jvmtiEvent event) {
+ALWAYS_INLINE static inline FnType* GetCallback(ArtJvmTiEnv* env, ArtJvmtiEvent event) {
if (env->event_callbacks == nullptr) {
return nullptr;
}
@@ -33,84 +38,79 @@
// function.
switch (event) {
- case JVMTI_EVENT_VM_INIT:
+ case ArtJvmtiEvent::kVmInit:
return reinterpret_cast<FnType*>(env->event_callbacks->VMInit);
- case JVMTI_EVENT_VM_DEATH:
+ case ArtJvmtiEvent::kVmDeath:
return reinterpret_cast<FnType*>(env->event_callbacks->VMDeath);
- case JVMTI_EVENT_THREAD_START:
+ case ArtJvmtiEvent::kThreadStart:
return reinterpret_cast<FnType*>(env->event_callbacks->ThreadStart);
- case JVMTI_EVENT_THREAD_END:
+ case ArtJvmtiEvent::kThreadEnd:
return reinterpret_cast<FnType*>(env->event_callbacks->ThreadEnd);
- case JVMTI_EVENT_CLASS_FILE_LOAD_HOOK:
+ case ArtJvmtiEvent::kClassFileLoadHook:
return reinterpret_cast<FnType*>(env->event_callbacks->ClassFileLoadHook);
- case JVMTI_EVENT_CLASS_LOAD:
+ case ArtJvmtiEvent::kClassLoad:
return reinterpret_cast<FnType*>(env->event_callbacks->ClassLoad);
- case JVMTI_EVENT_CLASS_PREPARE:
+ case ArtJvmtiEvent::kClassPrepare:
return reinterpret_cast<FnType*>(env->event_callbacks->ClassPrepare);
- case JVMTI_EVENT_VM_START:
+ case ArtJvmtiEvent::kVmStart:
return reinterpret_cast<FnType*>(env->event_callbacks->VMStart);
- case JVMTI_EVENT_EXCEPTION:
+ case ArtJvmtiEvent::kException:
return reinterpret_cast<FnType*>(env->event_callbacks->Exception);
- case JVMTI_EVENT_EXCEPTION_CATCH:
+ case ArtJvmtiEvent::kExceptionCatch:
return reinterpret_cast<FnType*>(env->event_callbacks->ExceptionCatch);
- case JVMTI_EVENT_SINGLE_STEP:
+ case ArtJvmtiEvent::kSingleStep:
return reinterpret_cast<FnType*>(env->event_callbacks->SingleStep);
- case JVMTI_EVENT_FRAME_POP:
+ case ArtJvmtiEvent::kFramePop:
return reinterpret_cast<FnType*>(env->event_callbacks->FramePop);
- case JVMTI_EVENT_BREAKPOINT:
+ case ArtJvmtiEvent::kBreakpoint:
return reinterpret_cast<FnType*>(env->event_callbacks->Breakpoint);
- case JVMTI_EVENT_FIELD_ACCESS:
+ case ArtJvmtiEvent::kFieldAccess:
return reinterpret_cast<FnType*>(env->event_callbacks->FieldAccess);
- case JVMTI_EVENT_FIELD_MODIFICATION:
+ case ArtJvmtiEvent::kFieldModification:
return reinterpret_cast<FnType*>(env->event_callbacks->FieldModification);
- case JVMTI_EVENT_METHOD_ENTRY:
+ case ArtJvmtiEvent::kMethodEntry:
return reinterpret_cast<FnType*>(env->event_callbacks->MethodEntry);
- case JVMTI_EVENT_METHOD_EXIT:
+ case ArtJvmtiEvent::kMethodExit:
return reinterpret_cast<FnType*>(env->event_callbacks->MethodExit);
- case JVMTI_EVENT_NATIVE_METHOD_BIND:
+ case ArtJvmtiEvent::kNativeMethodBind:
return reinterpret_cast<FnType*>(env->event_callbacks->NativeMethodBind);
- case JVMTI_EVENT_COMPILED_METHOD_LOAD:
+ case ArtJvmtiEvent::kCompiledMethodLoad:
return reinterpret_cast<FnType*>(env->event_callbacks->CompiledMethodLoad);
- case JVMTI_EVENT_COMPILED_METHOD_UNLOAD:
+ case ArtJvmtiEvent::kCompiledMethodUnload:
return reinterpret_cast<FnType*>(env->event_callbacks->CompiledMethodUnload);
- case JVMTI_EVENT_DYNAMIC_CODE_GENERATED:
+ case ArtJvmtiEvent::kDynamicCodeGenerated:
return reinterpret_cast<FnType*>(env->event_callbacks->DynamicCodeGenerated);
- case JVMTI_EVENT_DATA_DUMP_REQUEST:
+ case ArtJvmtiEvent::kDataDumpRequest:
return reinterpret_cast<FnType*>(env->event_callbacks->DataDumpRequest);
- case JVMTI_EVENT_MONITOR_WAIT:
+ case ArtJvmtiEvent::kMonitorWait:
return reinterpret_cast<FnType*>(env->event_callbacks->MonitorWait);
- case JVMTI_EVENT_MONITOR_WAITED:
+ case ArtJvmtiEvent::kMonitorWaited:
return reinterpret_cast<FnType*>(env->event_callbacks->MonitorWaited);
- case JVMTI_EVENT_MONITOR_CONTENDED_ENTER:
+ case ArtJvmtiEvent::kMonitorContendedEnter:
return reinterpret_cast<FnType*>(env->event_callbacks->MonitorContendedEnter);
- case JVMTI_EVENT_MONITOR_CONTENDED_ENTERED:
+ case ArtJvmtiEvent::kMonitorContendedEntered:
return reinterpret_cast<FnType*>(env->event_callbacks->MonitorContendedEntered);
- case JVMTI_EVENT_RESOURCE_EXHAUSTED:
+ case ArtJvmtiEvent::kResourceExhausted:
return reinterpret_cast<FnType*>(env->event_callbacks->ResourceExhausted);
- case JVMTI_EVENT_GARBAGE_COLLECTION_START:
+ case ArtJvmtiEvent::kGarbageCollectionStart:
return reinterpret_cast<FnType*>(env->event_callbacks->GarbageCollectionStart);
- case JVMTI_EVENT_GARBAGE_COLLECTION_FINISH:
+ case ArtJvmtiEvent::kGarbageCollectionFinish:
return reinterpret_cast<FnType*>(env->event_callbacks->GarbageCollectionFinish);
- case JVMTI_EVENT_OBJECT_FREE:
+ case ArtJvmtiEvent::kObjectFree:
return reinterpret_cast<FnType*>(env->event_callbacks->ObjectFree);
- case JVMTI_EVENT_VM_OBJECT_ALLOC:
+ case ArtJvmtiEvent::kVmObjectAlloc:
return reinterpret_cast<FnType*>(env->event_callbacks->VMObjectAlloc);
}
return nullptr;
}
template <typename ...Args>
-inline void EventHandler::DispatchEvent(art::Thread* thread, jvmtiEvent event, Args... args) {
+inline void EventHandler::DispatchEvent(art::Thread* thread,
+ ArtJvmtiEvent event,
+ Args... args) const {
using FnType = void(jvmtiEnv*, Args...);
for (ArtJvmTiEnv* env : envs) {
- bool dispatch = env->event_masks.global_event_mask.Test(event);
-
- if (!dispatch && thread != nullptr && env->event_masks.unioned_thread_event_mask.Test(event)) {
- EventMask* mask = env->event_masks.GetEventMaskOrNull(thread);
- dispatch = mask != nullptr && mask->Test(event);
- }
-
- if (dispatch) {
+ if (ShouldDispatch(event, env, thread)) {
FnType* callback = GetCallback<FnType>(env, event);
if (callback != nullptr) {
(*callback)(env, args...);
@@ -119,6 +119,18 @@
}
}
+inline bool EventHandler::ShouldDispatch(ArtJvmtiEvent event,
+ ArtJvmTiEnv* env,
+ art::Thread* thread) {
+ bool dispatch = env->event_masks.global_event_mask.Test(event);
+
+ if (!dispatch && thread != nullptr && env->event_masks.unioned_thread_event_mask.Test(event)) {
+ EventMask* mask = env->event_masks.GetEventMaskOrNull(thread);
+ dispatch = mask != nullptr && mask->Test(event);
+ }
+ return dispatch;
+}
+
} // namespace openjdkjvmti
#endif // ART_RUNTIME_OPENJDKJVMTI_EVENTS_INL_H_
diff --git a/runtime/openjdkjvmti/events.cc b/runtime/openjdkjvmti/events.cc
index 12692a1..66929cf 100644
--- a/runtime/openjdkjvmti/events.cc
+++ b/runtime/openjdkjvmti/events.cc
@@ -83,7 +83,7 @@
}
-void EventMasks::EnableEvent(art::Thread* thread, jvmtiEvent event) {
+void EventMasks::EnableEvent(art::Thread* thread, ArtJvmtiEvent event) {
DCHECK(EventMask::EventIsInRange(event));
GetEventMask(thread).Set(event);
if (thread != nullptr) {
@@ -91,7 +91,7 @@
}
}
-void EventMasks::DisableEvent(art::Thread* thread, jvmtiEvent event) {
+void EventMasks::DisableEvent(art::Thread* thread, ArtJvmtiEvent event) {
DCHECK(EventMask::EventIsInRange(event));
GetEventMask(thread).Set(event, false);
if (thread != nullptr) {
@@ -111,16 +111,16 @@
envs.push_back(env);
}
-static bool IsThreadControllable(jvmtiEvent event) {
+static bool IsThreadControllable(ArtJvmtiEvent event) {
switch (event) {
- case JVMTI_EVENT_VM_INIT:
- case JVMTI_EVENT_VM_START:
- case JVMTI_EVENT_VM_DEATH:
- case JVMTI_EVENT_THREAD_START:
- case JVMTI_EVENT_COMPILED_METHOD_LOAD:
- case JVMTI_EVENT_COMPILED_METHOD_UNLOAD:
- case JVMTI_EVENT_DYNAMIC_CODE_GENERATED:
- case JVMTI_EVENT_DATA_DUMP_REQUEST:
+ case ArtJvmtiEvent::kVmInit:
+ case ArtJvmtiEvent::kVmStart:
+ case ArtJvmtiEvent::kVmDeath:
+ case ArtJvmtiEvent::kThreadStart:
+ case ArtJvmtiEvent::kCompiledMethodLoad:
+ case ArtJvmtiEvent::kCompiledMethodUnload:
+ case ArtJvmtiEvent::kDynamicCodeGenerated:
+ case ArtJvmtiEvent::kDataDumpRequest:
return false;
default:
@@ -136,7 +136,7 @@
OVERRIDE REQUIRES_SHARED(art::Locks::mutator_lock_) {
DCHECK_EQ(self, art::Thread::Current());
- if (handler_->IsEventEnabledAnywhere(JVMTI_EVENT_VM_OBJECT_ALLOC)) {
+ if (handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kVmObjectAlloc)) {
art::StackHandleScope<1> hs(self);
auto h = hs.NewHandleWrapper(obj);
// jvmtiEventVMObjectAlloc parameters:
@@ -162,7 +162,7 @@
jni_env, jni_env->AddLocalReference<jclass>(obj->Ptr()->GetClass()));
handler_->DispatchEvent(self,
- JVMTI_EVENT_VM_OBJECT_ALLOC,
+ ArtJvmtiEvent::kVmObjectAlloc,
jni_env,
thread.get(),
object.get(),
@@ -196,11 +196,11 @@
finish_enabled_(false) {}
void StartPause() OVERRIDE {
- handler_->DispatchEvent(nullptr, JVMTI_EVENT_GARBAGE_COLLECTION_START);
+ handler_->DispatchEvent(nullptr, ArtJvmtiEvent::kGarbageCollectionStart);
}
void EndPause() OVERRIDE {
- handler_->DispatchEvent(nullptr, JVMTI_EVENT_GARBAGE_COLLECTION_FINISH);
+ handler_->DispatchEvent(nullptr, ArtJvmtiEvent::kGarbageCollectionFinish);
}
bool IsEnabled() {
@@ -221,10 +221,10 @@
bool finish_enabled_;
};
-static void SetupGcPauseTracking(JvmtiGcPauseListener* listener, jvmtiEvent event, bool enable) {
+static void SetupGcPauseTracking(JvmtiGcPauseListener* listener, ArtJvmtiEvent event, bool enable) {
bool old_state = listener->IsEnabled();
- if (event == JVMTI_EVENT_GARBAGE_COLLECTION_START) {
+ if (event == ArtJvmtiEvent::kGarbageCollectionStart) {
listener->SetStartEnabled(enable);
} else {
listener->SetFinishEnabled(enable);
@@ -242,14 +242,14 @@
}
// Handle special work for the given event type, if necessary.
-void EventHandler::HandleEventType(jvmtiEvent event, bool enable) {
+void EventHandler::HandleEventType(ArtJvmtiEvent event, bool enable) {
switch (event) {
- case JVMTI_EVENT_VM_OBJECT_ALLOC:
+ case ArtJvmtiEvent::kVmObjectAlloc:
SetupObjectAllocationTracking(alloc_listener_.get(), enable);
return;
- case JVMTI_EVENT_GARBAGE_COLLECTION_START:
- case JVMTI_EVENT_GARBAGE_COLLECTION_FINISH:
+ case ArtJvmtiEvent::kGarbageCollectionStart:
+ case ArtJvmtiEvent::kGarbageCollectionFinish:
SetupGcPauseTracking(gc_pause_listener_.get(), event, enable);
return;
@@ -260,7 +260,7 @@
jvmtiError EventHandler::SetEvent(ArtJvmTiEnv* env,
art::Thread* thread,
- jvmtiEvent event,
+ ArtJvmtiEvent event,
jvmtiEventMode mode) {
if (thread != nullptr) {
art::ThreadState state = thread->GetState();
diff --git a/runtime/openjdkjvmti/events.h b/runtime/openjdkjvmti/events.h
index 07d6bfd..8f56145 100644
--- a/runtime/openjdkjvmti/events.h
+++ b/runtime/openjdkjvmti/events.h
@@ -30,22 +30,70 @@
class JvmtiAllocationListener;
class JvmtiGcPauseListener;
+// an enum for ArtEvents.
+enum class ArtJvmtiEvent {
+ 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,
+ kClassFileLoadHook = 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,
+ kMaxEventTypeVal = JVMTI_MAX_EVENT_TYPE_VAL,
+};
+
+// Convert a jvmtiEvent into a ArtJvmtiEvent
+ALWAYS_INLINE static inline ArtJvmtiEvent GetArtJvmtiEvent(ArtJvmTiEnv* env, jvmtiEvent e);
+
+ALWAYS_INLINE static inline jvmtiEvent GetJvmtiEvent(ArtJvmtiEvent e) {
+ return static_cast<jvmtiEvent>(e);
+}
+
struct EventMask {
- static constexpr size_t kEventsSize = JVMTI_MAX_EVENT_TYPE_VAL - JVMTI_MIN_EVENT_TYPE_VAL + 1;
+ static constexpr size_t kEventsSize =
+ static_cast<size_t>(ArtJvmtiEvent::kMaxEventTypeVal) -
+ static_cast<size_t>(ArtJvmtiEvent::kMinEventTypeVal) + 1;
std::bitset<kEventsSize> bit_set;
- static bool EventIsInRange(jvmtiEvent event) {
- return event >= JVMTI_MIN_EVENT_TYPE_VAL && event <= JVMTI_MAX_EVENT_TYPE_VAL;
+ static bool EventIsInRange(ArtJvmtiEvent event) {
+ return event >= ArtJvmtiEvent::kMinEventTypeVal && event <= ArtJvmtiEvent::kMaxEventTypeVal;
}
- void Set(jvmtiEvent event, bool value = true) {
+ void Set(ArtJvmtiEvent event, bool value = true) {
DCHECK(EventIsInRange(event));
- bit_set.set(event - JVMTI_MIN_EVENT_TYPE_VAL, value);
+ bit_set.set(static_cast<size_t>(event) - static_cast<size_t>(ArtJvmtiEvent::kMinEventTypeVal),
+ value);
}
- bool Test(jvmtiEvent event) const {
+ bool Test(ArtJvmtiEvent event) const {
DCHECK(EventIsInRange(event));
- return bit_set.test(event - JVMTI_MIN_EVENT_TYPE_VAL);
+ return bit_set.test(
+ static_cast<size_t>(event) - static_cast<size_t>(ArtJvmtiEvent::kMinEventTypeVal));
}
};
@@ -68,8 +116,8 @@
EventMask& GetEventMask(art::Thread* thread);
EventMask* GetEventMaskOrNull(art::Thread* thread);
- void EnableEvent(art::Thread* thread, jvmtiEvent event);
- void DisableEvent(art::Thread* thread, jvmtiEvent event);
+ void EnableEvent(art::Thread* thread, ArtJvmtiEvent event);
+ void DisableEvent(art::Thread* thread, ArtJvmtiEvent event);
};
// Helper class for event handling.
@@ -82,20 +130,27 @@
// enabled, yet.
void RegisterArtJvmTiEnv(ArtJvmTiEnv* env);
- bool IsEventEnabledAnywhere(jvmtiEvent event) {
+ bool IsEventEnabledAnywhere(ArtJvmtiEvent event) const {
if (!EventMask::EventIsInRange(event)) {
return false;
}
return global_mask.Test(event);
}
- jvmtiError SetEvent(ArtJvmTiEnv* env, art::Thread* thread, jvmtiEvent event, jvmtiEventMode mode);
+ jvmtiError SetEvent(ArtJvmTiEnv* env,
+ art::Thread* thread,
+ ArtJvmtiEvent event,
+ jvmtiEventMode mode);
template <typename ...Args>
- ALWAYS_INLINE inline void DispatchEvent(art::Thread* thread, jvmtiEvent event, Args... args);
+ ALWAYS_INLINE
+ inline void DispatchEvent(art::Thread* thread, ArtJvmtiEvent event, Args... args) const;
private:
- void HandleEventType(jvmtiEvent event, bool enable);
+ ALWAYS_INLINE
+ static inline bool ShouldDispatch(ArtJvmtiEvent event, ArtJvmTiEnv* env, art::Thread* thread);
+
+ void HandleEventType(ArtJvmtiEvent event, bool enable);
// List of all JvmTiEnv objects that have been created, in their creation order.
std::vector<ArtJvmTiEnv*> envs;
diff --git a/runtime/openjdkjvmti/object_tagging.cc b/runtime/openjdkjvmti/object_tagging.cc
index b983e79..94cb46a 100644
--- a/runtime/openjdkjvmti/object_tagging.cc
+++ b/runtime/openjdkjvmti/object_tagging.cc
@@ -177,7 +177,7 @@
}
void ObjectTagTable::Sweep(art::IsMarkedVisitor* visitor) {
- if (event_handler_->IsEventEnabledAnywhere(JVMTI_EVENT_OBJECT_FREE)) {
+ if (event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kObjectFree)) {
SweepImpl<true>(visitor);
} else {
SweepImpl<false>(visitor);
@@ -207,7 +207,7 @@
}
void ObjectTagTable::HandleNullSweep(jlong tag) {
- event_handler_->DispatchEvent(nullptr, JVMTI_EVENT_OBJECT_FREE, tag);
+ event_handler_->DispatchEvent(nullptr, ArtJvmtiEvent::kObjectFree, tag);
}
template <typename T, ObjectTagTable::TableUpdateNullTarget kTargetNull>