Path: blob/main/sys/contrib/openzfs/module/zstd/lib/common/zstd_internal.h
105194 views
// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only1/*2* Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.3* All rights reserved.4*5* This source code is licensed under both the BSD-style license (found in the6* LICENSE file in the root directory of this source tree) and the GPLv2 (found7* in the COPYING file in the root directory of this source tree).8* You may select, at your option, one of the above-listed licenses.9*/1011#ifndef ZSTD_CCOMMON_H_MODULE12#define ZSTD_CCOMMON_H_MODULE1314/*15* Disable the aarch64 NEON SIMD intrinsics for kernel builds. Safely16* using them in the kernel context requires saving/restoring the FPU17* registers which is not currently done.18*/19#ifdef _KERNEL20#define ZSTD_NO_INTRINSICS21#endif2223/* this module contains definitions which must be identical24* across compression, decompression and dictBuilder.25* It also contains a few functions useful to at least 2 of them26* and which benefit from being inlined */2728/*-*************************************29* Dependencies30***************************************/31#if !defined(ZSTD_NO_INTRINSICS) && defined(__ARM_NEON)32#include <arm_neon.h>33#endif34#include "compiler.h"35#include "mem.h"36#include "debug.h" /* assert, DEBUGLOG, RAWLOG, g_debuglevel */37#include "error_private.h"38#define ZSTD_STATIC_LINKING_ONLY39#include "../zstd.h"40#define FSE_STATIC_LINKING_ONLY41#include "fse.h"42#define HUF_STATIC_LINKING_ONLY43#include "huf.h"44#ifndef XXH_STATIC_LINKING_ONLY45# define XXH_STATIC_LINKING_ONLY /* XXH64_state_t */46#endif47#include "xxhash.h" /* XXH_reset, update, digest */4849#if defined (__cplusplus)50extern "C" {51#endif5253/* ---- static assert (debug) --- */54#define ZSTD_STATIC_ASSERT(c) DEBUG_STATIC_ASSERT(c)55#define FSE_isError ERR_isError56#define HUF_isError ERR_isError575859/*-*************************************60* shared macros61***************************************/62#undef MIN63#undef MAX64#define MIN(a,b) ((a)<(b) ? (a) : (b))65#define MAX(a,b) ((a)>(b) ? (a) : (b))6667/**68* Ignore: this is an internal helper.69*70* This is a helper function to help force C99-correctness during compilation.71* Under strict compilation modes, variadic macro arguments can't be empty.72* However, variadic function arguments can be. Using a function therefore lets73* us statically check that at least one (string) argument was passed,74* independent of the compilation flags.75*/76static INLINE_KEYWORD UNUSED_ATTR77void _force_has_format_string(const char *format, ...) {78(void)format;79}8081/**82* Ignore: this is an internal helper.83*84* We want to force this function invocation to be syntactically correct, but85* we don't want to force runtime evaluation of its arguments.86*/87#define _FORCE_HAS_FORMAT_STRING(...) \88if (0) { \89_force_has_format_string(__VA_ARGS__); \90}9192/**93* Return the specified error if the condition evaluates to true.94*95* In debug modes, prints additional information.96* In order to do that (particularly, printing the conditional that failed),97* this can't just wrap RETURN_ERROR().98*/99#define RETURN_ERROR_IF(cond, err, ...) \100if (cond) { \101RAWLOG(3, "%s:%d: ERROR!: check %s failed, returning %s", \102__FILE__, __LINE__, ZSTD_QUOTE(cond), ZSTD_QUOTE(ERROR(err))); \103_FORCE_HAS_FORMAT_STRING(__VA_ARGS__); \104RAWLOG(3, ": " __VA_ARGS__); \105RAWLOG(3, "\n"); \106return ERROR(err); \107}108109/**110* Unconditionally return the specified error.111*112* In debug modes, prints additional information.113*/114#define RETURN_ERROR(err, ...) \115do { \116RAWLOG(3, "%s:%d: ERROR!: unconditional check failed, returning %s", \117__FILE__, __LINE__, ZSTD_QUOTE(ERROR(err))); \118_FORCE_HAS_FORMAT_STRING(__VA_ARGS__); \119RAWLOG(3, ": " __VA_ARGS__); \120RAWLOG(3, "\n"); \121return ERROR(err); \122} while(0);123124/**125* If the provided expression evaluates to an error code, returns that error code.126*127* In debug modes, prints additional information.128*/129#define FORWARD_IF_ERROR(err, ...) \130do { \131size_t const err_code = (err); \132if (ERR_isError(err_code)) { \133RAWLOG(3, "%s:%d: ERROR!: forwarding error in %s: %s", \134__FILE__, __LINE__, ZSTD_QUOTE(err), ERR_getErrorName(err_code)); \135_FORCE_HAS_FORMAT_STRING(__VA_ARGS__); \136RAWLOG(3, ": " __VA_ARGS__); \137RAWLOG(3, "\n"); \138return err_code; \139} \140} while(0);141142143/*-*************************************144* Common constants145***************************************/146#define ZSTD_OPT_NUM (1<<12)147148#define ZSTD_REP_NUM 3 /* number of repcodes */149#define ZSTD_REP_MOVE (ZSTD_REP_NUM-1)150static const U32 repStartValue[ZSTD_REP_NUM] = { 1, 4, 8 };151152#define KB *(1 <<10)153#define MB *(1 <<20)154#define GB *(1U<<30)155156#define BIT7 128157#define BIT6 64158#define BIT5 32159#define BIT4 16160#define BIT1 2161#define BIT0 1162163#define ZSTD_WINDOWLOG_ABSOLUTEMIN 10164static const size_t ZSTD_fcs_fieldSize[4] = { 0, 2, 4, 8 };165static const size_t ZSTD_did_fieldSize[4] = { 0, 1, 2, 4 };166167#define ZSTD_FRAMEIDSIZE 4 /* magic number size */168169#define ZSTD_BLOCKHEADERSIZE 3 /* C standard doesn't allow `static const` variable to be init using another `static const` variable */170static const size_t ZSTD_blockHeaderSize = ZSTD_BLOCKHEADERSIZE;171typedef enum { bt_raw, bt_rle, bt_compressed, bt_reserved } blockType_e;172173#define ZSTD_FRAMECHECKSUMSIZE 4174175#define MIN_SEQUENCES_SIZE 1 /* nbSeq==0 */176#define MIN_CBLOCK_SIZE (1 /*litCSize*/ + 1 /* RLE or RAW */ + MIN_SEQUENCES_SIZE /* nbSeq==0 */) /* for a non-null block */177178#define HufLog 12179typedef enum { set_basic, set_rle, set_compressed, set_repeat } symbolEncodingType_e;180181#define LONGNBSEQ 0x7F00182183#define MINMATCH 3184185#define Litbits 8186#define MaxLit ((1<<Litbits) - 1)187#define MaxML 52188#define MaxLL 35189#define DefaultMaxOff 28190#define MaxOff 31191#define MaxSeq MAX(MaxLL, MaxML) /* Assumption : MaxOff < MaxLL,MaxML */192#define MLFSELog 9193#define LLFSELog 9194#define OffFSELog 8195#define MaxFSELog MAX(MAX(MLFSELog, LLFSELog), OffFSELog)196197static const U32 LL_bits[MaxLL+1] = { 0, 0, 0, 0, 0, 0, 0, 0,1980, 0, 0, 0, 0, 0, 0, 0,1991, 1, 1, 1, 2, 2, 3, 3,2004, 6, 7, 8, 9,10,11,12,20113,14,15,16 };202static const S16 LL_defaultNorm[MaxLL+1] = { 4, 3, 2, 2, 2, 2, 2, 2,2032, 2, 2, 2, 2, 1, 1, 1,2042, 2, 2, 2, 2, 2, 2, 2,2052, 3, 2, 1, 1, 1, 1, 1,206-1,-1,-1,-1 };207#define LL_DEFAULTNORMLOG 6 /* for static allocation */208static const U32 LL_defaultNormLog = LL_DEFAULTNORMLOG;209210static const U32 ML_bits[MaxML+1] = { 0, 0, 0, 0, 0, 0, 0, 0,2110, 0, 0, 0, 0, 0, 0, 0,2120, 0, 0, 0, 0, 0, 0, 0,2130, 0, 0, 0, 0, 0, 0, 0,2141, 1, 1, 1, 2, 2, 3, 3,2154, 4, 5, 7, 8, 9,10,11,21612,13,14,15,16 };217static const S16 ML_defaultNorm[MaxML+1] = { 1, 4, 3, 2, 2, 2, 2, 2,2182, 1, 1, 1, 1, 1, 1, 1,2191, 1, 1, 1, 1, 1, 1, 1,2201, 1, 1, 1, 1, 1, 1, 1,2211, 1, 1, 1, 1, 1, 1, 1,2221, 1, 1, 1, 1, 1,-1,-1,223-1,-1,-1,-1,-1 };224#define ML_DEFAULTNORMLOG 6 /* for static allocation */225static const U32 ML_defaultNormLog = ML_DEFAULTNORMLOG;226227static const S16 OF_defaultNorm[DefaultMaxOff+1] = { 1, 1, 1, 1, 1, 1, 2, 2,2282, 1, 1, 1, 1, 1, 1, 1,2291, 1, 1, 1, 1, 1, 1, 1,230-1,-1,-1,-1,-1 };231#define OF_DEFAULTNORMLOG 5 /* for static allocation */232static const U32 OF_defaultNormLog = OF_DEFAULTNORMLOG;233234235/*-*******************************************236* Shared functions to include for inlining237*********************************************/238static void ZSTD_copy8(void* dst, const void* src) {239#if !defined(ZSTD_NO_INTRINSICS) && defined(__ARM_NEON)240vst1_u8((uint8_t*)dst, vld1_u8((const uint8_t*)src));241#else242memcpy(dst, src, 8);243#endif244}245246#define COPY8(d,s) { ZSTD_copy8(d,s); d+=8; s+=8; }247static void ZSTD_copy16(void* dst, const void* src) {248#if !defined(ZSTD_NO_INTRINSICS) && defined(__ARM_NEON)249vst1q_u8((uint8_t*)dst, vld1q_u8((const uint8_t*)src));250#else251memcpy(dst, src, 16);252#endif253}254#define COPY16(d,s) { ZSTD_copy16(d,s); d+=16; s+=16; }255256#define WILDCOPY_OVERLENGTH 32257#define WILDCOPY_VECLEN 16258259typedef enum {260ZSTD_no_overlap,261ZSTD_overlap_src_before_dst262/* ZSTD_overlap_dst_before_src, */263} ZSTD_overlap_e;264265/*! ZSTD_wildcopy() :266* Custom version of memcpy(), can over read/write up to WILDCOPY_OVERLENGTH bytes (if length==0)267* @param ovtype controls the overlap detection268* - ZSTD_no_overlap: The source and destination are guaranteed to be at least WILDCOPY_VECLEN bytes apart.269* - ZSTD_overlap_src_before_dst: The src and dst may overlap, but they MUST be at least 8 bytes apart.270* The src buffer must be before the dst buffer.271*/272MEM_STATIC FORCE_INLINE_ATTR273void ZSTD_wildcopy(void* dst, const void* src, ptrdiff_t length, ZSTD_overlap_e const ovtype)274{275ptrdiff_t diff = (BYTE*)dst - (const BYTE*)src;276const BYTE* ip = (const BYTE*)src;277BYTE* op = (BYTE*)dst;278BYTE* const oend = op + length;279280assert(diff >= 8 || (ovtype == ZSTD_no_overlap && diff <= -WILDCOPY_VECLEN));281282if (ovtype == ZSTD_overlap_src_before_dst && diff < WILDCOPY_VECLEN) {283/* Handle short offset copies. */284do {285COPY8(op, ip)286} while (op < oend);287} else {288assert(diff >= WILDCOPY_VECLEN || diff <= -WILDCOPY_VECLEN);289/* Separate out the first COPY16() call because the copy length is290* almost certain to be short, so the branches have different291* probabilities. Since it is almost certain to be short, only do292* one COPY16() in the first call. Then, do two calls per loop since293* at that point it is more likely to have a high trip count.294*/295#ifndef __aarch64__296do {297COPY16(op, ip);298}299while (op < oend);300#else301COPY16(op, ip);302if (op >= oend) return;303do {304COPY16(op, ip);305COPY16(op, ip);306}307while (op < oend);308#endif309}310}311312MEM_STATIC size_t ZSTD_limitCopy(void* dst, size_t dstCapacity, const void* src, size_t srcSize)313{314size_t const length = MIN(dstCapacity, srcSize);315if (length > 0) {316memcpy(dst, src, length);317}318return length;319}320321/* define "workspace is too large" as this number of times larger than needed */322#define ZSTD_WORKSPACETOOLARGE_FACTOR 3323324/* when workspace is continuously too large325* during at least this number of times,326* context's memory usage is considered wasteful,327* because it's sized to handle a worst case scenario which rarely happens.328* In which case, resize it down to free some memory */329#define ZSTD_WORKSPACETOOLARGE_MAXDURATION 128330331332/*-*******************************************333* Private declarations334*********************************************/335typedef struct seqDef_s {336U32 offset;337U16 litLength;338U16 matchLength;339} seqDef;340341typedef struct {342seqDef* sequencesStart;343seqDef* sequences;344BYTE* litStart;345BYTE* lit;346BYTE* llCode;347BYTE* mlCode;348BYTE* ofCode;349size_t maxNbSeq;350size_t maxNbLit;351U32 longLengthID; /* 0 == no longLength; 1 == Lit.longLength; 2 == Match.longLength; */352U32 longLengthPos;353} seqStore_t;354355typedef struct {356U32 litLength;357U32 matchLength;358} ZSTD_sequenceLength;359360/**361* Returns the ZSTD_sequenceLength for the given sequences. It handles the decoding of long sequences362* indicated by longLengthPos and longLengthID, and adds MINMATCH back to matchLength.363*/364MEM_STATIC ZSTD_sequenceLength ZSTD_getSequenceLength(seqStore_t const* seqStore, seqDef const* seq)365{366ZSTD_sequenceLength seqLen;367seqLen.litLength = seq->litLength;368seqLen.matchLength = seq->matchLength + MINMATCH;369if (seqStore->longLengthPos == (U32)(seq - seqStore->sequencesStart)) {370if (seqStore->longLengthID == 1) {371seqLen.litLength += 0xFFFF;372}373if (seqStore->longLengthID == 2) {374seqLen.matchLength += 0xFFFF;375}376}377return seqLen;378}379380/**381* Contains the compressed frame size and an upper-bound for the decompressed frame size.382* Note: before using `compressedSize`, check for errors using ZSTD_isError().383* similarly, before using `decompressedBound`, check for errors using:384* `decompressedBound != ZSTD_CONTENTSIZE_ERROR`385*/386typedef struct {387size_t compressedSize;388unsigned long long decompressedBound;389} ZSTD_frameSizeInfo; /* decompress & legacy */390391const seqStore_t* ZSTD_getSeqStore(const ZSTD_CCtx* ctx); /* compress & dictBuilder */392void ZSTD_seqToCodes(const seqStore_t* seqStorePtr); /* compress, dictBuilder, decodeCorpus (shouldn't get its definition from here) */393394/* custom memory allocation functions */395void* ZSTD_malloc(size_t size, ZSTD_customMem customMem);396void* ZSTD_calloc(size_t size, ZSTD_customMem customMem);397void ZSTD_free(void* ptr, ZSTD_customMem customMem);398399400MEM_STATIC U32 ZSTD_highbit32(U32 val) /* compress, dictBuilder, decodeCorpus */401{402assert(val != 0);403{404# if defined(_MSC_VER) /* Visual */405unsigned long r=0;406return _BitScanReverse(&r, val) ? (unsigned)r : 0;407# elif defined(__GNUC__) && (__GNUC__ >= 3) /* GCC Intrinsic */408return __builtin_clz (val) ^ 31;409# elif defined(__ICCARM__) /* IAR Intrinsic */410return 31 - __CLZ(val);411# else /* Software version */412static const U32 DeBruijnClz[32] = { 0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30, 8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31 };413U32 v = val;414v |= v >> 1;415v |= v >> 2;416v |= v >> 4;417v |= v >> 8;418v |= v >> 16;419return DeBruijnClz[(v * 0x07C4ACDDU) >> 27];420# endif421}422}423424425/* ZSTD_invalidateRepCodes() :426* ensures next compression will not use repcodes from previous block.427* Note : only works with regular variant;428* do not use with extDict variant ! */429void ZSTD_invalidateRepCodes(ZSTD_CCtx* cctx); /* zstdmt, adaptive_compression (shouldn't get this definition from here) */430431432typedef struct {433blockType_e blockType;434U32 lastBlock;435U32 origSize;436} blockProperties_t; /* declared here for decompress and fullbench */437438/*! ZSTD_getcBlockSize() :439* Provides the size of compressed block from block header `src` */440/* Used by: decompress, fullbench (does not get its definition from here) */441size_t ZSTD_getcBlockSize(const void* src, size_t srcSize,442blockProperties_t* bpPtr);443444/*! ZSTD_decodeSeqHeaders() :445* decode sequence header from src */446/* Used by: decompress, fullbench (does not get its definition from here) */447size_t ZSTD_decodeSeqHeaders(ZSTD_DCtx* dctx, int* nbSeqPtr,448const void* src, size_t srcSize);449450451#if defined (__cplusplus)452}453#endif454455#endif /* ZSTD_CCOMMON_H_MODULE */456457458