zstd-ruby 1.5.5.1 → 1.5.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/ext/zstdruby/libzstd/common/allocations.h +1 -1
- data/ext/zstdruby/libzstd/common/bitstream.h +49 -29
- data/ext/zstdruby/libzstd/common/compiler.h +114 -22
- data/ext/zstdruby/libzstd/common/cpu.h +36 -0
- data/ext/zstdruby/libzstd/common/debug.c +6 -0
- data/ext/zstdruby/libzstd/common/debug.h +20 -11
- data/ext/zstdruby/libzstd/common/error_private.h +45 -36
- data/ext/zstdruby/libzstd/common/fse.h +3 -2
- data/ext/zstdruby/libzstd/common/fse_decompress.c +19 -17
- data/ext/zstdruby/libzstd/common/huf.h +14 -1
- data/ext/zstdruby/libzstd/common/mem.h +0 -9
- data/ext/zstdruby/libzstd/common/pool.c +1 -1
- data/ext/zstdruby/libzstd/common/pool.h +1 -1
- data/ext/zstdruby/libzstd/common/portability_macros.h +2 -0
- data/ext/zstdruby/libzstd/common/threading.c +8 -2
- data/ext/zstdruby/libzstd/common/xxhash.c +5 -11
- data/ext/zstdruby/libzstd/common/xxhash.h +2341 -1007
- data/ext/zstdruby/libzstd/common/zstd_internal.h +5 -5
- data/ext/zstdruby/libzstd/compress/fse_compress.c +8 -7
- data/ext/zstdruby/libzstd/compress/huf_compress.c +54 -25
- data/ext/zstdruby/libzstd/compress/zstd_compress.c +282 -161
- data/ext/zstdruby/libzstd/compress/zstd_compress_internal.h +29 -27
- data/ext/zstdruby/libzstd/compress/zstd_compress_superblock.c +224 -113
- data/ext/zstdruby/libzstd/compress/zstd_cwksp.h +19 -13
- data/ext/zstdruby/libzstd/compress/zstd_double_fast.c +17 -5
- data/ext/zstdruby/libzstd/compress/zstd_double_fast.h +11 -0
- data/ext/zstdruby/libzstd/compress/zstd_fast.c +14 -6
- data/ext/zstdruby/libzstd/compress/zstd_lazy.c +129 -87
- data/ext/zstdruby/libzstd/compress/zstd_lazy.h +103 -28
- data/ext/zstdruby/libzstd/compress/zstd_ldm.c +8 -2
- data/ext/zstdruby/libzstd/compress/zstd_opt.c +216 -112
- data/ext/zstdruby/libzstd/compress/zstd_opt.h +31 -7
- data/ext/zstdruby/libzstd/compress/zstdmt_compress.c +94 -79
- data/ext/zstdruby/libzstd/decompress/huf_decompress.c +188 -126
- data/ext/zstdruby/libzstd/decompress/huf_decompress_amd64.S +38 -19
- data/ext/zstdruby/libzstd/decompress/zstd_decompress.c +84 -32
- data/ext/zstdruby/libzstd/decompress/zstd_decompress_block.c +231 -208
- data/ext/zstdruby/libzstd/decompress/zstd_decompress_block.h +1 -1
- data/ext/zstdruby/libzstd/decompress/zstd_decompress_internal.h +2 -0
- data/ext/zstdruby/libzstd/dictBuilder/cover.c +16 -12
- data/ext/zstdruby/libzstd/dictBuilder/cover.h +2 -8
- data/ext/zstdruby/libzstd/dictBuilder/fastcover.c +2 -2
- data/ext/zstdruby/libzstd/dictBuilder/zdict.c +12 -6
- data/ext/zstdruby/libzstd/zstd.h +129 -60
- data/lib/zstd-ruby/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3f071ec996e63976c8391a34fe8b3b66e2551b3ad6cac027e81bffe9c65ee3f7
|
4
|
+
data.tar.gz: 1e71eb86fc8378c8d1e9932717fa1a79d2ba5e40de9f0defdc331b6d3de280a0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4ef3fdf69acc7a09bddc9bade06555f16fab4a77a2849411007fcb38ded652c02eb12f3470f9231cefc5537bd486235772662777e6aec45b0f8e3b6d7da3d911
|
7
|
+
data.tar.gz: 1e79f3d09cd17cf76795a0ea76c64eb279c34fda421e74b10db2f02eff0bde1cbc8c8396fc276acb549422201257b9b18f3199c7fd245b5ee0fd818a3045fc03
|
data/README.md
CHANGED
@@ -14,7 +14,7 @@
|
|
14
14
|
#define ZSTD_DEPS_NEED_MALLOC
|
15
15
|
#include "zstd_deps.h" /* ZSTD_malloc, ZSTD_calloc, ZSTD_free, ZSTD_memset */
|
16
16
|
|
17
|
-
#include "
|
17
|
+
#include "compiler.h" /* MEM_STATIC */
|
18
18
|
#define ZSTD_STATIC_LINKING_ONLY
|
19
19
|
#include "../zstd.h" /* ZSTD_customMem */
|
20
20
|
|
@@ -90,19 +90,20 @@ MEM_STATIC size_t BIT_closeCStream(BIT_CStream_t* bitC);
|
|
90
90
|
/*-********************************************
|
91
91
|
* bitStream decoding API (read backward)
|
92
92
|
**********************************************/
|
93
|
+
typedef size_t BitContainerType;
|
93
94
|
typedef struct {
|
94
|
-
|
95
|
+
BitContainerType bitContainer;
|
95
96
|
unsigned bitsConsumed;
|
96
97
|
const char* ptr;
|
97
98
|
const char* start;
|
98
99
|
const char* limitPtr;
|
99
100
|
} BIT_DStream_t;
|
100
101
|
|
101
|
-
typedef enum { BIT_DStream_unfinished = 0,
|
102
|
-
BIT_DStream_endOfBuffer = 1,
|
103
|
-
BIT_DStream_completed = 2,
|
104
|
-
BIT_DStream_overflow = 3
|
105
|
-
|
102
|
+
typedef enum { BIT_DStream_unfinished = 0, /* fully refilled */
|
103
|
+
BIT_DStream_endOfBuffer = 1, /* still some bits left in bitstream */
|
104
|
+
BIT_DStream_completed = 2, /* bitstream entirely consumed, bit-exact */
|
105
|
+
BIT_DStream_overflow = 3 /* user requested more bits than present in bitstream */
|
106
|
+
} BIT_DStream_status; /* result of BIT_reloadDStream() */
|
106
107
|
|
107
108
|
MEM_STATIC size_t BIT_initDStream(BIT_DStream_t* bitD, const void* srcBuffer, size_t srcSize);
|
108
109
|
MEM_STATIC size_t BIT_readBits(BIT_DStream_t* bitD, unsigned nbBits);
|
@@ -112,7 +113,7 @@ MEM_STATIC unsigned BIT_endOfDStream(const BIT_DStream_t* bitD);
|
|
112
113
|
|
113
114
|
/* Start by invoking BIT_initDStream().
|
114
115
|
* A chunk of the bitStream is then stored into a local register.
|
115
|
-
* Local register size is 64-bits on 64-bits systems, 32-bits on 32-bits systems (
|
116
|
+
* Local register size is 64-bits on 64-bits systems, 32-bits on 32-bits systems (BitContainerType).
|
116
117
|
* You can then retrieve bitFields stored into the local register, **in reverse order**.
|
117
118
|
* Local register is explicitly reloaded from memory by the BIT_reloadDStream() method.
|
118
119
|
* A reload guarantee a minimum of ((8*sizeof(bitD->bitContainer))-7) bits when its result is BIT_DStream_unfinished.
|
@@ -162,7 +163,7 @@ MEM_STATIC size_t BIT_initCStream(BIT_CStream_t* bitC,
|
|
162
163
|
return 0;
|
163
164
|
}
|
164
165
|
|
165
|
-
|
166
|
+
FORCE_INLINE_TEMPLATE size_t BIT_getLowerBits(size_t bitContainer, U32 const nbBits)
|
166
167
|
{
|
167
168
|
#if defined(STATIC_BMI2) && STATIC_BMI2 == 1 && !defined(ZSTD_NO_INTRINSICS)
|
168
169
|
return _bzhi_u64(bitContainer, nbBits);
|
@@ -267,22 +268,22 @@ MEM_STATIC size_t BIT_initDStream(BIT_DStream_t* bitD, const void* srcBuffer, si
|
|
267
268
|
bitD->bitContainer = *(const BYTE*)(bitD->start);
|
268
269
|
switch(srcSize)
|
269
270
|
{
|
270
|
-
case 7: bitD->bitContainer += (
|
271
|
+
case 7: bitD->bitContainer += (BitContainerType)(((const BYTE*)(srcBuffer))[6]) << (sizeof(bitD->bitContainer)*8 - 16);
|
271
272
|
ZSTD_FALLTHROUGH;
|
272
273
|
|
273
|
-
case 6: bitD->bitContainer += (
|
274
|
+
case 6: bitD->bitContainer += (BitContainerType)(((const BYTE*)(srcBuffer))[5]) << (sizeof(bitD->bitContainer)*8 - 24);
|
274
275
|
ZSTD_FALLTHROUGH;
|
275
276
|
|
276
|
-
case 5: bitD->bitContainer += (
|
277
|
+
case 5: bitD->bitContainer += (BitContainerType)(((const BYTE*)(srcBuffer))[4]) << (sizeof(bitD->bitContainer)*8 - 32);
|
277
278
|
ZSTD_FALLTHROUGH;
|
278
279
|
|
279
|
-
case 4: bitD->bitContainer += (
|
280
|
+
case 4: bitD->bitContainer += (BitContainerType)(((const BYTE*)(srcBuffer))[3]) << 24;
|
280
281
|
ZSTD_FALLTHROUGH;
|
281
282
|
|
282
|
-
case 3: bitD->bitContainer += (
|
283
|
+
case 3: bitD->bitContainer += (BitContainerType)(((const BYTE*)(srcBuffer))[2]) << 16;
|
283
284
|
ZSTD_FALLTHROUGH;
|
284
285
|
|
285
|
-
case 2: bitD->bitContainer += (
|
286
|
+
case 2: bitD->bitContainer += (BitContainerType)(((const BYTE*)(srcBuffer))[1]) << 8;
|
286
287
|
ZSTD_FALLTHROUGH;
|
287
288
|
|
288
289
|
default: break;
|
@@ -297,12 +298,12 @@ MEM_STATIC size_t BIT_initDStream(BIT_DStream_t* bitD, const void* srcBuffer, si
|
|
297
298
|
return srcSize;
|
298
299
|
}
|
299
300
|
|
300
|
-
|
301
|
+
FORCE_INLINE_TEMPLATE size_t BIT_getUpperBits(BitContainerType bitContainer, U32 const start)
|
301
302
|
{
|
302
303
|
return bitContainer >> start;
|
303
304
|
}
|
304
305
|
|
305
|
-
|
306
|
+
FORCE_INLINE_TEMPLATE size_t BIT_getMiddleBits(BitContainerType bitContainer, U32 const start, U32 const nbBits)
|
306
307
|
{
|
307
308
|
U32 const regMask = sizeof(bitContainer)*8 - 1;
|
308
309
|
/* if start > regMask, bitstream is corrupted, and result is undefined */
|
@@ -325,7 +326,7 @@ MEM_STATIC FORCE_INLINE_ATTR size_t BIT_getMiddleBits(size_t bitContainer, U32 c
|
|
325
326
|
* On 32-bits, maxNbBits==24.
|
326
327
|
* On 64-bits, maxNbBits==56.
|
327
328
|
* @return : value extracted */
|
328
|
-
|
329
|
+
FORCE_INLINE_TEMPLATE size_t BIT_lookBits(const BIT_DStream_t* bitD, U32 nbBits)
|
329
330
|
{
|
330
331
|
/* arbitrate between double-shift and shift+mask */
|
331
332
|
#if 1
|
@@ -348,7 +349,7 @@ MEM_STATIC size_t BIT_lookBitsFast(const BIT_DStream_t* bitD, U32 nbBits)
|
|
348
349
|
return (bitD->bitContainer << (bitD->bitsConsumed & regMask)) >> (((regMask+1)-nbBits) & regMask);
|
349
350
|
}
|
350
351
|
|
351
|
-
|
352
|
+
FORCE_INLINE_TEMPLATE void BIT_skipBits(BIT_DStream_t* bitD, U32 nbBits)
|
352
353
|
{
|
353
354
|
bitD->bitsConsumed += nbBits;
|
354
355
|
}
|
@@ -357,7 +358,7 @@ MEM_STATIC FORCE_INLINE_ATTR void BIT_skipBits(BIT_DStream_t* bitD, U32 nbBits)
|
|
357
358
|
* Read (consume) next n bits from local register and update.
|
358
359
|
* Pay attention to not read more than nbBits contained into local register.
|
359
360
|
* @return : extracted value. */
|
360
|
-
|
361
|
+
FORCE_INLINE_TEMPLATE size_t BIT_readBits(BIT_DStream_t* bitD, unsigned nbBits)
|
361
362
|
{
|
362
363
|
size_t const value = BIT_lookBits(bitD, nbBits);
|
363
364
|
BIT_skipBits(bitD, nbBits);
|
@@ -374,6 +375,21 @@ MEM_STATIC size_t BIT_readBitsFast(BIT_DStream_t* bitD, unsigned nbBits)
|
|
374
375
|
return value;
|
375
376
|
}
|
376
377
|
|
378
|
+
/*! BIT_reloadDStream_internal() :
|
379
|
+
* Simple variant of BIT_reloadDStream(), with two conditions:
|
380
|
+
* 1. bitstream is valid : bitsConsumed <= sizeof(bitD->bitContainer)*8
|
381
|
+
* 2. look window is valid after shifted down : bitD->ptr >= bitD->start
|
382
|
+
*/
|
383
|
+
MEM_STATIC BIT_DStream_status BIT_reloadDStream_internal(BIT_DStream_t* bitD)
|
384
|
+
{
|
385
|
+
assert(bitD->bitsConsumed <= sizeof(bitD->bitContainer)*8);
|
386
|
+
bitD->ptr -= bitD->bitsConsumed >> 3;
|
387
|
+
assert(bitD->ptr >= bitD->start);
|
388
|
+
bitD->bitsConsumed &= 7;
|
389
|
+
bitD->bitContainer = MEM_readLEST(bitD->ptr);
|
390
|
+
return BIT_DStream_unfinished;
|
391
|
+
}
|
392
|
+
|
377
393
|
/*! BIT_reloadDStreamFast() :
|
378
394
|
* Similar to BIT_reloadDStream(), but with two differences:
|
379
395
|
* 1. bitsConsumed <= sizeof(bitD->bitContainer)*8 must hold!
|
@@ -384,31 +400,35 @@ MEM_STATIC BIT_DStream_status BIT_reloadDStreamFast(BIT_DStream_t* bitD)
|
|
384
400
|
{
|
385
401
|
if (UNLIKELY(bitD->ptr < bitD->limitPtr))
|
386
402
|
return BIT_DStream_overflow;
|
387
|
-
|
388
|
-
bitD->ptr -= bitD->bitsConsumed >> 3;
|
389
|
-
bitD->bitsConsumed &= 7;
|
390
|
-
bitD->bitContainer = MEM_readLEST(bitD->ptr);
|
391
|
-
return BIT_DStream_unfinished;
|
403
|
+
return BIT_reloadDStream_internal(bitD);
|
392
404
|
}
|
393
405
|
|
394
406
|
/*! BIT_reloadDStream() :
|
395
407
|
* Refill `bitD` from buffer previously set in BIT_initDStream() .
|
396
|
-
* This function is safe, it guarantees it will not
|
408
|
+
* This function is safe, it guarantees it will not never beyond src buffer.
|
397
409
|
* @return : status of `BIT_DStream_t` internal register.
|
398
410
|
* when status == BIT_DStream_unfinished, internal register is filled with at least 25 or 57 bits */
|
399
|
-
|
411
|
+
FORCE_INLINE_TEMPLATE BIT_DStream_status BIT_reloadDStream(BIT_DStream_t* bitD)
|
400
412
|
{
|
401
|
-
|
413
|
+
/* note : once in overflow mode, a bitstream remains in this mode until it's reset */
|
414
|
+
if (UNLIKELY(bitD->bitsConsumed > (sizeof(bitD->bitContainer)*8))) {
|
415
|
+
static const BitContainerType zeroFilled = 0;
|
416
|
+
bitD->ptr = (const char*)&zeroFilled; /* aliasing is allowed for char */
|
417
|
+
/* overflow detected, erroneous scenario or end of stream: no update */
|
402
418
|
return BIT_DStream_overflow;
|
419
|
+
}
|
420
|
+
|
421
|
+
assert(bitD->ptr >= bitD->start);
|
403
422
|
|
404
423
|
if (bitD->ptr >= bitD->limitPtr) {
|
405
|
-
return
|
424
|
+
return BIT_reloadDStream_internal(bitD);
|
406
425
|
}
|
407
426
|
if (bitD->ptr == bitD->start) {
|
427
|
+
/* reached end of bitStream => no update */
|
408
428
|
if (bitD->bitsConsumed < sizeof(bitD->bitContainer)*8) return BIT_DStream_endOfBuffer;
|
409
429
|
return BIT_DStream_completed;
|
410
430
|
}
|
411
|
-
/* start < ptr < limitPtr */
|
431
|
+
/* start < ptr < limitPtr => cautious update */
|
412
432
|
{ U32 nbBytes = bitD->bitsConsumed >> 3;
|
413
433
|
BIT_DStream_status result = BIT_DStream_unfinished;
|
414
434
|
if (bitD->ptr - nbBytes < bitD->start) {
|
@@ -11,6 +11,8 @@
|
|
11
11
|
#ifndef ZSTD_COMPILER_H
|
12
12
|
#define ZSTD_COMPILER_H
|
13
13
|
|
14
|
+
#include <stddef.h>
|
15
|
+
|
14
16
|
#include "portability_macros.h"
|
15
17
|
|
16
18
|
/*-*******************************************************
|
@@ -51,12 +53,19 @@
|
|
51
53
|
# define WIN_CDECL
|
52
54
|
#endif
|
53
55
|
|
56
|
+
/* UNUSED_ATTR tells the compiler it is okay if the function is unused. */
|
57
|
+
#if defined(__GNUC__)
|
58
|
+
# define UNUSED_ATTR __attribute__((unused))
|
59
|
+
#else
|
60
|
+
# define UNUSED_ATTR
|
61
|
+
#endif
|
62
|
+
|
54
63
|
/**
|
55
64
|
* FORCE_INLINE_TEMPLATE is used to define C "templates", which take constant
|
56
65
|
* parameters. They must be inlined for the compiler to eliminate the constant
|
57
66
|
* branches.
|
58
67
|
*/
|
59
|
-
#define FORCE_INLINE_TEMPLATE static INLINE_KEYWORD FORCE_INLINE_ATTR
|
68
|
+
#define FORCE_INLINE_TEMPLATE static INLINE_KEYWORD FORCE_INLINE_ATTR UNUSED_ATTR
|
60
69
|
/**
|
61
70
|
* HINT_INLINE is used to help the compiler generate better code. It is *not*
|
62
71
|
* used for "templates", so it can be tweaked based on the compilers
|
@@ -71,14 +80,28 @@
|
|
71
80
|
#if !defined(__clang__) && defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 8 && __GNUC__ < 5
|
72
81
|
# define HINT_INLINE static INLINE_KEYWORD
|
73
82
|
#else
|
74
|
-
# define HINT_INLINE
|
83
|
+
# define HINT_INLINE FORCE_INLINE_TEMPLATE
|
75
84
|
#endif
|
76
85
|
|
77
|
-
/*
|
86
|
+
/* "soft" inline :
|
87
|
+
* The compiler is free to select if it's a good idea to inline or not.
|
88
|
+
* The main objective is to silence compiler warnings
|
89
|
+
* when a defined function in included but not used.
|
90
|
+
*
|
91
|
+
* Note : this macro is prefixed `MEM_` because it used to be provided by `mem.h` unit.
|
92
|
+
* Updating the prefix is probably preferable, but requires a fairly large codemod,
|
93
|
+
* since this name is used everywhere.
|
94
|
+
*/
|
95
|
+
#ifndef MEM_STATIC /* already defined in Linux Kernel mem.h */
|
78
96
|
#if defined(__GNUC__)
|
79
|
-
# define UNUSED_ATTR
|
97
|
+
# define MEM_STATIC static __inline UNUSED_ATTR
|
98
|
+
#elif defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */)
|
99
|
+
# define MEM_STATIC static inline
|
100
|
+
#elif defined(_MSC_VER)
|
101
|
+
# define MEM_STATIC static __inline
|
80
102
|
#else
|
81
|
-
# define
|
103
|
+
# define MEM_STATIC static /* this version may generate warnings for unused static functions; disable the relevant warning */
|
104
|
+
#endif
|
82
105
|
#endif
|
83
106
|
|
84
107
|
/* force no inlining */
|
@@ -109,10 +132,10 @@
|
|
109
132
|
/* prefetch
|
110
133
|
* can be disabled, by declaring NO_PREFETCH build macro */
|
111
134
|
#if defined(NO_PREFETCH)
|
112
|
-
# define PREFETCH_L1(ptr) (void)(ptr) /* disabled */
|
113
|
-
# define PREFETCH_L2(ptr) (void)(ptr) /* disabled */
|
135
|
+
# define PREFETCH_L1(ptr) do { (void)(ptr); } while (0) /* disabled */
|
136
|
+
# define PREFETCH_L2(ptr) do { (void)(ptr); } while (0) /* disabled */
|
114
137
|
#else
|
115
|
-
# if defined(_MSC_VER) && (defined(_M_X64) || defined(_M_I86)) /* _mm_prefetch() is not defined outside of x86/x64 */
|
138
|
+
# if defined(_MSC_VER) && (defined(_M_X64) || defined(_M_I86)) && !defined(_M_ARM64EC) /* _mm_prefetch() is not defined outside of x86/x64 */
|
116
139
|
# include <mmintrin.h> /* https://msdn.microsoft.com/fr-fr/library/84szxsww(v=vs.90).aspx */
|
117
140
|
# define PREFETCH_L1(ptr) _mm_prefetch((const char*)(ptr), _MM_HINT_T0)
|
118
141
|
# define PREFETCH_L2(ptr) _mm_prefetch((const char*)(ptr), _MM_HINT_T1)
|
@@ -120,24 +143,25 @@
|
|
120
143
|
# define PREFETCH_L1(ptr) __builtin_prefetch((ptr), 0 /* rw==read */, 3 /* locality */)
|
121
144
|
# define PREFETCH_L2(ptr) __builtin_prefetch((ptr), 0 /* rw==read */, 2 /* locality */)
|
122
145
|
# elif defined(__aarch64__)
|
123
|
-
# define PREFETCH_L1(ptr) __asm__ __volatile__("prfm pldl1keep, %0" ::"Q"(*(ptr)))
|
124
|
-
# define PREFETCH_L2(ptr) __asm__ __volatile__("prfm pldl2keep, %0" ::"Q"(*(ptr)))
|
146
|
+
# define PREFETCH_L1(ptr) do { __asm__ __volatile__("prfm pldl1keep, %0" ::"Q"(*(ptr))); } while (0)
|
147
|
+
# define PREFETCH_L2(ptr) do { __asm__ __volatile__("prfm pldl2keep, %0" ::"Q"(*(ptr))); } while (0)
|
125
148
|
# else
|
126
|
-
# define PREFETCH_L1(ptr) (void)(ptr) /* disabled */
|
127
|
-
# define PREFETCH_L2(ptr) (void)(ptr) /* disabled */
|
149
|
+
# define PREFETCH_L1(ptr) do { (void)(ptr); } while (0) /* disabled */
|
150
|
+
# define PREFETCH_L2(ptr) do { (void)(ptr); } while (0) /* disabled */
|
128
151
|
# endif
|
129
152
|
#endif /* NO_PREFETCH */
|
130
153
|
|
131
154
|
#define CACHELINE_SIZE 64
|
132
155
|
|
133
|
-
#define PREFETCH_AREA(p, s)
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
}
|
156
|
+
#define PREFETCH_AREA(p, s) \
|
157
|
+
do { \
|
158
|
+
const char* const _ptr = (const char*)(p); \
|
159
|
+
size_t const _size = (size_t)(s); \
|
160
|
+
size_t _pos; \
|
161
|
+
for (_pos=0; _pos<_size; _pos+=CACHELINE_SIZE) { \
|
162
|
+
PREFETCH_L2(_ptr + _pos); \
|
163
|
+
} \
|
164
|
+
} while (0)
|
141
165
|
|
142
166
|
/* vectorization
|
143
167
|
* older GCC (pre gcc-4.3 picked as the cutoff) uses a different syntax,
|
@@ -166,9 +190,9 @@
|
|
166
190
|
#endif
|
167
191
|
|
168
192
|
#if __has_builtin(__builtin_unreachable) || (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)))
|
169
|
-
# define ZSTD_UNREACHABLE { assert(0), __builtin_unreachable(); }
|
193
|
+
# define ZSTD_UNREACHABLE do { assert(0), __builtin_unreachable(); } while (0)
|
170
194
|
#else
|
171
|
-
# define ZSTD_UNREACHABLE { assert(0); }
|
195
|
+
# define ZSTD_UNREACHABLE do { assert(0); } while (0)
|
172
196
|
#endif
|
173
197
|
|
174
198
|
/* disable warnings */
|
@@ -281,6 +305,74 @@
|
|
281
305
|
* Sanitizer
|
282
306
|
*****************************************************************/
|
283
307
|
|
308
|
+
/**
|
309
|
+
* Zstd relies on pointer overflow in its decompressor.
|
310
|
+
* We add this attribute to functions that rely on pointer overflow.
|
311
|
+
*/
|
312
|
+
#ifndef ZSTD_ALLOW_POINTER_OVERFLOW_ATTR
|
313
|
+
# if __has_attribute(no_sanitize)
|
314
|
+
# if !defined(__clang__) && defined(__GNUC__) && __GNUC__ < 8
|
315
|
+
/* gcc < 8 only has signed-integer-overlow which triggers on pointer overflow */
|
316
|
+
# define ZSTD_ALLOW_POINTER_OVERFLOW_ATTR __attribute__((no_sanitize("signed-integer-overflow")))
|
317
|
+
# else
|
318
|
+
/* older versions of clang [3.7, 5.0) will warn that pointer-overflow is ignored. */
|
319
|
+
# define ZSTD_ALLOW_POINTER_OVERFLOW_ATTR __attribute__((no_sanitize("pointer-overflow")))
|
320
|
+
# endif
|
321
|
+
# else
|
322
|
+
# define ZSTD_ALLOW_POINTER_OVERFLOW_ATTR
|
323
|
+
# endif
|
324
|
+
#endif
|
325
|
+
|
326
|
+
/**
|
327
|
+
* Helper function to perform a wrapped pointer difference without trigging
|
328
|
+
* UBSAN.
|
329
|
+
*
|
330
|
+
* @returns lhs - rhs with wrapping
|
331
|
+
*/
|
332
|
+
MEM_STATIC
|
333
|
+
ZSTD_ALLOW_POINTER_OVERFLOW_ATTR
|
334
|
+
ptrdiff_t ZSTD_wrappedPtrDiff(unsigned char const* lhs, unsigned char const* rhs)
|
335
|
+
{
|
336
|
+
return lhs - rhs;
|
337
|
+
}
|
338
|
+
|
339
|
+
/**
|
340
|
+
* Helper function to perform a wrapped pointer add without triggering UBSAN.
|
341
|
+
*
|
342
|
+
* @return ptr + add with wrapping
|
343
|
+
*/
|
344
|
+
MEM_STATIC
|
345
|
+
ZSTD_ALLOW_POINTER_OVERFLOW_ATTR
|
346
|
+
unsigned char const* ZSTD_wrappedPtrAdd(unsigned char const* ptr, ptrdiff_t add)
|
347
|
+
{
|
348
|
+
return ptr + add;
|
349
|
+
}
|
350
|
+
|
351
|
+
/**
|
352
|
+
* Helper function to perform a wrapped pointer subtraction without triggering
|
353
|
+
* UBSAN.
|
354
|
+
*
|
355
|
+
* @return ptr - sub with wrapping
|
356
|
+
*/
|
357
|
+
MEM_STATIC
|
358
|
+
ZSTD_ALLOW_POINTER_OVERFLOW_ATTR
|
359
|
+
unsigned char const* ZSTD_wrappedPtrSub(unsigned char const* ptr, ptrdiff_t sub)
|
360
|
+
{
|
361
|
+
return ptr - sub;
|
362
|
+
}
|
363
|
+
|
364
|
+
/**
|
365
|
+
* Helper function to add to a pointer that works around C's undefined behavior
|
366
|
+
* of adding 0 to NULL.
|
367
|
+
*
|
368
|
+
* @returns `ptr + add` except it defines `NULL + 0 == NULL`.
|
369
|
+
*/
|
370
|
+
MEM_STATIC
|
371
|
+
unsigned char* ZSTD_maybeNullPtrAdd(unsigned char* ptr, ptrdiff_t add)
|
372
|
+
{
|
373
|
+
return add > 0 ? ptr + add : ptr;
|
374
|
+
}
|
375
|
+
|
284
376
|
/* Issue #3240 reports an ASAN failure on an llvm-mingw build. Out of an
|
285
377
|
* abundance of caution, disable our custom poisoning on mingw. */
|
286
378
|
#ifdef __MINGW32__
|
@@ -35,6 +35,7 @@ MEM_STATIC ZSTD_cpuid_t ZSTD_cpuid(void) {
|
|
35
35
|
U32 f7b = 0;
|
36
36
|
U32 f7c = 0;
|
37
37
|
#if defined(_MSC_VER) && (defined(_M_X64) || defined(_M_IX86))
|
38
|
+
#if !defined(__clang__)
|
38
39
|
int reg[4];
|
39
40
|
__cpuid((int*)reg, 0);
|
40
41
|
{
|
@@ -50,6 +51,41 @@ MEM_STATIC ZSTD_cpuid_t ZSTD_cpuid(void) {
|
|
50
51
|
f7c = (U32)reg[2];
|
51
52
|
}
|
52
53
|
}
|
54
|
+
#else
|
55
|
+
/* Clang compiler has a bug (fixed in https://reviews.llvm.org/D101338) in
|
56
|
+
* which the `__cpuid` intrinsic does not save and restore `rbx` as it needs
|
57
|
+
* to due to being a reserved register. So in that case, do the `cpuid`
|
58
|
+
* ourselves. Clang supports inline assembly anyway.
|
59
|
+
*/
|
60
|
+
U32 n;
|
61
|
+
__asm__(
|
62
|
+
"pushq %%rbx\n\t"
|
63
|
+
"cpuid\n\t"
|
64
|
+
"popq %%rbx\n\t"
|
65
|
+
: "=a"(n)
|
66
|
+
: "a"(0)
|
67
|
+
: "rcx", "rdx");
|
68
|
+
if (n >= 1) {
|
69
|
+
U32 f1a;
|
70
|
+
__asm__(
|
71
|
+
"pushq %%rbx\n\t"
|
72
|
+
"cpuid\n\t"
|
73
|
+
"popq %%rbx\n\t"
|
74
|
+
: "=a"(f1a), "=c"(f1c), "=d"(f1d)
|
75
|
+
: "a"(1)
|
76
|
+
:);
|
77
|
+
}
|
78
|
+
if (n >= 7) {
|
79
|
+
__asm__(
|
80
|
+
"pushq %%rbx\n\t"
|
81
|
+
"cpuid\n\t"
|
82
|
+
"movq %%rbx, %%rax\n\t"
|
83
|
+
"popq %%rbx"
|
84
|
+
: "=a"(f7b), "=c"(f7c)
|
85
|
+
: "a"(7), "c"(0)
|
86
|
+
: "rdx");
|
87
|
+
}
|
88
|
+
#endif
|
53
89
|
#elif defined(__i386__) && defined(__PIC__) && !defined(__clang__) && defined(__GNUC__)
|
54
90
|
/* The following block like the normal cpuid branch below, but gcc
|
55
91
|
* reserves ebx for use of its pic register so we must specially
|
@@ -21,4 +21,10 @@
|
|
21
21
|
|
22
22
|
#include "debug.h"
|
23
23
|
|
24
|
+
#if !defined(ZSTD_LINUX_KERNEL) || (DEBUGLEVEL>=2)
|
25
|
+
/* We only use this when DEBUGLEVEL>=2, but we get -Werror=pedantic errors if a
|
26
|
+
* translation unit is empty. So remove this from Linux kernel builds, but
|
27
|
+
* otherwise just leave it in.
|
28
|
+
*/
|
24
29
|
int g_debuglevel = DEBUGLEVEL;
|
30
|
+
#endif
|
@@ -85,18 +85,27 @@ extern int g_debuglevel; /* the variable is only declared,
|
|
85
85
|
It's useful when enabling very verbose levels
|
86
86
|
on selective conditions (such as position in src) */
|
87
87
|
|
88
|
-
# define RAWLOG(l, ...)
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
88
|
+
# define RAWLOG(l, ...) \
|
89
|
+
do { \
|
90
|
+
if (l<=g_debuglevel) { \
|
91
|
+
ZSTD_DEBUG_PRINT(__VA_ARGS__); \
|
92
|
+
} \
|
93
|
+
} while (0)
|
94
|
+
|
95
|
+
#define STRINGIFY(x) #x
|
96
|
+
#define TOSTRING(x) STRINGIFY(x)
|
97
|
+
#define LINE_AS_STRING TOSTRING(__LINE__)
|
98
|
+
|
99
|
+
# define DEBUGLOG(l, ...) \
|
100
|
+
do { \
|
101
|
+
if (l<=g_debuglevel) { \
|
102
|
+
ZSTD_DEBUG_PRINT(__FILE__ ":" LINE_AS_STRING ": " __VA_ARGS__); \
|
103
|
+
ZSTD_DEBUG_PRINT(" \n"); \
|
104
|
+
} \
|
105
|
+
} while (0)
|
97
106
|
#else
|
98
|
-
# define RAWLOG(l, ...)
|
99
|
-
# define DEBUGLOG(l, ...)
|
107
|
+
# define RAWLOG(l, ...) do { } while (0) /* disabled */
|
108
|
+
# define DEBUGLOG(l, ...) do { } while (0) /* disabled */
|
100
109
|
#endif
|
101
110
|
|
102
111
|
|
@@ -60,8 +60,13 @@ ERR_STATIC unsigned ERR_isError(size_t code) { return (code > ERROR(maxCode)); }
|
|
60
60
|
ERR_STATIC ERR_enum ERR_getErrorCode(size_t code) { if (!ERR_isError(code)) return (ERR_enum)0; return (ERR_enum) (0-code); }
|
61
61
|
|
62
62
|
/* check and forward error code */
|
63
|
-
#define CHECK_V_F(e, f)
|
64
|
-
|
63
|
+
#define CHECK_V_F(e, f) \
|
64
|
+
size_t const e = f; \
|
65
|
+
do { \
|
66
|
+
if (ERR_isError(e)) \
|
67
|
+
return e; \
|
68
|
+
} while (0)
|
69
|
+
#define CHECK_F(f) do { CHECK_V_F(_var_err__, f); } while (0)
|
65
70
|
|
66
71
|
|
67
72
|
/*-****************************************
|
@@ -95,10 +100,12 @@ void _force_has_format_string(const char *format, ...) {
|
|
95
100
|
* We want to force this function invocation to be syntactically correct, but
|
96
101
|
* we don't want to force runtime evaluation of its arguments.
|
97
102
|
*/
|
98
|
-
#define _FORCE_HAS_FORMAT_STRING(...)
|
99
|
-
|
100
|
-
|
101
|
-
|
103
|
+
#define _FORCE_HAS_FORMAT_STRING(...) \
|
104
|
+
do { \
|
105
|
+
if (0) { \
|
106
|
+
_force_has_format_string(__VA_ARGS__); \
|
107
|
+
} \
|
108
|
+
} while (0)
|
102
109
|
|
103
110
|
#define ERR_QUOTE(str) #str
|
104
111
|
|
@@ -109,48 +116,50 @@ void _force_has_format_string(const char *format, ...) {
|
|
109
116
|
* In order to do that (particularly, printing the conditional that failed),
|
110
117
|
* this can't just wrap RETURN_ERROR().
|
111
118
|
*/
|
112
|
-
#define RETURN_ERROR_IF(cond, err, ...)
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
119
|
+
#define RETURN_ERROR_IF(cond, err, ...) \
|
120
|
+
do { \
|
121
|
+
if (cond) { \
|
122
|
+
RAWLOG(3, "%s:%d: ERROR!: check %s failed, returning %s", \
|
123
|
+
__FILE__, __LINE__, ERR_QUOTE(cond), ERR_QUOTE(ERROR(err))); \
|
124
|
+
_FORCE_HAS_FORMAT_STRING(__VA_ARGS__); \
|
125
|
+
RAWLOG(3, ": " __VA_ARGS__); \
|
126
|
+
RAWLOG(3, "\n"); \
|
127
|
+
return ERROR(err); \
|
128
|
+
} \
|
129
|
+
} while (0)
|
121
130
|
|
122
131
|
/**
|
123
132
|
* Unconditionally return the specified error.
|
124
133
|
*
|
125
134
|
* In debug modes, prints additional information.
|
126
135
|
*/
|
127
|
-
#define RETURN_ERROR(err, ...)
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
+
#define RETURN_ERROR(err, ...) \
|
137
|
+
do { \
|
138
|
+
RAWLOG(3, "%s:%d: ERROR!: unconditional check failed, returning %s", \
|
139
|
+
__FILE__, __LINE__, ERR_QUOTE(ERROR(err))); \
|
140
|
+
_FORCE_HAS_FORMAT_STRING(__VA_ARGS__); \
|
141
|
+
RAWLOG(3, ": " __VA_ARGS__); \
|
142
|
+
RAWLOG(3, "\n"); \
|
143
|
+
return ERROR(err); \
|
144
|
+
} while(0)
|
136
145
|
|
137
146
|
/**
|
138
147
|
* If the provided expression evaluates to an error code, returns that error code.
|
139
148
|
*
|
140
149
|
* In debug modes, prints additional information.
|
141
150
|
*/
|
142
|
-
#define FORWARD_IF_ERROR(err, ...)
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
151
|
+
#define FORWARD_IF_ERROR(err, ...) \
|
152
|
+
do { \
|
153
|
+
size_t const err_code = (err); \
|
154
|
+
if (ERR_isError(err_code)) { \
|
155
|
+
RAWLOG(3, "%s:%d: ERROR!: forwarding error in %s: %s", \
|
156
|
+
__FILE__, __LINE__, ERR_QUOTE(err), ERR_getErrorName(err_code)); \
|
157
|
+
_FORCE_HAS_FORMAT_STRING(__VA_ARGS__); \
|
158
|
+
RAWLOG(3, ": " __VA_ARGS__); \
|
159
|
+
RAWLOG(3, "\n"); \
|
160
|
+
return err_code; \
|
161
|
+
} \
|
162
|
+
} while(0)
|
154
163
|
|
155
164
|
#if defined (__cplusplus)
|
156
165
|
}
|
@@ -229,6 +229,7 @@ If there is an error, the function will return an error code, which can be teste
|
|
229
229
|
|
230
230
|
#endif /* FSE_H */
|
231
231
|
|
232
|
+
|
232
233
|
#if defined(FSE_STATIC_LINKING_ONLY) && !defined(FSE_H_FSE_STATIC_LINKING_ONLY)
|
233
234
|
#define FSE_H_FSE_STATIC_LINKING_ONLY
|
234
235
|
|
@@ -464,13 +465,13 @@ MEM_STATIC void FSE_encodeSymbol(BIT_CStream_t* bitC, FSE_CState_t* statePtr, un
|
|
464
465
|
FSE_symbolCompressionTransform const symbolTT = ((const FSE_symbolCompressionTransform*)(statePtr->symbolTT))[symbol];
|
465
466
|
const U16* const stateTable = (const U16*)(statePtr->stateTable);
|
466
467
|
U32 const nbBitsOut = (U32)((statePtr->value + symbolTT.deltaNbBits) >> 16);
|
467
|
-
BIT_addBits(bitC,
|
468
|
+
BIT_addBits(bitC, (size_t)statePtr->value, nbBitsOut);
|
468
469
|
statePtr->value = stateTable[ (statePtr->value >> nbBitsOut) + symbolTT.deltaFindState];
|
469
470
|
}
|
470
471
|
|
471
472
|
MEM_STATIC void FSE_flushCState(BIT_CStream_t* bitC, const FSE_CState_t* statePtr)
|
472
473
|
{
|
473
|
-
BIT_addBits(bitC, statePtr->value, statePtr->stateLog);
|
474
|
+
BIT_addBits(bitC, (size_t)statePtr->value, statePtr->stateLog);
|
474
475
|
BIT_flushBits(bitC);
|
475
476
|
}
|
476
477
|
|