aboutsummaryrefslogtreecommitdiff
path: root/lib/std/Build/Fuzz
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2024-08-08 21:44:37 -0700
committerAndrew Kelley <andrew@ziglang.org>2024-08-08 21:46:36 -0700
commitf6f1ecf0f9227bee33b963a6ff5dfc3001ad2c46 (patch)
tree0995711a5355f2526ab4455909892a8107e500be /lib/std/Build/Fuzz
parent4e32edbff5d34dfc779797d73bb61d32ffa02953 (diff)
downloadzig-f6f1ecf0f9227bee33b963a6ff5dfc3001ad2c46.tar.gz
zig-f6f1ecf0f9227bee33b963a6ff5dfc3001ad2c46.zip
more optimized and correct management of 8-bit PC counters
* Upgrade from u8 to usize element types. - WebAssembly assumes u64. It should probably try to be target-aware instead. * Move the covered PC bits to after the header so it goes on the same page with the other rapidly changing memory (the header stats). depends on the semantics of accepted proposal #19755 closes #20994
Diffstat (limited to 'lib/std/Build/Fuzz')
-rw-r--r--lib/std/Build/Fuzz/WebServer.zig17
-rw-r--r--lib/std/Build/Fuzz/abi.zig43
2 files changed, 41 insertions, 19 deletions
diff --git a/lib/std/Build/Fuzz/WebServer.zig b/lib/std/Build/Fuzz/WebServer.zig
index f0c9e8dfe3..17bc2c918f 100644
--- a/lib/std/Build/Fuzz/WebServer.zig
+++ b/lib/std/Build/Fuzz/WebServer.zig
@@ -384,10 +384,7 @@ fn sendCoverageContext(
// TODO: make each events URL correspond to one coverage map
const coverage_map = &coverage_maps[0];
const cov_header: *const abi.SeenPcsHeader = @ptrCast(coverage_map.mapped_memory[0..@sizeOf(abi.SeenPcsHeader)]);
- comptime assert(abi.SeenPcsHeader.trailing[0] == .pc_addr);
- const seen_pcs = coverage_map.mapped_memory[@sizeOf(abi.SeenPcsHeader) + coverage_map.source_locations.len * @sizeOf(usize) ..];
- comptime assert(abi.SeenPcsHeader.trailing[1][0] == .pc_bits);
- comptime assert(abi.SeenPcsHeader.trailing[1][1] == u8);
+ const seen_pcs = cov_header.seenBits();
const n_runs = @atomicLoad(usize, &cov_header.n_runs, .monotonic);
const unique_runs = @atomicLoad(usize, &cov_header.unique_runs, .monotonic);
const lowest_stack = @atomicLoad(usize, &cov_header.lowest_stack, .monotonic);
@@ -419,7 +416,7 @@ fn sendCoverageContext(
};
const iovecs: [2]std.posix.iovec_const = .{
makeIov(std.mem.asBytes(&header)),
- makeIov(seen_pcs),
+ makeIov(std.mem.sliceAsBytes(seen_pcs)),
};
try web_socket.writeMessagev(&iovecs, .binary);
@@ -634,9 +631,7 @@ fn prepareTables(
gop.value_ptr.mapped_memory = mapped_memory;
const header: *const abi.SeenPcsHeader = @ptrCast(mapped_memory[0..@sizeOf(abi.SeenPcsHeader)]);
- comptime assert(abi.SeenPcsHeader.trailing[0] == .pc_addr);
- const pcs_bytes = mapped_memory[@sizeOf(abi.SeenPcsHeader)..][0 .. header.pcs_len * @sizeOf(usize)];
- const pcs = std.mem.bytesAsSlice(usize, pcs_bytes);
+ const pcs = header.pcAddrs();
const source_locations = try gpa.alloc(Coverage.SourceLocation, pcs.len);
errdefer gpa.free(source_locations);
debug_info.resolveAddresses(gpa, pcs, source_locations) catch |err| {
@@ -653,10 +648,8 @@ fn addEntryPoint(ws: *WebServer, coverage_id: u64, addr: u64) error{ AlreadyRepo
defer ws.coverage_mutex.unlock();
const coverage_map = ws.coverage_files.getPtr(coverage_id).?;
- const ptr = coverage_map.mapped_memory;
- comptime assert(abi.SeenPcsHeader.trailing[0] == .pc_addr);
- const pcs_bytes = ptr[@sizeOf(abi.SeenPcsHeader)..][0 .. coverage_map.source_locations.len * @sizeOf(usize)];
- const pcs: []const usize = @alignCast(std.mem.bytesAsSlice(usize, pcs_bytes));
+ const header: *const abi.SeenPcsHeader = @ptrCast(coverage_map.mapped_memory[0..@sizeOf(abi.SeenPcsHeader)]);
+ const pcs = header.pcAddrs();
const index = std.sort.upperBound(usize, pcs, addr, struct {
fn order(context: usize, item: usize) std.math.Order {
return std.math.order(item, context);
diff --git a/lib/std/Build/Fuzz/abi.zig b/lib/std/Build/Fuzz/abi.zig
index 1d6585de7a..0e16f0d5fa 100644
--- a/lib/std/Build/Fuzz/abi.zig
+++ b/lib/std/Build/Fuzz/abi.zig
@@ -7,8 +7,8 @@
/// make the ints be the size of the target used with libfuzzer.
///
/// Trailing:
+/// * 1 bit per pc_addr, usize elements
/// * pc_addr: usize for each pcs_len
-/// * 1 bit per pc_addr, u8 elements
pub const SeenPcsHeader = extern struct {
n_runs: usize,
unique_runs: usize,
@@ -18,9 +18,29 @@ pub const SeenPcsHeader = extern struct {
/// Used for comptime assertions. Provides a mechanism for strategically
/// causing compile errors.
pub const trailing = .{
+ .pc_bits_usize,
.pc_addr,
- .{ .pc_bits, u8 },
};
+
+ pub fn headerEnd(header: *const SeenPcsHeader) []const usize {
+ const ptr: [*]align(@alignOf(usize)) const u8 = @ptrCast(header);
+ const header_end_ptr: [*]const usize = @ptrCast(ptr + @sizeOf(SeenPcsHeader));
+ const pcs_len = header.pcs_len;
+ return header_end_ptr[0 .. pcs_len + seenElemsLen(pcs_len)];
+ }
+
+ pub fn seenBits(header: *const SeenPcsHeader) []const usize {
+ return header.headerEnd()[0..seenElemsLen(header.pcs_len)];
+ }
+
+ pub fn seenElemsLen(pcs_len: usize) usize {
+ return (pcs_len + @bitSizeOf(usize) - 1) / @bitSizeOf(usize);
+ }
+
+ pub fn pcAddrs(header: *const SeenPcsHeader) []const usize {
+ const pcs_len = header.pcs_len;
+ return header.headerEnd()[seenElemsLen(pcs_len)..][0..pcs_len];
+ }
};
pub const ToClientTag = enum(u8) {
@@ -54,12 +74,21 @@ pub const SourceIndexHeader = extern struct {
/// changes.
///
/// Trailing:
-/// * one bit per source_locations_len, contained in u8 elements
+/// * one bit per source_locations_len, contained in u64 elements
pub const CoverageUpdateHeader = extern struct {
- tag: ToClientTag = .coverage_update,
- n_runs: u64 align(1),
- unique_runs: u64 align(1),
- lowest_stack: u64 align(1),
+ flags: Flags = .{},
+ n_runs: u64,
+ unique_runs: u64,
+ lowest_stack: u64,
+
+ pub const Flags = packed struct(u64) {
+ tag: ToClientTag = .coverage_update,
+ _: u56 = 0,
+ };
+
+ pub const trailing = .{
+ .pc_bits_usize,
+ };
};
/// Sent to the fuzzer web client when the set of entry points is updated.