diff options
Diffstat (limited to 'lib/zstd/common')
| -rw-r--r-- | lib/zstd/common/allocations.h | 56 | ||||
| -rw-r--r-- | lib/zstd/common/bits.h | 150 | ||||
| -rw-r--r-- | lib/zstd/common/bitstream.h | 155 | ||||
| -rw-r--r-- | lib/zstd/common/compiler.h | 151 | ||||
| -rw-r--r-- | lib/zstd/common/cpu.h | 3 | ||||
| -rw-r--r-- | lib/zstd/common/debug.c | 9 | ||||
| -rw-r--r-- | lib/zstd/common/debug.h | 37 | ||||
| -rw-r--r-- | lib/zstd/common/entropy_common.c | 42 | ||||
| -rw-r--r-- | lib/zstd/common/error_private.c | 13 | ||||
| -rw-r--r-- | lib/zstd/common/error_private.h | 88 | ||||
| -rw-r--r-- | lib/zstd/common/fse.h | 103 | ||||
| -rw-r--r-- | lib/zstd/common/fse_decompress.c | 132 | ||||
| -rw-r--r-- | lib/zstd/common/huf.h | 240 | ||||
| -rw-r--r-- | lib/zstd/common/mem.h | 3 | ||||
| -rw-r--r-- | lib/zstd/common/portability_macros.h | 47 | ||||
| -rw-r--r-- | lib/zstd/common/zstd_common.c | 38 | ||||
| -rw-r--r-- | lib/zstd/common/zstd_deps.h | 16 | ||||
| -rw-r--r-- | lib/zstd/common/zstd_internal.h | 153 | 
18 files changed, 698 insertions, 738 deletions
| diff --git a/lib/zstd/common/allocations.h b/lib/zstd/common/allocations.h new file mode 100644 index 000000000000..16c3d08e8d1a --- /dev/null +++ b/lib/zstd/common/allocations.h @@ -0,0 +1,56 @@ +/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +/* This file provides custom allocation primitives + */ + +#define ZSTD_DEPS_NEED_MALLOC +#include "zstd_deps.h"   /* ZSTD_malloc, ZSTD_calloc, ZSTD_free, ZSTD_memset */ + +#include "compiler.h" /* MEM_STATIC */ +#define ZSTD_STATIC_LINKING_ONLY +#include <linux/zstd.h> /* ZSTD_customMem */ + +#ifndef ZSTD_ALLOCATIONS_H +#define ZSTD_ALLOCATIONS_H + +/* custom memory allocation functions */ + +MEM_STATIC void* ZSTD_customMalloc(size_t size, ZSTD_customMem customMem) +{ +    if (customMem.customAlloc) +        return customMem.customAlloc(customMem.opaque, size); +    return ZSTD_malloc(size); +} + +MEM_STATIC void* ZSTD_customCalloc(size_t size, ZSTD_customMem customMem) +{ +    if (customMem.customAlloc) { +        /* calloc implemented as malloc+memset; +         * not as efficient as calloc, but next best guess for custom malloc */ +        void* const ptr = customMem.customAlloc(customMem.opaque, size); +        ZSTD_memset(ptr, 0, size); +        return ptr; +    } +    return ZSTD_calloc(1, size); +} + +MEM_STATIC void ZSTD_customFree(void* ptr, ZSTD_customMem customMem) +{ +    if (ptr!=NULL) { +        if (customMem.customFree) +            customMem.customFree(customMem.opaque, ptr); +        else +            ZSTD_free(ptr); +    } +} + +#endif /* ZSTD_ALLOCATIONS_H */ diff --git a/lib/zstd/common/bits.h b/lib/zstd/common/bits.h new file mode 100644 index 000000000000..c5faaa3d7b08 --- /dev/null +++ b/lib/zstd/common/bits.h @@ -0,0 +1,150 @@ +/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#ifndef ZSTD_BITS_H +#define ZSTD_BITS_H + +#include "mem.h" + +MEM_STATIC unsigned ZSTD_countTrailingZeros32_fallback(U32 val) +{ +    assert(val != 0); +    { +        static const U32 DeBruijnBytePos[32] = {0, 1, 28, 2, 29, 14, 24, 3, +                                                30, 22, 20, 15, 25, 17, 4, 8, +                                                31, 27, 13, 23, 21, 19, 16, 7, +                                                26, 12, 18, 6, 11, 5, 10, 9}; +        return DeBruijnBytePos[((U32) ((val & -(S32) val) * 0x077CB531U)) >> 27]; +    } +} + +MEM_STATIC unsigned ZSTD_countTrailingZeros32(U32 val) +{ +    assert(val != 0); +#if (__GNUC__ >= 4) +    return (unsigned)__builtin_ctz(val); +#else +    return ZSTD_countTrailingZeros32_fallback(val); +#endif +} + +MEM_STATIC unsigned ZSTD_countLeadingZeros32_fallback(U32 val) +{ +    assert(val != 0); +    { +        static 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}; +        val |= val >> 1; +        val |= val >> 2; +        val |= val >> 4; +        val |= val >> 8; +        val |= val >> 16; +        return 31 - DeBruijnClz[(val * 0x07C4ACDDU) >> 27]; +    } +} + +MEM_STATIC unsigned ZSTD_countLeadingZeros32(U32 val) +{ +    assert(val != 0); +#if (__GNUC__ >= 4) +    return (unsigned)__builtin_clz(val); +#else +    return ZSTD_countLeadingZeros32_fallback(val); +#endif +} + +MEM_STATIC unsigned ZSTD_countTrailingZeros64(U64 val) +{ +    assert(val != 0); +#if (__GNUC__ >= 4) && defined(__LP64__) +    return (unsigned)__builtin_ctzll(val); +#else +    { +        U32 mostSignificantWord = (U32)(val >> 32); +        U32 leastSignificantWord = (U32)val; +        if (leastSignificantWord == 0) { +            return 32 + ZSTD_countTrailingZeros32(mostSignificantWord); +        } else { +            return ZSTD_countTrailingZeros32(leastSignificantWord); +        } +    } +#endif +} + +MEM_STATIC unsigned ZSTD_countLeadingZeros64(U64 val) +{ +    assert(val != 0); +#if (__GNUC__ >= 4) +    return (unsigned)(__builtin_clzll(val)); +#else +    { +        U32 mostSignificantWord = (U32)(val >> 32); +        U32 leastSignificantWord = (U32)val; +        if (mostSignificantWord == 0) { +            return 32 + ZSTD_countLeadingZeros32(leastSignificantWord); +        } else { +            return ZSTD_countLeadingZeros32(mostSignificantWord); +        } +    } +#endif +} + +MEM_STATIC unsigned ZSTD_NbCommonBytes(size_t val) +{ +    if (MEM_isLittleEndian()) { +        if (MEM_64bits()) { +            return ZSTD_countTrailingZeros64((U64)val) >> 3; +        } else { +            return ZSTD_countTrailingZeros32((U32)val) >> 3; +        } +    } else {  /* Big Endian CPU */ +        if (MEM_64bits()) { +            return ZSTD_countLeadingZeros64((U64)val) >> 3; +        } else { +            return ZSTD_countLeadingZeros32((U32)val) >> 3; +        } +    } +} + +MEM_STATIC unsigned ZSTD_highbit32(U32 val)   /* compress, dictBuilder, decodeCorpus */ +{ +    assert(val != 0); +    return 31 - ZSTD_countLeadingZeros32(val); +} + +/* ZSTD_rotateRight_*(): + * Rotates a bitfield to the right by "count" bits. + * https://en.wikipedia.org/w/index.php?title=Circular_shift&oldid=991635599#Implementing_circular_shifts + */ +MEM_STATIC +U64 ZSTD_rotateRight_U64(U64 const value, U32 count) { +    assert(count < 64); +    count &= 0x3F; /* for fickle pattern recognition */ +    return (value >> count) | (U64)(value << ((0U - count) & 0x3F)); +} + +MEM_STATIC +U32 ZSTD_rotateRight_U32(U32 const value, U32 count) { +    assert(count < 32); +    count &= 0x1F; /* for fickle pattern recognition */ +    return (value >> count) | (U32)(value << ((0U - count) & 0x1F)); +} + +MEM_STATIC +U16 ZSTD_rotateRight_U16(U16 const value, U32 count) { +    assert(count < 16); +    count &= 0x0F; /* for fickle pattern recognition */ +    return (value >> count) | (U16)(value << ((0U - count) & 0x0F)); +} + +#endif /* ZSTD_BITS_H */ diff --git a/lib/zstd/common/bitstream.h b/lib/zstd/common/bitstream.h index feef3a1b1d60..86439da0eea7 100644 --- a/lib/zstd/common/bitstream.h +++ b/lib/zstd/common/bitstream.h @@ -1,7 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */  /* ******************************************************************   * bitstream   * Part of FSE library - * Copyright (c) Yann Collet, Facebook, Inc. + * Copyright (c) Meta Platforms, Inc. and affiliates.   *   * You can contact the author at :   * - Source repository : https://github.com/Cyan4973/FiniteStateEntropy @@ -27,7 +28,7 @@  #include "compiler.h"       /* UNLIKELY() */  #include "debug.h"          /* assert(), DEBUGLOG(), RAWLOG() */  #include "error_private.h"  /* error codes and messages */ - +#include "bits.h"           /* ZSTD_highbit32 */  /*=========================================  *  Target specific @@ -41,12 +42,13 @@  /*-******************************************  *  bitStream encoding API (write forward)  ********************************************/ +typedef size_t BitContainerType;  /* bitStream can mix input from multiple sources.   * A critical property of these streams is that they encode and decode in **reverse** direction.   * So the first bit sequence you add will be the last to be read, like a LIFO stack.   */  typedef struct { -    size_t bitContainer; +    BitContainerType bitContainer;      unsigned bitPos;      char*  startPtr;      char*  ptr; @@ -54,7 +56,7 @@ typedef struct {  } BIT_CStream_t;  MEM_STATIC size_t BIT_initCStream(BIT_CStream_t* bitC, void* dstBuffer, size_t dstCapacity); -MEM_STATIC void   BIT_addBits(BIT_CStream_t* bitC, size_t value, unsigned nbBits); +MEM_STATIC void   BIT_addBits(BIT_CStream_t* bitC, BitContainerType value, unsigned nbBits);  MEM_STATIC void   BIT_flushBits(BIT_CStream_t* bitC);  MEM_STATIC size_t BIT_closeCStream(BIT_CStream_t* bitC); @@ -63,7 +65,7 @@ MEM_STATIC size_t BIT_closeCStream(BIT_CStream_t* bitC);  *  `dstCapacity` must be >= sizeof(bitD->bitContainer), otherwise @return will be an error code.  *  *  bits are first added to a local register. -*  Local register is size_t, hence 64-bits on 64-bits systems, or 32-bits on 32-bits systems. +*  Local register is BitContainerType, 64-bits on 64-bits systems, or 32-bits on 32-bits systems.  *  Writing data into memory is an explicit operation, performed by the flushBits function.  *  Hence keep track how many bits are potentially stored into local register to avoid register overflow.  *  After a flushBits, a maximum of 7 bits might still be stored into local register. @@ -80,28 +82,28 @@ MEM_STATIC size_t BIT_closeCStream(BIT_CStream_t* bitC);  *  bitStream decoding API (read backward)  **********************************************/  typedef struct { -    size_t   bitContainer; +    BitContainerType bitContainer;      unsigned bitsConsumed;      const char* ptr;      const char* start;      const char* limitPtr;  } BIT_DStream_t; -typedef enum { BIT_DStream_unfinished = 0, -               BIT_DStream_endOfBuffer = 1, -               BIT_DStream_completed = 2, -               BIT_DStream_overflow = 3 } BIT_DStream_status;  /* result of BIT_reloadDStream() */ -               /* 1,2,4,8 would be better for bitmap combinations, but slows down performance a bit ... :( */ +typedef enum { BIT_DStream_unfinished = 0,  /* fully refilled */ +               BIT_DStream_endOfBuffer = 1, /* still some bits left in bitstream */ +               BIT_DStream_completed = 2,   /* bitstream entirely consumed, bit-exact */ +               BIT_DStream_overflow = 3     /* user requested more bits than present in bitstream */ +    } BIT_DStream_status;  /* result of BIT_reloadDStream() */  MEM_STATIC size_t   BIT_initDStream(BIT_DStream_t* bitD, const void* srcBuffer, size_t srcSize); -MEM_STATIC size_t   BIT_readBits(BIT_DStream_t* bitD, unsigned nbBits); +MEM_STATIC BitContainerType BIT_readBits(BIT_DStream_t* bitD, unsigned nbBits);  MEM_STATIC BIT_DStream_status BIT_reloadDStream(BIT_DStream_t* bitD);  MEM_STATIC unsigned BIT_endOfDStream(const BIT_DStream_t* bitD);  /* Start by invoking BIT_initDStream().  *  A chunk of the bitStream is then stored into a local register. -*  Local register size is 64-bits on 64-bits systems, 32-bits on 32-bits systems (size_t). +*  Local register size is 64-bits on 64-bits systems, 32-bits on 32-bits systems (BitContainerType).  *  You can then retrieve bitFields stored into the local register, **in reverse order**.  *  Local register is explicitly reloaded from memory by the BIT_reloadDStream() method.  *  A reload guarantee a minimum of ((8*sizeof(bitD->bitContainer))-7) bits when its result is BIT_DStream_unfinished. @@ -113,7 +115,7 @@ MEM_STATIC unsigned BIT_endOfDStream(const BIT_DStream_t* bitD);  /*-****************************************  *  unsafe API  ******************************************/ -MEM_STATIC void BIT_addBitsFast(BIT_CStream_t* bitC, size_t value, unsigned nbBits); +MEM_STATIC void BIT_addBitsFast(BIT_CStream_t* bitC, BitContainerType value, unsigned nbBits);  /* faster, but works only if value is "clean", meaning all high bits above nbBits are 0 */  MEM_STATIC void BIT_flushBitsFast(BIT_CStream_t* bitC); @@ -122,33 +124,6 @@ MEM_STATIC void BIT_flushBitsFast(BIT_CStream_t* bitC);  MEM_STATIC size_t BIT_readBitsFast(BIT_DStream_t* bitD, unsigned nbBits);  /* faster, but works only if nbBits >= 1 */ - - -/*-************************************************************** -*  Internal functions -****************************************************************/ -MEM_STATIC unsigned BIT_highbit32 (U32 val) -{ -    assert(val != 0); -    { -#   if (__GNUC__ >= 3)   /* Use GCC Intrinsic */ -        return __builtin_clz (val) ^ 31; -#   else   /* Software version */ -        static const unsigned 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 }; -        U32 v = val; -        v |= v >> 1; -        v |= v >> 2; -        v |= v >> 4; -        v |= v >> 8; -        v |= v >> 16; -        return DeBruijnClz[ (U32) (v * 0x07C4ACDDU) >> 27]; -#   endif -    } -} -  /*=====    Local Constants   =====*/  static const unsigned BIT_mask[] = {      0,          1,         3,         7,         0xF,       0x1F, @@ -178,16 +153,22 @@ MEM_STATIC size_t BIT_initCStream(BIT_CStream_t* bitC,      return 0;  } +FORCE_INLINE_TEMPLATE BitContainerType BIT_getLowerBits(BitContainerType bitContainer, U32 const nbBits) +{ +    assert(nbBits < BIT_MASK_SIZE); +    return bitContainer & BIT_mask[nbBits]; +} +  /*! BIT_addBits() :   *  can add up to 31 bits into `bitC`.   *  Note : does not check for register overflow ! */  MEM_STATIC void BIT_addBits(BIT_CStream_t* bitC, -                            size_t value, unsigned nbBits) +                            BitContainerType value, unsigned nbBits)  {      DEBUG_STATIC_ASSERT(BIT_MASK_SIZE == 32);      assert(nbBits < BIT_MASK_SIZE);      assert(nbBits + bitC->bitPos < sizeof(bitC->bitContainer) * 8); -    bitC->bitContainer |= (value & BIT_mask[nbBits]) << bitC->bitPos; +    bitC->bitContainer |= BIT_getLowerBits(value, nbBits) << bitC->bitPos;      bitC->bitPos += nbBits;  } @@ -195,7 +176,7 @@ MEM_STATIC void BIT_addBits(BIT_CStream_t* bitC,   *  works only if `value` is _clean_,   *  meaning all high bits above nbBits are 0 */  MEM_STATIC void BIT_addBitsFast(BIT_CStream_t* bitC, -                                size_t value, unsigned nbBits) +                                BitContainerType value, unsigned nbBits)  {      assert((value>>nbBits) == 0);      assert(nbBits + bitC->bitPos < sizeof(bitC->bitContainer) * 8); @@ -242,7 +223,7 @@ MEM_STATIC size_t BIT_closeCStream(BIT_CStream_t* bitC)      BIT_addBitsFast(bitC, 1, 1);   /* endMark */      BIT_flushBits(bitC);      if (bitC->ptr >= bitC->endPtr) return 0; /* overflow detected */ -    return (bitC->ptr - bitC->startPtr) + (bitC->bitPos > 0); +    return (size_t)(bitC->ptr - bitC->startPtr) + (bitC->bitPos > 0);  } @@ -266,35 +247,35 @@ MEM_STATIC size_t BIT_initDStream(BIT_DStream_t* bitD, const void* srcBuffer, si          bitD->ptr   = (const char*)srcBuffer + srcSize - sizeof(bitD->bitContainer);          bitD->bitContainer = MEM_readLEST(bitD->ptr);          { BYTE const lastByte = ((const BYTE*)srcBuffer)[srcSize-1]; -          bitD->bitsConsumed = lastByte ? 8 - BIT_highbit32(lastByte) : 0;  /* ensures bitsConsumed is always set */ +          bitD->bitsConsumed = lastByte ? 8 - ZSTD_highbit32(lastByte) : 0;  /* ensures bitsConsumed is always set */            if (lastByte == 0) return ERROR(GENERIC); /* endMark not present */ }      } else {          bitD->ptr   = bitD->start;          bitD->bitContainer = *(const BYTE*)(bitD->start);          switch(srcSize)          { -        case 7: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[6]) << (sizeof(bitD->bitContainer)*8 - 16); +        case 7: bitD->bitContainer += (BitContainerType)(((const BYTE*)(srcBuffer))[6]) << (sizeof(bitD->bitContainer)*8 - 16);                  ZSTD_FALLTHROUGH; -        case 6: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[5]) << (sizeof(bitD->bitContainer)*8 - 24); +        case 6: bitD->bitContainer += (BitContainerType)(((const BYTE*)(srcBuffer))[5]) << (sizeof(bitD->bitContainer)*8 - 24);                  ZSTD_FALLTHROUGH; -        case 5: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[4]) << (sizeof(bitD->bitContainer)*8 - 32); +        case 5: bitD->bitContainer += (BitContainerType)(((const BYTE*)(srcBuffer))[4]) << (sizeof(bitD->bitContainer)*8 - 32);                  ZSTD_FALLTHROUGH; -        case 4: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[3]) << 24; +        case 4: bitD->bitContainer += (BitContainerType)(((const BYTE*)(srcBuffer))[3]) << 24;                  ZSTD_FALLTHROUGH; -        case 3: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[2]) << 16; +        case 3: bitD->bitContainer += (BitContainerType)(((const BYTE*)(srcBuffer))[2]) << 16;                  ZSTD_FALLTHROUGH; -        case 2: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[1]) <<  8; +        case 2: bitD->bitContainer += (BitContainerType)(((const BYTE*)(srcBuffer))[1]) <<  8;                  ZSTD_FALLTHROUGH;          default: break;          }          {   BYTE const lastByte = ((const BYTE*)srcBuffer)[srcSize-1]; -            bitD->bitsConsumed = lastByte ? 8 - BIT_highbit32(lastByte) : 0; +            bitD->bitsConsumed = lastByte ? 8 - ZSTD_highbit32(lastByte) : 0;              if (lastByte == 0) return ERROR(corruption_detected);  /* endMark not present */          }          bitD->bitsConsumed += (U32)(sizeof(bitD->bitContainer) - srcSize)*8; @@ -303,12 +284,12 @@ MEM_STATIC size_t BIT_initDStream(BIT_DStream_t* bitD, const void* srcBuffer, si      return srcSize;  } -MEM_STATIC FORCE_INLINE_ATTR size_t BIT_getUpperBits(size_t bitContainer, U32 const start) +FORCE_INLINE_TEMPLATE BitContainerType BIT_getUpperBits(BitContainerType bitContainer, U32 const start)  {      return bitContainer >> start;  } -MEM_STATIC FORCE_INLINE_ATTR size_t BIT_getMiddleBits(size_t bitContainer, U32 const start, U32 const nbBits) +FORCE_INLINE_TEMPLATE BitContainerType BIT_getMiddleBits(BitContainerType bitContainer, U32 const start, U32 const nbBits)  {      U32 const regMask = sizeof(bitContainer)*8 - 1;      /* if start > regMask, bitstream is corrupted, and result is undefined */ @@ -318,26 +299,20 @@ MEM_STATIC FORCE_INLINE_ATTR size_t BIT_getMiddleBits(size_t bitContainer, U32 c       * such cpus old (pre-Haswell, 2013) and their performance is not of that       * importance.       */ -#if defined(__x86_64__) || defined(_M_X86) +#if defined(__x86_64__) || defined(_M_X64)      return (bitContainer >> (start & regMask)) & ((((U64)1) << nbBits) - 1);  #else      return (bitContainer >> (start & regMask)) & BIT_mask[nbBits];  #endif  } -MEM_STATIC FORCE_INLINE_ATTR size_t BIT_getLowerBits(size_t bitContainer, U32 const nbBits) -{ -    assert(nbBits < BIT_MASK_SIZE); -    return bitContainer & BIT_mask[nbBits]; -} -  /*! BIT_lookBits() :   *  Provides next n bits from local register.   *  local register is not modified.   *  On 32-bits, maxNbBits==24.   *  On 64-bits, maxNbBits==56.   * @return : value extracted */ -MEM_STATIC  FORCE_INLINE_ATTR size_t BIT_lookBits(const BIT_DStream_t*  bitD, U32 nbBits) +FORCE_INLINE_TEMPLATE BitContainerType BIT_lookBits(const BIT_DStream_t*  bitD, U32 nbBits)  {      /* arbitrate between double-shift and shift+mask */  #if 1 @@ -353,14 +328,14 @@ MEM_STATIC  FORCE_INLINE_ATTR size_t BIT_lookBits(const BIT_DStream_t*  bitD, U3  /*! BIT_lookBitsFast() :   *  unsafe version; only works if nbBits >= 1 */ -MEM_STATIC size_t BIT_lookBitsFast(const BIT_DStream_t* bitD, U32 nbBits) +MEM_STATIC BitContainerType BIT_lookBitsFast(const BIT_DStream_t* bitD, U32 nbBits)  {      U32 const regMask = sizeof(bitD->bitContainer)*8 - 1;      assert(nbBits >= 1);      return (bitD->bitContainer << (bitD->bitsConsumed & regMask)) >> (((regMask+1)-nbBits) & regMask);  } -MEM_STATIC FORCE_INLINE_ATTR void BIT_skipBits(BIT_DStream_t* bitD, U32 nbBits) +FORCE_INLINE_TEMPLATE void BIT_skipBits(BIT_DStream_t* bitD, U32 nbBits)  {      bitD->bitsConsumed += nbBits;  } @@ -369,23 +344,38 @@ MEM_STATIC FORCE_INLINE_ATTR void BIT_skipBits(BIT_DStream_t* bitD, U32 nbBits)   *  Read (consume) next n bits from local register and update.   *  Pay attention to not read more than nbBits contained into local register.   * @return : extracted value. */ -MEM_STATIC FORCE_INLINE_ATTR size_t BIT_readBits(BIT_DStream_t* bitD, unsigned nbBits) +FORCE_INLINE_TEMPLATE BitContainerType BIT_readBits(BIT_DStream_t* bitD, unsigned nbBits)  { -    size_t const value = BIT_lookBits(bitD, nbBits); +    BitContainerType const value = BIT_lookBits(bitD, nbBits);      BIT_skipBits(bitD, nbBits);      return value;  }  /*! BIT_readBitsFast() : - *  unsafe version; only works only if nbBits >= 1 */ -MEM_STATIC size_t BIT_readBitsFast(BIT_DStream_t* bitD, unsigned nbBits) + *  unsafe version; only works if nbBits >= 1 */ +MEM_STATIC BitContainerType BIT_readBitsFast(BIT_DStream_t* bitD, unsigned nbBits)  { -    size_t const value = BIT_lookBitsFast(bitD, nbBits); +    BitContainerType const value = BIT_lookBitsFast(bitD, nbBits);      assert(nbBits >= 1);      BIT_skipBits(bitD, nbBits);      return value;  } +/*! BIT_reloadDStream_internal() : + *  Simple variant of BIT_reloadDStream(), with two conditions: + *  1. bitstream is valid : bitsConsumed <= sizeof(bitD->bitContainer)*8 + *  2. look window is valid after shifted down : bitD->ptr >= bitD->start + */ +MEM_STATIC BIT_DStream_status BIT_reloadDStream_internal(BIT_DStream_t* bitD) +{ +    assert(bitD->bitsConsumed <= sizeof(bitD->bitContainer)*8); +    bitD->ptr -= bitD->bitsConsumed >> 3; +    assert(bitD->ptr >= bitD->start); +    bitD->bitsConsumed &= 7; +    bitD->bitContainer = MEM_readLEST(bitD->ptr); +    return BIT_DStream_unfinished; +} +  /*! BIT_reloadDStreamFast() :   *  Similar to BIT_reloadDStream(), but with two differences:   *  1. bitsConsumed <= sizeof(bitD->bitContainer)*8 must hold! @@ -396,31 +386,35 @@ MEM_STATIC BIT_DStream_status BIT_reloadDStreamFast(BIT_DStream_t* bitD)  {      if (UNLIKELY(bitD->ptr < bitD->limitPtr))          return BIT_DStream_overflow; -    assert(bitD->bitsConsumed <= sizeof(bitD->bitContainer)*8); -    bitD->ptr -= bitD->bitsConsumed >> 3; -    bitD->bitsConsumed &= 7; -    bitD->bitContainer = MEM_readLEST(bitD->ptr); -    return BIT_DStream_unfinished; +    return BIT_reloadDStream_internal(bitD);  }  /*! BIT_reloadDStream() :   *  Refill `bitD` from buffer previously set in BIT_initDStream() . - *  This function is safe, it guarantees it will not read beyond src buffer. + *  This function is safe, it guarantees it will not never beyond src buffer.   * @return : status of `BIT_DStream_t` internal register.   *           when status == BIT_DStream_unfinished, internal register is filled with at least 25 or 57 bits */ -MEM_STATIC BIT_DStream_status BIT_reloadDStream(BIT_DStream_t* bitD) +FORCE_INLINE_TEMPLATE BIT_DStream_status BIT_reloadDStream(BIT_DStream_t* bitD)  { -    if (bitD->bitsConsumed > (sizeof(bitD->bitContainer)*8))  /* overflow detected, like end of stream */ +    /* note : once in overflow mode, a bitstream remains in this mode until it's reset */ +    if (UNLIKELY(bitD->bitsConsumed > (sizeof(bitD->bitContainer)*8))) { +        static const BitContainerType zeroFilled = 0; +        bitD->ptr = (const char*)&zeroFilled; /* aliasing is allowed for char */ +        /* overflow detected, erroneous scenario or end of stream: no update */          return BIT_DStream_overflow; +    } + +    assert(bitD->ptr >= bitD->start);      if (bitD->ptr >= bitD->limitPtr) { -        return BIT_reloadDStreamFast(bitD); +        return BIT_reloadDStream_internal(bitD);      }      if (bitD->ptr == bitD->start) { +        /* reached end of bitStream => no update */          if (bitD->bitsConsumed < sizeof(bitD->bitContainer)*8) return BIT_DStream_endOfBuffer;          return BIT_DStream_completed;      } -    /* start < ptr < limitPtr */ +    /* start < ptr < limitPtr => cautious update */      {   U32 nbBytes = bitD->bitsConsumed >> 3;          BIT_DStream_status result = BIT_DStream_unfinished;          if (bitD->ptr - nbBytes < bitD->start) { @@ -442,5 +436,4 @@ MEM_STATIC unsigned BIT_endOfDStream(const BIT_DStream_t* DStream)      return ((DStream->ptr == DStream->start) && (DStream->bitsConsumed == sizeof(DStream->bitContainer)*8));  } -  #endif /* BITSTREAM_H_MODULE */ diff --git a/lib/zstd/common/compiler.h b/lib/zstd/common/compiler.h index c42d39faf9bd..dc9bd15e174e 100644 --- a/lib/zstd/common/compiler.h +++ b/lib/zstd/common/compiler.h @@ -1,5 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */  /* - * Copyright (c) Yann Collet, Facebook, Inc. + * Copyright (c) Meta Platforms, Inc. and affiliates.   * All rights reserved.   *   * This source code is licensed under both the BSD-style license (found in the @@ -11,6 +12,8 @@  #ifndef ZSTD_COMPILER_H  #define ZSTD_COMPILER_H +#include <linux/types.h> +  #include "portability_macros.h"  /*-******************************************************* @@ -41,12 +44,15 @@  */  #define WIN_CDECL +/* UNUSED_ATTR tells the compiler it is okay if the function is unused. */ +#define UNUSED_ATTR __attribute__((unused)) +  /*   * FORCE_INLINE_TEMPLATE is used to define C "templates", which take constant   * parameters. They must be inlined for the compiler to eliminate the constant   * branches.   */ -#define FORCE_INLINE_TEMPLATE static INLINE_KEYWORD FORCE_INLINE_ATTR +#define FORCE_INLINE_TEMPLATE static INLINE_KEYWORD FORCE_INLINE_ATTR UNUSED_ATTR  /*   * HINT_INLINE is used to help the compiler generate better code. It is *not*   * used for "templates", so it can be tweaked based on the compilers @@ -61,11 +67,21 @@  #if !defined(__clang__) && defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 8 && __GNUC__ < 5  #  define HINT_INLINE static INLINE_KEYWORD  #else -#  define HINT_INLINE static INLINE_KEYWORD FORCE_INLINE_ATTR +#  define HINT_INLINE FORCE_INLINE_TEMPLATE  #endif -/* UNUSED_ATTR tells the compiler it is okay if the function is unused. */ -#define UNUSED_ATTR __attribute__((unused)) +/* "soft" inline : + * The compiler is free to select if it's a good idea to inline or not. + * The main objective is to silence compiler warnings + * when a defined function in included but not used. + * + * Note : this macro is prefixed `MEM_` because it used to be provided by `mem.h` unit. + * Updating the prefix is probably preferable, but requires a fairly large codemod, + * since this name is used everywhere. + */ +#ifndef MEM_STATIC  /* already defined in Linux Kernel mem.h */ +#define MEM_STATIC static __inline UNUSED_ATTR +#endif  /* force no inlining */  #define FORCE_NOINLINE static __attribute__((__noinline__)) @@ -86,23 +102,24 @@  #  define PREFETCH_L1(ptr)  __builtin_prefetch((ptr), 0 /* rw==read */, 3 /* locality */)  #  define PREFETCH_L2(ptr)  __builtin_prefetch((ptr), 0 /* rw==read */, 2 /* locality */)  #elif defined(__aarch64__) -#  define PREFETCH_L1(ptr)  __asm__ __volatile__("prfm pldl1keep, %0" ::"Q"(*(ptr))) -#  define PREFETCH_L2(ptr)  __asm__ __volatile__("prfm pldl2keep, %0" ::"Q"(*(ptr))) +#  define PREFETCH_L1(ptr)  do { __asm__ __volatile__("prfm pldl1keep, %0" ::"Q"(*(ptr))); } while (0) +#  define PREFETCH_L2(ptr)  do { __asm__ __volatile__("prfm pldl2keep, %0" ::"Q"(*(ptr))); } while (0)  #else -#  define PREFETCH_L1(ptr) (void)(ptr)  /* disabled */ -#  define PREFETCH_L2(ptr) (void)(ptr)  /* disabled */ +#  define PREFETCH_L1(ptr) do { (void)(ptr); } while (0)  /* disabled */ +#  define PREFETCH_L2(ptr) do { (void)(ptr); } while (0)  /* disabled */  #endif  /* NO_PREFETCH */  #define CACHELINE_SIZE 64 -#define PREFETCH_AREA(p, s)  {            \ -    const char* const _ptr = (const char*)(p);  \ -    size_t const _size = (size_t)(s);     \ -    size_t _pos;                          \ -    for (_pos=0; _pos<_size; _pos+=CACHELINE_SIZE) {  \ -        PREFETCH_L2(_ptr + _pos);         \ -    }                                     \ -} +#define PREFETCH_AREA(p, s)                              \ +    do {                                                 \ +        const char* const _ptr = (const char*)(p);       \ +        size_t const _size = (size_t)(s);                \ +        size_t _pos;                                     \ +        for (_pos=0; _pos<_size; _pos+=CACHELINE_SIZE) { \ +            PREFETCH_L2(_ptr + _pos);                    \ +        }                                                \ +    } while (0)  /* vectorization   * older GCC (pre gcc-4.3 picked as the cutoff) uses a different syntax, @@ -126,16 +143,13 @@  #define UNLIKELY(x) (__builtin_expect((x), 0))  #if __has_builtin(__builtin_unreachable) || (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5))) -#  define ZSTD_UNREACHABLE { assert(0), __builtin_unreachable(); } +#  define ZSTD_UNREACHABLE do { assert(0), __builtin_unreachable(); } while (0)  #else -#  define ZSTD_UNREACHABLE { assert(0); } +#  define ZSTD_UNREACHABLE do { assert(0); } while (0)  #endif  /* disable warnings */ -/*Like DYNAMIC_BMI2 but for compile time determination of BMI2 support*/ - -  /* compile time determination of SIMD support */  /* C-language Attributes are added in C23. */ @@ -158,9 +172,15 @@  #define ZSTD_FALLTHROUGH fallthrough  /*-************************************************************** -*  Alignment check +*  Alignment  *****************************************************************/ +/* @return 1 if @u is a 2^n value, 0 otherwise + * useful to check a value is valid for alignment restrictions */ +MEM_STATIC int ZSTD_isPower2(size_t u) { +    return (u & (u-1)) == 0; +} +  /* this test was initially positioned in mem.h,   * but this file is removed (or replaced) for linux kernel   * so it's now hosted in compiler.h, @@ -175,10 +195,95 @@  #endif /* ZSTD_ALIGNOF */ +#ifndef ZSTD_ALIGNED +/* C90-compatible alignment macro (GCC/Clang). Adjust for other compilers if needed. */ +#define ZSTD_ALIGNED(a) __attribute__((aligned(a))) +#endif /* ZSTD_ALIGNED */ + +  /*-**************************************************************  *  Sanitizer  *****************************************************************/ +/* + * Zstd relies on pointer overflow in its decompressor. + * We add this attribute to functions that rely on pointer overflow. + */ +#ifndef ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +#  if __has_attribute(no_sanitize) +#    if !defined(__clang__) && defined(__GNUC__) && __GNUC__ < 8 +       /* gcc < 8 only has signed-integer-overlow which triggers on pointer overflow */ +#      define ZSTD_ALLOW_POINTER_OVERFLOW_ATTR __attribute__((no_sanitize("signed-integer-overflow"))) +#    else +       /* older versions of clang [3.7, 5.0) will warn that pointer-overflow is ignored. */ +#      define ZSTD_ALLOW_POINTER_OVERFLOW_ATTR __attribute__((no_sanitize("pointer-overflow"))) +#    endif +#  else +#    define ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +#  endif +#endif + +/* + * Helper function to perform a wrapped pointer difference without triggering + * UBSAN. + * + * @returns lhs - rhs with wrapping + */ +MEM_STATIC +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +ptrdiff_t ZSTD_wrappedPtrDiff(unsigned char const* lhs, unsigned char const* rhs) +{ +    return lhs - rhs; +} + +/* + * Helper function to perform a wrapped pointer add without triggering UBSAN. + * + * @return ptr + add with wrapping + */ +MEM_STATIC +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +unsigned char const* ZSTD_wrappedPtrAdd(unsigned char const* ptr, ptrdiff_t add) +{ +    return ptr + add; +} + +/* + * Helper function to perform a wrapped pointer subtraction without triggering + * UBSAN. + * + * @return ptr - sub with wrapping + */ +MEM_STATIC +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +unsigned char const* ZSTD_wrappedPtrSub(unsigned char const* ptr, ptrdiff_t sub) +{ +    return ptr - sub; +} + +/* + * Helper function to add to a pointer that works around C's undefined behavior + * of adding 0 to NULL. + * + * @returns `ptr + add` except it defines `NULL + 0 == NULL`. + */ +MEM_STATIC +unsigned char* ZSTD_maybeNullPtrAdd(unsigned char* ptr, ptrdiff_t add) +{ +    return add > 0 ? ptr + add : ptr; +} + +/* Issue #3240 reports an ASAN failure on an llvm-mingw build. Out of an + * abundance of caution, disable our custom poisoning on mingw. */ +#ifdef __MINGW32__ +#ifndef ZSTD_ASAN_DONT_POISON_WORKSPACE +#define ZSTD_ASAN_DONT_POISON_WORKSPACE 1 +#endif +#ifndef ZSTD_MSAN_DONT_POISON_WORKSPACE +#define ZSTD_MSAN_DONT_POISON_WORKSPACE 1 +#endif +#endif +  #endif /* ZSTD_COMPILER_H */ diff --git a/lib/zstd/common/cpu.h b/lib/zstd/common/cpu.h index 0db7b42407ee..d8319a2bef4c 100644 --- a/lib/zstd/common/cpu.h +++ b/lib/zstd/common/cpu.h @@ -1,5 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */  /* - * Copyright (c) Facebook, Inc. + * Copyright (c) Meta Platforms, Inc. and affiliates.   * All rights reserved.   *   * This source code is licensed under both the BSD-style license (found in the diff --git a/lib/zstd/common/debug.c b/lib/zstd/common/debug.c index bb863c9ea616..8eb6aa9a3b20 100644 --- a/lib/zstd/common/debug.c +++ b/lib/zstd/common/debug.c @@ -1,7 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause  /* ******************************************************************   * debug   * Part of FSE library - * Copyright (c) Yann Collet, Facebook, Inc. + * Copyright (c) Meta Platforms, Inc. and affiliates.   *   * You can contact the author at :   * - Source repository : https://github.com/Cyan4973/FiniteStateEntropy @@ -21,4 +22,10 @@  #include "debug.h" +#if (DEBUGLEVEL>=2) +/* We only use this when DEBUGLEVEL>=2, but we get -Werror=pedantic errors if a + * translation unit is empty. So remove this from Linux kernel builds, but + * otherwise just leave it in. + */  int g_debuglevel = DEBUGLEVEL; +#endif diff --git a/lib/zstd/common/debug.h b/lib/zstd/common/debug.h index 6dd88d1fbd02..c8a10281f112 100644 --- a/lib/zstd/common/debug.h +++ b/lib/zstd/common/debug.h @@ -1,7 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */  /* ******************************************************************   * debug   * Part of FSE library - * Copyright (c) Yann Collet, Facebook, Inc. + * Copyright (c) Meta Platforms, Inc. and affiliates.   *   * You can contact the author at :   * - Source repository : https://github.com/Cyan4973/FiniteStateEntropy @@ -33,7 +34,6 @@  #define DEBUG_H_12987983217 -  /* static assert is triggered at compile time, leaving no runtime artefact.   * static assert only works with compile-time constants.   * Also, this variant can only be used inside a function. */ @@ -82,20 +82,27 @@ extern int g_debuglevel; /* the variable is only declared,                              It's useful when enabling very verbose levels                              on selective conditions (such as position in src) */ -#  define RAWLOG(l, ...) {                                       \ -                if (l<=g_debuglevel) {                           \ -                    ZSTD_DEBUG_PRINT(__VA_ARGS__);               \ -            }   } -#  define DEBUGLOG(l, ...) {                                     \ -                if (l<=g_debuglevel) {                           \ -                    ZSTD_DEBUG_PRINT(__FILE__ ": " __VA_ARGS__); \ -                    ZSTD_DEBUG_PRINT(" \n");                     \ -            }   } +#  define RAWLOG(l, ...)                   \ +    do {                                   \ +        if (l<=g_debuglevel) {             \ +            ZSTD_DEBUG_PRINT(__VA_ARGS__); \ +        }                                  \ +    } while (0) + +#define STRINGIFY(x) #x +#define TOSTRING(x) STRINGIFY(x) +#define LINE_AS_STRING TOSTRING(__LINE__) + +#  define DEBUGLOG(l, ...)                               \ +    do {                                                 \ +        if (l<=g_debuglevel) {                           \ +            ZSTD_DEBUG_PRINT(__FILE__ ":" LINE_AS_STRING ": " __VA_ARGS__); \ +            ZSTD_DEBUG_PRINT(" \n");                     \ +        }                                                \ +    } while (0)  #else -#  define RAWLOG(l, ...)      {}    /* disabled */ -#  define DEBUGLOG(l, ...)    {}    /* disabled */ +#  define RAWLOG(l, ...)   do { } while (0)    /* disabled */ +#  define DEBUGLOG(l, ...) do { } while (0)    /* disabled */  #endif - -  #endif /* DEBUG_H_12987983217 */ diff --git a/lib/zstd/common/entropy_common.c b/lib/zstd/common/entropy_common.c index fef67056f052..6cdd82233fb5 100644 --- a/lib/zstd/common/entropy_common.c +++ b/lib/zstd/common/entropy_common.c @@ -1,6 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause  /* ******************************************************************   * Common functions of New Generation Entropy library - * Copyright (c) Yann Collet, Facebook, Inc. + * Copyright (c) Meta Platforms, Inc. and affiliates.   *   *  You can contact the author at :   *  - FSE+HUF source repository : https://github.com/Cyan4973/FiniteStateEntropy @@ -19,8 +20,8 @@  #include "error_private.h"       /* ERR_*, ERROR */  #define FSE_STATIC_LINKING_ONLY  /* FSE_MIN_TABLELOG */  #include "fse.h" -#define HUF_STATIC_LINKING_ONLY  /* HUF_TABLELOG_ABSOLUTEMAX */  #include "huf.h" +#include "bits.h"                /* ZSDT_highbit32, ZSTD_countTrailingZeros32 */  /*===   Version   ===*/ @@ -38,23 +39,6 @@ const char* HUF_getErrorName(size_t code) { return ERR_getErrorName(code); }  /*-**************************************************************  *  FSE NCount encoding-decoding  ****************************************************************/ -static U32 FSE_ctz(U32 val) -{ -    assert(val != 0); -    { -#   if (__GNUC__ >= 3)   /* GCC Intrinsic */ -        return __builtin_ctz(val); -#   else   /* Software version */ -        U32 count = 0; -        while ((val & 1) == 0) { -            val >>= 1; -            ++count; -        } -        return count; -#   endif -    } -} -  FORCE_INLINE_TEMPLATE  size_t FSE_readNCount_body(short* normalizedCounter, unsigned* maxSVPtr, unsigned* tableLogPtr,                             const void* headerBuffer, size_t hbSize) @@ -102,7 +86,7 @@ size_t FSE_readNCount_body(short* normalizedCounter, unsigned* maxSVPtr, unsigne               * repeat.               * Avoid UB by setting the high bit to 1.               */ -            int repeats = FSE_ctz(~bitStream | 0x80000000) >> 1; +            int repeats = ZSTD_countTrailingZeros32(~bitStream | 0x80000000) >> 1;              while (repeats >= 12) {                  charnum += 3 * 12;                  if (LIKELY(ip <= iend-7)) { @@ -113,7 +97,7 @@ size_t FSE_readNCount_body(short* normalizedCounter, unsigned* maxSVPtr, unsigne                      ip = iend - 4;                  }                  bitStream = MEM_readLE32(ip) >> bitCount; -                repeats = FSE_ctz(~bitStream | 0x80000000) >> 1; +                repeats = ZSTD_countTrailingZeros32(~bitStream | 0x80000000) >> 1;              }              charnum += 3 * repeats;              bitStream >>= 2 * repeats; @@ -178,7 +162,7 @@ size_t FSE_readNCount_body(short* normalizedCounter, unsigned* maxSVPtr, unsigne                   * know that threshold > 1.                   */                  if (remaining <= 1) break; -                nbBits = BIT_highbit32(remaining) + 1; +                nbBits = ZSTD_highbit32(remaining) + 1;                  threshold = 1 << (nbBits - 1);              }              if (charnum >= maxSV1) break; @@ -253,7 +237,7 @@ size_t HUF_readStats(BYTE* huffWeight, size_t hwSize, U32* rankStats,                       const void* src, size_t srcSize)  {      U32 wksp[HUF_READ_STATS_WORKSPACE_SIZE_U32]; -    return HUF_readStats_wksp(huffWeight, hwSize, rankStats, nbSymbolsPtr, tableLogPtr, src, srcSize, wksp, sizeof(wksp), /* bmi2 */ 0); +    return HUF_readStats_wksp(huffWeight, hwSize, rankStats, nbSymbolsPtr, tableLogPtr, src, srcSize, wksp, sizeof(wksp), /* flags */ 0);  }  FORCE_INLINE_TEMPLATE size_t @@ -301,14 +285,14 @@ HUF_readStats_body(BYTE* huffWeight, size_t hwSize, U32* rankStats,      if (weightTotal == 0) return ERROR(corruption_detected);      /* get last non-null symbol weight (implied, total must be 2^n) */ -    {   U32 const tableLog = BIT_highbit32(weightTotal) + 1; +    {   U32 const tableLog = ZSTD_highbit32(weightTotal) + 1;          if (tableLog > HUF_TABLELOG_MAX) return ERROR(corruption_detected);          *tableLogPtr = tableLog;          /* determine last weight */          {   U32 const total = 1 << tableLog;              U32 const rest = total - weightTotal; -            U32 const verif = 1 << BIT_highbit32(rest); -            U32 const lastWeight = BIT_highbit32(rest) + 1; +            U32 const verif = 1 << ZSTD_highbit32(rest); +            U32 const lastWeight = ZSTD_highbit32(rest) + 1;              if (verif != rest) return ERROR(corruption_detected);    /* last value must be a clean power of 2 */              huffWeight[oSize] = (BYTE)lastWeight;              rankStats[lastWeight]++; @@ -345,13 +329,13 @@ size_t HUF_readStats_wksp(BYTE* huffWeight, size_t hwSize, U32* rankStats,                       U32* nbSymbolsPtr, U32* tableLogPtr,                       const void* src, size_t srcSize,                       void* workSpace, size_t wkspSize, -                     int bmi2) +                     int flags)  {  #if DYNAMIC_BMI2 -    if (bmi2) { +    if (flags & HUF_flags_bmi2) {          return HUF_readStats_body_bmi2(huffWeight, hwSize, rankStats, nbSymbolsPtr, tableLogPtr, src, srcSize, workSpace, wkspSize);      }  #endif -    (void)bmi2; +    (void)flags;      return HUF_readStats_body_default(huffWeight, hwSize, rankStats, nbSymbolsPtr, tableLogPtr, src, srcSize, workSpace, wkspSize);  } diff --git a/lib/zstd/common/error_private.c b/lib/zstd/common/error_private.c index 6d1135f8c373..6c3dbad838b6 100644 --- a/lib/zstd/common/error_private.c +++ b/lib/zstd/common/error_private.c @@ -1,5 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause  /* - * Copyright (c) Yann Collet, Facebook, Inc. + * Copyright (c) Meta Platforms, Inc. and affiliates.   * All rights reserved.   *   * This source code is licensed under both the BSD-style license (found in the @@ -27,9 +28,11 @@ const char* ERR_getErrorString(ERR_enum code)      case PREFIX(version_unsupported): return "Version not supported";      case PREFIX(frameParameter_unsupported): return "Unsupported frame parameter";      case PREFIX(frameParameter_windowTooLarge): return "Frame requires too much memory for decoding"; -    case PREFIX(corruption_detected): return "Corrupted block detected"; +    case PREFIX(corruption_detected): return "Data corruption detected";      case PREFIX(checksum_wrong): return "Restored data doesn't match checksum"; +    case PREFIX(literals_headerWrong): return "Header of Literals' block doesn't respect format specification";      case PREFIX(parameter_unsupported): return "Unsupported parameter"; +    case PREFIX(parameter_combination_unsupported): return "Unsupported combination of parameters";      case PREFIX(parameter_outOfBound): return "Parameter is out of bound";      case PREFIX(init_missing): return "Context should be init first";      case PREFIX(memory_allocation): return "Allocation error : not enough memory"; @@ -38,17 +41,23 @@ const char* ERR_getErrorString(ERR_enum code)      case PREFIX(tableLog_tooLarge): return "tableLog requires too much memory : unsupported";      case PREFIX(maxSymbolValue_tooLarge): return "Unsupported max Symbol Value : too large";      case PREFIX(maxSymbolValue_tooSmall): return "Specified maxSymbolValue is too small"; +    case PREFIX(cannotProduce_uncompressedBlock): return "This mode cannot generate an uncompressed block"; +    case PREFIX(stabilityCondition_notRespected): return "pledged buffer stability condition is not respected";      case PREFIX(dictionary_corrupted): return "Dictionary is corrupted";      case PREFIX(dictionary_wrong): return "Dictionary mismatch";      case PREFIX(dictionaryCreation_failed): return "Cannot create Dictionary from provided samples";      case PREFIX(dstSize_tooSmall): return "Destination buffer is too small";      case PREFIX(srcSize_wrong): return "Src size is incorrect";      case PREFIX(dstBuffer_null): return "Operation on NULL destination buffer"; +    case PREFIX(noForwardProgress_destFull): return "Operation made no progress over multiple calls, due to output buffer being full"; +    case PREFIX(noForwardProgress_inputEmpty): return "Operation made no progress over multiple calls, due to input being empty";          /* following error codes are not stable and may be removed or changed in a future version */      case PREFIX(frameIndex_tooLarge): return "Frame index is too large";      case PREFIX(seekableIO): return "An I/O error occurred when reading/seeking";      case PREFIX(dstBuffer_wrong): return "Destination buffer is wrong";      case PREFIX(srcBuffer_wrong): return "Source buffer is wrong"; +    case PREFIX(sequenceProducer_failed): return "Block-level external sequence producer returned an error code"; +    case PREFIX(externalSequences_invalid): return "External sequences are not valid";      case PREFIX(maxCode):      default: return notErrorCode;      } diff --git a/lib/zstd/common/error_private.h b/lib/zstd/common/error_private.h index ca5101e542fa..08ee87b68cca 100644 --- a/lib/zstd/common/error_private.h +++ b/lib/zstd/common/error_private.h @@ -1,5 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */  /* - * Copyright (c) Yann Collet, Facebook, Inc. + * Copyright (c) Meta Platforms, Inc. and affiliates.   * All rights reserved.   *   * This source code is licensed under both the BSD-style license (found in the @@ -13,8 +14,6 @@  #ifndef ERROR_H_MODULE  #define ERROR_H_MODULE - -  /* ****************************************  *  Dependencies  ******************************************/ @@ -23,7 +22,6 @@  #include "debug.h"  #include "zstd_deps.h"       /* size_t */ -  /* ****************************************  *  Compiler-specific  ******************************************/ @@ -49,8 +47,13 @@ ERR_STATIC unsigned ERR_isError(size_t code) { return (code > ERROR(maxCode)); }  ERR_STATIC ERR_enum ERR_getErrorCode(size_t code) { if (!ERR_isError(code)) return (ERR_enum)0; return (ERR_enum) (0-code); }  /* check and forward error code */ -#define CHECK_V_F(e, f) size_t const e = f; if (ERR_isError(e)) return e -#define CHECK_F(f)   { CHECK_V_F(_var_err__, f); } +#define CHECK_V_F(e, f)     \ +    size_t const e = f;     \ +    do {                    \ +        if (ERR_isError(e)) \ +            return e;       \ +    } while (0) +#define CHECK_F(f)   do { CHECK_V_F(_var_err__, f); } while (0)  /*-**************************************** @@ -84,10 +87,12 @@ void _force_has_format_string(const char *format, ...) {   * We want to force this function invocation to be syntactically correct, but   * we don't want to force runtime evaluation of its arguments.   */ -#define _FORCE_HAS_FORMAT_STRING(...) \ -  if (0) { \ -    _force_has_format_string(__VA_ARGS__); \ -  } +#define _FORCE_HAS_FORMAT_STRING(...)              \ +    do {                                           \ +        if (0) {                                   \ +            _force_has_format_string(__VA_ARGS__); \ +        }                                          \ +    } while (0)  #define ERR_QUOTE(str) #str @@ -98,48 +103,49 @@ void _force_has_format_string(const char *format, ...) {   * In order to do that (particularly, printing the conditional that failed),   * this can't just wrap RETURN_ERROR().   */ -#define RETURN_ERROR_IF(cond, err, ...) \ -  if (cond) { \ -    RAWLOG(3, "%s:%d: ERROR!: check %s failed, returning %s", \ -           __FILE__, __LINE__, ERR_QUOTE(cond), ERR_QUOTE(ERROR(err))); \ -    _FORCE_HAS_FORMAT_STRING(__VA_ARGS__); \ -    RAWLOG(3, ": " __VA_ARGS__); \ -    RAWLOG(3, "\n"); \ -    return ERROR(err); \ -  } +#define RETURN_ERROR_IF(cond, err, ...)                                        \ +    do {                                                                       \ +        if (cond) {                                                            \ +            RAWLOG(3, "%s:%d: ERROR!: check %s failed, returning %s",          \ +                  __FILE__, __LINE__, ERR_QUOTE(cond), ERR_QUOTE(ERROR(err))); \ +            _FORCE_HAS_FORMAT_STRING(__VA_ARGS__);                             \ +            RAWLOG(3, ": " __VA_ARGS__);                                       \ +            RAWLOG(3, "\n");                                                   \ +            return ERROR(err);                                                 \ +        }                                                                      \ +    } while (0)  /*   * Unconditionally return the specified error.   *   * In debug modes, prints additional information.   */ -#define RETURN_ERROR(err, ...) \ -  do { \ -    RAWLOG(3, "%s:%d: ERROR!: unconditional check failed, returning %s", \ -           __FILE__, __LINE__, ERR_QUOTE(ERROR(err))); \ -    _FORCE_HAS_FORMAT_STRING(__VA_ARGS__); \ -    RAWLOG(3, ": " __VA_ARGS__); \ -    RAWLOG(3, "\n"); \ -    return ERROR(err); \ -  } while(0); +#define RETURN_ERROR(err, ...)                                               \ +    do {                                                                     \ +        RAWLOG(3, "%s:%d: ERROR!: unconditional check failed, returning %s", \ +              __FILE__, __LINE__, ERR_QUOTE(ERROR(err)));                    \ +        _FORCE_HAS_FORMAT_STRING(__VA_ARGS__);                               \ +        RAWLOG(3, ": " __VA_ARGS__);                                         \ +        RAWLOG(3, "\n");                                                     \ +        return ERROR(err);                                                   \ +    } while(0)  /*   * If the provided expression evaluates to an error code, returns that error code.   *   * In debug modes, prints additional information.   */ -#define FORWARD_IF_ERROR(err, ...) \ -  do { \ -    size_t const err_code = (err); \ -    if (ERR_isError(err_code)) { \ -      RAWLOG(3, "%s:%d: ERROR!: forwarding error in %s: %s", \ -             __FILE__, __LINE__, ERR_QUOTE(err), ERR_getErrorName(err_code)); \ -      _FORCE_HAS_FORMAT_STRING(__VA_ARGS__); \ -      RAWLOG(3, ": " __VA_ARGS__); \ -      RAWLOG(3, "\n"); \ -      return err_code; \ -    } \ -  } while(0); - +#define FORWARD_IF_ERROR(err, ...)                                                 \ +    do {                                                                           \ +        size_t const err_code = (err);                                             \ +        if (ERR_isError(err_code)) {                                               \ +            RAWLOG(3, "%s:%d: ERROR!: forwarding error in %s: %s",                 \ +                  __FILE__, __LINE__, ERR_QUOTE(err), ERR_getErrorName(err_code)); \ +            _FORCE_HAS_FORMAT_STRING(__VA_ARGS__);                                 \ +            RAWLOG(3, ": " __VA_ARGS__);                                           \ +            RAWLOG(3, "\n");                                                       \ +            return err_code;                                                       \ +        }                                                                          \ +    } while(0)  #endif /* ERROR_H_MODULE */ diff --git a/lib/zstd/common/fse.h b/lib/zstd/common/fse.h index 4507043b2287..b36ce7a2a8c3 100644 --- a/lib/zstd/common/fse.h +++ b/lib/zstd/common/fse.h @@ -1,7 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */  /* ******************************************************************   * FSE : Finite State Entropy codec   * Public Prototypes declaration - * Copyright (c) Yann Collet, Facebook, Inc. + * Copyright (c) Meta Platforms, Inc. and affiliates.   *   * You can contact the author at :   * - Source repository : https://github.com/Cyan4973/FiniteStateEntropy @@ -11,8 +12,6 @@   * in the COPYING file in the root directory of this source tree).   * You may select, at your option, one of the above-listed licenses.  ****************************************************************** */ - -  #ifndef FSE_H  #define FSE_H @@ -22,7 +21,6 @@  ******************************************/  #include "zstd_deps.h"    /* size_t, ptrdiff_t */ -  /*-*****************************************  *  FSE_PUBLIC_API : control library symbols visibility  ******************************************/ @@ -50,34 +48,6 @@  FSE_PUBLIC_API unsigned FSE_versionNumber(void);   /*< library version number; to be used when checking dll version */ -/*-**************************************** -*  FSE simple functions -******************************************/ -/*! FSE_compress() : -    Compress content of buffer 'src', of size 'srcSize', into destination buffer 'dst'. -    'dst' buffer must be already allocated. Compression runs faster is dstCapacity >= FSE_compressBound(srcSize). -    @return : size of compressed data (<= dstCapacity). -    Special values : if return == 0, srcData is not compressible => Nothing is stored within dst !!! -                     if return == 1, srcData is a single byte symbol * srcSize times. Use RLE compression instead. -                     if FSE_isError(return), compression failed (more details using FSE_getErrorName()) -*/ -FSE_PUBLIC_API size_t FSE_compress(void* dst, size_t dstCapacity, -                             const void* src, size_t srcSize); - -/*! FSE_decompress(): -    Decompress FSE data from buffer 'cSrc', of size 'cSrcSize', -    into already allocated destination buffer 'dst', of size 'dstCapacity'. -    @return : size of regenerated data (<= maxDstSize), -              or an error code, which can be tested using FSE_isError() . - -    ** Important ** : FSE_decompress() does not decompress non-compressible nor RLE data !!! -    Why ? : making this distinction requires a header. -    Header management is intentionally delegated to the user layer, which can better manage special cases. -*/ -FSE_PUBLIC_API size_t FSE_decompress(void* dst,  size_t dstCapacity, -                               const void* cSrc, size_t cSrcSize); - -  /*-*****************************************  *  Tool functions  ******************************************/ @@ -89,20 +59,6 @@ FSE_PUBLIC_API const char* FSE_getErrorName(size_t code);   /* provides error co  /*-***************************************** -*  FSE advanced functions -******************************************/ -/*! FSE_compress2() : -    Same as FSE_compress(), but allows the selection of 'maxSymbolValue' and 'tableLog' -    Both parameters can be defined as '0' to mean : use default value -    @return : size of compressed data -    Special values : if return == 0, srcData is not compressible => Nothing is stored within cSrc !!! -                     if return == 1, srcData is a single byte symbol * srcSize times. Use RLE compression. -                     if FSE_isError(return), it's an error code. -*/ -FSE_PUBLIC_API size_t FSE_compress2 (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog); - - -/*-*****************************************  *  FSE detailed API  ******************************************/  /*! @@ -161,8 +117,6 @@ FSE_PUBLIC_API size_t FSE_writeNCount (void* buffer, size_t bufferSize,  /*! Constructor and Destructor of FSE_CTable.      Note that FSE_CTable size depends on 'tableLog' and 'maxSymbolValue' */  typedef unsigned FSE_CTable;   /* don't allocate that. It's only meant to be more restrictive than void* */ -FSE_PUBLIC_API FSE_CTable* FSE_createCTable (unsigned maxSymbolValue, unsigned tableLog); -FSE_PUBLIC_API void        FSE_freeCTable (FSE_CTable* ct);  /*! FSE_buildCTable():      Builds `ct`, which must be already allocated, using FSE_createCTable(). @@ -238,23 +192,7 @@ FSE_PUBLIC_API size_t FSE_readNCount_bmi2(short* normalizedCounter,                             unsigned* maxSymbolValuePtr, unsigned* tableLogPtr,                             const void* rBuffer, size_t rBuffSize, int bmi2); -/*! Constructor and Destructor of FSE_DTable. -    Note that its size depends on 'tableLog' */  typedef unsigned FSE_DTable;   /* don't allocate that. It's just a way to be more restrictive than void* */ -FSE_PUBLIC_API FSE_DTable* FSE_createDTable(unsigned tableLog); -FSE_PUBLIC_API void        FSE_freeDTable(FSE_DTable* dt); - -/*! FSE_buildDTable(): -    Builds 'dt', which must be already allocated, using FSE_createDTable(). -    return : 0, or an errorCode, which can be tested using FSE_isError() */ -FSE_PUBLIC_API size_t FSE_buildDTable (FSE_DTable* dt, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog); - -/*! FSE_decompress_usingDTable(): -    Decompress compressed source `cSrc` of size `cSrcSize` using `dt` -    into `dst` which must be already allocated. -    @return : size of regenerated data (necessarily <= `dstCapacity`), -              or an errorCode, which can be tested using FSE_isError() */ -FSE_PUBLIC_API size_t FSE_decompress_usingDTable(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize, const FSE_DTable* dt);  /*!  Tutorial : @@ -286,13 +224,11 @@ If there is an error, the function will return an error code, which can be teste  #endif  /* FSE_H */ +  #if !defined(FSE_H_FSE_STATIC_LINKING_ONLY)  #define FSE_H_FSE_STATIC_LINKING_ONLY - -/* *** Dependency *** */  #include "bitstream.h" -  /* *****************************************  *  Static allocation  *******************************************/ @@ -317,16 +253,6 @@ If there is an error, the function will return an error code, which can be teste  unsigned FSE_optimalTableLog_internal(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue, unsigned minus);  /*< same as FSE_optimalTableLog(), which used `minus==2` */ -/* FSE_compress_wksp() : - * Same as FSE_compress2(), but using an externally allocated scratch buffer (`workSpace`). - * FSE_COMPRESS_WKSP_SIZE_U32() provides the minimum size required for `workSpace` as a table of FSE_CTable. - */ -#define FSE_COMPRESS_WKSP_SIZE_U32(maxTableLog, maxSymbolValue)   ( FSE_CTABLE_SIZE_U32(maxTableLog, maxSymbolValue) + ((maxTableLog > 12) ? (1 << (maxTableLog - 2)) : 1024) ) -size_t FSE_compress_wksp (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize); - -size_t FSE_buildCTable_raw (FSE_CTable* ct, unsigned nbBits); -/*< build a fake FSE_CTable, designed for a flat distribution, where each symbol uses nbBits */ -  size_t FSE_buildCTable_rle (FSE_CTable* ct, unsigned char symbolValue);  /*< build a fake FSE_CTable, designed to compress always the same symbolValue */ @@ -344,19 +270,11 @@ size_t FSE_buildCTable_wksp(FSE_CTable* ct, const short* normalizedCounter, unsi  FSE_PUBLIC_API size_t FSE_buildDTable_wksp(FSE_DTable* dt, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize);  /*< Same as FSE_buildDTable(), using an externally allocated `workspace` produced with `FSE_BUILD_DTABLE_WKSP_SIZE_U32(maxSymbolValue)` */ -size_t FSE_buildDTable_raw (FSE_DTable* dt, unsigned nbBits); -/*< build a fake FSE_DTable, designed to read a flat distribution where each symbol uses nbBits */ - -size_t FSE_buildDTable_rle (FSE_DTable* dt, unsigned char symbolValue); -/*< build a fake FSE_DTable, designed to always generate the same symbolValue */ - -#define FSE_DECOMPRESS_WKSP_SIZE_U32(maxTableLog, maxSymbolValue) (FSE_DTABLE_SIZE_U32(maxTableLog) + FSE_BUILD_DTABLE_WKSP_SIZE_U32(maxTableLog, maxSymbolValue) + (FSE_MAX_SYMBOL_VALUE + 1) / 2 + 1) +#define FSE_DECOMPRESS_WKSP_SIZE_U32(maxTableLog, maxSymbolValue) (FSE_DTABLE_SIZE_U32(maxTableLog) + 1 + FSE_BUILD_DTABLE_WKSP_SIZE_U32(maxTableLog, maxSymbolValue) + (FSE_MAX_SYMBOL_VALUE + 1) / 2 + 1)  #define FSE_DECOMPRESS_WKSP_SIZE(maxTableLog, maxSymbolValue) (FSE_DECOMPRESS_WKSP_SIZE_U32(maxTableLog, maxSymbolValue) * sizeof(unsigned)) -size_t FSE_decompress_wksp(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize, unsigned maxLog, void* workSpace, size_t wkspSize); -/*< same as FSE_decompress(), using an externally allocated `workSpace` produced with `FSE_DECOMPRESS_WKSP_SIZE_U32(maxLog, maxSymbolValue)` */ -  size_t FSE_decompress_wksp_bmi2(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize, unsigned maxLog, void* workSpace, size_t wkspSize, int bmi2); -/*< Same as FSE_decompress_wksp() but with dynamic BMI2 support. Pass 1 if your CPU supports BMI2 or 0 if it doesn't. */ +/*< same as FSE_decompress(), using an externally allocated `workSpace` produced with `FSE_DECOMPRESS_WKSP_SIZE_U32(maxLog, maxSymbolValue)`. + * Set bmi2 to 1 if your CPU supports BMI2 or 0 if it doesn't */  typedef enum {     FSE_repeat_none,  /*< Cannot use the previous table */ @@ -539,20 +457,20 @@ MEM_STATIC void FSE_encodeSymbol(BIT_CStream_t* bitC, FSE_CState_t* statePtr, un      FSE_symbolCompressionTransform const symbolTT = ((const FSE_symbolCompressionTransform*)(statePtr->symbolTT))[symbol];      const U16* const stateTable = (const U16*)(statePtr->stateTable);      U32 const nbBitsOut  = (U32)((statePtr->value + symbolTT.deltaNbBits) >> 16); -    BIT_addBits(bitC, statePtr->value, nbBitsOut); +    BIT_addBits(bitC, (BitContainerType)statePtr->value, nbBitsOut);      statePtr->value = stateTable[ (statePtr->value >> nbBitsOut) + symbolTT.deltaFindState];  }  MEM_STATIC void FSE_flushCState(BIT_CStream_t* bitC, const FSE_CState_t* statePtr)  { -    BIT_addBits(bitC, statePtr->value, statePtr->stateLog); +    BIT_addBits(bitC, (BitContainerType)statePtr->value, statePtr->stateLog);      BIT_flushBits(bitC);  }  /* FSE_getMaxNbBits() :   * Approximate maximum cost of a symbol, in bits. - * Fractional get rounded up (i.e : a symbol with a normalized frequency of 3 gives the same result as a frequency of 2) + * Fractional get rounded up (i.e. a symbol with a normalized frequency of 3 gives the same result as a frequency of 2)   * note 1 : assume symbolValue is valid (<= maxSymbolValue)   * note 2 : if freq[symbolValue]==0, @return a fake cost of tableLog+1 bits */  MEM_STATIC U32 FSE_getMaxNbBits(const void* symbolTTPtr, U32 symbolValue) @@ -705,7 +623,4 @@ MEM_STATIC unsigned FSE_endOfDState(const FSE_DState_t* DStatePtr)  #define FSE_TABLESTEP(tableSize) (((tableSize)>>1) + ((tableSize)>>3) + 3) -  #endif /* FSE_STATIC_LINKING_ONLY */ - - diff --git a/lib/zstd/common/fse_decompress.c b/lib/zstd/common/fse_decompress.c index 8dcb8ca39767..15081d8dc607 100644 --- a/lib/zstd/common/fse_decompress.c +++ b/lib/zstd/common/fse_decompress.c @@ -1,6 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause  /* ******************************************************************   * FSE : Finite State Entropy decoder - * Copyright (c) Yann Collet, Facebook, Inc. + * Copyright (c) Meta Platforms, Inc. and affiliates.   *   *  You can contact the author at :   *  - FSE source repository : https://github.com/Cyan4973/FiniteStateEntropy @@ -22,8 +23,8 @@  #define FSE_STATIC_LINKING_ONLY  #include "fse.h"  #include "error_private.h" -#define ZSTD_DEPS_NEED_MALLOC -#include "zstd_deps.h" +#include "zstd_deps.h"  /* ZSTD_memcpy */ +#include "bits.h"       /* ZSTD_highbit32 */  /* ************************************************************** @@ -55,19 +56,6 @@  #define FSE_FUNCTION_NAME(X,Y) FSE_CAT(X,Y)  #define FSE_TYPE_NAME(X,Y) FSE_CAT(X,Y) - -/* Function templates */ -FSE_DTable* FSE_createDTable (unsigned tableLog) -{ -    if (tableLog > FSE_TABLELOG_ABSOLUTE_MAX) tableLog = FSE_TABLELOG_ABSOLUTE_MAX; -    return (FSE_DTable*)ZSTD_malloc( FSE_DTABLE_SIZE_U32(tableLog) * sizeof (U32) ); -} - -void FSE_freeDTable (FSE_DTable* dt) -{ -    ZSTD_free(dt); -} -  static size_t FSE_buildDTable_internal(FSE_DTable* dt, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize)  {      void* const tdPtr = dt+1;   /* because *dt is unsigned, 32-bits aligned on 32-bits */ @@ -96,7 +84,7 @@ static size_t FSE_buildDTable_internal(FSE_DTable* dt, const short* normalizedCo                      symbolNext[s] = 1;                  } else {                      if (normalizedCounter[s] >= largeLimit) DTableH.fastMode=0; -                    symbolNext[s] = normalizedCounter[s]; +                    symbolNext[s] = (U16)normalizedCounter[s];          }   }   }          ZSTD_memcpy(dt, &DTableH, sizeof(DTableH));      } @@ -111,8 +99,7 @@ static size_t FSE_buildDTable_internal(FSE_DTable* dt, const short* normalizedCo           * all symbols have counts <= 8. We ensure we have 8 bytes at the end of           * our buffer to handle the over-write.           */ -        { -            U64 const add = 0x0101010101010101ull; +        {   U64 const add = 0x0101010101010101ull;              size_t pos = 0;              U64 sv = 0;              U32 s; @@ -123,14 +110,13 @@ static size_t FSE_buildDTable_internal(FSE_DTable* dt, const short* normalizedCo                  for (i = 8; i < n; i += 8) {                      MEM_write64(spread + pos + i, sv);                  } -                pos += n; -            } -        } +                pos += (size_t)n; +        }   }          /* Now we spread those positions across the table. -         * The benefit of doing it in two stages is that we avoid the the +         * The benefit of doing it in two stages is that we avoid the           * variable size inner loop, which caused lots of branch misses.           * Now we can run through all the positions without any branch misses. -         * We unroll the loop twice, since that is what emperically worked best. +         * We unroll the loop twice, since that is what empirically worked best.           */          {              size_t position = 0; @@ -166,7 +152,7 @@ static size_t FSE_buildDTable_internal(FSE_DTable* dt, const short* normalizedCo          for (u=0; u<tableSize; u++) {              FSE_FUNCTION_TYPE const symbol = (FSE_FUNCTION_TYPE)(tableDecode[u].symbol);              U32 const nextState = symbolNext[symbol]++; -            tableDecode[u].nbBits = (BYTE) (tableLog - BIT_highbit32(nextState) ); +            tableDecode[u].nbBits = (BYTE) (tableLog - ZSTD_highbit32(nextState) );              tableDecode[u].newState = (U16) ( (nextState << tableDecode[u].nbBits) - tableSize);      }   } @@ -184,49 +170,6 @@ size_t FSE_buildDTable_wksp(FSE_DTable* dt, const short* normalizedCounter, unsi  /*-*******************************************************  *  Decompression (Byte symbols)  *********************************************************/ -size_t FSE_buildDTable_rle (FSE_DTable* dt, BYTE symbolValue) -{ -    void* ptr = dt; -    FSE_DTableHeader* const DTableH = (FSE_DTableHeader*)ptr; -    void* dPtr = dt + 1; -    FSE_decode_t* const cell = (FSE_decode_t*)dPtr; - -    DTableH->tableLog = 0; -    DTableH->fastMode = 0; - -    cell->newState = 0; -    cell->symbol = symbolValue; -    cell->nbBits = 0; - -    return 0; -} - - -size_t FSE_buildDTable_raw (FSE_DTable* dt, unsigned nbBits) -{ -    void* ptr = dt; -    FSE_DTableHeader* const DTableH = (FSE_DTableHeader*)ptr; -    void* dPtr = dt + 1; -    FSE_decode_t* const dinfo = (FSE_decode_t*)dPtr; -    const unsigned tableSize = 1 << nbBits; -    const unsigned tableMask = tableSize - 1; -    const unsigned maxSV1 = tableMask+1; -    unsigned s; - -    /* Sanity checks */ -    if (nbBits < 1) return ERROR(GENERIC);         /* min size */ - -    /* Build Decoding Table */ -    DTableH->tableLog = (U16)nbBits; -    DTableH->fastMode = 1; -    for (s=0; s<maxSV1; s++) { -        dinfo[s].newState = 0; -        dinfo[s].symbol = (BYTE)s; -        dinfo[s].nbBits = (BYTE)nbBits; -    } - -    return 0; -}  FORCE_INLINE_TEMPLATE size_t FSE_decompress_usingDTable_generic(            void* dst, size_t maxDstSize, @@ -248,6 +191,8 @@ FORCE_INLINE_TEMPLATE size_t FSE_decompress_usingDTable_generic(      FSE_initDState(&state1, &bitD, dt);      FSE_initDState(&state2, &bitD, dt); +    RETURN_ERROR_IF(BIT_reloadDStream(&bitD)==BIT_DStream_overflow, corruption_detected, ""); +  #define FSE_GETSYMBOL(statePtr) fast ? FSE_decodeSymbolFast(statePtr, &bitD) : FSE_decodeSymbol(statePtr, &bitD)      /* 4 symbols per loop */ @@ -287,32 +232,12 @@ FORCE_INLINE_TEMPLATE size_t FSE_decompress_usingDTable_generic(              break;      }   } -    return op-ostart; -} - - -size_t FSE_decompress_usingDTable(void* dst, size_t originalSize, -                            const void* cSrc, size_t cSrcSize, -                            const FSE_DTable* dt) -{ -    const void* ptr = dt; -    const FSE_DTableHeader* DTableH = (const FSE_DTableHeader*)ptr; -    const U32 fastMode = DTableH->fastMode; - -    /* select fast mode (static) */ -    if (fastMode) return FSE_decompress_usingDTable_generic(dst, originalSize, cSrc, cSrcSize, dt, 1); -    return FSE_decompress_usingDTable_generic(dst, originalSize, cSrc, cSrcSize, dt, 0); -} - - -size_t FSE_decompress_wksp(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize, unsigned maxLog, void* workSpace, size_t wkspSize) -{ -    return FSE_decompress_wksp_bmi2(dst, dstCapacity, cSrc, cSrcSize, maxLog, workSpace, wkspSize, /* bmi2 */ 0); +    assert(op >= ostart); +    return (size_t)(op-ostart);  }  typedef struct {      short ncount[FSE_MAX_SYMBOL_VALUE + 1]; -    FSE_DTable dtable[]; /* Dynamically sized */  } FSE_DecompressWksp; @@ -327,13 +252,18 @@ FORCE_INLINE_TEMPLATE size_t FSE_decompress_wksp_body(      unsigned tableLog;      unsigned maxSymbolValue = FSE_MAX_SYMBOL_VALUE;      FSE_DecompressWksp* const wksp = (FSE_DecompressWksp*)workSpace; +    size_t const dtablePos = sizeof(FSE_DecompressWksp) / sizeof(FSE_DTable); +    FSE_DTable* const dtable = (FSE_DTable*)workSpace + dtablePos; -    DEBUG_STATIC_ASSERT((FSE_MAX_SYMBOL_VALUE + 1) % 2 == 0); +    FSE_STATIC_ASSERT((FSE_MAX_SYMBOL_VALUE + 1) % 2 == 0);      if (wkspSize < sizeof(*wksp)) return ERROR(GENERIC); +    /* correct offset to dtable depends on this property */ +    FSE_STATIC_ASSERT(sizeof(FSE_DecompressWksp) % sizeof(FSE_DTable) == 0); +      /* normal FSE decoding mode */ -    { -        size_t const NCountLength = FSE_readNCount_bmi2(wksp->ncount, &maxSymbolValue, &tableLog, istart, cSrcSize, bmi2); +    {   size_t const NCountLength = +            FSE_readNCount_bmi2(wksp->ncount, &maxSymbolValue, &tableLog, istart, cSrcSize, bmi2);          if (FSE_isError(NCountLength)) return NCountLength;          if (tableLog > maxLog) return ERROR(tableLog_tooLarge);          assert(NCountLength <= cSrcSize); @@ -342,19 +272,20 @@ FORCE_INLINE_TEMPLATE size_t FSE_decompress_wksp_body(      }      if (FSE_DECOMPRESS_WKSP_SIZE(tableLog, maxSymbolValue) > wkspSize) return ERROR(tableLog_tooLarge); -    workSpace = wksp->dtable + FSE_DTABLE_SIZE_U32(tableLog); +    assert(sizeof(*wksp) + FSE_DTABLE_SIZE(tableLog) <= wkspSize); +    workSpace = (BYTE*)workSpace + sizeof(*wksp) + FSE_DTABLE_SIZE(tableLog);      wkspSize -= sizeof(*wksp) + FSE_DTABLE_SIZE(tableLog); -    CHECK_F( FSE_buildDTable_internal(wksp->dtable, wksp->ncount, maxSymbolValue, tableLog, workSpace, wkspSize) ); +    CHECK_F( FSE_buildDTable_internal(dtable, wksp->ncount, maxSymbolValue, tableLog, workSpace, wkspSize) );      { -        const void* ptr = wksp->dtable; +        const void* ptr = dtable;          const FSE_DTableHeader* DTableH = (const FSE_DTableHeader*)ptr;          const U32 fastMode = DTableH->fastMode;          /* select fast mode (static) */ -        if (fastMode) return FSE_decompress_usingDTable_generic(dst, dstCapacity, ip, cSrcSize, wksp->dtable, 1); -        return FSE_decompress_usingDTable_generic(dst, dstCapacity, ip, cSrcSize, wksp->dtable, 0); +        if (fastMode) return FSE_decompress_usingDTable_generic(dst, dstCapacity, ip, cSrcSize, dtable, 1); +        return FSE_decompress_usingDTable_generic(dst, dstCapacity, ip, cSrcSize, dtable, 0);      }  } @@ -382,9 +313,4 @@ size_t FSE_decompress_wksp_bmi2(void* dst, size_t dstCapacity, const void* cSrc,      return FSE_decompress_wksp_body_default(dst, dstCapacity, cSrc, cSrcSize, maxLog, workSpace, wkspSize);  } - -typedef FSE_DTable DTable_max_t[FSE_DTABLE_SIZE_U32(FSE_MAX_TABLELOG)]; - - -  #endif   /* FSE_COMMONDEFS_ONLY */ diff --git a/lib/zstd/common/huf.h b/lib/zstd/common/huf.h index 5042ff870308..49736dcd8f49 100644 --- a/lib/zstd/common/huf.h +++ b/lib/zstd/common/huf.h @@ -1,7 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */  /* ******************************************************************   * huff0 huffman codec,   * part of Finite State Entropy library - * Copyright (c) Yann Collet, Facebook, Inc. + * Copyright (c) Meta Platforms, Inc. and affiliates.   *   * You can contact the author at :   * - Source repository : https://github.com/Cyan4973/FiniteStateEntropy @@ -12,105 +13,26 @@   * You may select, at your option, one of the above-listed licenses.  ****************************************************************** */ -  #ifndef HUF_H_298734234  #define HUF_H_298734234  /* *** Dependencies *** */  #include "zstd_deps.h"    /* size_t */ - - -/* *** library symbols visibility *** */ -/* Note : when linking with -fvisibility=hidden on gcc, or by default on Visual, - *        HUF symbols remain "private" (internal symbols for library only). - *        Set macro FSE_DLL_EXPORT to 1 if you want HUF symbols visible on DLL interface */ -#if defined(FSE_DLL_EXPORT) && (FSE_DLL_EXPORT==1) && defined(__GNUC__) && (__GNUC__ >= 4) -#  define HUF_PUBLIC_API __attribute__ ((visibility ("default"))) -#elif defined(FSE_DLL_EXPORT) && (FSE_DLL_EXPORT==1)   /* Visual expected */ -#  define HUF_PUBLIC_API __declspec(dllexport) -#elif defined(FSE_DLL_IMPORT) && (FSE_DLL_IMPORT==1) -#  define HUF_PUBLIC_API __declspec(dllimport)  /* not required, just to generate faster code (saves a function pointer load from IAT and an indirect jump) */ -#else -#  define HUF_PUBLIC_API -#endif - - -/* ========================== */ -/* ***  simple functions  *** */ -/* ========================== */ - -/* HUF_compress() : - *  Compress content from buffer 'src', of size 'srcSize', into buffer 'dst'. - * 'dst' buffer must be already allocated. - *  Compression runs faster if `dstCapacity` >= HUF_compressBound(srcSize). - * `srcSize` must be <= `HUF_BLOCKSIZE_MAX` == 128 KB. - * @return : size of compressed data (<= `dstCapacity`). - *  Special values : if return == 0, srcData is not compressible => Nothing is stored within dst !!! - *                   if HUF_isError(return), compression failed (more details using HUF_getErrorName()) - */ -HUF_PUBLIC_API size_t HUF_compress(void* dst, size_t dstCapacity, -                             const void* src, size_t srcSize); - -/* HUF_decompress() : - *  Decompress HUF data from buffer 'cSrc', of size 'cSrcSize', - *  into already allocated buffer 'dst', of minimum size 'dstSize'. - * `originalSize` : **must** be the ***exact*** size of original (uncompressed) data. - *  Note : in contrast with FSE, HUF_decompress can regenerate - *         RLE (cSrcSize==1) and uncompressed (cSrcSize==dstSize) data, - *         because it knows size to regenerate (originalSize). - * @return : size of regenerated data (== originalSize), - *           or an error code, which can be tested using HUF_isError() - */ -HUF_PUBLIC_API size_t HUF_decompress(void* dst,  size_t originalSize, -                               const void* cSrc, size_t cSrcSize); - +#include "mem.h"          /* U32 */ +#define FSE_STATIC_LINKING_ONLY +#include "fse.h"  /* ***   Tool functions *** */ -#define HUF_BLOCKSIZE_MAX (128 * 1024)                  /*< maximum input size for a single block compressed with HUF_compress */ -HUF_PUBLIC_API size_t HUF_compressBound(size_t size);   /*< maximum compressed size (worst case) */ +#define HUF_BLOCKSIZE_MAX (128 * 1024)   /*< maximum input size for a single block compressed with HUF_compress */ +size_t HUF_compressBound(size_t size);   /*< maximum compressed size (worst case) */  /* Error Management */ -HUF_PUBLIC_API unsigned    HUF_isError(size_t code);       /*< tells if a return value is an error code */ -HUF_PUBLIC_API const char* HUF_getErrorName(size_t code);  /*< provides error code string (useful for debugging) */ +unsigned    HUF_isError(size_t code);       /*< tells if a return value is an error code */ +const char* HUF_getErrorName(size_t code);  /*< provides error code string (useful for debugging) */ -/* ***   Advanced function   *** */ - -/* HUF_compress2() : - *  Same as HUF_compress(), but offers control over `maxSymbolValue` and `tableLog`. - * `maxSymbolValue` must be <= HUF_SYMBOLVALUE_MAX . - * `tableLog` must be `<= HUF_TABLELOG_MAX` . */ -HUF_PUBLIC_API size_t HUF_compress2 (void* dst, size_t dstCapacity, -                               const void* src, size_t srcSize, -                               unsigned maxSymbolValue, unsigned tableLog); - -/* HUF_compress4X_wksp() : - *  Same as HUF_compress2(), but uses externally allocated `workSpace`. - * `workspace` must be at least as large as HUF_WORKSPACE_SIZE */  #define HUF_WORKSPACE_SIZE ((8 << 10) + 512 /* sorting scratch space */)  #define HUF_WORKSPACE_SIZE_U64 (HUF_WORKSPACE_SIZE / sizeof(U64)) -HUF_PUBLIC_API size_t HUF_compress4X_wksp (void* dst, size_t dstCapacity, -                                     const void* src, size_t srcSize, -                                     unsigned maxSymbolValue, unsigned tableLog, -                                     void* workSpace, size_t wkspSize); - -#endif   /* HUF_H_298734234 */ - -/* ****************************************************************** - *  WARNING !! - *  The following section contains advanced and experimental definitions - *  which shall never be used in the context of a dynamic library, - *  because they are not guaranteed to remain stable in the future. - *  Only consider them in association with static linking. - * *****************************************************************/ -#if !defined(HUF_H_HUF_STATIC_LINKING_ONLY) -#define HUF_H_HUF_STATIC_LINKING_ONLY - -/* *** Dependencies *** */ -#include "mem.h"   /* U32 */ -#define FSE_STATIC_LINKING_ONLY -#include "fse.h" -  /* *** Constants *** */  #define HUF_TABLELOG_MAX      12      /* max runtime value of tableLog (due to static allocation); can be modified up to HUF_TABLELOG_ABSOLUTEMAX */ @@ -151,25 +73,49 @@ typedef U32 HUF_DTable;  /* ****************************************  *  Advanced decompression functions  ******************************************/ -size_t HUF_decompress4X1 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize);   /*< single-symbol decoder */ -#ifndef HUF_FORCE_DECOMPRESS_X1 -size_t HUF_decompress4X2 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize);   /*< double-symbols decoder */ -#endif -size_t HUF_decompress4X_DCtx (HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize);   /*< decodes RLE and uncompressed */ -size_t HUF_decompress4X_hufOnly(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /*< considers RLE and uncompressed as errors */ -size_t HUF_decompress4X_hufOnly_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize); /*< considers RLE and uncompressed as errors */ -size_t HUF_decompress4X1_DCtx(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize);   /*< single-symbol decoder */ -size_t HUF_decompress4X1_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize);   /*< single-symbol decoder */ -#ifndef HUF_FORCE_DECOMPRESS_X1 -size_t HUF_decompress4X2_DCtx(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize);   /*< double-symbols decoder */ -size_t HUF_decompress4X2_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize);   /*< double-symbols decoder */ -#endif +/* + * Huffman flags bitset. + * For all flags, 0 is the default value. + */ +typedef enum { +    /* +     * If compiled with DYNAMIC_BMI2: Set flag only if the CPU supports BMI2 at runtime. +     * Otherwise: Ignored. +     */ +    HUF_flags_bmi2 = (1 << 0), +    /* +     * If set: Test possible table depths to find the one that produces the smallest header + encoded size. +     * If unset: Use heuristic to find the table depth. +     */ +    HUF_flags_optimalDepth = (1 << 1), +    /* +     * If set: If the previous table can encode the input, always reuse the previous table. +     * If unset: If the previous table can encode the input, reuse the previous table if it results in a smaller output. +     */ +    HUF_flags_preferRepeat = (1 << 2), +    /* +     * If set: Sample the input and check if the sample is uncompressible, if it is then don't attempt to compress. +     * If unset: Always histogram the entire input. +     */ +    HUF_flags_suspectUncompressible = (1 << 3), +    /* +     * If set: Don't use assembly implementations +     * If unset: Allow using assembly implementations +     */ +    HUF_flags_disableAsm = (1 << 4), +    /* +     * If set: Don't use the fast decoding loop, always use the fallback decoding loop. +     * If unset: Use the fast decoding loop when possible. +     */ +    HUF_flags_disableFast = (1 << 5) +} HUF_flags_e;  /* ****************************************   *  HUF detailed API   * ****************************************/ +#define HUF_OPTIMAL_DEPTH_THRESHOLD ZSTD_btultra  /*! HUF_compress() does the following:   *  1. count symbol occurrence from source[] into table count[] using FSE_count() (exposed within "fse.h") @@ -182,12 +128,12 @@ size_t HUF_decompress4X2_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize,   *  For example, it's possible to compress several blocks using the same 'CTable',   *  or to save and regenerate 'CTable' using external methods.   */ -unsigned HUF_optimalTableLog(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue); -size_t HUF_buildCTable (HUF_CElt* CTable, const unsigned* count, unsigned maxSymbolValue, unsigned maxNbBits);   /* @return : maxNbBits; CTable and count can overlap. In which case, CTable will overwrite count content */ -size_t HUF_writeCTable (void* dst, size_t maxDstSize, const HUF_CElt* CTable, unsigned maxSymbolValue, unsigned huffLog); +unsigned HUF_minTableLog(unsigned symbolCardinality); +unsigned HUF_cardinality(const unsigned* count, unsigned maxSymbolValue); +unsigned HUF_optimalTableLog(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue, void* workSpace, + size_t wkspSize, HUF_CElt* table, const unsigned* count, int flags); /* table is used as scratch space for building and testing tables, not a return value */  size_t HUF_writeCTable_wksp(void* dst, size_t maxDstSize, const HUF_CElt* CTable, unsigned maxSymbolValue, unsigned huffLog, void* workspace, size_t workspaceSize); -size_t HUF_compress4X_usingCTable(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable); -size_t HUF_compress4X_usingCTable_bmi2(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable, int bmi2); +size_t HUF_compress4X_usingCTable(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable, int flags);  size_t HUF_estimateCompressedSize(const HUF_CElt* CTable, const unsigned* count, unsigned maxSymbolValue);  int HUF_validateCTable(const HUF_CElt* CTable, const unsigned* count, unsigned maxSymbolValue); @@ -196,6 +142,7 @@ typedef enum {     HUF_repeat_check, /*< Can use the previous table but it must be checked. Note : The previous table must have been constructed by HUF_compress{1, 4}X_repeat */     HUF_repeat_valid  /*< Can use the previous table and it is assumed to be valid */   } HUF_repeat; +  /* HUF_compress4X_repeat() :   *  Same as HUF_compress4X_wksp(), but considers using hufTable if *repeat != HUF_repeat_none.   *  If it uses hufTable it does not modify hufTable or repeat. @@ -206,13 +153,13 @@ size_t HUF_compress4X_repeat(void* dst, size_t dstSize,                         const void* src, size_t srcSize,                         unsigned maxSymbolValue, unsigned tableLog,                         void* workSpace, size_t wkspSize,    /*< `workSpace` must be aligned on 4-bytes boundaries, `wkspSize` must be >= HUF_WORKSPACE_SIZE */ -                       HUF_CElt* hufTable, HUF_repeat* repeat, int preferRepeat, int bmi2, unsigned suspectUncompressible); +                       HUF_CElt* hufTable, HUF_repeat* repeat, int flags);  /* HUF_buildCTable_wksp() :   *  Same as HUF_buildCTable(), but using externally allocated scratch buffer.   * `workSpace` must be aligned on 4-bytes boundaries, and its size must be >= HUF_CTABLE_WORKSPACE_SIZE.   */ -#define HUF_CTABLE_WORKSPACE_SIZE_U32 (2*HUF_SYMBOLVALUE_MAX +1 +1) +#define HUF_CTABLE_WORKSPACE_SIZE_U32 ((4 * (HUF_SYMBOLVALUE_MAX + 1)) + 192)  #define HUF_CTABLE_WORKSPACE_SIZE (HUF_CTABLE_WORKSPACE_SIZE_U32 * sizeof(unsigned))  size_t HUF_buildCTable_wksp (HUF_CElt* tree,                         const unsigned* count, U32 maxSymbolValue, U32 maxNbBits, @@ -238,7 +185,7 @@ size_t HUF_readStats_wksp(BYTE* huffWeight, size_t hwSize,                            U32* rankStats, U32* nbSymbolsPtr, U32* tableLogPtr,                            const void* src, size_t srcSize,                            void* workspace, size_t wkspSize, -                          int bmi2); +                          int flags);  /* HUF_readCTable() :   *  Loading a CTable saved with HUF_writeCTable() */ @@ -246,9 +193,22 @@ size_t HUF_readCTable (HUF_CElt* CTable, unsigned* maxSymbolValuePtr, const void  /* HUF_getNbBitsFromCTable() :   *  Read nbBits from CTable symbolTable, for symbol `symbolValue` presumed <= HUF_SYMBOLVALUE_MAX - *  Note 1 : is not inlined, as HUF_CElt definition is private */ + *  Note 1 : If symbolValue > HUF_readCTableHeader(symbolTable).maxSymbolValue, returns 0 + *  Note 2 : is not inlined, as HUF_CElt definition is private + */  U32 HUF_getNbBitsFromCTable(const HUF_CElt* symbolTable, U32 symbolValue); +typedef struct { +    BYTE tableLog; +    BYTE maxSymbolValue; +    BYTE unused[sizeof(size_t) - 2]; +} HUF_CTableHeader; + +/* HUF_readCTableHeader() : + *  @returns The header from the CTable specifying the tableLog and the maxSymbolValue. + */ +HUF_CTableHeader HUF_readCTableHeader(HUF_CElt const* ctable); +  /*   * HUF_decompress() does the following:   * 1. select the decompression algorithm (X1, X2) based on pre-computed heuristics @@ -276,32 +236,12 @@ U32 HUF_selectDecoder (size_t dstSize, size_t cSrcSize);  #define HUF_DECOMPRESS_WORKSPACE_SIZE ((2 << 10) + (1 << 9))  #define HUF_DECOMPRESS_WORKSPACE_SIZE_U32 (HUF_DECOMPRESS_WORKSPACE_SIZE / sizeof(U32)) -#ifndef HUF_FORCE_DECOMPRESS_X2 -size_t HUF_readDTableX1 (HUF_DTable* DTable, const void* src, size_t srcSize); -size_t HUF_readDTableX1_wksp (HUF_DTable* DTable, const void* src, size_t srcSize, void* workSpace, size_t wkspSize); -#endif -#ifndef HUF_FORCE_DECOMPRESS_X1 -size_t HUF_readDTableX2 (HUF_DTable* DTable, const void* src, size_t srcSize); -size_t HUF_readDTableX2_wksp (HUF_DTable* DTable, const void* src, size_t srcSize, void* workSpace, size_t wkspSize); -#endif - -size_t HUF_decompress4X_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable); -#ifndef HUF_FORCE_DECOMPRESS_X2 -size_t HUF_decompress4X1_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable); -#endif -#ifndef HUF_FORCE_DECOMPRESS_X1 -size_t HUF_decompress4X2_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable); -#endif -  /* ====================== */  /* single stream variants */  /* ====================== */ -size_t HUF_compress1X (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog); -size_t HUF_compress1X_wksp (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize);  /*< `workSpace` must be a table of at least HUF_WORKSPACE_SIZE_U64 U64 */ -size_t HUF_compress1X_usingCTable(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable); -size_t HUF_compress1X_usingCTable_bmi2(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable, int bmi2); +size_t HUF_compress1X_usingCTable(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable, int flags);  /* HUF_compress1X_repeat() :   *  Same as HUF_compress1X_wksp(), but considers using hufTable if *repeat != HUF_repeat_none.   *  If it uses hufTable it does not modify hufTable or repeat. @@ -312,47 +252,27 @@ size_t HUF_compress1X_repeat(void* dst, size_t dstSize,                         const void* src, size_t srcSize,                         unsigned maxSymbolValue, unsigned tableLog,                         void* workSpace, size_t wkspSize,   /*< `workSpace` must be aligned on 4-bytes boundaries, `wkspSize` must be >= HUF_WORKSPACE_SIZE */ -                       HUF_CElt* hufTable, HUF_repeat* repeat, int preferRepeat, int bmi2, unsigned suspectUncompressible); - -size_t HUF_decompress1X1 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize);   /* single-symbol decoder */ -#ifndef HUF_FORCE_DECOMPRESS_X1 -size_t HUF_decompress1X2 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize);   /* double-symbol decoder */ -#endif - -size_t HUF_decompress1X_DCtx (HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); -size_t HUF_decompress1X_DCtx_wksp (HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize); -#ifndef HUF_FORCE_DECOMPRESS_X2 -size_t HUF_decompress1X1_DCtx(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize);   /*< single-symbol decoder */ -size_t HUF_decompress1X1_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize);   /*< single-symbol decoder */ -#endif -#ifndef HUF_FORCE_DECOMPRESS_X1 -size_t HUF_decompress1X2_DCtx(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize);   /*< double-symbols decoder */ -size_t HUF_decompress1X2_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize);   /*< double-symbols decoder */ -#endif +                       HUF_CElt* hufTable, HUF_repeat* repeat, int flags); -size_t HUF_decompress1X_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable);   /*< automatic selection of sing or double symbol decoder, based on DTable */ -#ifndef HUF_FORCE_DECOMPRESS_X2 -size_t HUF_decompress1X1_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable); -#endif +size_t HUF_decompress1X_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize, int flags);  #ifndef HUF_FORCE_DECOMPRESS_X1 -size_t HUF_decompress1X2_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable); +size_t HUF_decompress1X2_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize, int flags);   /*< double-symbols decoder */  #endif  /* BMI2 variants.   * If the CPU has BMI2 support, pass bmi2=1, otherwise pass bmi2=0.   */ -size_t HUF_decompress1X_usingDTable_bmi2(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable, int bmi2); +size_t HUF_decompress1X_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable, int flags);  #ifndef HUF_FORCE_DECOMPRESS_X2 -size_t HUF_decompress1X1_DCtx_wksp_bmi2(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize, int bmi2); +size_t HUF_decompress1X1_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize, int flags);  #endif -size_t HUF_decompress4X_usingDTable_bmi2(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable, int bmi2); -size_t HUF_decompress4X_hufOnly_wksp_bmi2(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize, int bmi2); +size_t HUF_decompress4X_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable, int flags); +size_t HUF_decompress4X_hufOnly_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize, int flags);  #ifndef HUF_FORCE_DECOMPRESS_X2 -size_t HUF_readDTableX1_wksp_bmi2(HUF_DTable* DTable, const void* src, size_t srcSize, void* workSpace, size_t wkspSize, int bmi2); +size_t HUF_readDTableX1_wksp(HUF_DTable* DTable, const void* src, size_t srcSize, void* workSpace, size_t wkspSize, int flags);  #endif  #ifndef HUF_FORCE_DECOMPRESS_X1 -size_t HUF_readDTableX2_wksp_bmi2(HUF_DTable* DTable, const void* src, size_t srcSize, void* workSpace, size_t wkspSize, int bmi2); +size_t HUF_readDTableX2_wksp(HUF_DTable* DTable, const void* src, size_t srcSize, void* workSpace, size_t wkspSize, int flags);  #endif -#endif /* HUF_STATIC_LINKING_ONLY */ - +#endif   /* HUF_H_298734234 */ diff --git a/lib/zstd/common/mem.h b/lib/zstd/common/mem.h index c22a2e69bf46..d9bd752fe17b 100644 --- a/lib/zstd/common/mem.h +++ b/lib/zstd/common/mem.h @@ -1,6 +1,6 @@  /* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */  /* - * Copyright (c) Yann Collet, Facebook, Inc. + * Copyright (c) Meta Platforms, Inc. and affiliates.   * All rights reserved.   *   * This source code is licensed under both the BSD-style license (found in the @@ -24,6 +24,7 @@  /*-****************************************  *  Compiler specifics  ******************************************/ +#undef MEM_STATIC /* may be already defined from common/compiler.h */  #define MEM_STATIC static inline  /*-************************************************************** diff --git a/lib/zstd/common/portability_macros.h b/lib/zstd/common/portability_macros.h index 0e3b2c0a527d..e1890b32da88 100644 --- a/lib/zstd/common/portability_macros.h +++ b/lib/zstd/common/portability_macros.h @@ -1,5 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */  /* - * Copyright (c) Facebook, Inc. + * Copyright (c) Meta Platforms, Inc. and affiliates.   * All rights reserved.   *   * This source code is licensed under both the BSD-style license (found in the @@ -12,7 +13,7 @@  #define ZSTD_PORTABILITY_MACROS_H  /* - * This header file contains macro defintions to support portability. + * This header file contains macro definitions to support portability.   * This header is shared between C and ASM code, so it MUST only   * contain macro definitions. It MUST not contain any C code.   * @@ -45,30 +46,35 @@  /* Mark the internal assembly functions as hidden  */  #ifdef __ELF__  # define ZSTD_HIDE_ASM_FUNCTION(func) .hidden func +#elif defined(__APPLE__) +# define ZSTD_HIDE_ASM_FUNCTION(func) .private_extern func  #else  # define ZSTD_HIDE_ASM_FUNCTION(func)  #endif +/* Compile time determination of BMI2 support */ + +  /* Enable runtime BMI2 dispatch based on the CPU.   * Enabled for clang & gcc >=4.8 on x86 when BMI2 isn't enabled by default.   */  #ifndef DYNAMIC_BMI2 -  #if ((defined(__clang__) && __has_attribute(__target__)) \ +#  if ((defined(__clang__) && __has_attribute(__target__)) \        || (defined(__GNUC__) \ -          && (__GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)))) \ -      && (defined(__x86_64__) || defined(_M_X64)) \ +          && (__GNUC__ >= 11))) \ +      && (defined(__i386__) || defined(__x86_64__) || defined(_M_IX86) || defined(_M_X64)) \        && !defined(__BMI2__) -  #  define DYNAMIC_BMI2 1 -  #else -  #  define DYNAMIC_BMI2 0 -  #endif +#    define DYNAMIC_BMI2 1 +#  else +#    define DYNAMIC_BMI2 0 +#  endif  #endif  /* - * Only enable assembly for GNUC comptabile compilers, + * Only enable assembly for GNU C compatible compilers,   * because other platforms may not support GAS assembly syntax.   * - * Only enable assembly for Linux / MacOS, other platforms may + * Only enable assembly for Linux / MacOS / Win32, other platforms may   * work, but they haven't been tested. This could likely be   * extended to BSD systems.   * @@ -90,4 +96,23 @@   */  #define ZSTD_ENABLE_ASM_X86_64_BMI2 0 +/* + * For x86 ELF targets, add .note.gnu.property section for Intel CET in + * assembly sources when CET is enabled. + * + * Additionally, any function that may be called indirectly must begin + * with ZSTD_CET_ENDBRANCH. + */ +#if defined(__ELF__) && (defined(__x86_64__) || defined(__i386__)) \ +    && defined(__has_include) +# if __has_include(<cet.h>) +#  include <cet.h> +#  define ZSTD_CET_ENDBRANCH _CET_ENDBR +# endif +#endif + +#ifndef ZSTD_CET_ENDBRANCH +# define ZSTD_CET_ENDBRANCH +#endif +  #endif /* ZSTD_PORTABILITY_MACROS_H */ diff --git a/lib/zstd/common/zstd_common.c b/lib/zstd/common/zstd_common.c index 3d7e35b309b5..44b95b25344a 100644 --- a/lib/zstd/common/zstd_common.c +++ b/lib/zstd/common/zstd_common.c @@ -1,5 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause  /* - * Copyright (c) Yann Collet, Facebook, Inc. + * Copyright (c) Meta Platforms, Inc. and affiliates.   * All rights reserved.   *   * This source code is licensed under both the BSD-style license (found in the @@ -14,7 +15,6 @@  *  Dependencies  ***************************************/  #define ZSTD_DEPS_NEED_MALLOC -#include "zstd_deps.h"   /* ZSTD_malloc, ZSTD_calloc, ZSTD_free, ZSTD_memset */  #include "error_private.h"  #include "zstd_internal.h" @@ -47,37 +47,3 @@ ZSTD_ErrorCode ZSTD_getErrorCode(size_t code) { return ERR_getErrorCode(code); }  /*! ZSTD_getErrorString() :   *  provides error code string from enum */  const char* ZSTD_getErrorString(ZSTD_ErrorCode code) { return ERR_getErrorString(code); } - - - -/*=************************************************************** -*  Custom allocator -****************************************************************/ -void* ZSTD_customMalloc(size_t size, ZSTD_customMem customMem) -{ -    if (customMem.customAlloc) -        return customMem.customAlloc(customMem.opaque, size); -    return ZSTD_malloc(size); -} - -void* ZSTD_customCalloc(size_t size, ZSTD_customMem customMem) -{ -    if (customMem.customAlloc) { -        /* calloc implemented as malloc+memset; -         * not as efficient as calloc, but next best guess for custom malloc */ -        void* const ptr = customMem.customAlloc(customMem.opaque, size); -        ZSTD_memset(ptr, 0, size); -        return ptr; -    } -    return ZSTD_calloc(1, size); -} - -void ZSTD_customFree(void* ptr, ZSTD_customMem customMem) -{ -    if (ptr!=NULL) { -        if (customMem.customFree) -            customMem.customFree(customMem.opaque, ptr); -        else -            ZSTD_free(ptr); -    } -} diff --git a/lib/zstd/common/zstd_deps.h b/lib/zstd/common/zstd_deps.h index 2c34e8a33a1c..f931f7d0e294 100644 --- a/lib/zstd/common/zstd_deps.h +++ b/lib/zstd/common/zstd_deps.h @@ -1,6 +1,6 @@  /* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */  /* - * Copyright (c) Facebook, Inc. + * Copyright (c) Meta Platforms, Inc. and affiliates.   * All rights reserved.   *   * This source code is licensed under both the BSD-style license (found in the @@ -105,3 +105,17 @@ static uint64_t ZSTD_div64(uint64_t dividend, uint32_t divisor) {  #endif /* ZSTD_DEPS_IO */  #endif /* ZSTD_DEPS_NEED_IO */ + +/* + * Only requested when MSAN is enabled. + * Need: + * intptr_t + */ +#ifdef ZSTD_DEPS_NEED_STDINT +#ifndef ZSTD_DEPS_STDINT +#define ZSTD_DEPS_STDINT + +/* intptr_t already provided by ZSTD_DEPS_COMMON */ + +#endif /* ZSTD_DEPS_STDINT */ +#endif /* ZSTD_DEPS_NEED_STDINT */ diff --git a/lib/zstd/common/zstd_internal.h b/lib/zstd/common/zstd_internal.h index 93305d9b41bb..52a79435caf6 100644 --- a/lib/zstd/common/zstd_internal.h +++ b/lib/zstd/common/zstd_internal.h @@ -1,5 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */  /* - * Copyright (c) Yann Collet, Facebook, Inc. + * Copyright (c) Meta Platforms, Inc. and affiliates.   * All rights reserved.   *   * This source code is licensed under both the BSD-style license (found in the @@ -28,12 +29,10 @@  #include <linux/zstd.h>  #define FSE_STATIC_LINKING_ONLY  #include "fse.h" -#define HUF_STATIC_LINKING_ONLY  #include "huf.h"  #include <linux/xxhash.h>                /* XXH_reset, update, digest */  #define ZSTD_TRACE 0 -  /* ---- static assert (debug) --- */  #define ZSTD_STATIC_ASSERT(c) DEBUG_STATIC_ASSERT(c)  #define ZSTD_isError ERR_isError   /* for inlining */ @@ -83,16 +82,17 @@ typedef enum { bt_raw, bt_rle, bt_compressed, bt_reserved } blockType_e;  #define ZSTD_FRAMECHECKSUMSIZE 4  #define MIN_SEQUENCES_SIZE 1 /* nbSeq==0 */ -#define MIN_CBLOCK_SIZE (1 /*litCSize*/ + 1 /* RLE or RAW */ + MIN_SEQUENCES_SIZE /* nbSeq==0 */)   /* for a non-null block */ +#define MIN_CBLOCK_SIZE (1 /*litCSize*/ + 1 /* RLE or RAW */)   /* for a non-null block */ +#define MIN_LITERALS_FOR_4_STREAMS 6 -#define HufLog 12 -typedef enum { set_basic, set_rle, set_compressed, set_repeat } symbolEncodingType_e; +typedef enum { set_basic, set_rle, set_compressed, set_repeat } SymbolEncodingType_e;  #define LONGNBSEQ 0x7F00  #define MINMATCH 3  #define Litbits  8 +#define LitHufLog 11  #define MaxLit ((1<<Litbits) - 1)  #define MaxML   52  #define MaxLL   35 @@ -103,6 +103,8 @@ typedef enum { set_basic, set_rle, set_compressed, set_repeat } symbolEncodingTy  #define LLFSELog    9  #define OffFSELog   8  #define MaxFSELog  MAX(MAX(MLFSELog, LLFSELog), OffFSELog) +#define MaxMLBits 16 +#define MaxLLBits 16  #define ZSTD_MAX_HUF_HEADER_SIZE 128 /* header + <= 127 byte tree description */  /* Each table cannot take more than #symbols * FSELog bits */ @@ -166,7 +168,7 @@ static void ZSTD_copy8(void* dst, const void* src) {      ZSTD_memcpy(dst, src, 8);  #endif  } -#define COPY8(d,s) { ZSTD_copy8(d,s); d+=8; s+=8; } +#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 @@ -186,7 +188,7 @@ static void ZSTD_copy16(void* dst, const void* src) {      ZSTD_memcpy(dst, copy16_buf, 16);  #endif  } -#define COPY16(d,s) { ZSTD_copy16(d,s); d+=16; s+=16; } +#define COPY16(d,s) do { ZSTD_copy16(d,s); d+=16; s+=16; } while (0)  #define WILDCOPY_OVERLENGTH 32  #define WILDCOPY_VECLEN 16 @@ -215,7 +217,7 @@ void ZSTD_wildcopy(void* dst, const void* src, ptrdiff_t length, ZSTD_overlap_e      if (ovtype == ZSTD_overlap_src_before_dst && diff < WILDCOPY_VECLEN) {          /* Handle short offset copies. */          do { -            COPY8(op, ip) +            COPY8(op, ip);          } while (op < oend);      } else {          assert(diff >= WILDCOPY_VECLEN || diff <= -WILDCOPY_VECLEN); @@ -225,12 +227,6 @@ void ZSTD_wildcopy(void* dst, const void* src, ptrdiff_t length, ZSTD_overlap_e           * 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.           */ -#ifdef __aarch64__ -        do { -            COPY16(op, ip); -        } -        while (op < oend); -#else          ZSTD_copy16(op, ip);          if (16 >= length) return;          op += 16; @@ -240,7 +236,6 @@ void ZSTD_wildcopy(void* dst, const void* src, ptrdiff_t length, ZSTD_overlap_e              COPY16(op, ip);          }          while (op < oend); -#endif      }  } @@ -273,62 +268,6 @@ typedef enum {  /*-*******************************************  *  Private declarations  *********************************************/ -typedef struct seqDef_s { -    U32 offBase;   /* offBase == Offset + ZSTD_REP_NUM, or repcode 1,2,3 */ -    U16 litLength; -    U16 mlBase;    /* mlBase == matchLength - MINMATCH */ -} seqDef; - -/* Controls whether seqStore has a single "long" litLength or matchLength. See seqStore_t. */ -typedef enum { -    ZSTD_llt_none = 0,             /* no longLengthType */ -    ZSTD_llt_literalLength = 1,    /* represents a long literal */ -    ZSTD_llt_matchLength = 2       /* represents a long match */ -} ZSTD_longLengthType_e; - -typedef struct { -    seqDef* sequencesStart; -    seqDef* sequences;      /* ptr to end of sequences */ -    BYTE* litStart; -    BYTE* lit;              /* ptr to end of literals */ -    BYTE* llCode; -    BYTE* mlCode; -    BYTE* ofCode; -    size_t maxNbSeq; -    size_t maxNbLit; - -    /* longLengthPos and longLengthType to allow us to represent either a single litLength or matchLength -     * in the seqStore that has a value larger than U16 (if it exists). To do so, we increment -     * the existing value of the litLength or matchLength by 0x10000. -     */ -    ZSTD_longLengthType_e   longLengthType; -    U32                     longLengthPos;  /* Index of the sequence to apply long length modification to */ -} seqStore_t; - -typedef struct { -    U32 litLength; -    U32 matchLength; -} ZSTD_sequenceLength; - -/* - * Returns the ZSTD_sequenceLength for the given sequences. It handles the decoding of long sequences - * indicated by longLengthPos and longLengthType, and adds MINMATCH back to matchLength. - */ -MEM_STATIC ZSTD_sequenceLength ZSTD_getSequenceLength(seqStore_t const* seqStore, seqDef const* seq) -{ -    ZSTD_sequenceLength seqLen; -    seqLen.litLength = seq->litLength; -    seqLen.matchLength = seq->mlBase + MINMATCH; -    if (seqStore->longLengthPos == (U32)(seq - seqStore->sequencesStart)) { -        if (seqStore->longLengthType == ZSTD_llt_literalLength) { -            seqLen.litLength += 0xFFFF; -        } -        if (seqStore->longLengthType == ZSTD_llt_matchLength) { -            seqLen.matchLength += 0xFFFF; -        } -    } -    return seqLen; -}  /*   * Contains the compressed frame size and an upper-bound for the decompressed frame size. @@ -337,74 +276,11 @@ MEM_STATIC ZSTD_sequenceLength ZSTD_getSequenceLength(seqStore_t const* seqStore   *          `decompressedBound != ZSTD_CONTENTSIZE_ERROR`   */  typedef struct { +    size_t nbBlocks;      size_t compressedSize;      unsigned long long decompressedBound;  } ZSTD_frameSizeInfo;   /* decompress & legacy */ -const seqStore_t* ZSTD_getSeqStore(const ZSTD_CCtx* ctx);   /* compress & dictBuilder */ -void ZSTD_seqToCodes(const seqStore_t* seqStorePtr);   /* compress, dictBuilder, decodeCorpus (shouldn't get its definition from here) */ - -/* custom memory allocation functions */ -void* ZSTD_customMalloc(size_t size, ZSTD_customMem customMem); -void* ZSTD_customCalloc(size_t size, ZSTD_customMem customMem); -void ZSTD_customFree(void* ptr, ZSTD_customMem customMem); - - -MEM_STATIC U32 ZSTD_highbit32(U32 val)   /* compress, dictBuilder, decodeCorpus */ -{ -    assert(val != 0); -    { -#   if (__GNUC__ >= 3)   /* GCC Intrinsic */ -        return __builtin_clz (val) ^ 31; -#   else   /* Software version */ -        static 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 }; -        U32 v = val; -        v |= v >> 1; -        v |= v >> 2; -        v |= v >> 4; -        v |= v >> 8; -        v |= v >> 16; -        return DeBruijnClz[(v * 0x07C4ACDDU) >> 27]; -#   endif -    } -} - -/* - * Counts the number of trailing zeros of a `size_t`. - * Most compilers should support CTZ as a builtin. A backup - * implementation is provided if the builtin isn't supported, but - * it may not be terribly efficient. - */ -MEM_STATIC unsigned ZSTD_countTrailingZeros(size_t val) -{ -    if (MEM_64bits()) { -#       if (__GNUC__ >= 4) -            return __builtin_ctzll((U64)val); -#       else -            static const int DeBruijnBytePos[64] = {  0,  1,  2,  7,  3, 13,  8, 19, -                                                      4, 25, 14, 28,  9, 34, 20, 56, -                                                      5, 17, 26, 54, 15, 41, 29, 43, -                                                      10, 31, 38, 35, 21, 45, 49, 57, -                                                      63,  6, 12, 18, 24, 27, 33, 55, -                                                      16, 53, 40, 42, 30, 37, 44, 48, -                                                      62, 11, 23, 32, 52, 39, 36, 47, -                                                      61, 22, 51, 46, 60, 50, 59, 58 }; -            return DeBruijnBytePos[((U64)((val & -(long long)val) * 0x0218A392CDABBD3FULL)) >> 58]; -#       endif -    } else { /* 32 bits */ -#       if (__GNUC__ >= 3) -            return __builtin_ctz((U32)val); -#       else -            static const int DeBruijnBytePos[32] = {  0,  1, 28,  2, 29, 14, 24,  3, -                                                     30, 22, 20, 15, 25, 17,  4,  8, -                                                     31, 27, 13, 23, 21, 19, 16,  7, -                                                     26, 12, 18,  6, 11,  5, 10,  9 }; -            return DeBruijnBytePos[((U32)((val & -(S32)val) * 0x077CB531U)) >> 27]; -#       endif -    } -} - -  /* ZSTD_invalidateRepCodes() :   * ensures next compression will not use repcodes from previous block.   * Note : only works with regular variant; @@ -420,13 +296,13 @@ typedef struct {  /*! ZSTD_getcBlockSize() :   *  Provides the size of compressed block from block header `src` */ -/* Used by: decompress, fullbench (does not get its definition from here) */ +/*  Used by: decompress, fullbench */  size_t ZSTD_getcBlockSize(const void* src, size_t srcSize,                            blockProperties_t* bpPtr);  /*! ZSTD_decodeSeqHeaders() :   *  decode sequence header from src */ -/* Used by: decompress, fullbench (does not get its definition from here) */ +/*  Used by: zstd_decompress_block, fullbench */  size_t ZSTD_decodeSeqHeaders(ZSTD_DCtx* dctx, int* nbSeqPtr,                         const void* src, size_t srcSize); @@ -439,5 +315,4 @@ MEM_STATIC int ZSTD_cpuSupportsBmi2(void)      return ZSTD_cpuid_bmi1(cpuid) && ZSTD_cpuid_bmi2(cpuid);  } -  #endif   /* ZSTD_CCOMMON_H_MODULE */ | 
