extzstd 0.3.2 → 0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +4 -3
- data/contrib/zstd/CHANGELOG +225 -1
- data/contrib/zstd/CONTRIBUTING.md +158 -75
- data/contrib/zstd/LICENSE +4 -4
- data/contrib/zstd/Makefile +106 -69
- data/contrib/zstd/Package.swift +36 -0
- data/contrib/zstd/README.md +64 -36
- data/contrib/zstd/SECURITY.md +15 -0
- data/contrib/zstd/TESTING.md +2 -3
- data/contrib/zstd/lib/BUCK +5 -7
- data/contrib/zstd/lib/Makefile +117 -199
- data/contrib/zstd/lib/README.md +37 -7
- data/contrib/zstd/lib/common/allocations.h +55 -0
- data/contrib/zstd/lib/common/bits.h +200 -0
- data/contrib/zstd/lib/common/bitstream.h +80 -86
- data/contrib/zstd/lib/common/compiler.h +225 -63
- data/contrib/zstd/lib/common/cpu.h +37 -1
- data/contrib/zstd/lib/common/debug.c +7 -1
- data/contrib/zstd/lib/common/debug.h +21 -12
- data/contrib/zstd/lib/common/entropy_common.c +15 -37
- data/contrib/zstd/lib/common/error_private.c +9 -2
- data/contrib/zstd/lib/common/error_private.h +93 -5
- data/contrib/zstd/lib/common/fse.h +12 -87
- data/contrib/zstd/lib/common/fse_decompress.c +37 -117
- data/contrib/zstd/lib/common/huf.h +97 -172
- data/contrib/zstd/lib/common/mem.h +58 -58
- data/contrib/zstd/lib/common/pool.c +38 -17
- data/contrib/zstd/lib/common/pool.h +10 -4
- data/contrib/zstd/lib/common/portability_macros.h +158 -0
- data/contrib/zstd/lib/common/threading.c +74 -14
- data/contrib/zstd/lib/common/threading.h +5 -10
- data/contrib/zstd/lib/common/xxhash.c +6 -814
- data/contrib/zstd/lib/common/xxhash.h +6930 -195
- data/contrib/zstd/lib/common/zstd_common.c +1 -36
- data/contrib/zstd/lib/common/zstd_deps.h +1 -1
- data/contrib/zstd/lib/common/zstd_internal.h +68 -154
- data/contrib/zstd/lib/common/zstd_trace.h +163 -0
- data/contrib/zstd/lib/compress/clevels.h +134 -0
- data/contrib/zstd/lib/compress/fse_compress.c +75 -155
- data/contrib/zstd/lib/compress/hist.c +1 -1
- data/contrib/zstd/lib/compress/hist.h +1 -1
- data/contrib/zstd/lib/compress/huf_compress.c +810 -259
- data/contrib/zstd/lib/compress/zstd_compress.c +2864 -919
- data/contrib/zstd/lib/compress/zstd_compress_internal.h +523 -192
- data/contrib/zstd/lib/compress/zstd_compress_literals.c +117 -40
- data/contrib/zstd/lib/compress/zstd_compress_literals.h +16 -6
- data/contrib/zstd/lib/compress/zstd_compress_sequences.c +28 -19
- data/contrib/zstd/lib/compress/zstd_compress_sequences.h +1 -1
- data/contrib/zstd/lib/compress/zstd_compress_superblock.c +251 -412
- data/contrib/zstd/lib/compress/zstd_compress_superblock.h +1 -1
- data/contrib/zstd/lib/compress/zstd_cwksp.h +284 -97
- data/contrib/zstd/lib/compress/zstd_double_fast.c +382 -133
- data/contrib/zstd/lib/compress/zstd_double_fast.h +14 -2
- data/contrib/zstd/lib/compress/zstd_fast.c +732 -260
- data/contrib/zstd/lib/compress/zstd_fast.h +3 -2
- data/contrib/zstd/lib/compress/zstd_lazy.c +1177 -390
- data/contrib/zstd/lib/compress/zstd_lazy.h +129 -14
- data/contrib/zstd/lib/compress/zstd_ldm.c +280 -210
- data/contrib/zstd/lib/compress/zstd_ldm.h +3 -2
- data/contrib/zstd/lib/compress/zstd_ldm_geartab.h +106 -0
- data/contrib/zstd/lib/compress/zstd_opt.c +516 -285
- data/contrib/zstd/lib/compress/zstd_opt.h +32 -8
- data/contrib/zstd/lib/compress/zstdmt_compress.c +202 -131
- data/contrib/zstd/lib/compress/zstdmt_compress.h +9 -6
- data/contrib/zstd/lib/decompress/huf_decompress.c +1149 -555
- data/contrib/zstd/lib/decompress/huf_decompress_amd64.S +595 -0
- data/contrib/zstd/lib/decompress/zstd_ddict.c +4 -4
- data/contrib/zstd/lib/decompress/zstd_ddict.h +1 -1
- data/contrib/zstd/lib/decompress/zstd_decompress.c +583 -106
- data/contrib/zstd/lib/decompress/zstd_decompress_block.c +1054 -379
- data/contrib/zstd/lib/decompress/zstd_decompress_block.h +14 -3
- data/contrib/zstd/lib/decompress/zstd_decompress_internal.h +56 -6
- data/contrib/zstd/lib/deprecated/zbuff.h +1 -1
- data/contrib/zstd/lib/deprecated/zbuff_common.c +1 -1
- data/contrib/zstd/lib/deprecated/zbuff_compress.c +24 -4
- data/contrib/zstd/lib/deprecated/zbuff_decompress.c +3 -1
- data/contrib/zstd/lib/dictBuilder/cover.c +60 -44
- data/contrib/zstd/lib/dictBuilder/cover.h +6 -11
- data/contrib/zstd/lib/dictBuilder/divsufsort.c +1 -1
- data/contrib/zstd/lib/dictBuilder/fastcover.c +26 -18
- data/contrib/zstd/lib/dictBuilder/zdict.c +100 -101
- data/contrib/zstd/lib/legacy/zstd_legacy.h +38 -1
- data/contrib/zstd/lib/legacy/zstd_v01.c +18 -53
- data/contrib/zstd/lib/legacy/zstd_v01.h +1 -1
- data/contrib/zstd/lib/legacy/zstd_v02.c +28 -85
- data/contrib/zstd/lib/legacy/zstd_v02.h +1 -1
- data/contrib/zstd/lib/legacy/zstd_v03.c +29 -88
- data/contrib/zstd/lib/legacy/zstd_v03.h +1 -1
- data/contrib/zstd/lib/legacy/zstd_v04.c +27 -80
- data/contrib/zstd/lib/legacy/zstd_v04.h +1 -1
- data/contrib/zstd/lib/legacy/zstd_v05.c +36 -85
- data/contrib/zstd/lib/legacy/zstd_v05.h +1 -1
- data/contrib/zstd/lib/legacy/zstd_v06.c +44 -96
- data/contrib/zstd/lib/legacy/zstd_v06.h +1 -1
- data/contrib/zstd/lib/legacy/zstd_v07.c +37 -92
- data/contrib/zstd/lib/legacy/zstd_v07.h +1 -1
- data/contrib/zstd/lib/libzstd.mk +237 -0
- data/contrib/zstd/lib/libzstd.pc.in +4 -3
- data/contrib/zstd/lib/module.modulemap +35 -0
- data/contrib/zstd/lib/{dictBuilder/zdict.h → zdict.h} +202 -33
- data/contrib/zstd/lib/zstd.h +1030 -332
- data/contrib/zstd/lib/{common/zstd_errors.h → zstd_errors.h} +27 -8
- data/ext/extconf.rb +26 -7
- data/ext/extzstd.c +51 -24
- data/ext/extzstd.h +33 -6
- data/ext/extzstd_stream.c +74 -31
- data/ext/libzstd_conf.h +0 -1
- data/ext/zstd_decompress_asm.S +1 -0
- metadata +17 -7
- data/contrib/zstd/appveyor.yml +0 -292
- data/ext/depend +0 -2
@@ -1,5 +1,5 @@
|
|
1
1
|
/*
|
2
|
-
* Copyright (c)
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
3
3
|
* All rights reserved.
|
4
4
|
*
|
5
5
|
* This source code is licensed under both the BSD-style license (found in the
|
@@ -11,6 +11,10 @@
|
|
11
11
|
#ifndef ZSTD_COMPILER_H
|
12
12
|
#define ZSTD_COMPILER_H
|
13
13
|
|
14
|
+
#include <stddef.h>
|
15
|
+
|
16
|
+
#include "portability_macros.h"
|
17
|
+
|
14
18
|
/*-*******************************************************
|
15
19
|
* Compiler specifics
|
16
20
|
*********************************************************/
|
@@ -40,7 +44,7 @@
|
|
40
44
|
|
41
45
|
/**
|
42
46
|
On MSVC qsort requires that functions passed into it use the __cdecl calling conversion(CC).
|
43
|
-
This
|
47
|
+
This explicitly marks such functions as __cdecl so that the code will still compile
|
44
48
|
if a CC other than __cdecl has been made the default.
|
45
49
|
*/
|
46
50
|
#if defined(_MSC_VER)
|
@@ -49,12 +53,19 @@
|
|
49
53
|
# define WIN_CDECL
|
50
54
|
#endif
|
51
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
|
+
|
52
63
|
/**
|
53
64
|
* FORCE_INLINE_TEMPLATE is used to define C "templates", which take constant
|
54
65
|
* parameters. They must be inlined for the compiler to eliminate the constant
|
55
66
|
* branches.
|
56
67
|
*/
|
57
|
-
#define FORCE_INLINE_TEMPLATE static INLINE_KEYWORD FORCE_INLINE_ATTR
|
68
|
+
#define FORCE_INLINE_TEMPLATE static INLINE_KEYWORD FORCE_INLINE_ATTR UNUSED_ATTR
|
58
69
|
/**
|
59
70
|
* HINT_INLINE is used to help the compiler generate better code. It is *not*
|
60
71
|
* used for "templates", so it can be tweaked based on the compilers
|
@@ -69,14 +80,28 @@
|
|
69
80
|
#if !defined(__clang__) && defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 8 && __GNUC__ < 5
|
70
81
|
# define HINT_INLINE static INLINE_KEYWORD
|
71
82
|
#else
|
72
|
-
# define HINT_INLINE
|
83
|
+
# define HINT_INLINE FORCE_INLINE_TEMPLATE
|
73
84
|
#endif
|
74
85
|
|
75
|
-
/*
|
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 */
|
76
96
|
#if defined(__GNUC__)
|
77
|
-
# 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
|
78
102
|
#else
|
79
|
-
# define
|
103
|
+
# define MEM_STATIC static /* this version may generate warnings for unused static functions; disable the relevant warning */
|
104
|
+
#endif
|
80
105
|
#endif
|
81
106
|
|
82
107
|
/* force no inlining */
|
@@ -90,38 +115,27 @@
|
|
90
115
|
# endif
|
91
116
|
#endif
|
92
117
|
|
118
|
+
|
93
119
|
/* target attribute */
|
94
|
-
#ifndef __has_attribute
|
95
|
-
#define __has_attribute(x) 0 /* Compatibility with non-clang compilers. */
|
96
|
-
#endif
|
97
120
|
#if defined(__GNUC__) || defined(__ICCARM__)
|
98
121
|
# define TARGET_ATTRIBUTE(target) __attribute__((__target__(target)))
|
99
122
|
#else
|
100
123
|
# define TARGET_ATTRIBUTE(target)
|
101
124
|
#endif
|
102
125
|
|
103
|
-
/*
|
104
|
-
*
|
126
|
+
/* Target attribute for BMI2 dynamic dispatch.
|
127
|
+
* Enable lzcnt, bmi, and bmi2.
|
128
|
+
* We test for bmi1 & bmi2. lzcnt is included in bmi1.
|
105
129
|
*/
|
106
|
-
#
|
107
|
-
#if ((defined(__clang__) && __has_attribute(__target__)) \
|
108
|
-
|| (defined(__GNUC__) \
|
109
|
-
&& (__GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)))) \
|
110
|
-
&& (defined(__x86_64__) || defined(_M_X86)) \
|
111
|
-
&& !defined(__BMI2__)
|
112
|
-
# define DYNAMIC_BMI2 1
|
113
|
-
#else
|
114
|
-
# define DYNAMIC_BMI2 0
|
115
|
-
#endif
|
116
|
-
#endif
|
130
|
+
#define BMI2_TARGET_ATTRIBUTE TARGET_ATTRIBUTE("lzcnt,bmi,bmi2")
|
117
131
|
|
118
132
|
/* prefetch
|
119
133
|
* can be disabled, by declaring NO_PREFETCH build macro */
|
120
134
|
#if defined(NO_PREFETCH)
|
121
|
-
# define PREFETCH_L1(ptr) (void)(ptr) /* disabled */
|
122
|
-
# 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 */
|
123
137
|
#else
|
124
|
-
# 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 */
|
125
139
|
# include <mmintrin.h> /* https://msdn.microsoft.com/fr-fr/library/84szxsww(v=vs.90).aspx */
|
126
140
|
# define PREFETCH_L1(ptr) _mm_prefetch((const char*)(ptr), _MM_HINT_T0)
|
127
141
|
# define PREFETCH_L2(ptr) _mm_prefetch((const char*)(ptr), _MM_HINT_T1)
|
@@ -129,28 +143,30 @@
|
|
129
143
|
# define PREFETCH_L1(ptr) __builtin_prefetch((ptr), 0 /* rw==read */, 3 /* locality */)
|
130
144
|
# define PREFETCH_L2(ptr) __builtin_prefetch((ptr), 0 /* rw==read */, 2 /* locality */)
|
131
145
|
# elif defined(__aarch64__)
|
132
|
-
# define PREFETCH_L1(ptr) __asm__ __volatile__("prfm pldl1keep, %0" ::"Q"(*(ptr)))
|
133
|
-
# 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)
|
134
148
|
# else
|
135
|
-
# define PREFETCH_L1(ptr) (void)(ptr) /* disabled */
|
136
|
-
# 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 */
|
137
151
|
# endif
|
138
152
|
#endif /* NO_PREFETCH */
|
139
153
|
|
140
154
|
#define CACHELINE_SIZE 64
|
141
155
|
|
142
|
-
#define PREFETCH_AREA(p, s)
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
}
|
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)
|
150
165
|
|
151
166
|
/* vectorization
|
152
|
-
* older GCC (pre gcc-4.3 picked as the cutoff) uses a different syntax
|
153
|
-
|
167
|
+
* older GCC (pre gcc-4.3 picked as the cutoff) uses a different syntax,
|
168
|
+
* and some compilers, like Intel ICC and MCST LCC, do not support it at all. */
|
169
|
+
#if !defined(__INTEL_COMPILER) && !defined(__clang__) && defined(__GNUC__) && !defined(__LCC__)
|
154
170
|
# if (__GNUC__ == 4 && __GNUC_MINOR__ > 3) || (__GNUC__ >= 5)
|
155
171
|
# define DONT_VECTORIZE __attribute__((optimize("no-tree-vectorize")))
|
156
172
|
# else
|
@@ -173,6 +189,12 @@
|
|
173
189
|
#define UNLIKELY(x) (x)
|
174
190
|
#endif
|
175
191
|
|
192
|
+
#if __has_builtin(__builtin_unreachable) || (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)))
|
193
|
+
# define ZSTD_UNREACHABLE do { assert(0), __builtin_unreachable(); } while (0)
|
194
|
+
#else
|
195
|
+
# define ZSTD_UNREACHABLE do { assert(0); } while (0)
|
196
|
+
#endif
|
197
|
+
|
176
198
|
/* disable warnings */
|
177
199
|
#ifdef _MSC_VER /* Visual Studio */
|
178
200
|
# include <intrin.h> /* For Visual 2005 */
|
@@ -189,6 +211,8 @@
|
|
189
211
|
# ifdef __AVX2__ //MSVC does not have a BMI2 specific flag, but every CPU that supports AVX2 also supports BMI2
|
190
212
|
# define STATIC_BMI2 1
|
191
213
|
# endif
|
214
|
+
# elif defined(__BMI2__) && defined(__x86_64__) && defined(__GNUC__)
|
215
|
+
# define STATIC_BMI2 1
|
192
216
|
# endif
|
193
217
|
#endif
|
194
218
|
|
@@ -196,26 +220,171 @@
|
|
196
220
|
#define STATIC_BMI2 0
|
197
221
|
#endif
|
198
222
|
|
199
|
-
/*
|
200
|
-
#
|
201
|
-
#
|
223
|
+
/* compile time determination of SIMD support */
|
224
|
+
#if !defined(ZSTD_NO_INTRINSICS)
|
225
|
+
# if defined(__SSE2__) || defined(_M_AMD64) || (defined (_M_IX86) && defined(_M_IX86_FP) && (_M_IX86_FP >= 2))
|
226
|
+
# define ZSTD_ARCH_X86_SSE2
|
227
|
+
# endif
|
228
|
+
# if defined(__ARM_NEON) || defined(_M_ARM64)
|
229
|
+
# define ZSTD_ARCH_ARM_NEON
|
230
|
+
# endif
|
231
|
+
#
|
232
|
+
# if defined(ZSTD_ARCH_X86_SSE2)
|
233
|
+
# include <emmintrin.h>
|
234
|
+
# elif defined(ZSTD_ARCH_ARM_NEON)
|
235
|
+
# include <arm_neon.h>
|
236
|
+
# endif
|
237
|
+
#endif
|
238
|
+
|
239
|
+
/* C-language Attributes are added in C23. */
|
240
|
+
#if defined(__STDC_VERSION__) && (__STDC_VERSION__ > 201710L) && defined(__has_c_attribute)
|
241
|
+
# define ZSTD_HAS_C_ATTRIBUTE(x) __has_c_attribute(x)
|
242
|
+
#else
|
243
|
+
# define ZSTD_HAS_C_ATTRIBUTE(x) 0
|
202
244
|
#endif
|
203
245
|
|
204
|
-
/*
|
205
|
-
|
206
|
-
|
246
|
+
/* Only use C++ attributes in C++. Some compilers report support for C++
|
247
|
+
* attributes when compiling with C.
|
248
|
+
*/
|
249
|
+
#if defined(__cplusplus) && defined(__has_cpp_attribute)
|
250
|
+
# define ZSTD_HAS_CPP_ATTRIBUTE(x) __has_cpp_attribute(x)
|
251
|
+
#else
|
252
|
+
# define ZSTD_HAS_CPP_ATTRIBUTE(x) 0
|
207
253
|
#endif
|
208
254
|
|
209
|
-
/*
|
210
|
-
|
211
|
-
|
212
|
-
|
255
|
+
/* Define ZSTD_FALLTHROUGH macro for annotating switch case with the 'fallthrough' attribute.
|
256
|
+
* - C23: https://en.cppreference.com/w/c/language/attributes/fallthrough
|
257
|
+
* - CPP17: https://en.cppreference.com/w/cpp/language/attributes/fallthrough
|
258
|
+
* - Else: __attribute__((__fallthrough__))
|
259
|
+
*/
|
260
|
+
#ifndef ZSTD_FALLTHROUGH
|
261
|
+
# if ZSTD_HAS_C_ATTRIBUTE(fallthrough)
|
262
|
+
# define ZSTD_FALLTHROUGH [[fallthrough]]
|
263
|
+
# elif ZSTD_HAS_CPP_ATTRIBUTE(fallthrough)
|
264
|
+
# define ZSTD_FALLTHROUGH [[fallthrough]]
|
265
|
+
# elif __has_attribute(__fallthrough__)
|
266
|
+
/* Leading semicolon is to satisfy gcc-11 with -pedantic. Without the semicolon
|
267
|
+
* gcc complains about: a label can only be part of a statement and a declaration is not a statement.
|
268
|
+
*/
|
269
|
+
# define ZSTD_FALLTHROUGH ; __attribute__((__fallthrough__))
|
270
|
+
# else
|
271
|
+
# define ZSTD_FALLTHROUGH
|
272
|
+
# endif
|
273
|
+
#endif
|
274
|
+
|
275
|
+
/*-**************************************************************
|
276
|
+
* Alignment check
|
277
|
+
*****************************************************************/
|
278
|
+
|
279
|
+
/* this test was initially positioned in mem.h,
|
280
|
+
* but this file is removed (or replaced) for linux kernel
|
281
|
+
* so it's now hosted in compiler.h,
|
282
|
+
* which remains valid for both user & kernel spaces.
|
283
|
+
*/
|
284
|
+
|
285
|
+
#ifndef ZSTD_ALIGNOF
|
286
|
+
# if defined(__GNUC__) || defined(_MSC_VER)
|
287
|
+
/* covers gcc, clang & MSVC */
|
288
|
+
/* note : this section must come first, before C11,
|
289
|
+
* due to a limitation in the kernel source generator */
|
290
|
+
# define ZSTD_ALIGNOF(T) __alignof(T)
|
291
|
+
|
292
|
+
# elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)
|
293
|
+
/* C11 support */
|
294
|
+
# include <stdalign.h>
|
295
|
+
# define ZSTD_ALIGNOF(T) alignof(T)
|
296
|
+
|
297
|
+
# else
|
298
|
+
/* No known support for alignof() - imperfect backup */
|
299
|
+
# define ZSTD_ALIGNOF(T) (sizeof(void*) < sizeof(T) ? sizeof(void*) : sizeof(T))
|
300
|
+
|
301
|
+
# endif
|
302
|
+
#endif /* ZSTD_ALIGNOF */
|
303
|
+
|
304
|
+
/*-**************************************************************
|
305
|
+
* Sanitizer
|
306
|
+
*****************************************************************/
|
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
|
213
321
|
# else
|
214
|
-
# define
|
322
|
+
# define ZSTD_ALLOW_POINTER_OVERFLOW_ATTR
|
215
323
|
# endif
|
216
324
|
#endif
|
217
325
|
|
218
|
-
|
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
|
+
|
376
|
+
/* Issue #3240 reports an ASAN failure on an llvm-mingw build. Out of an
|
377
|
+
* abundance of caution, disable our custom poisoning on mingw. */
|
378
|
+
#ifdef __MINGW32__
|
379
|
+
#ifndef ZSTD_ASAN_DONT_POISON_WORKSPACE
|
380
|
+
#define ZSTD_ASAN_DONT_POISON_WORKSPACE 1
|
381
|
+
#endif
|
382
|
+
#ifndef ZSTD_MSAN_DONT_POISON_WORKSPACE
|
383
|
+
#define ZSTD_MSAN_DONT_POISON_WORKSPACE 1
|
384
|
+
#endif
|
385
|
+
#endif
|
386
|
+
|
387
|
+
#if ZSTD_MEMORY_SANITIZER && !defined(ZSTD_MSAN_DONT_POISON_WORKSPACE)
|
219
388
|
/* Not all platforms that support msan provide sanitizers/msan_interface.h.
|
220
389
|
* We therefore declare the functions we need ourselves, rather than trying to
|
221
390
|
* include the header file... */
|
@@ -234,20 +403,13 @@ void __msan_poison(const volatile void *a, size_t size);
|
|
234
403
|
/* Returns the offset of the first (at least partially) poisoned byte in the
|
235
404
|
memory range, or -1 if the whole range is good. */
|
236
405
|
intptr_t __msan_test_shadow(const volatile void *x, size_t size);
|
237
|
-
#endif
|
238
406
|
|
239
|
-
/*
|
240
|
-
|
241
|
-
|
242
|
-
# define ZSTD_ADDRESS_SANITIZER 1
|
243
|
-
# elif defined(__SANITIZE_ADDRESS__)
|
244
|
-
# define ZSTD_ADDRESS_SANITIZER 1
|
245
|
-
# else
|
246
|
-
# define ZSTD_ADDRESS_SANITIZER 0
|
247
|
-
# endif
|
407
|
+
/* Print shadow and origin for the memory range to stderr in a human-readable
|
408
|
+
format. */
|
409
|
+
void __msan_print_shadow(const volatile void *x, size_t size);
|
248
410
|
#endif
|
249
411
|
|
250
|
-
#if ZSTD_ADDRESS_SANITIZER
|
412
|
+
#if ZSTD_ADDRESS_SANITIZER && !defined(ZSTD_ASAN_DONT_POISON_WORKSPACE)
|
251
413
|
/* Not all platforms that support asan provide sanitizers/asan_interface.h.
|
252
414
|
* We therefore declare the functions we need ourselves, rather than trying to
|
253
415
|
* include the header file... */
|
@@ -1,5 +1,5 @@
|
|
1
1
|
/*
|
2
|
-
* Copyright (c)
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
3
3
|
* All rights reserved.
|
4
4
|
*
|
5
5
|
* This source code is licensed under both the BSD-style license (found in the
|
@@ -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
|
@@ -1,7 +1,7 @@
|
|
1
1
|
/* ******************************************************************
|
2
2
|
* debug
|
3
3
|
* Part of FSE library
|
4
|
-
* Copyright (c)
|
4
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
5
5
|
*
|
6
6
|
* You can contact the author at :
|
7
7
|
* - Source repository : https://github.com/Cyan4973/FiniteStateEntropy
|
@@ -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
|
@@ -1,7 +1,7 @@
|
|
1
1
|
/* ******************************************************************
|
2
2
|
* debug
|
3
3
|
* Part of FSE library
|
4
|
-
* Copyright (c)
|
4
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
5
5
|
*
|
6
6
|
* You can contact the author at :
|
7
7
|
* - Source repository : https://github.com/Cyan4973/FiniteStateEntropy
|
@@ -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
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
/* ******************************************************************
|
2
2
|
* Common functions of New Generation Entropy library
|
3
|
-
* Copyright (c)
|
3
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
4
4
|
*
|
5
5
|
* You can contact the author at :
|
6
6
|
* - FSE+HUF source repository : https://github.com/Cyan4973/FiniteStateEntropy
|
@@ -19,8 +19,8 @@
|
|
19
19
|
#include "error_private.h" /* ERR_*, ERROR */
|
20
20
|
#define FSE_STATIC_LINKING_ONLY /* FSE_MIN_TABLELOG */
|
21
21
|
#include "fse.h"
|
22
|
-
#define HUF_STATIC_LINKING_ONLY /* HUF_TABLELOG_ABSOLUTEMAX */
|
23
22
|
#include "huf.h"
|
23
|
+
#include "bits.h" /* ZSDT_highbit32, ZSTD_countTrailingZeros32 */
|
24
24
|
|
25
25
|
|
26
26
|
/*=== Version ===*/
|
@@ -38,28 +38,6 @@ const char* HUF_getErrorName(size_t code) { return ERR_getErrorName(code); }
|
|
38
38
|
/*-**************************************************************
|
39
39
|
* FSE NCount encoding-decoding
|
40
40
|
****************************************************************/
|
41
|
-
static U32 FSE_ctz(U32 val)
|
42
|
-
{
|
43
|
-
assert(val != 0);
|
44
|
-
{
|
45
|
-
# if defined(_MSC_VER) /* Visual */
|
46
|
-
unsigned long r=0;
|
47
|
-
return _BitScanForward(&r, val) ? (unsigned)r : 0;
|
48
|
-
# elif defined(__GNUC__) && (__GNUC__ >= 3) /* GCC Intrinsic */
|
49
|
-
return __builtin_ctz(val);
|
50
|
-
# elif defined(__ICCARM__) /* IAR Intrinsic */
|
51
|
-
return __CTZ(val);
|
52
|
-
# else /* Software version */
|
53
|
-
U32 count = 0;
|
54
|
-
while ((val & 1) == 0) {
|
55
|
-
val >>= 1;
|
56
|
-
++count;
|
57
|
-
}
|
58
|
-
return count;
|
59
|
-
# endif
|
60
|
-
}
|
61
|
-
}
|
62
|
-
|
63
41
|
FORCE_INLINE_TEMPLATE
|
64
42
|
size_t FSE_readNCount_body(short* normalizedCounter, unsigned* maxSVPtr, unsigned* tableLogPtr,
|
65
43
|
const void* headerBuffer, size_t hbSize)
|
@@ -107,7 +85,7 @@ size_t FSE_readNCount_body(short* normalizedCounter, unsigned* maxSVPtr, unsigne
|
|
107
85
|
* repeat.
|
108
86
|
* Avoid UB by setting the high bit to 1.
|
109
87
|
*/
|
110
|
-
int repeats =
|
88
|
+
int repeats = ZSTD_countTrailingZeros32(~bitStream | 0x80000000) >> 1;
|
111
89
|
while (repeats >= 12) {
|
112
90
|
charnum += 3 * 12;
|
113
91
|
if (LIKELY(ip <= iend-7)) {
|
@@ -118,7 +96,7 @@ size_t FSE_readNCount_body(short* normalizedCounter, unsigned* maxSVPtr, unsigne
|
|
118
96
|
ip = iend - 4;
|
119
97
|
}
|
120
98
|
bitStream = MEM_readLE32(ip) >> bitCount;
|
121
|
-
repeats =
|
99
|
+
repeats = ZSTD_countTrailingZeros32(~bitStream | 0x80000000) >> 1;
|
122
100
|
}
|
123
101
|
charnum += 3 * repeats;
|
124
102
|
bitStream >>= 2 * repeats;
|
@@ -183,7 +161,7 @@ size_t FSE_readNCount_body(short* normalizedCounter, unsigned* maxSVPtr, unsigne
|
|
183
161
|
* know that threshold > 1.
|
184
162
|
*/
|
185
163
|
if (remaining <= 1) break;
|
186
|
-
nbBits =
|
164
|
+
nbBits = ZSTD_highbit32(remaining) + 1;
|
187
165
|
threshold = 1 << (nbBits - 1);
|
188
166
|
}
|
189
167
|
if (charnum >= maxSV1) break;
|
@@ -217,7 +195,7 @@ static size_t FSE_readNCount_body_default(
|
|
217
195
|
}
|
218
196
|
|
219
197
|
#if DYNAMIC_BMI2
|
220
|
-
|
198
|
+
BMI2_TARGET_ATTRIBUTE static size_t FSE_readNCount_body_bmi2(
|
221
199
|
short* normalizedCounter, unsigned* maxSVPtr, unsigned* tableLogPtr,
|
222
200
|
const void* headerBuffer, size_t hbSize)
|
223
201
|
{
|
@@ -258,7 +236,7 @@ size_t HUF_readStats(BYTE* huffWeight, size_t hwSize, U32* rankStats,
|
|
258
236
|
const void* src, size_t srcSize)
|
259
237
|
{
|
260
238
|
U32 wksp[HUF_READ_STATS_WORKSPACE_SIZE_U32];
|
261
|
-
return HUF_readStats_wksp(huffWeight, hwSize, rankStats, nbSymbolsPtr, tableLogPtr, src, srcSize, wksp, sizeof(wksp), /*
|
239
|
+
return HUF_readStats_wksp(huffWeight, hwSize, rankStats, nbSymbolsPtr, tableLogPtr, src, srcSize, wksp, sizeof(wksp), /* flags */ 0);
|
262
240
|
}
|
263
241
|
|
264
242
|
FORCE_INLINE_TEMPLATE size_t
|
@@ -299,21 +277,21 @@ HUF_readStats_body(BYTE* huffWeight, size_t hwSize, U32* rankStats,
|
|
299
277
|
ZSTD_memset(rankStats, 0, (HUF_TABLELOG_MAX + 1) * sizeof(U32));
|
300
278
|
weightTotal = 0;
|
301
279
|
{ U32 n; for (n=0; n<oSize; n++) {
|
302
|
-
if (huffWeight[n]
|
280
|
+
if (huffWeight[n] > HUF_TABLELOG_MAX) return ERROR(corruption_detected);
|
303
281
|
rankStats[huffWeight[n]]++;
|
304
282
|
weightTotal += (1 << huffWeight[n]) >> 1;
|
305
283
|
} }
|
306
284
|
if (weightTotal == 0) return ERROR(corruption_detected);
|
307
285
|
|
308
286
|
/* get last non-null symbol weight (implied, total must be 2^n) */
|
309
|
-
{ U32 const tableLog =
|
287
|
+
{ U32 const tableLog = ZSTD_highbit32(weightTotal) + 1;
|
310
288
|
if (tableLog > HUF_TABLELOG_MAX) return ERROR(corruption_detected);
|
311
289
|
*tableLogPtr = tableLog;
|
312
290
|
/* determine last weight */
|
313
291
|
{ U32 const total = 1 << tableLog;
|
314
292
|
U32 const rest = total - weightTotal;
|
315
|
-
U32 const verif = 1 <<
|
316
|
-
U32 const lastWeight =
|
293
|
+
U32 const verif = 1 << ZSTD_highbit32(rest);
|
294
|
+
U32 const lastWeight = ZSTD_highbit32(rest) + 1;
|
317
295
|
if (verif != rest) return ERROR(corruption_detected); /* last value must be a clean power of 2 */
|
318
296
|
huffWeight[oSize] = (BYTE)lastWeight;
|
319
297
|
rankStats[lastWeight]++;
|
@@ -337,7 +315,7 @@ static size_t HUF_readStats_body_default(BYTE* huffWeight, size_t hwSize, U32* r
|
|
337
315
|
}
|
338
316
|
|
339
317
|
#if DYNAMIC_BMI2
|
340
|
-
static
|
318
|
+
static BMI2_TARGET_ATTRIBUTE size_t HUF_readStats_body_bmi2(BYTE* huffWeight, size_t hwSize, U32* rankStats,
|
341
319
|
U32* nbSymbolsPtr, U32* tableLogPtr,
|
342
320
|
const void* src, size_t srcSize,
|
343
321
|
void* workSpace, size_t wkspSize)
|
@@ -350,13 +328,13 @@ size_t HUF_readStats_wksp(BYTE* huffWeight, size_t hwSize, U32* rankStats,
|
|
350
328
|
U32* nbSymbolsPtr, U32* tableLogPtr,
|
351
329
|
const void* src, size_t srcSize,
|
352
330
|
void* workSpace, size_t wkspSize,
|
353
|
-
int
|
331
|
+
int flags)
|
354
332
|
{
|
355
333
|
#if DYNAMIC_BMI2
|
356
|
-
if (
|
334
|
+
if (flags & HUF_flags_bmi2) {
|
357
335
|
return HUF_readStats_body_bmi2(huffWeight, hwSize, rankStats, nbSymbolsPtr, tableLogPtr, src, srcSize, workSpace, wkspSize);
|
358
336
|
}
|
359
337
|
#endif
|
360
|
-
(void)
|
338
|
+
(void)flags;
|
361
339
|
return HUF_readStats_body_default(huffWeight, hwSize, rankStats, nbSymbolsPtr, tableLogPtr, src, srcSize, workSpace, wkspSize);
|
362
340
|
}
|