summaryrefslogtreecommitdiff
path: root/openjdkjvmti/events.cc
diff options
context:
space:
mode:
Diffstat (limited to 'openjdkjvmti/events.cc')
-rw-r--r--openjdkjvmti/events.cc75
1 files changed, 75 insertions, 0 deletions
diff --git a/openjdkjvmti/events.cc b/openjdkjvmti/events.cc
index 6a64441a4a..d1d606de48 100644
--- a/openjdkjvmti/events.cc
+++ b/openjdkjvmti/events.cc
@@ -60,6 +60,45 @@
namespace openjdkjvmti {
+void ArtJvmtiEventCallbacks::CopyExtensionsFrom(const ArtJvmtiEventCallbacks* cb) {
+ if (art::kIsDebugBuild) {
+ ArtJvmtiEventCallbacks clean;
+ DCHECK_EQ(memcmp(&clean, this, sizeof(clean)), 0)
+ << "CopyExtensionsFrom called with initialized eventsCallbacks!";
+ }
+ if (cb != nullptr) {
+ memcpy(this, cb, sizeof(*this));
+ } else {
+ memset(this, 0, sizeof(*this));
+ }
+}
+
+jvmtiError ArtJvmtiEventCallbacks::Set(jint index, jvmtiExtensionEvent cb) {
+ switch (index) {
+ case static_cast<jint>(ArtJvmtiEvent::kDdmPublishChunk):
+ DdmPublishChunk = reinterpret_cast<ArtJvmtiEventDdmPublishChunk>(cb);
+ return OK;
+ default:
+ return ERR(ILLEGAL_ARGUMENT);
+ }
+}
+
+
+bool IsExtensionEvent(jint e) {
+ return e >= static_cast<jint>(ArtJvmtiEvent::kMinEventTypeVal) &&
+ e <= static_cast<jint>(ArtJvmtiEvent::kMaxEventTypeVal) &&
+ IsExtensionEvent(static_cast<ArtJvmtiEvent>(e));
+}
+
+bool IsExtensionEvent(ArtJvmtiEvent e) {
+ switch (e) {
+ case ArtJvmtiEvent::kDdmPublishChunk:
+ return true;
+ default:
+ return false;
+ }
+}
+
bool EventMasks::IsEnabledAnywhere(ArtJvmtiEvent event) {
return global_event_mask.Test(event) || unioned_thread_event_mask.Test(event);
}
@@ -213,6 +252,38 @@ static void RunEventCallback(EventHandler* handler,
args...);
}
+static void SetupDdmTracking(art::DdmCallback* listener, bool enable) {
+ art::ScopedObjectAccess soa(art::Thread::Current());
+ if (enable) {
+ art::Runtime::Current()->GetRuntimeCallbacks()->AddDdmCallback(listener);
+ } else {
+ art::Runtime::Current()->GetRuntimeCallbacks()->RemoveDdmCallback(listener);
+ }
+}
+
+class JvmtiDdmChunkListener : public art::DdmCallback {
+ public:
+ explicit JvmtiDdmChunkListener(EventHandler* handler) : handler_(handler) {}
+
+ void DdmPublishChunk(uint32_t type, const art::ArrayRef<const uint8_t>& data)
+ OVERRIDE REQUIRES_SHARED(art::Locks::mutator_lock_) {
+ if (handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kDdmPublishChunk)) {
+ art::Thread* self = art::Thread::Current();
+ handler_->DispatchEvent<ArtJvmtiEvent::kDdmPublishChunk>(
+ self,
+ static_cast<JNIEnv*>(self->GetJniEnv()),
+ static_cast<jint>(type),
+ static_cast<jint>(data.size()),
+ reinterpret_cast<const jbyte*>(data.data()));
+ }
+ }
+
+ private:
+ EventHandler* handler_;
+
+ DISALLOW_COPY_AND_ASSIGN(JvmtiDdmChunkListener);
+};
+
class JvmtiAllocationListener : public art::gc::AllocationListener {
public:
explicit JvmtiAllocationListener(EventHandler* handler) : handler_(handler) {}
@@ -924,6 +995,9 @@ bool EventHandler::OtherMonitorEventsEnabledAnywhere(ArtJvmtiEvent event) {
// Handle special work for the given event type, if necessary.
void EventHandler::HandleEventType(ArtJvmtiEvent event, bool enable) {
switch (event) {
+ case ArtJvmtiEvent::kDdmPublishChunk:
+ SetupDdmTracking(ddm_listener_.get(), enable);
+ return;
case ArtJvmtiEvent::kVmObjectAlloc:
SetupObjectAllocationTracking(alloc_listener_.get(), enable);
return;
@@ -1104,6 +1178,7 @@ void EventHandler::Shutdown() {
EventHandler::EventHandler() {
alloc_listener_.reset(new JvmtiAllocationListener(this));
+ ddm_listener_.reset(new JvmtiDdmChunkListener(this));
gc_pause_listener_.reset(new JvmtiGcPauseListener(this));
method_trace_listener_.reset(new JvmtiMethodTraceListener(this));
monitor_listener_.reset(new JvmtiMonitorListener(this));