feat(rust): move wildcopy behind a narrow ABI leaf
Keep the C header's ZSTD_wildcopy signature as the enum-facing wrapper, but move its over-copying implementation into rust/src/mem.rs. The wrapper passes the enum's int representation to ZSTD_rust_wildcopy, where only the two valid values are converted to ZstdOverlap. This leaves C's ZSTD_copy16/COPY16 helpers available to their direct compression callers and removes the now unused COPY8 helper. ZSTD_copy16 is marked unused-safe for C translation units that include the shared header without calling that direct helper. The Rust leaf preserves the original first-copy behavior for zero and short lengths, the source-before-destination 8-byte do-while path, the no-overlap distance assertion, and the first-then-two-COPY16 loop. Its ABI contract does not take ownership of caller buffers. ABI tests use 32-byte padded buffers and exercise no-overlap plus offsets 8 and 15 across the boundary lengths, checking both copied bytes and guard regions. Test Plan: - `cargo test mem::tests` -- passed (4 tests) - `make lib-nomt` and `make lib-mt` -- passed - `make -C tests test-zstream` -- passed - `make -C tests test-fullbench` -- completed; its `-P0` run printed the existing Scenario 17 diagnostic, but the target returned normally - `cargo clippy`, `cargo clippy --benches`, `cargo clippy --tests`, `cargo +nightly fmt`, then the same three clippy commands -- passed on the final repeat - `git diff --cached --check` -- passed
This commit is contained in:
@@ -167,20 +167,11 @@ static UNUSED_ATTR const U32 OF_defaultNormLog = OF_DEFAULTNORMLOG;
|
||||
/*-*******************************************
|
||||
* Shared functions to include for inlining
|
||||
*********************************************/
|
||||
static void ZSTD_copy8(void* dst, const void* src) {
|
||||
#if defined(ZSTD_ARCH_ARM_NEON)
|
||||
vst1_u8((uint8_t*)dst, vld1_u8((const uint8_t*)src));
|
||||
#else
|
||||
ZSTD_memcpy(dst, src, 8);
|
||||
#endif
|
||||
}
|
||||
#define COPY8(d,s) do { ZSTD_copy8(d,s); d+=8; s+=8; } while (0)
|
||||
|
||||
/* Need to use memmove here since the literal buffer can now be located within
|
||||
the dst buffer. In circumstances where the op "catches up" to where the
|
||||
literal buffer is, there can be partial overlaps in this call on the final
|
||||
copy if the literal is being shifted by less than 16 bytes. */
|
||||
static void ZSTD_copy16(void* dst, const void* src) {
|
||||
static UNUSED_ATTR void ZSTD_copy16(void* dst, const void* src) {
|
||||
#if defined(ZSTD_ARCH_ARM_NEON)
|
||||
vst1q_u8((uint8_t*)dst, vld1q_u8((const uint8_t*)src));
|
||||
#elif defined(ZSTD_ARCH_X86_SSE2)
|
||||
@@ -205,6 +196,8 @@ typedef enum {
|
||||
/* ZSTD_overlap_dst_before_src, */
|
||||
} ZSTD_overlap_e;
|
||||
|
||||
void ZSTD_rust_wildcopy(void* dst, const void* src, ptrdiff_t length, int ovtype);
|
||||
|
||||
/*! ZSTD_wildcopy() :
|
||||
* Custom version of ZSTD_memcpy(), can over read/write up to WILDCOPY_OVERLENGTH bytes (if length==0)
|
||||
* @param ovtype controls the overlap detection
|
||||
@@ -215,34 +208,7 @@ typedef enum {
|
||||
MEM_STATIC FORCE_INLINE_ATTR
|
||||
void ZSTD_wildcopy(void* dst, const void* src, ptrdiff_t length, ZSTD_overlap_e const ovtype)
|
||||
{
|
||||
ptrdiff_t diff = (BYTE*)dst - (const BYTE*)src;
|
||||
const BYTE* ip = (const BYTE*)src;
|
||||
BYTE* op = (BYTE*)dst;
|
||||
BYTE* const oend = op + length;
|
||||
|
||||
if (ovtype == ZSTD_overlap_src_before_dst && diff < WILDCOPY_VECLEN) {
|
||||
/* Handle short offset copies. */
|
||||
do {
|
||||
COPY8(op, ip);
|
||||
} while (op < oend);
|
||||
} else {
|
||||
assert(diff >= WILDCOPY_VECLEN || diff <= -WILDCOPY_VECLEN);
|
||||
/* Separate out the first COPY16() call because the copy length is
|
||||
* almost certain to be short, so the branches have different
|
||||
* probabilities. Since it is almost certain to be short, only do
|
||||
* one COPY16() in the first call. Then, do two calls per loop since
|
||||
* at that point it is more likely to have a high trip count.
|
||||
*/
|
||||
ZSTD_copy16(op, ip);
|
||||
if (16 >= length) return;
|
||||
op += 16;
|
||||
ip += 16;
|
||||
do {
|
||||
COPY16(op, ip);
|
||||
COPY16(op, ip);
|
||||
}
|
||||
while (op < oend);
|
||||
}
|
||||
ZSTD_rust_wildcopy(dst, src, length, (int)ovtype);
|
||||
}
|
||||
|
||||
MEM_STATIC size_t ZSTD_limitCopy(void* dst, size_t dstCapacity, const void* src, size_t srcSize)
|
||||
|
||||
Reference in New Issue
Block a user