Skip to content

Commit c8c1e95

Browse files
Always encode events in little endian format so the file is platform independent.
1 parent 5bdf4f2 commit c8c1e95

File tree

4 files changed

+70
-28
lines changed

4 files changed

+70
-28
lines changed

analyzeme/src/profiling_data.rs

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -100,15 +100,7 @@ impl<'a> ProfilerEventIterator<'a> {
100100
let event_end_addr = event_start_addr.checked_add(RAW_EVENT_SIZE).unwrap();
101101

102102
let raw_event_bytes = &self.data.event_data[event_start_addr..event_end_addr];
103-
104-
let mut raw_event = RawEvent::default();
105-
unsafe {
106-
let raw_event = std::slice::from_raw_parts_mut(
107-
&mut raw_event as *mut RawEvent as *mut u8,
108-
std::mem::size_of::<RawEvent>(),
109-
);
110-
raw_event.copy_from_slice(raw_event_bytes);
111-
};
103+
let raw_event = RawEvent::deserialize(raw_event_bytes);
112104

113105
let string_table = &self.data.string_table;
114106

@@ -277,17 +269,9 @@ impl ProfilingDataBuilder {
277269
}
278270

279271
fn write_raw_event(&mut self, raw_event: &RawEvent) {
280-
let raw_event_bytes: &[u8] = unsafe {
281-
std::slice::from_raw_parts(
282-
raw_event as *const _ as *const u8,
283-
std::mem::size_of::<RawEvent>(),
284-
)
285-
};
286-
287272
self.event_sink
288273
.write_atomic(std::mem::size_of::<RawEvent>(), |bytes| {
289-
debug_assert_eq!(bytes.len(), std::mem::size_of::<RawEvent>());
290-
bytes.copy_from_slice(raw_event_bytes);
274+
raw_event.serialize(bytes);
291275
});
292276
}
293277
}

measureme/src/profiler.rs

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -110,16 +110,7 @@ impl<S: SerializationSink> Profiler<S> {
110110
fn record_raw_event(&self, raw_event: &RawEvent) {
111111
self.event_sink
112112
.write_atomic(std::mem::size_of::<RawEvent>(), |bytes| {
113-
debug_assert_eq!(bytes.len(), std::mem::size_of::<RawEvent>());
114-
115-
let raw_event_bytes: &[u8] = unsafe {
116-
std::slice::from_raw_parts(
117-
raw_event as *const _ as *const u8,
118-
std::mem::size_of::<RawEvent>(),
119-
)
120-
};
121-
122-
bytes.copy_from_slice(raw_event_bytes);
113+
raw_event.serialize(bytes);
123114
});
124115
}
125116

measureme/src/raw_event.rs

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,68 @@ impl RawEvent {
9595
pub fn is_instant(&self) -> bool {
9696
self.end_nanos() == INSTANT_TIMESTAMP_MARKER
9797
}
98+
99+
#[inline]
100+
pub fn serialize(&self, bytes: &mut [u8]) {
101+
assert!(bytes.len() == std::mem::size_of::<RawEvent>());
102+
103+
#[cfg(target_endian = "little")]
104+
{
105+
let raw_event_bytes: &[u8] = unsafe {
106+
std::slice::from_raw_parts(
107+
self as *const _ as *const u8,
108+
std::mem::size_of::<RawEvent>(),
109+
)
110+
};
111+
112+
bytes.copy_from_slice(raw_event_bytes);
113+
}
114+
115+
#[cfg(target_endian = "big")]
116+
{
117+
// We always emit data as little endian, which we have to do
118+
// manually on big endian targets.
119+
use byteorder::{LittleEndian, ByteOrder};
120+
121+
LittleEndian::write_u32(&mut bytes[0..], self.event_kind.as_u32());
122+
LittleEndian::write_u32(&mut bytes[4..], self.event_id.as_u32());
123+
LittleEndian::write_u32(&mut bytes[8..], self.thread_id);
124+
LittleEndian::write_u32(&mut bytes[12..], self.start_time_lower);
125+
LittleEndian::write_u32(&mut bytes[16..], self.end_time_lower);
126+
LittleEndian::write_u32(&mut bytes[20..], self.start_and_end_upper);
127+
}
128+
}
129+
130+
#[inline]
131+
pub fn deserialize(bytes: &[u8]) -> RawEvent {
132+
assert!(bytes.len() == std::mem::size_of::<RawEvent>());
133+
134+
#[cfg(target_endian = "little")]
135+
{
136+
let mut raw_event = RawEvent::default();
137+
unsafe {
138+
let raw_event = std::slice::from_raw_parts_mut(
139+
&mut raw_event as *mut RawEvent as *mut u8,
140+
std::mem::size_of::<RawEvent>(),
141+
);
142+
raw_event.copy_from_slice(bytes);
143+
};
144+
raw_event
145+
}
146+
147+
#[cfg(target_endian = "big")]
148+
{
149+
use byteorder::{LittleEndian, ByteOrder};
150+
RawEvent {
151+
event_kind: StringId::reserved(LittleEndian::read_u32(&bytes[0..])),
152+
event_id: StringId::reserved(LittleEndian::read_u32(&bytes[4..])),
153+
thread_id: LittleEndian::read_u32(&bytes[8..]),
154+
start_time_lower: LittleEndian::read_u32(&bytes[12..]),
155+
end_time_lower: LittleEndian::read_u32(&bytes[16..]),
156+
start_and_end_upper: LittleEndian::read_u32(&bytes[20..]),
157+
}
158+
}
159+
}
98160
}
99161

100162
impl Default for RawEvent {

measureme/src/stringtable.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,11 @@ impl StringId {
5151
pub fn reserved(id: u32) -> StringId {
5252
StringId(id)
5353
}
54+
55+
#[inline]
56+
pub fn as_u32(self) -> u32 {
57+
self.0
58+
}
5459
}
5560

5661
// Tags for the binary encoding of strings

0 commit comments

Comments
 (0)