Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 28 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,8 @@ jobs:
$FEATURES \
--verbose \
-- \
--skip ui
--skip ui \
--skip codegen

# Only run tests when targetting Linux x86 (32- or 64-bit) - we're
# executing on Linux x86_64, so we can't run tests for any non-x86 target.
Expand Down Expand Up @@ -609,6 +610,28 @@ jobs:
matrix.target != 'wasm32-unknown-unknown' &&
env.ZC_SKIP_CARGO_SEMVER_CHECKS != '1'

codegen:
runs-on: ubuntu-latest
name: Run codegen tests
needs: generate_cache
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
persist-credentials: false
- name: Populate cache
uses: ./.github/actions/cache
- name: Run tests
run: |
set -eo pipefail
sudo apt install -qq llvm
./cargo.sh +nightly install --quiet cargo-show-asm
RUSTFLAGS="$RUSTFLAGS -Awarnings" ./cargo.sh +nightly test \
--package zerocopy \
--target x86_64-unknown-linux-gnu \
--all-features \
--verbose \
--test codegen

coverage:
runs-on: ubuntu-latest
name: Generate code coverage
Expand All @@ -631,7 +654,9 @@ jobs:
--lcov \
--output-path lcov.info \
--verbose \
-- --skip ui
-- \
--skip ui \
--skip codegen
- name: Upload coverage to Codecov
uses: codecov/codecov-action@671740ac38dd9b0130fbe1cec585b89eea48d3de # v5.5.2
with:
Expand Down Expand Up @@ -988,7 +1013,7 @@ jobs:
# https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/collaborating-on-repositories-with-code-quality-features/troubleshooting-required-status-checks#handling-skipped-but-required-checks
if: failure()
runs-on: ubuntu-latest
needs: [build_test, coverage, kani, check_be_aarch64, check_avr_atmega, check_fmt, check_actions, check_readme, check_versions, check_msrv_is_minimal, check_stale_stderr, generate_cache, check-all-toolchains-tested, check-job-dependencies, check-todo, run-git-hooks, zizmor]
needs: [build_test, codegen, coverage, kani, check_be_aarch64, check_avr_atmega, check_fmt, check_actions, check_readme, check_versions, check_msrv_is_minimal, check_stale_stderr, generate_cache, check-all-toolchains-tested, check-job-dependencies, check-todo, run-git-hooks, zizmor]
steps:
- name: Mark the job as failed
run: exit 1
44 changes: 44 additions & 0 deletions benches/formats/coco.rs
Comment thread
joshlf marked this conversation as resolved.
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Copyright 2026 The Fuchsia Authors
//
// Licensed under a BSD-style license <LICENSE-BSD>, Apache License, Version 2.0
// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
// This file may not be copied, modified, or distributed except according to
// those terms.

//! This modules defines two formats similar to the one used to illustrate the
//! examples of [`zerocopy::TryFromBytes`]. The basic structure of these formats
//! is a [`Packet`], which has a parameterizable leading field, followed by
//! two-fixed byte fields, followed by a dynamically sized field. This format is
//! consumed by our benchmarks either as a [`CocoPacket`] (which begins with the
//! leading bytes `0xC0C0`), or a [`LocoPacket`] (which begins two bytes of any
//! value). Both formats share the following qualities which stress-test our
//! benchmarks:
//!
//! - They have a minimum alignment of two.
//! - They have a minimum size of four bytes.
//! - They have an even size.

use zerocopy_derive::*;

// The only valid value of this type are the bytes `0xC0C0`.
#[derive(TryFromBytes, KnownLayout, Immutable)]
#[repr(u16)]
pub enum C0C0 {
_XC0C0 = 0xC0C0,
}

#[derive(FromBytes, KnownLayout, Immutable)]
#[repr(C, align(2))]
pub struct Packet<Magic> {
magic_number: Magic,
mug_size: u8,
temperature: u8,
marshmallows: [[u8; 2]],
}

/// A packet begining with the magic number `0xC0C0`.
pub type CocoPacket = Packet<C0C0>;

/// A packet beginning with any two initialized bytes.
pub type LocoPacket = Packet<[u8; 2]>;
17 changes: 17 additions & 0 deletions benches/ref_from_bytes.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Copyright 2026 The Fuchsia Authors
//
// Licensed under a BSD-style license <LICENSE-BSD>, Apache License, Version 2.0
// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
// This file may not be copied, modified, or distributed except according to
// those terms.

use zerocopy::FromBytes;

#[path = "formats/coco.rs"]
mod format;

#[unsafe(no_mangle)]
fn codegen_test(source: &[u8]) -> Option<&format::LocoPacket> {
FromBytes::ref_from_bytes(source).ok()
}
75 changes: 75 additions & 0 deletions benches/ref_from_bytes.x86-64.mca
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
Iterations: 100
Instructions: 1800
Total Cycles: 704
Total uOps: 2000

