[cwksp] Align all allocated "tables" and "aligneds" to 64 bytes (#2546)
* Perform 64-byte alignment of wksp tables and aligneds internally * Clean up cwskp_finalize() function to only do two allocs * Refactor aligned/buffer reservation code, remove ASAN req for alignment reservations * Change from allocating 128 bytes always to allocating only buffer space as needed for tables/aligned * Back out aligned/table reservation order restriction * Add stricter bounds for new/resized wksps, fix comment in zstd_cwksp.h
This commit is contained in:
@@ -1339,18 +1339,23 @@ ZSTD_sizeof_matchState(const ZSTD_compressionParameters* const cParams,
|
||||
+ hSize * sizeof(U32)
|
||||
+ h3Size * sizeof(U32);
|
||||
size_t const optPotentialSpace =
|
||||
ZSTD_cwksp_alloc_size((MaxML+1) * sizeof(U32))
|
||||
+ ZSTD_cwksp_alloc_size((MaxLL+1) * sizeof(U32))
|
||||
+ ZSTD_cwksp_alloc_size((MaxOff+1) * sizeof(U32))
|
||||
+ ZSTD_cwksp_alloc_size((1<<Litbits) * sizeof(U32))
|
||||
+ ZSTD_cwksp_alloc_size((ZSTD_OPT_NUM+1) * sizeof(ZSTD_match_t))
|
||||
+ ZSTD_cwksp_alloc_size((ZSTD_OPT_NUM+1) * sizeof(ZSTD_optimal_t));
|
||||
ZSTD_cwksp_aligned_alloc_size((MaxML+1) * sizeof(U32))
|
||||
+ ZSTD_cwksp_aligned_alloc_size((MaxLL+1) * sizeof(U32))
|
||||
+ ZSTD_cwksp_aligned_alloc_size((MaxOff+1) * sizeof(U32))
|
||||
+ ZSTD_cwksp_aligned_alloc_size((1<<Litbits) * sizeof(U32))
|
||||
+ ZSTD_cwksp_aligned_alloc_size((ZSTD_OPT_NUM+1) * sizeof(ZSTD_match_t))
|
||||
+ ZSTD_cwksp_aligned_alloc_size((ZSTD_OPT_NUM+1) * sizeof(ZSTD_optimal_t));
|
||||
size_t const optSpace = (forCCtx && (cParams->strategy >= ZSTD_btopt))
|
||||
? optPotentialSpace
|
||||
: 0;
|
||||
size_t const slackSpace = ZSTD_cwksp_slack_space_required();
|
||||
|
||||
/* tables are guaranteed to be sized in multiples of 64 bytes (or 16 uint32_t) */
|
||||
ZSTD_STATIC_ASSERT(ZSTD_HASHLOG_MIN >= 4 && ZSTD_WINDOWLOG_MIN >= 4 && ZSTD_CHAINLOG_MIN >= 4);
|
||||
|
||||
DEBUGLOG(4, "chainSize: %u - hSize: %u - h3Size: %u",
|
||||
(U32)chainSize, (U32)hSize, (U32)h3Size);
|
||||
return tableSpace + optSpace;
|
||||
return tableSpace + optSpace + slackSpace;
|
||||
}
|
||||
|
||||
static size_t ZSTD_estimateCCtxSize_usingCCtxParams_internal(
|
||||
@@ -1366,7 +1371,7 @@ static size_t ZSTD_estimateCCtxSize_usingCCtxParams_internal(
|
||||
U32 const divider = (cParams->minMatch==3) ? 3 : 4;
|
||||
size_t const maxNbSeq = blockSize / divider;
|
||||
size_t const tokenSpace = ZSTD_cwksp_alloc_size(WILDCOPY_OVERLENGTH + blockSize)
|
||||
+ ZSTD_cwksp_alloc_size(maxNbSeq * sizeof(seqDef))
|
||||
+ ZSTD_cwksp_aligned_alloc_size(maxNbSeq * sizeof(seqDef))
|
||||
+ 3 * ZSTD_cwksp_alloc_size(maxNbSeq * sizeof(BYTE));
|
||||
size_t const entropySpace = ZSTD_cwksp_alloc_size(ENTROPY_WORKSPACE_SIZE);
|
||||
size_t const blockStateSpace = 2 * ZSTD_cwksp_alloc_size(sizeof(ZSTD_compressedBlockState_t));
|
||||
@@ -1375,7 +1380,7 @@ static size_t ZSTD_estimateCCtxSize_usingCCtxParams_internal(
|
||||
size_t const ldmSpace = ZSTD_ldm_getTableSize(*ldmParams);
|
||||
size_t const maxNbLdmSeq = ZSTD_ldm_getMaxNbSeq(*ldmParams, blockSize);
|
||||
size_t const ldmSeqSpace = ldmParams->enableLdm ?
|
||||
ZSTD_cwksp_alloc_size(maxNbLdmSeq * sizeof(rawSeq)) : 0;
|
||||
ZSTD_cwksp_aligned_alloc_size(maxNbLdmSeq * sizeof(rawSeq)) : 0;
|
||||
|
||||
|
||||
size_t const bufferSpace = ZSTD_cwksp_alloc_size(buffInSize)
|
||||
@@ -1703,19 +1708,20 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
|
||||
ZSTD_estimateCCtxSize_usingCCtxParams_internal(
|
||||
¶ms.cParams, ¶ms.ldmParams, zc->staticSize != 0,
|
||||
buffInSize, buffOutSize, pledgedSrcSize);
|
||||
int resizeWorkspace;
|
||||
|
||||
FORWARD_IF_ERROR(neededSpace, "cctx size estimate failed!");
|
||||
|
||||
if (!zc->staticSize) ZSTD_cwksp_bump_oversized_duration(ws, 0);
|
||||
|
||||
/* Check if workspace is large enough, alloc a new one if needed */
|
||||
{
|
||||
{ /* Check if workspace is large enough, alloc a new one if needed */
|
||||
int const workspaceTooSmall = ZSTD_cwksp_sizeof(ws) < neededSpace;
|
||||
int const workspaceWasteful = ZSTD_cwksp_check_wasteful(ws, neededSpace);
|
||||
|
||||
resizeWorkspace = workspaceTooSmall || workspaceWasteful;
|
||||
DEBUGLOG(4, "Need %zu B workspace", neededSpace);
|
||||
DEBUGLOG(4, "windowSize: %zu - blockSize: %zu", windowSize, blockSize);
|
||||
|
||||
if (workspaceTooSmall || workspaceWasteful) {
|
||||
if (resizeWorkspace) {
|
||||
DEBUGLOG(4, "Resize workspaceSize from %zuKB to %zuKB",
|
||||
ZSTD_cwksp_sizeof(ws) >> 10,
|
||||
neededSpace >> 10);
|
||||
@@ -1814,13 +1820,9 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
|
||||
zc->ldmState.loadedDictEnd = 0;
|
||||
}
|
||||
|
||||
/* Due to alignment, when reusing a workspace, we can actually consume
|
||||
* up to 3 extra bytes for alignment. See the comments in zstd_cwksp.h
|
||||
*/
|
||||
assert(ZSTD_cwksp_used(ws) >= neededSpace &&
|
||||
ZSTD_cwksp_used(ws) <= neededSpace + 3);
|
||||
|
||||
assert(ZSTD_cwksp_estimated_space_within_bounds(ws, neededSpace, resizeWorkspace));
|
||||
DEBUGLOG(3, "wksp: finished allocating, %zd bytes remain available", ZSTD_cwksp_available_space(ws));
|
||||
|
||||
zc->initialized = 1;
|
||||
|
||||
return 0;
|
||||
|
||||
Reference in New Issue
Block a user