feat(decompress): reuse canonical Dctx view for DDict
Remove the C-only DDict offset globals and route production ZSTD_copyDDictParameters() through the existing C-produced DCtx view. This keeps the private decoder layout and optional fuzzing fields owned by the canonical projection while preserving the DDict entropy, prefix, window, and checksum state updates. Keep the synthetic offset writer test-only so the Rust unit tests remain independently linkable. Test Plan: - ulimit -v 41943040; CARGO_BUILD_JOBS=1 cargo check --manifest-path rust/cli/Cargo.toml --all-targets - ulimit -v 41943040; CARGO_BUILD_JOBS=1 cargo test --manifest-path rust/cli/Cargo.toml --all-targets (207 passed) - ulimit -v 41943040; CARGO_BUILD_JOBS=1 cargo clippy --manifest-path rust/cli/Cargo.toml --all-targets -- -D warnings - ulimit -v 41943040; CARGO_BUILD_JOBS=1 make -j1 - ulimit -v 41943040; CARGO_BUILD_JOBS=1 make -j1 -C tests test - git diff --check
This commit is contained in:
@@ -2,32 +2,7 @@
|
||||
* ZSTD_DDict implementation moved to rust/src/zstd_ddict.rs.
|
||||
*
|
||||
* Keep this translation unit in the original source list so the C build keeps
|
||||
* the same header configuration while the Rust static library provides the
|
||||
* exported symbols. The metadata below is deliberately compiled with the C
|
||||
* decoder's exact conditional layout: Rust uses it to fill the opaque DCtx
|
||||
* fields without duplicating optional C layout choices such as DYNAMIC_BMI2.
|
||||
* the same source topology while the Rust static library provides the
|
||||
* exported symbols. DDict parameter copying uses the canonical C-produced
|
||||
* ZSTD_rustDctxView, so this file no longer publishes private DCtx offsets.
|
||||
*/
|
||||
#define ZSTD_STATIC_LINKING_ONLY
|
||||
#include "zstd_decompress_internal.h"
|
||||
#include "zstd_ddict.h"
|
||||
|
||||
const size_t ZSTD_rust_ddict_llt_ptr_offset = offsetof(struct ZSTD_DCtx_s, LLTptr);
|
||||
const size_t ZSTD_rust_ddict_mlt_ptr_offset = offsetof(struct ZSTD_DCtx_s, MLTptr);
|
||||
const size_t ZSTD_rust_ddict_oft_ptr_offset = offsetof(struct ZSTD_DCtx_s, OFTptr);
|
||||
const size_t ZSTD_rust_ddict_huf_ptr_offset = offsetof(struct ZSTD_DCtx_s, HUFptr);
|
||||
const size_t ZSTD_rust_ddict_entropy_rep_offset = offsetof(struct ZSTD_DCtx_s, entropy.rep);
|
||||
const size_t ZSTD_rust_ddict_previous_dst_end_offset = offsetof(struct ZSTD_DCtx_s, previousDstEnd);
|
||||
const size_t ZSTD_rust_ddict_prefix_start_offset = offsetof(struct ZSTD_DCtx_s, prefixStart);
|
||||
const size_t ZSTD_rust_ddict_virtual_start_offset = offsetof(struct ZSTD_DCtx_s, virtualStart);
|
||||
const size_t ZSTD_rust_ddict_dict_end_offset = offsetof(struct ZSTD_DCtx_s, dictEnd);
|
||||
const size_t ZSTD_rust_ddict_lit_entropy_offset = offsetof(struct ZSTD_DCtx_s, litEntropy);
|
||||
const size_t ZSTD_rust_ddict_fse_entropy_offset = offsetof(struct ZSTD_DCtx_s, fseEntropy);
|
||||
const size_t ZSTD_rust_ddict_dict_id_offset = offsetof(struct ZSTD_DCtx_s, dictID);
|
||||
|
||||
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
|
||||
const size_t ZSTD_rust_ddict_fuzz_begin_offset = offsetof(struct ZSTD_DCtx_s, dictContentBeginForFuzzing);
|
||||
const size_t ZSTD_rust_ddict_fuzz_end_offset = offsetof(struct ZSTD_DCtx_s, dictContentEndForFuzzing);
|
||||
#else
|
||||
const size_t ZSTD_rust_ddict_fuzz_begin_offset = (size_t)-1;
|
||||
const size_t ZSTD_rust_ddict_fuzz_end_offset = (size_t)-1;
|
||||
#endif
|
||||
|
||||
+90
-46
@@ -12,7 +12,7 @@ use crate::common::{LL_FSE_LOG, ML_FSE_LOG, OFF_FSE_LOG, ZSTD_FRAMEIDSIZE, ZSTD_
|
||||
use crate::errors::{ERR_isError, ZstdErrorCode, ERROR};
|
||||
use crate::mem::MEM_readLE32;
|
||||
use std::ffi::c_void;
|
||||
use std::mem::size_of;
|
||||
use std::mem::{offset_of, size_of};
|
||||
use std::os::raw::{c_int, c_uint};
|
||||
use std::ptr;
|
||||
|
||||
@@ -25,6 +25,7 @@ const ZSTD_DLM_BY_COPY: c_int = 0;
|
||||
const ZSTD_DLM_BY_REF: c_int = 1;
|
||||
const ZSTD_DCT_RAW_CONTENT: c_int = 1;
|
||||
const ZSTD_DCT_FULL_DICT: c_int = 2;
|
||||
#[cfg(test)]
|
||||
const ZSTD_DDICT_NO_FUZZING_OFFSET: usize = usize::MAX;
|
||||
|
||||
type ZstdAllocFunction = unsafe extern "C" fn(*mut c_void, usize) -> *mut c_void;
|
||||
@@ -83,6 +84,7 @@ pub struct ZSTD_DCtx {
|
||||
_private: [u8; 0],
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[derive(Clone, Copy)]
|
||||
struct ZstdDctxOffsets {
|
||||
llt_ptr: usize,
|
||||
@@ -108,54 +110,11 @@ unsafe extern "C" {
|
||||
dict: *const c_void,
|
||||
dict_size: usize,
|
||||
) -> usize;
|
||||
|
||||
/*
|
||||
* These are emitted by zstd_ddict.c with the exact C preprocessor state
|
||||
* used for struct ZSTD_DCtx_s. Keeping the opaque context as C-provided
|
||||
* offsets avoids duplicating optional fields such as DYNAMIC_BMI2 in Rust.
|
||||
*/
|
||||
static ZSTD_rust_ddict_llt_ptr_offset: usize;
|
||||
static ZSTD_rust_ddict_mlt_ptr_offset: usize;
|
||||
static ZSTD_rust_ddict_oft_ptr_offset: usize;
|
||||
static ZSTD_rust_ddict_huf_ptr_offset: usize;
|
||||
static ZSTD_rust_ddict_entropy_rep_offset: usize;
|
||||
static ZSTD_rust_ddict_previous_dst_end_offset: usize;
|
||||
static ZSTD_rust_ddict_prefix_start_offset: usize;
|
||||
static ZSTD_rust_ddict_virtual_start_offset: usize;
|
||||
static ZSTD_rust_ddict_dict_end_offset: usize;
|
||||
static ZSTD_rust_ddict_lit_entropy_offset: usize;
|
||||
static ZSTD_rust_ddict_fse_entropy_offset: usize;
|
||||
static ZSTD_rust_ddict_dict_id_offset: usize;
|
||||
static ZSTD_rust_ddict_fuzz_begin_offset: usize;
|
||||
static ZSTD_rust_ddict_fuzz_end_offset: usize;
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[inline]
|
||||
unsafe fn ddict_dctx_offsets() -> ZstdDctxOffsets {
|
||||
#[cfg(not(test))]
|
||||
{
|
||||
unsafe {
|
||||
ZstdDctxOffsets {
|
||||
llt_ptr: ZSTD_rust_ddict_llt_ptr_offset,
|
||||
mlt_ptr: ZSTD_rust_ddict_mlt_ptr_offset,
|
||||
oft_ptr: ZSTD_rust_ddict_oft_ptr_offset,
|
||||
huf_ptr: ZSTD_rust_ddict_huf_ptr_offset,
|
||||
entropy_rep: ZSTD_rust_ddict_entropy_rep_offset,
|
||||
previous_dst_end: ZSTD_rust_ddict_previous_dst_end_offset,
|
||||
prefix_start: ZSTD_rust_ddict_prefix_start_offset,
|
||||
virtual_start: ZSTD_rust_ddict_virtual_start_offset,
|
||||
dict_end: ZSTD_rust_ddict_dict_end_offset,
|
||||
lit_entropy: ZSTD_rust_ddict_lit_entropy_offset,
|
||||
fse_entropy: ZSTD_rust_ddict_fse_entropy_offset,
|
||||
dict_id: ZSTD_rust_ddict_dict_id_offset,
|
||||
fuzz_begin: ZSTD_rust_ddict_fuzz_begin_offset,
|
||||
fuzz_end: ZSTD_rust_ddict_fuzz_end_offset,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
{
|
||||
ZstdDctxOffsets {
|
||||
llt_ptr: 0,
|
||||
mlt_ptr: size_of::<*const c_void>(),
|
||||
@@ -172,9 +131,9 @@ unsafe fn ddict_dctx_offsets() -> ZstdDctxOffsets {
|
||||
fuzz_begin: ZSTD_DDICT_NO_FUZZING_OFFSET,
|
||||
fuzz_end: ZSTD_DDICT_NO_FUZZING_OFFSET,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
unsafe fn write_dctx_field<T>(dctx: *mut ZSTD_DCtx, offset: usize, value: T) {
|
||||
unsafe {
|
||||
dctx.cast::<u8>()
|
||||
@@ -184,6 +143,7 @@ unsafe fn write_dctx_field<T>(dctx: *mut ZSTD_DCtx, offset: usize, value: T) {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
unsafe fn copy_fuzzing_bounds_at_offsets(
|
||||
dctx: *mut ZSTD_DCtx,
|
||||
begin: *const c_void,
|
||||
@@ -208,6 +168,7 @@ unsafe fn copy_fuzzing_bounds_at_offsets(
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
unsafe fn copy_fuzzing_bounds(dctx: *mut ZSTD_DCtx, begin: *const c_void, end: *const c_void) {
|
||||
let offsets = unsafe { ddict_dctx_offsets() };
|
||||
unsafe {
|
||||
@@ -215,6 +176,82 @@ unsafe fn copy_fuzzing_bounds(dctx: *mut ZSTD_DCtx, begin: *const c_void, end: *
|
||||
};
|
||||
}
|
||||
|
||||
#[cfg(not(test))]
|
||||
unsafe fn write_dctx_view_field<T>(field: *mut c_void, value: T) {
|
||||
unsafe { field.cast::<T>().write_unaligned(value) };
|
||||
}
|
||||
|
||||
#[cfg(not(test))]
|
||||
unsafe fn copy_fuzzing_bounds_view(
|
||||
view: &crate::zstd_decompress::ZSTD_rustDctxView,
|
||||
begin: *const c_void,
|
||||
end: *const c_void,
|
||||
) {
|
||||
if view.fuzz_begin.is_null() {
|
||||
debug_assert!(view.fuzz_end.is_null());
|
||||
return;
|
||||
}
|
||||
debug_assert!(!view.fuzz_end.is_null());
|
||||
unsafe {
|
||||
write_dctx_view_field(view.fuzz_begin, begin);
|
||||
write_dctx_view_field(view.fuzz_end, end);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(test))]
|
||||
unsafe fn copy_ddict_parameters_at_view(
|
||||
view: &crate::zstd_decompress::ZSTD_rustDctxView,
|
||||
ddict: *const ZSTD_DDict,
|
||||
) {
|
||||
unsafe {
|
||||
let dict_content = (*ddict).dict_content;
|
||||
let dict_end = if dict_content.is_null() {
|
||||
ptr::null()
|
||||
} else {
|
||||
dict_content.cast::<u8>().add((*ddict).dict_size).cast()
|
||||
};
|
||||
|
||||
write_dctx_view_field(view.dict_id, (*ddict).dict_id);
|
||||
write_dctx_view_field(view.prefix_start, dict_content);
|
||||
write_dctx_view_field(view.virtual_start, dict_content);
|
||||
write_dctx_view_field(view.dict_end, dict_end);
|
||||
write_dctx_view_field(view.previous_dst_end, dict_end);
|
||||
copy_fuzzing_bounds_view(view, dict_content, dict_end);
|
||||
|
||||
if (*ddict).entropy_present != 0 {
|
||||
write_dctx_view_field(view.lit_entropy, 1u32);
|
||||
write_dctx_view_field(view.fse_entropy, 1u32);
|
||||
write_dctx_view_field(
|
||||
view.llt_ptr,
|
||||
(*ddict).entropy.ll_table.as_ptr().cast::<c_void>(),
|
||||
);
|
||||
write_dctx_view_field(
|
||||
view.mlt_ptr,
|
||||
(*ddict).entropy.ml_table.as_ptr().cast::<c_void>(),
|
||||
);
|
||||
write_dctx_view_field(
|
||||
view.oft_ptr,
|
||||
(*ddict).entropy.of_table.as_ptr().cast::<c_void>(),
|
||||
);
|
||||
write_dctx_view_field(
|
||||
view.huf_ptr,
|
||||
(*ddict).entropy.huf_table.as_ptr().cast::<c_void>(),
|
||||
);
|
||||
let entropy_rep = view
|
||||
.entropy
|
||||
.cast::<u8>()
|
||||
.add(offset_of!(ZSTD_entropyDTables, rep))
|
||||
.cast::<u32>();
|
||||
for (index, value) in (*ddict).entropy.rep.iter().copied().enumerate() {
|
||||
entropy_rep.add(index).write_unaligned(value);
|
||||
}
|
||||
} else {
|
||||
write_dctx_view_field(view.lit_entropy, 0u32);
|
||||
write_dctx_view_field(view.fse_entropy, 0u32);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn load_d_entropy(
|
||||
entropy: *mut ZSTD_entropyDTables,
|
||||
@@ -353,6 +390,7 @@ pub unsafe extern "C" fn ZSTD_copyDDictParameters(dctx: *mut ZSTD_DCtx, ddict: *
|
||||
debug_assert!(!dctx.is_null());
|
||||
debug_assert!(!ddict.is_null());
|
||||
|
||||
#[cfg(test)]
|
||||
unsafe {
|
||||
let offsets = ddict_dctx_offsets();
|
||||
let dict_content = (*ddict).dict_content;
|
||||
@@ -400,6 +438,12 @@ pub unsafe extern "C" fn ZSTD_copyDDictParameters(dctx: *mut ZSTD_DCtx, ddict: *
|
||||
write_dctx_field(dctx, offsets.fse_entropy, 0u32);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(test))]
|
||||
unsafe {
|
||||
let view = crate::zstd_decompress::dctx_view_for_ddict(dctx.cast());
|
||||
copy_ddict_parameters_at_view(&view, ddict);
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
|
||||
+20
-15
@@ -228,27 +228,27 @@ pub struct ZSTD_entropyDTables_t {
|
||||
/// decoder-context offset.
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy)]
|
||||
struct ZSTD_rustDctxView {
|
||||
pub(crate) struct ZSTD_rustDctxView {
|
||||
dctx: *mut c_void,
|
||||
llt_ptr: *mut c_void,
|
||||
mlt_ptr: *mut c_void,
|
||||
oft_ptr: *mut c_void,
|
||||
huf_ptr: *mut c_void,
|
||||
entropy: *mut c_void,
|
||||
pub(crate) llt_ptr: *mut c_void,
|
||||
pub(crate) mlt_ptr: *mut c_void,
|
||||
pub(crate) oft_ptr: *mut c_void,
|
||||
pub(crate) huf_ptr: *mut c_void,
|
||||
pub(crate) entropy: *mut c_void,
|
||||
workspace: *mut c_void,
|
||||
workspace_size: usize,
|
||||
previous_dst_end: *mut c_void,
|
||||
prefix_start: *mut c_void,
|
||||
virtual_start: *mut c_void,
|
||||
dict_end: *mut c_void,
|
||||
pub(crate) previous_dst_end: *mut c_void,
|
||||
pub(crate) prefix_start: *mut c_void,
|
||||
pub(crate) virtual_start: *mut c_void,
|
||||
pub(crate) dict_end: *mut c_void,
|
||||
expected: *mut c_void,
|
||||
f_params: *mut c_void,
|
||||
processed_c_size: *mut c_void,
|
||||
decoded_size: *mut c_void,
|
||||
b_type: *mut c_void,
|
||||
stage: *mut c_void,
|
||||
lit_entropy: *mut c_void,
|
||||
fse_entropy: *mut c_void,
|
||||
pub(crate) lit_entropy: *mut c_void,
|
||||
pub(crate) fse_entropy: *mut c_void,
|
||||
xxh_state: *mut c_void,
|
||||
header_size: *mut c_void,
|
||||
format: *mut c_void,
|
||||
@@ -262,7 +262,7 @@ struct ZSTD_rustDctxView {
|
||||
is_frame_decompression: *mut c_void,
|
||||
ddict_local: *mut c_void,
|
||||
ddict: *mut c_void,
|
||||
dict_id: *mut c_void,
|
||||
pub(crate) dict_id: *mut c_void,
|
||||
ddict_is_cold: *mut c_void,
|
||||
dict_uses: *mut c_void,
|
||||
ddict_set: *mut c_void,
|
||||
@@ -294,8 +294,8 @@ struct ZSTD_rustDctxView {
|
||||
header_buffer: *mut c_void,
|
||||
header_buffer_size: usize,
|
||||
oversized_duration: *mut c_void,
|
||||
fuzz_begin: *mut c_void,
|
||||
fuzz_end: *mut c_void,
|
||||
pub(crate) fuzz_begin: *mut c_void,
|
||||
pub(crate) fuzz_end: *mut c_void,
|
||||
dctx_size: usize,
|
||||
}
|
||||
|
||||
@@ -530,6 +530,11 @@ unsafe fn dctx_view(dctx: *mut ZSTD_DCtx) -> ZSTD_rustDctxView {
|
||||
unsafe { view.assume_init() }
|
||||
}
|
||||
|
||||
#[cfg(not(test))]
|
||||
pub(crate) unsafe fn dctx_view_for_ddict(dctx: *mut c_void) -> ZSTD_rustDctxView {
|
||||
unsafe { dctx_view(dctx.cast()) }
|
||||
}
|
||||
|
||||
unsafe fn dctx_trace_view(dctx: *mut ZSTD_DCtx) -> ZSTD_rustDctxTraceView {
|
||||
let mut view = MaybeUninit::<ZSTD_rustDctxTraceView>::zeroed();
|
||||
unsafe { ZSTD_rust_dctx_trace_view(dctx, view.as_mut_ptr()) };
|
||||
|
||||
Reference in New Issue
Block a user