jvmti_rs/wrapper/builder/
compiled_method_record.rs

1use std::ffi::c_void;
2use crate::{objects::*, builder::*};
3use crate::sys::{jvmtiCompiledMethodLoadRecordHeader, JVMTI_CMLR_MAJOR_VERSION, JVMTI_CMLR_MINOR_VERSION,
4                 JVMTI_CMLR_DUMMY, JVMTI_CMLR_INLINE_INFO, jvmtiCompiledMethodLoadInlineRecord,
5                 PCStackInfo, jvmtiCompiledMethodLoadDummyRecord};
6use log::debug;
7
8// see https://github.com/rel-eng/rvmti/blob/master/src/rvmti.rs#L1376
9pub fn parse_compiled_method_load_record<'a>(compile_info: *const c_void) -> Option<Vec<JCompiledMethodLoadRecord<'a>>> {
10    unsafe {
11        if compile_info.is_null() {
12            return None;
13        }
14
15        let mut result = Vec::new();
16        let mut record_ptr = compile_info as *const jvmtiCompiledMethodLoadRecordHeader;
17        loop {
18            let record = *record_ptr;
19            if record.majorinfoversion == JVMTI_CMLR_MAJOR_VERSION && record.minorinfoversion == JVMTI_CMLR_MINOR_VERSION {
20                match record.kind {
21                    JVMTI_CMLR_DUMMY => {
22                        let dummy_record_ptr = record_ptr as *const jvmtiCompiledMethodLoadDummyRecord;
23                        if dummy_record_ptr.is_null() {
24                            continue;
25                        }
26                        debug!("jvmtiCompiledMethodLoadDummyRecord: {:?}", dummy_record_ptr);
27                        result.push(JCompiledMethodLoadRecord::Dummy);
28                    }
29                    JVMTI_CMLR_INLINE_INFO => {
30                        let inline_record_ptr = record_ptr as *const jvmtiCompiledMethodLoadInlineRecord;
31                        if inline_record_ptr.is_null() {
32                            continue;
33                        }
34                        let inline_record = *inline_record_ptr;
35                        let builder: MutObjectArrayBuilder<PCStackInfo> = MutObjectArrayBuilder::create(inline_record.numpcs, inline_record.pcinfo);
36                        result.push(JCompiledMethodLoadRecord::Inline { stack_infos: builder.build() });
37                    }
38                    _ => {}
39                }
40            }
41            if record.next.is_null() {
42                break;
43            } else {
44                record_ptr = record.next;
45            }
46        }
47        Some(result)
48    }
49}