diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2024-08-08 21:44:37 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2024-08-08 21:46:36 -0700 |
| commit | f6f1ecf0f9227bee33b963a6ff5dfc3001ad2c46 (patch) | |
| tree | 0995711a5355f2526ab4455909892a8107e500be /lib/std/Build/Fuzz | |
| parent | 4e32edbff5d34dfc779797d73bb61d32ffa02953 (diff) | |
| download | zig-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.zig | 17 | ||||
| -rw-r--r-- | lib/std/Build/Fuzz/abi.zig | 43 |
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. |
