1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
use byteorder::{BigEndian, ByteOrder, LittleEndian};
use linux_perf_event_reader::{Endianness, RawData};
use super::records::*;
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct JitDumpRecordType(pub u32);
impl JitDumpRecordType {
    pub const JIT_CODE_LOAD: Self = Self(0);
    pub const JIT_CODE_MOVE: Self = Self(1);
    pub const JIT_CODE_DEBUG_INFO: Self = Self(2);
    pub const JIT_CODE_CLOSE: Self = Self(3);
    pub const JIT_CODE_UNWINDING_INFO: Self = Self(4);
}
#[derive(Debug, Clone)]
pub struct JitDumpRecordHeader {
    pub record_type: JitDumpRecordType,
    pub total_size: u32,
    pub timestamp: u64,
}
impl JitDumpRecordHeader {
    pub const SIZE: usize = 16; pub fn parse(endian: Endianness, data: RawData) -> Result<Self, std::io::Error> {
        match endian {
            Endianness::LittleEndian => Self::parse_impl::<LittleEndian>(data),
            Endianness::BigEndian => Self::parse_impl::<BigEndian>(data),
        }
    }
    pub fn parse_impl<O: ByteOrder>(data: RawData) -> Result<Self, std::io::Error> {
        let mut cur = data;
        let record_type = JitDumpRecordType(cur.read_u32::<O>()?);
        let total_size = cur.read_u32::<O>()?;
        let timestamp = cur.read_u64::<O>()?;
        Ok(Self {
            record_type,
            total_size,
            timestamp,
        })
    }
}
#[derive(Debug, Clone)]
pub enum JitDumpRecord<'a> {
    CodeLoad(JitCodeLoadRecord<'a>),
    CodeMove(JitCodeMoveRecord),
    CodeDebugInfo(JitCodeDebugInfoRecord<'a>),
    CodeClose,
    CodeUnwindingInfo(JitCodeUnwindingInfoRecord<'a>),
    Other(JitDumpRawRecord<'a>),
}
#[derive(Debug, Clone)]
pub struct JitDumpRawRecord<'a> {
    pub endian: Endianness,
    pub record_type: JitDumpRecordType,
    pub timestamp: u64,
    pub start_offset: u64,
    pub record_size: u32,
    pub body: RawData<'a>,
}
impl<'a> JitDumpRawRecord<'a> {
    pub fn parse(&self) -> Result<JitDumpRecord, std::io::Error> {
        match self.record_type {
            JitDumpRecordType::JIT_CODE_LOAD => {
                let record = JitCodeLoadRecord::parse(self.endian, self.body)?;
                Ok(JitDumpRecord::CodeLoad(record))
            }
            JitDumpRecordType::JIT_CODE_MOVE => {
                let record = JitCodeMoveRecord::parse(self.endian, self.body)?;
                Ok(JitDumpRecord::CodeMove(record))
            }
            JitDumpRecordType::JIT_CODE_DEBUG_INFO => {
                let record = JitCodeDebugInfoRecord::parse(self.endian, self.body)?;
                Ok(JitDumpRecord::CodeDebugInfo(record))
            }
            JitDumpRecordType::JIT_CODE_CLOSE => Ok(JitDumpRecord::CodeClose),
            JitDumpRecordType::JIT_CODE_UNWINDING_INFO => {
                let record = JitCodeUnwindingInfoRecord::parse(self.endian, self.body)?;
                Ok(JitDumpRecord::CodeUnwindingInfo(record))
            }
            _ => Ok(JitDumpRecord::Other(self.clone())),
        }
    }
}