|
| 1 | +/// Debug-only pointer alignment assertion that is safe to export. |
| 2 | +/// |
| 3 | +/// Why this style: |
| 4 | +/// - We need to re-export a symbol other crates can call, but we do not |
| 5 | +/// want benches or release builds to pull in debug-only deps or code. |
| 6 | +/// - Putting `#[cfg(...)]` on the function itself makes the symbol |
| 7 | +/// vanish in release/bench. Callers would then need their own cfg |
| 8 | +/// fences, which is brittle across crates. |
| 9 | +/// - By keeping the function always present and gating only its body, |
| 10 | +/// callers can invoke it unconditionally. In debug/test it asserts; |
| 11 | +/// in release/bench it compiles to a no-op. |
| 12 | +/// |
| 13 | +/// Build behavior: |
| 14 | +/// - In debug/test, the inner block runs and uses `debug_assert!`. |
| 15 | +/// - In release/bench, the else block keeps the args "used" so the |
| 16 | +/// function is a true no-op (no codegen warnings, no panic paths). |
| 17 | +/// |
| 18 | +/// Cost: |
| 19 | +/// - Inlining plus the cfg-ed body means zero runtime cost in release |
| 20 | +/// and bench profiles. |
| 21 | +/// |
| 22 | +/// Usage: |
| 23 | +/// - Call anywhere you want a cheap alignment check in debug/test, |
| 24 | +/// including from other crates that depend on this one. |
| 25 | +#[inline] |
| 26 | +pub fn debug_assert_aligned(ptr: *const u8, align: usize) { |
| 27 | + #[cfg(any(test, debug_assertions))] |
| 28 | + { |
| 29 | + debug_assert!(align.is_power_of_two()); |
| 30 | + debug_assert!( |
| 31 | + (ptr as usize & (align - 1)) == 0, |
| 32 | + "buffer base is not {}-byte aligned", |
| 33 | + align |
| 34 | + ); |
| 35 | + } |
| 36 | + |
| 37 | + #[cfg(not(any(test, debug_assertions)))] |
| 38 | + { |
| 39 | + // Release/bench: no-op. Keep args used to avoid warnings. |
| 40 | + let _ = ptr; |
| 41 | + let _ = align; |
| 42 | + } |
| 43 | +} |
| 44 | + |
| 45 | +/// Debug-only file-offset alignment assertion that is safe to export. |
| 46 | +/// |
| 47 | +/// Same rationale as `debug_assert_aligned`: keep a stable symbol that |
| 48 | +/// callers can invoke without cfg fences, while ensuring zero cost in |
| 49 | +/// release/bench builds. |
| 50 | +/// |
| 51 | +/// Why not a module-level cfg or `use`: |
| 52 | +/// - Some bench setups compile with `--all-features` and may still pull |
| 53 | +/// modules in ways that trip cfg-ed imports. Gating inside the body |
| 54 | +/// avoids those hazards and keeps the bench linker happy. |
| 55 | +/// |
| 56 | +/// Behavior: |
| 57 | +/// - Debug/test: checks that `off` is a multiple of the configured |
| 58 | +/// `PAYLOAD_ALIGNMENT`. |
| 59 | +/// - Release/bench: no-op, arguments are marked used. |
| 60 | +/// |
| 61 | +/// Notes: |
| 62 | +/// - This asserts the *derived start offset* of a payload, not the |
| 63 | +/// pointer. Use the pointer variant to assert the actual address you |
| 64 | +/// hand to consumers like Arrow. |
| 65 | +#[inline] |
| 66 | +pub fn debug_assert_aligned_offset(off: u64) { |
| 67 | + #[cfg(any(test, debug_assertions))] |
| 68 | + { |
| 69 | + use crate::constants::PAYLOAD_ALIGNMENT; |
| 70 | + |
| 71 | + debug_assert!( |
| 72 | + PAYLOAD_ALIGNMENT.is_power_of_two(), |
| 73 | + "PAYLOAD_ALIGNMENT must be a power of two" |
| 74 | + ); |
| 75 | + debug_assert!( |
| 76 | + off.is_multiple_of(PAYLOAD_ALIGNMENT), |
| 77 | + "derived payload start not {}-byte aligned (got {})", |
| 78 | + PAYLOAD_ALIGNMENT, |
| 79 | + off |
| 80 | + ); |
| 81 | + } |
| 82 | + |
| 83 | + #[cfg(not(any(test, debug_assertions)))] |
| 84 | + { |
| 85 | + // Release/bench: no-op. Keep arg used to avoid warnings. |
| 86 | + let _ = off; |
| 87 | + } |
| 88 | +} |
0 commit comments