Dispatch Width: 4
uOps Per Cycle: 2.84
IPC: 2.56
Block RThroughput: 5.0


Instruction Info:
[1]: #uOps
[2]: Latency
[3]: RThroughput
[4]: MayLoad
[5]: MayStore
[6]: HasSideEffects (U)

[1] [2] [3] [4] [5] [6] Instructions:
1 1 0.33 mov rdx, rsi
1 1 0.33 cmp rsi, 4
1 1 0.50 setb al
1 1 0.33 or al, dil
1 1 0.33 test al, 1
1 1 1.00 je .LBB5_2
1 0 0.25 xor eax, eax
1 1 1.00 U ret
1 1 0.50 lea rcx, [rdx - 4]
1 1 0.33 mov rsi, rcx
1 1 0.33 and rsi, -2
1 1 0.33 add rsi, 4
1 1 0.50 shr rcx
1 0 0.25 xor eax, eax
1 1 0.33 cmp rdx, rsi
2 2 0.67 cmove rdx, rcx
2 2 0.67 cmove rax, rdi
1 1 1.00 U ret


Resources:
[0] - SBDivider
[1] - SBFPDivider
[2] - SBPort0
[3] - SBPort1
[4] - SBPort4
[5] - SBPort5
[6.0] - SBPort23
[6.1] - SBPort23


Resource pressure per iteration:
[0] [1] [2] [3] [4] [5] [6.0] [6.1]
- - 5.97 5.98 - 6.05 - -

Resource pressure by instruction:
[0] [1] [2] [3] [4] [5] [6.0] [6.1] Instructions:
- - 0.97 0.01 - 0.02 - - mov rdx, rsi
- - 0.01 0.02 - 0.97 - - cmp rsi, 4
- - 0.03 - - 0.97 - - setb al
- - 0.01 0.02 - 0.97 - - or al, dil
- - - 0.98 - 0.02 - - test al, 1
- - - - - 1.00 - - je .LBB5_2
- - - - - - - - xor eax, eax
- - - - - 1.00 - - ret
- - 0.98 0.02 - - - - lea rcx, [rdx - 4]
- - 0.01 0.99 - - - - mov rsi, rcx
- - - 0.98 - 0.02 - - and rsi, -2
- - 0.98 0.01 - 0.01 - - add rsi, 4
- - 0.99 - - 0.01 - - shr rcx
- - - - - - - - xor eax, eax
- - 0.02 0.97 - 0.01 - - cmp rdx, rsi
- - 0.99 0.99 - 0.02 - - cmove rdx, rcx
- - 0.98 0.99 - 0.03 - - cmove rax, rdi
- - - - - 1.00 - - ret
17 changes: 17 additions & 0 deletions benches/ref_from_bytes_with_elems.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Copyright 2026 The Fuchsia Authors
//
// Licensed under a BSD-style license <LICENSE-BSD>, Apache License, Version 2.0
// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
// This file may not be copied, modified, or distributed except according to
// those terms.

use zerocopy::FromBytes;

#[path = "formats/coco.rs"]
mod format;

#[unsafe(no_mangle)]
fn codegen_test(source: &[u8], count: usize) -> Option<&format::LocoPacket> {
FromBytes::ref_from_bytes_with_elems(source, count).ok()
}
65 changes: 65 additions & 0 deletions benches/ref_from_bytes_with_elems.x86-64.mca
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
Iterations: 100
Instructions: 1300
Total Cycles: 439
Total uOps: 1400

Dispatch Width: 4
uOps Per Cycle: 3.19
IPC: 2.96
Block RThroughput: 3.5


Instruction Info:
[1]: #uOps
[2]: Latency
[3]: RThroughput
[4]: MayLoad
[5]: MayStore
[6]: HasSideEffects (U)

[1] [2] [3] [4] [5] [6] Instructions:
1 1 0.33 movabs rax, 9223372036854775805
1 1 0.33 cmp rdx, rax
2 2 1.00 seta cl
1 1 0.33 mov rax, rdi
1 1 0.33 or dil, cl
1 1 0.33 test dil, 1
1 1 1.00 jne .LBB5_2
1 1 0.50 lea rcx, [2*rdx + 4]
1 1 0.33 cmp rsi, rcx
1 1 1.00 je .LBB5_3
1 0 0.25 xor eax, eax
1 1 0.33 mov rdx, rsi
1 1 1.00 U ret


Resources:
[0] - SBDivider
[1] - SBFPDivider
[2] - SBPort0
[3] - SBPort1
[4] - SBPort4
[5] - SBPort5
[6.0] - SBPort23
[6.1] - SBPort23


