Skip to content
This repository was archived by the owner on Jan 7, 2022. It is now read-only.

Commit ca660b4

Browse files
committed
Pull the trace struct out of the low-level interface.
By pulling the struct from here, and moving it into yktrace, we can offer the user a more abstracted interface, including a Drop and an Iterator. Also revise some comments while we are here.
1 parent 727080f commit ca660b4

5 files changed

Lines changed: 35 additions & 95 deletions

File tree

src/libcore/yk_swt.rs

Lines changed: 20 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -7,51 +7,33 @@
77
// option. This file may not be copied, modified, or distributed
88
// except according to those terms.
99

10-
/// The result of `yk_swt_stop_tracing_impl()` is an array of this C struct.
10+
/// A MIR basic block location.
11+
/// FIXME: This shouldn't live here, as it will need to be shared across all tracing backends.
1112
#[repr(C)]
1213
#[derive(Debug)]
1314
pub struct MirLoc {
1415
/// Unique identifier for the crate.
15-
pub crate_hash: u64,
16+
crate_hash: u64,
1617
/// The definition index.
17-
pub def_idx: u32,
18+
def_idx: u32,
1819
/// The basic block index.
19-
pub bb_idx: u32,
20+
bb_idx: u32,
2021
}
2122

22-
/// Wraps the raw C trace buffer and exposes a more "Rusty" interface to it.
23-
#[derive(Debug)]
24-
#[allow(dead_code)]
25-
pub struct SWTrace {
26-
/// A heap allocated array of `MirLoc` structs, which the consumer must free. Ideally we'd
27-
/// have this struct implement `std::ops::Drop` or at least provide a method to do the freeing,
28-
/// but we can do neither due to libcore restrictions.
29-
buf: *mut MirLoc,
30-
/// The number of items in the above array.
31-
len: usize,
32-
}
33-
34-
impl SWTrace {
35-
/// Returns the number of MIR locations recorded in the trace.
36-
pub fn len(&self) -> usize {
37-
self.len
23+
impl MirLoc {
24+
/// Returns the crate hash of the location.
25+
pub fn crate_hash(&self) -> u64 {
26+
self.crate_hash
3827
}
3928

40-
/// Return a pointer to the raw trace buffer. The consumer *must* free this pointer.
41-
pub fn buf(self) -> *mut MirLoc {
42-
self.buf
29+
/// Returns the definition index of the location.
30+
pub fn def_idx(&self) -> u32 {
31+
self.def_idx
4332
}
4433

45-
/// Returns the location at index `idx` or `None` if the index is out of bounds.
46-
pub fn loc<'a>(&'a self, idx: usize) -> &'a MirLoc {
47-
if idx >= self.len {
48-
panic!("software trace index out of bounds: len={}, idx={}", self.len, idx);
49-
} else {
50-
if idx > isize::max_value() as usize {
51-
panic!("index too large for ptr arithmetic");
52-
}
53-
unsafe { &*self.buf.offset(idx as isize) }
54-
}
34+
/// Returns the basic block index of the location.
35+
pub fn bb_idx(&self) -> u32 {
36+
self.bb_idx
5537
}
5638
}
5739

@@ -73,10 +55,11 @@ pub fn start_tracing() {
7355
unsafe { yk_swt_start_tracing_impl(); }
7456
}
7557

76-
/// Stop software tracing and return the trace, or `None` if the trace was invalidated.
77-
/// The current thread must already be tracing.
58+
/// Stop software tracing and on success return a tuple containing a pointer to the raw trace
59+
/// buffer, and the number of items inside. Returns `None` if the trace was invalidated, or if an
60+
/// error occurred. The current thread must already be tracing.
7861
#[cfg_attr(not(stage0), no_trace)]
79-
pub fn stop_tracing() -> Option<SWTrace> {
62+
pub fn stop_tracing() -> Option<(*mut MirLoc, usize)> {
8063
let len: usize = 0;
8164

8265
extern "C" { fn yk_swt_stop_tracing_impl(ret_len: &usize) -> *mut MirLoc; }
@@ -85,7 +68,7 @@ pub fn stop_tracing() -> Option<SWTrace> {
8568
if buf.is_null() {
8669
None
8770
} else {
88-
Some(SWTrace { buf, len })
71+
Some((buf, len))
8972
}
9073
}
9174

src/test/run-fail/yk_swt/oob-trace-idx.rs

Lines changed: 0 additions & 39 deletions
This file was deleted.

src/test/run-pass/yk_swt/collect-trace-twice.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,10 @@ pub fn main() {
2828
black_box(work2());
2929
let trace2 = stop_tracing().unwrap();
3030

31-
assert!(trace1.len() > trace2.len());
31+
assert!(trace1.1 > trace2.1);
3232

33-
unsafe { libc::free(trace1.buf() as *mut libc::c_void) };
34-
unsafe { libc::free(trace2.buf() as *mut libc::c_void) };
33+
unsafe { libc::free(trace1.0 as *mut libc::c_void) };
34+
unsafe { libc::free(trace2.0 as *mut libc::c_void) };
3535
}
3636

3737
#[inline(never)]

src/test/run-pass/yk_swt/collect-trace.rs

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,11 @@ pub fn main() {
2323
black_box(work());
2424
let trace = stop_tracing().unwrap();
2525

26-
let len = trace.len();
2726
// The default capacity of the trace buffer is 1024. We want to be sure we've tested the case
2827
// where it had to be reallocated beyond its starting capacity.
29-
assert!(len > 1024);
28+
assert!(trace.1 > 1024);
3029

31-
for idx in 0..len {
32-
trace.loc(idx); // All indices are in bounds, so should not panic.
33-
}
34-
35-
unsafe { libc::free(trace.buf() as *mut libc::c_void) };
30+
unsafe { libc::free(trace.0 as *mut libc::c_void) };
3631
}
3732

3833
#[inline(never)]

src/test/run-pass/yk_swt/collect-traces-threaded.rs

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ extern crate core;
1515
extern crate libc;
1616
extern crate test;
1717

18-
use core::yk_swt::{start_tracing, stop_tracing, SWTrace};
18+
use core::yk_swt::{start_tracing, stop_tracing, MirLoc};
1919
use std::thread;
2020
use test::black_box;
2121

@@ -25,29 +25,30 @@ fn main() {
2525
start_tracing();
2626
let _ = work2();
2727
let raw_trace2 = stop_tracing().unwrap();
28-
let trace2 = trace_to_vec(&raw_trace2);
29-
unsafe { libc::free(raw_trace2.buf() as *mut libc::c_void) };
28+
let trace2 = trace_to_vec(raw_trace2);
3029
trace2
3130
});
3231

3332
start_tracing();
3433
black_box(work1());
3534
let raw_trace1 = stop_tracing().unwrap();
36-
let trace1 = trace_to_vec(&raw_trace1);
37-
unsafe { libc::free(raw_trace1.buf() as *mut libc::c_void) };
35+
let trace1 = trace_to_vec(raw_trace1);
3836

3937
let trace2 = thr2.join().unwrap();
4038

4139
assert_ne!(trace1, trace2); // They should have been thread local.
4240
}
4341

4442
// Copies a trace into a plain Rust Vec of tuples so we can compare them.
45-
fn trace_to_vec(t: &SWTrace) -> Vec<(u64, u32, u32)> {
43+
fn trace_to_vec(tup: (*mut MirLoc, usize)) -> Vec<(u64, u32, u32)> {
44+
let (buf, len) = tup;
4645
let mut v = Vec::new();
47-
for i in 0..t.len() {
48-
let loc = t.loc(i);
49-
v.push((loc.crate_hash, loc.def_idx, loc.bb_idx));
46+
assert!(len < (isize::max_value() as usize)); // Or we can't do ptr arithmetic.
47+
for i in 0..len {
48+
let loc = unsafe { &*buf.offset(i as isize) };
49+
v.push((loc.crate_hash(), loc.def_idx(), loc.bb_idx()));
5050
}
51+
unsafe { libc::free(buf as *mut libc::c_void) };
5152
v
5253
}
5354

0 commit comments

Comments
 (0)