feat(compress): split static CCtx construction callbacks
Move static CCtx construction sequencing out of the monolithic C leaf. Rust now validates the existing public workspace contract, sequences workspace creation, CCtx and auxiliary reservations, publication, and BMI2 setup, and short-circuits callback-reported failures. C callbacks retain the private cwksp and CCtx layouts plus the native workspace-size and CPU-feature rules. Add matching ABI layout assertions and focused callback-order, reservation- failure, workspace-capacity, and NULL-path unit coverage. Static-CDict and heap-CCtx paths remain unchanged. Test Plan: - `rustfmt --edition 2021 --check rust/src/zstd_compress.rs` -- passed - GCC and Clang `-fsyntax-only` checks on `zstd_compress.c` -- passed - GCC syntax checks with `ZSTD_DISABLE_ASM=1` and `ZSTD_ADDRESS_SANITIZER=1` -- passed - `git diff --check` -- passed - Cargo, make, native suites, and fuzzers not run per request
This commit is contained in:
+123
-22
@@ -363,13 +363,29 @@ typedef char ZSTD_rust_init_cctx_state_layout[
|
||||
&& offsetof(ZSTD_rust_initCCtxState, reset) == 5 * sizeof(void*)
|
||||
&& sizeof(ZSTD_rust_initCCtxState) == 6 * sizeof(void*))
|
||||
? 1 : -1];
|
||||
typedef void* (*ZSTD_rust_initStaticCCtxInit_f)(void* context);
|
||||
typedef void (*ZSTD_rust_initStaticCCtxCreateWorkspace_f)(void* context);
|
||||
typedef void* (*ZSTD_rust_initStaticCCtxReserveObject_f)(void* context);
|
||||
typedef void (*ZSTD_rust_initStaticCCtxZero_f)(void* context, void* cctx);
|
||||
typedef void (*ZSTD_rust_initStaticCCtxMoveWorkspace_f)(
|
||||
void* context, void* cctx);
|
||||
typedef int (*ZSTD_rust_initStaticCCtxCheckAvailable_f)(void* context);
|
||||
typedef void* (*ZSTD_rust_initStaticCCtxReserveBlockState_f)(
|
||||
void* context, int blockState);
|
||||
typedef void* (*ZSTD_rust_initStaticCCtxReserveTmpWorkspace_f)(void* context);
|
||||
typedef void (*ZSTD_rust_initStaticCCtxSetBmi2_f)(void* context);
|
||||
typedef struct {
|
||||
void* callbackContext;
|
||||
void* workspace;
|
||||
size_t workspaceSize;
|
||||
size_t cctxSize;
|
||||
ZSTD_rust_initStaticCCtxInit_f init;
|
||||
ZSTD_rust_initStaticCCtxCreateWorkspace_f createWorkspace;
|
||||
ZSTD_rust_initStaticCCtxReserveObject_f reserveObject;
|
||||
ZSTD_rust_initStaticCCtxZero_f zero;
|
||||
ZSTD_rust_initStaticCCtxMoveWorkspace_f moveWorkspace;
|
||||
ZSTD_rust_initStaticCCtxCheckAvailable_f checkAvailable;
|
||||
ZSTD_rust_initStaticCCtxReserveBlockState_f reserveBlockState;
|
||||
ZSTD_rust_initStaticCCtxReserveTmpWorkspace_f reserveTmpWorkspace;
|
||||
ZSTD_rust_initStaticCCtxSetBmi2_f setBmi2;
|
||||
} ZSTD_rust_initStaticCCtxState;
|
||||
void* ZSTD_rust_initStaticCCtx(const ZSTD_rust_initStaticCCtxState* state);
|
||||
typedef char ZSTD_rust_init_static_cctx_state_layout[
|
||||
@@ -380,9 +396,23 @@ typedef char ZSTD_rust_init_static_cctx_state_layout[
|
||||
== 2 * sizeof(void*)
|
||||
&& offsetof(ZSTD_rust_initStaticCCtxState, cctxSize)
|
||||
== 3 * sizeof(void*)
|
||||
&& offsetof(ZSTD_rust_initStaticCCtxState, init)
|
||||
&& offsetof(ZSTD_rust_initStaticCCtxState, createWorkspace)
|
||||
== 4 * sizeof(void*)
|
||||
&& sizeof(ZSTD_rust_initStaticCCtxState) == 5 * sizeof(void*))
|
||||
&& offsetof(ZSTD_rust_initStaticCCtxState, reserveObject)
|
||||
== 5 * sizeof(void*)
|
||||
&& offsetof(ZSTD_rust_initStaticCCtxState, zero)
|
||||
== 6 * sizeof(void*)
|
||||
&& offsetof(ZSTD_rust_initStaticCCtxState, moveWorkspace)
|
||||
== 7 * sizeof(void*)
|
||||
&& offsetof(ZSTD_rust_initStaticCCtxState, checkAvailable)
|
||||
== 8 * sizeof(void*)
|
||||
&& offsetof(ZSTD_rust_initStaticCCtxState, reserveBlockState)
|
||||
== 9 * sizeof(void*)
|
||||
&& offsetof(ZSTD_rust_initStaticCCtxState, reserveTmpWorkspace)
|
||||
== 10 * sizeof(void*)
|
||||
&& offsetof(ZSTD_rust_initStaticCCtxState, setBmi2)
|
||||
== 11 * sizeof(void*)
|
||||
&& sizeof(ZSTD_rust_initStaticCCtxState) == 12 * sizeof(void*))
|
||||
? 1 : -1];
|
||||
typedef void* (*ZSTD_rust_createCDictCreate_f)(
|
||||
void* context, const void* dict, size_t dictSize,
|
||||
@@ -3347,32 +3377,93 @@ ZSTD_CCtx* ZSTD_createCCtx_advanced(ZSTD_customMem customMem)
|
||||
typedef struct {
|
||||
void* workspace;
|
||||
size_t workspaceSize;
|
||||
ZSTD_cwksp workspaceState;
|
||||
ZSTD_CCtx* cctx;
|
||||
} ZSTD_rust_initStaticCCtxContext;
|
||||
|
||||
static void* ZSTD_rust_initStaticCCtx_init(void* opaque)
|
||||
static void ZSTD_rust_initStaticCCtx_createWorkspace(void* opaque)
|
||||
{
|
||||
ZSTD_rust_initStaticCCtxContext* const context =
|
||||
(ZSTD_rust_initStaticCCtxContext*)opaque;
|
||||
ZSTD_cwksp ws;
|
||||
ZSTD_CCtx* cctx;
|
||||
|
||||
ZSTD_cwksp_init(&ws, context->workspace, context->workspaceSize,
|
||||
ZSTD_cwksp_init(&context->workspaceState, context->workspace,
|
||||
context->workspaceSize,
|
||||
ZSTD_cwksp_static_alloc);
|
||||
cctx = (ZSTD_CCtx*)ZSTD_cwksp_reserve_object(&ws, sizeof(ZSTD_CCtx));
|
||||
if (cctx == NULL) return NULL;
|
||||
}
|
||||
|
||||
static void* ZSTD_rust_initStaticCCtx_reserveObject(void* opaque)
|
||||
{
|
||||
ZSTD_rust_initStaticCCtxContext* const context =
|
||||
(ZSTD_rust_initStaticCCtxContext*)opaque;
|
||||
context->cctx = (ZSTD_CCtx*)ZSTD_cwksp_reserve_object(
|
||||
&context->workspaceState, sizeof(ZSTD_CCtx));
|
||||
return context->cctx;
|
||||
}
|
||||
|
||||
static void ZSTD_rust_initStaticCCtx_zero(void* opaque, void* cctx)
|
||||
{
|
||||
(void)opaque;
|
||||
ZSTD_memset(cctx, 0, sizeof(ZSTD_CCtx));
|
||||
ZSTD_cwksp_move(&cctx->workspace, &ws);
|
||||
cctx->staticSize = context->workspaceSize;
|
||||
}
|
||||
|
||||
/* statically sized space. tmpWorkspace never moves (but prev/next block swap places) */
|
||||
if (!ZSTD_cwksp_check_available(&cctx->workspace, TMP_WORKSPACE_SIZE + 2 * sizeof(ZSTD_compressedBlockState_t))) return NULL;
|
||||
cctx->blockState.prevCBlock = (ZSTD_compressedBlockState_t*)ZSTD_cwksp_reserve_object(&cctx->workspace, sizeof(ZSTD_compressedBlockState_t));
|
||||
cctx->blockState.nextCBlock = (ZSTD_compressedBlockState_t*)ZSTD_cwksp_reserve_object(&cctx->workspace, sizeof(ZSTD_compressedBlockState_t));
|
||||
cctx->tmpWorkspace = ZSTD_cwksp_reserve_object(&cctx->workspace, TMP_WORKSPACE_SIZE);
|
||||
cctx->tmpWkspSize = TMP_WORKSPACE_SIZE;
|
||||
cctx->bmi2 = ZSTD_cpuid_bmi2(ZSTD_cpuid());
|
||||
return cctx;
|
||||
static void ZSTD_rust_initStaticCCtx_moveWorkspace(void* opaque, void* cctx)
|
||||
{
|
||||
ZSTD_rust_initStaticCCtxContext* const context =
|
||||
(ZSTD_rust_initStaticCCtxContext*)opaque;
|
||||
ZSTD_CCtx* const contextCCtx = (ZSTD_CCtx*)cctx;
|
||||
ZSTD_cwksp_move(&contextCCtx->workspace, &context->workspaceState);
|
||||
contextCCtx->staticSize = context->workspaceSize;
|
||||
}
|
||||
|
||||
static int ZSTD_rust_initStaticCCtx_checkAvailable(void* opaque)
|
||||
{
|
||||
ZSTD_rust_initStaticCCtxContext const* const context =
|
||||
(const ZSTD_rust_initStaticCCtxContext*)opaque;
|
||||
return ZSTD_cwksp_check_available(
|
||||
&context->cctx->workspace,
|
||||
TMP_WORKSPACE_SIZE + 2 * sizeof(ZSTD_compressedBlockState_t));
|
||||
}
|
||||
|
||||
enum {
|
||||
ZSTD_RUST_INIT_STATIC_CCTX_PREV_CBLOCK = 0,
|
||||
ZSTD_RUST_INIT_STATIC_CCTX_NEXT_CBLOCK = 1
|
||||
};
|
||||
|
||||
static void* ZSTD_rust_initStaticCCtx_reserveBlockState(
|
||||
void* opaque, int blockState)
|
||||
{
|
||||
ZSTD_rust_initStaticCCtxContext* const context =
|
||||
(ZSTD_rust_initStaticCCtxContext*)opaque;
|
||||
void* const block = ZSTD_cwksp_reserve_object(
|
||||
&context->cctx->workspace,
|
||||
sizeof(ZSTD_compressedBlockState_t));
|
||||
if (blockState == ZSTD_RUST_INIT_STATIC_CCTX_PREV_CBLOCK) {
|
||||
context->cctx->blockState.prevCBlock =
|
||||
(ZSTD_compressedBlockState_t*)block;
|
||||
} else if (blockState == ZSTD_RUST_INIT_STATIC_CCTX_NEXT_CBLOCK) {
|
||||
context->cctx->blockState.nextCBlock =
|
||||
(ZSTD_compressedBlockState_t*)block;
|
||||
} else {
|
||||
assert(0);
|
||||
return NULL;
|
||||
}
|
||||
return block;
|
||||
}
|
||||
|
||||
static void* ZSTD_rust_initStaticCCtx_reserveTmpWorkspace(void* opaque)
|
||||
{
|
||||
ZSTD_rust_initStaticCCtxContext* const context =
|
||||
(ZSTD_rust_initStaticCCtxContext*)opaque;
|
||||
context->cctx->tmpWorkspace = ZSTD_cwksp_reserve_object(
|
||||
&context->cctx->workspace, TMP_WORKSPACE_SIZE);
|
||||
context->cctx->tmpWkspSize = TMP_WORKSPACE_SIZE;
|
||||
return context->cctx->tmpWorkspace;
|
||||
}
|
||||
|
||||
static void ZSTD_rust_initStaticCCtx_setBmi2(void* opaque)
|
||||
{
|
||||
ZSTD_rust_initStaticCCtxContext const* const context =
|
||||
(const ZSTD_rust_initStaticCCtxContext*)opaque;
|
||||
context->cctx->bmi2 = ZSTD_cpuid_bmi2(ZSTD_cpuid());
|
||||
}
|
||||
|
||||
ZSTD_CCtx* ZSTD_initStaticCCtx(void* workspace, size_t workspaceSize)
|
||||
@@ -3385,10 +3476,20 @@ ZSTD_CCtx* ZSTD_initStaticCCtx(void* workspace, size_t workspaceSize)
|
||||
state.workspace = workspace;
|
||||
state.workspaceSize = workspaceSize;
|
||||
state.cctxSize = sizeof(ZSTD_CCtx);
|
||||
state.init = ZSTD_rust_initStaticCCtx_init;
|
||||
state.createWorkspace = ZSTD_rust_initStaticCCtx_createWorkspace;
|
||||
state.reserveObject = ZSTD_rust_initStaticCCtx_reserveObject;
|
||||
state.zero = ZSTD_rust_initStaticCCtx_zero;
|
||||
state.moveWorkspace = ZSTD_rust_initStaticCCtx_moveWorkspace;
|
||||
state.checkAvailable = ZSTD_rust_initStaticCCtx_checkAvailable;
|
||||
state.reserveBlockState = ZSTD_rust_initStaticCCtx_reserveBlockState;
|
||||
state.reserveTmpWorkspace = ZSTD_rust_initStaticCCtx_reserveTmpWorkspace;
|
||||
state.setBmi2 = ZSTD_rust_initStaticCCtx_setBmi2;
|
||||
return (ZSTD_CCtx*)ZSTD_rust_initStaticCCtx(&state);
|
||||
}
|
||||
|
||||
/* Keep the private workspace and CCtx layout operations above in C. Rust
|
||||
* owns only the public checks, construction order, and failure policy. */
|
||||
|
||||
/**
|
||||
* Clears and frees all of the dictionaries in the CCtx.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user