Resource pressure per iteration:
[0] [1] [2] [3] [4] [5] [6.0] [6.1]
- - 4.32 4.33 - 4.35 - -

Resource pressure by instruction:
[0] [1] [2] [3] [4] [5] [6.0] [6.1] Instructions:
- - - 0.99 - 0.01 - - movabs rax, 9223372036854775805
- - 0.33 0.67 - - - - cmp rdx, rax
- - 1.98 - - 0.02 - - seta cl
- - 0.01 0.99 - - - - mov rax, rdi
- - 1.00 - - - - - or dil, cl
- - 0.99 0.01 - - - - test dil, 1
- - - - - 1.00 - - jne .LBB5_2
- - - 1.00 - - - - lea rcx, [2*rdx + 4]
- - 0.01 - - 0.99 - - cmp rsi, rcx
- - - - - 1.00 - - je .LBB5_3
- - - - - - - - xor eax, eax
- - - 0.67 - 0.33 - - mov rdx, rsi
- - - - - 1.00 - - ret
20 changes: 20 additions & 0 deletions benches/ref_from_prefix.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Copyright 2026 The Fuchsia Authors
//
// Licensed under a BSD-style license <LICENSE-BSD>, Apache License, Version 2.0
// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
// This file may not be copied, modified, or distributed except according to
// those terms.

use zerocopy::FromBytes;

#[path = "formats/coco.rs"]
mod format;

#[unsafe(no_mangle)]
fn codegen_test(source: &[u8]) -> Option<&format::LocoPacket> {
match FromBytes::ref_from_prefix(source) {
Ok((packet, _rest)) => Some(packet),
_ => None,
}
}
67 changes: 67 additions & 0 deletions benches/ref_from_prefix.x86-64.mca
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
Iterations: 100
Instructions: 1400
Total Cycles: 405
Total uOps: 1400

Dispatch Width: 4
uOps Per Cycle: 3.46
IPC: 3.46
Block RThroughput: 4.0


Instruction Info:
[1]: #uOps
[2]: Latency
[3]: RThroughput
[4]: MayLoad
[5]: MayStore
[6]: HasSideEffects (U)

[1] [2] [3] [4] [5] [6] Instructions:
1 0 0.25 xor edx, edx
1 1 0.33 mov eax, 0
1 1 0.33 test dil, 1
1 1 1.00 jne .LBB5_4
1 1 0.33 cmp rsi, 4
1 1 1.00 jae .LBB5_3
1 1 0.33 mov edx, 1
1 0 0.25 xor eax, eax
1 1 1.00 U ret
1 1 0.33 add rsi, -4
1 1 0.50 shr rsi
1 1 0.33 mov rdx, rsi
1 1 0.33 mov rax, rdi
1 1 1.00 U ret


Resources:
[0] - SBDivider
[1] - SBFPDivider
[2] - SBPort0
[3] - SBPort1
[4] - SBPort4
[5] - SBPort5
[6.0] - SBPort23
[6.1] - SBPort23


Resource pressure per iteration:
[0] [1] [2] [3] [4] [5] [6.0] [6.1]
- - 3.99 3.99 - 4.02 - -

Resource pressure by instruction:
[0] [1] [2] [3] [4] [5] [6.0] [6.1] Instructions:
- - - - - - - - xor edx, edx
- - 0.01 0.98 - 0.01 - - mov eax, 0
- - 0.98 0.02 - - - - test dil, 1
- - - - - 1.00 - - jne .LBB5_4
- - 0.02 0.98 - - - - cmp rsi, 4
- - - - - 1.00 - - jae .LBB5_3
- - 0.98 0.01 - 0.01 - - mov edx, 1
- - - - - - - - xor eax, eax
- - - - - 1.00 - - ret
- - 0.01 0.99 - - - - add rsi, -4
- - 1.00 - - - - - shr rsi
- - - 1.00 - - - - mov rdx, rsi
- - 0.99 0.01 - - - - mov rax, rdi
- - - - - 1.00 - - ret
20 changes: 20 additions & 0 deletions benches/ref_from_prefix_with_elems.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Copyright 2026 The Fuchsia Authors
//
// Licensed under a BSD-style license <LICENSE-BSD>, Apache License, Version 2.0
// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
// This file may not be copied, modified, or distributed except according to
// those terms.

use zerocopy::FromBytes;

#[path = "formats/coco.rs"]
mod format;

#[unsafe(no_mangle)]
fn codegen_test(source: &[u8], count: usize) -> Option<&format::LocoPacket> {
match FromBytes::ref_from_prefix_with_elems(source, count) {
Ok((packet, _rest)) => Some(packet),
_ => None,
}
}
Loading
Loading