jvmti_rs/wrapper/event/
manager.rs

1use crate::{objects::*, JVMTIEnv, JvmtiEvent, JvmtiEventMode};
2use log::debug;
3
4#[derive(Clone)]
5struct EventItem<'a> {
6    mode: JvmtiEventMode,
7    event: JvmtiEvent,
8    event_thread: Option<JThreadID<'a>>,
9}
10
11pub struct JEventManager<'a> {
12    capabilities: &'a mut JCapabilities<'a>,
13    callbacks: JEventCallbacks<'a>,
14    items: Vec<EventItem<'a>>,
15}
16
17impl<'a> JEventManager<'a> {
18    pub fn new<'b: 'a>(capabilities: &'b mut JCapabilities<'a>) -> JEventManager<'a> {
19        JEventManager {
20            capabilities,
21            callbacks: JEventCallbacks::new(),
22            items: Vec::new(),
23        }
24    }
25
26    pub fn get_capabilities(&mut self) -> &mut JCapabilities<'a> {
27        self.capabilities
28    }
29
30    pub fn apply(&mut self, env: &JVMTIEnv<'a>) {
31        let _ = env.add_capabilities(&self.capabilities);
32        debug!("Capabilities added to the environment");
33
34        let _ = env.set_event_callbacks(&self.callbacks);
35        debug!("Capabilities set event callbacks to the environment");
36
37        self.items.iter().for_each(|e| env.set_event_notification_mode(e.mode, e.event, &e.event_thread).unwrap());
38    }
39
40    fn add_enable_event_item(&mut self, event: JvmtiEvent, event_thread: Option<JThreadID<'a>>) {
41        // event_thread = None see https://docs.oracle.com/javase/8/docs/platform/jvmti/jvmti.html#SetEventNotificationMode
42        self.items.push(EventItem { mode: JvmtiEventMode::Enable, event, event_thread })
43    }
44
45    pub fn vm_init_enabled(&mut self) {
46        self.callbacks.vm_init_enabled();
47        self.add_enable_event_item(JvmtiEvent::VmInit, None);
48    }
49
50    pub fn vm_death_enabled(&mut self) {
51        self.callbacks.vm_death_enabled();
52        self.add_enable_event_item(JvmtiEvent::VmDeath, None);
53    }
54
55    pub fn thread_start_enabled(&mut self) {
56        self.callbacks.thread_start_enabled();
57        self.add_enable_event_item(JvmtiEvent::ThreadStart, None);
58    }
59
60    pub fn thread_end_enabled(&mut self, event_thread: Option<JThreadID<'a>>) {
61        self.callbacks.thread_end_enabled();
62        self.add_enable_event_item(JvmtiEvent::ThreadEnd, event_thread);
63    }
64
65    pub fn class_file_load_hook_enabled(&mut self, event_thread: Option<JThreadID<'a>>) {
66        self.callbacks.class_file_load_hook_enabled();
67        self.capabilities.can_generate_all_class_hook_events();
68        self.add_enable_event_item(JvmtiEvent::ClassFileLoadHook, event_thread);
69    }
70
71    pub fn class_load_enabled(&mut self, event_thread: Option<JThreadID<'a>>) {
72        self.callbacks.class_load_enabled();
73        self.add_enable_event_item(JvmtiEvent::ClassLoad, event_thread);
74    }
75
76    pub fn class_prepare_enabled(&mut self, event_thread: Option<JThreadID<'a>>) {
77        self.callbacks.class_prepare_enabled();
78        self.add_enable_event_item(JvmtiEvent::ClassPrepare, event_thread);
79    }
80
81    pub fn vm_start_enabled(&mut self) {
82        self.callbacks.vm_start_enabled();
83        self.add_enable_event_item(JvmtiEvent::VmStart, None);
84    }
85
86    pub fn exception_enabled(&mut self, event_thread: Option<JThreadID<'a>>) {
87        self.callbacks.exception_enabled();
88        self.capabilities.can_generate_exception_events();
89        self.add_enable_event_item(JvmtiEvent::Exception, event_thread);
90    }
91
92    pub fn exception_catch_enabled(&mut self, event_thread: Option<JThreadID<'a>>) {
93        self.callbacks.exception_catch_enabled();
94        self.capabilities.can_generate_exception_events();
95        self.add_enable_event_item(JvmtiEvent::ExceptionCatch, event_thread);
96    }
97
98    pub fn single_step_enabled(&mut self, event_thread: Option<JThreadID<'a>>) {
99        self.callbacks.single_step_enabled();
100        self.capabilities.can_generate_single_step_events();
101        self.add_enable_event_item(JvmtiEvent::SingleStep, event_thread);
102    }
103
104    pub fn frame_pop_enabled(&mut self, event_thread: Option<JThreadID<'a>>) {
105        self.callbacks.frame_pop_enabled();
106        self.capabilities.can_generate_frame_pop_events();
107        self.add_enable_event_item(JvmtiEvent::FramePop, event_thread);
108    }
109
110    pub fn breakpoint_enabled(&mut self, event_thread: Option<JThreadID<'a>>) {
111        self.callbacks.breakpoint_enabled();
112        self.capabilities.can_generate_breakpoint_events();
113        self.add_enable_event_item(JvmtiEvent::Breakpoint, event_thread);
114    }
115
116    pub fn field_access_enabled(&mut self, event_thread: Option<JThreadID<'a>>) {
117        self.callbacks.field_access_enabled();
118        self.capabilities.can_generate_field_access_events();
119        self.add_enable_event_item(JvmtiEvent::FieldAccess, event_thread);
120    }
121
122    pub fn field_modification_enabled(&mut self, event_thread: Option<JThreadID<'a>>) {
123        self.callbacks.field_modification_enabled();
124        self.capabilities.can_generate_field_modification_events();
125        self.add_enable_event_item(JvmtiEvent::FieldModification, event_thread);
126    }
127
128    pub fn method_entry_enabled(&mut self, event_thread: Option<JThreadID<'a>>) {
129        self.callbacks.method_entry_enabled();
130        self.capabilities.can_generate_method_entry_events();
131        self.add_enable_event_item(JvmtiEvent::MethodEntry, event_thread);
132    }
133
134    pub fn method_exit_enabled(&mut self, event_thread: Option<JThreadID<'a>>) {
135        self.callbacks.method_exit_enabled();
136        self.capabilities.can_generate_method_exit_events();
137        self.add_enable_event_item(JvmtiEvent::MethodExit, event_thread);
138    }
139
140    pub fn native_method_bind_enabled(&mut self, event_thread: Option<JThreadID<'a>>) {
141        self.callbacks.native_method_bind_enabled();
142        self.capabilities.can_generate_native_method_bind_events();
143        self.add_enable_event_item(JvmtiEvent::NativeMethodBind, event_thread);
144    }
145
146    pub fn compiled_method_load_enabled(&mut self) {
147        self.callbacks.compiled_method_load_enabled();
148        self.capabilities.can_generate_compiled_method_load_events();
149        self.add_enable_event_item(JvmtiEvent::CompiledMethodLoad, None);
150    }
151
152    pub fn compiled_method_unload_enabled(&mut self) {
153        self.callbacks.compiled_method_unload_enabled();
154        self.capabilities.can_generate_compiled_method_load_events();
155        self.add_enable_event_item(JvmtiEvent::CompiledMethodUnload, None);
156    }
157
158    pub fn dynamic_code_generated_enabled(&mut self) {
159        self.callbacks.dynamic_code_generated_enabled();
160        self.add_enable_event_item(JvmtiEvent::DynamicCodeGenerated, None);
161    }
162
163    pub fn data_dump_request_enabled(&mut self) {
164        self.callbacks.data_dump_request_enabled();
165        self.add_enable_event_item(JvmtiEvent::DataDumpRequest, None);
166    }
167
168    pub fn monitor_wait_enabled(&mut self, event_thread: Option<JThreadID<'a>>) {
169        self.callbacks.monitor_wait_enabled();
170        self.capabilities.can_generate_monitor_events();
171        self.add_enable_event_item(JvmtiEvent::MonitorWait, event_thread);
172    }
173
174    pub fn monitor_waited_enabled(&mut self, event_thread: Option<JThreadID<'a>>) {
175        self.callbacks.monitor_waited_enabled();
176        self.capabilities.can_generate_monitor_events();
177        self.add_enable_event_item(JvmtiEvent::MonitorWaited, event_thread);
178    }
179
180    pub fn monitor_contended_enter_enabled(&mut self, event_thread: Option<JThreadID<'a>>) {
181        self.callbacks.monitor_contended_enter_enabled();
182        self.capabilities.can_generate_monitor_events();
183        self.add_enable_event_item(JvmtiEvent::MonitorContendedEnter, event_thread);
184    }
185
186    pub fn monitor_contended_entered_enabled(&mut self, event_thread: Option<JThreadID<'a>>) {
187        self.callbacks.monitor_contended_entered_enabled();
188        self.capabilities.can_generate_monitor_events();
189        self.add_enable_event_item(JvmtiEvent::MonitorContendedEntered, event_thread);
190    }
191
192    pub fn resource_exhausted_enabled(&mut self, event_thread: Option<JThreadID<'a>>) {
193        self.callbacks.resource_exhausted_enabled();
194        self.capabilities.can_generate_resource_exhaustion_heap_events();
195        self.capabilities.can_generate_resource_exhaustion_threads_events();
196        self.add_enable_event_item(JvmtiEvent::ResourceExhausted, event_thread);
197    }
198
199    pub fn garbage_collection_start_enabled(&mut self, event_thread: Option<JThreadID<'a>>) {
200        self.callbacks.garbage_collection_start_enabled();
201        self.capabilities.can_generate_garbage_collection_events();
202        self.add_enable_event_item(JvmtiEvent::GarbageCollectionStart, event_thread);
203    }
204
205    pub fn garbage_collection_finish_enabled(&mut self, event_thread: Option<JThreadID<'a>>) {
206        self.callbacks.garbage_collection_finish_enabled();
207        self.capabilities.can_generate_garbage_collection_events();
208        self.add_enable_event_item(JvmtiEvent::GarbageCollectionFinish, event_thread);
209    }
210
211    pub fn object_free_enabled(&mut self, event_thread: Option<JThreadID<'a>>) {
212        self.callbacks.object_free_enabled();
213        self.capabilities.can_generate_object_free_events();
214        self.add_enable_event_item(JvmtiEvent::ObjectFree, event_thread);
215    }
216
217    pub fn vm_object_alloc_enabled(&mut self, event_thread: Option<JThreadID<'a>>) {
218        self.callbacks.vm_object_alloc_enabled();
219        self.capabilities.can_generate_vm_object_alloc_events();
220        self.add_enable_event_item(JvmtiEvent::VmObjectAlloc, event_thread);
221    }
222}