extzstd 0.1 → 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/HISTORY.ja.md +39 -0
- data/README.md +38 -56
- data/contrib/zstd/CHANGELOG +613 -0
- data/contrib/zstd/CODE_OF_CONDUCT.md +5 -0
- data/contrib/zstd/CONTRIBUTING.md +406 -0
- data/contrib/zstd/COPYING +339 -0
- data/contrib/zstd/Makefile +420 -0
- data/contrib/zstd/README.md +179 -41
- data/contrib/zstd/TESTING.md +44 -0
- data/contrib/zstd/appveyor.yml +292 -0
- data/contrib/zstd/lib/BUCK +234 -0
- data/contrib/zstd/lib/Makefile +451 -0
- data/contrib/zstd/lib/README.md +207 -0
- data/contrib/zstd/{common → lib/common}/bitstream.h +187 -138
- data/contrib/zstd/lib/common/compiler.h +288 -0
- data/contrib/zstd/lib/common/cpu.h +213 -0
- data/contrib/zstd/lib/common/debug.c +24 -0
- data/contrib/zstd/lib/common/debug.h +107 -0
- data/contrib/zstd/lib/common/entropy_common.c +362 -0
- data/contrib/zstd/{common → lib/common}/error_private.c +25 -12
- data/contrib/zstd/{common → lib/common}/error_private.h +14 -10
- data/contrib/zstd/{common → lib/common}/fse.h +173 -92
- data/contrib/zstd/{common → lib/common}/fse_decompress.c +149 -85
- data/contrib/zstd/lib/common/huf.h +361 -0
- data/contrib/zstd/{common → lib/common}/mem.h +115 -59
- data/contrib/zstd/lib/common/pool.c +350 -0
- data/contrib/zstd/lib/common/pool.h +84 -0
- data/contrib/zstd/lib/common/threading.c +122 -0
- data/contrib/zstd/lib/common/threading.h +155 -0
- data/contrib/zstd/{common → lib/common}/xxhash.c +55 -96
- data/contrib/zstd/{common → lib/common}/xxhash.h +23 -47
- data/contrib/zstd/lib/common/zstd_common.c +83 -0
- data/contrib/zstd/lib/common/zstd_deps.h +111 -0
- data/contrib/zstd/lib/common/zstd_errors.h +95 -0
- data/contrib/zstd/lib/common/zstd_internal.h +478 -0
- data/contrib/zstd/{compress → lib/compress}/fse_compress.c +214 -319
- data/contrib/zstd/lib/compress/hist.c +181 -0
- data/contrib/zstd/lib/compress/hist.h +75 -0
- data/contrib/zstd/lib/compress/huf_compress.c +913 -0
- data/contrib/zstd/lib/compress/zstd_compress.c +5208 -0
- data/contrib/zstd/lib/compress/zstd_compress_internal.h +1203 -0
- data/contrib/zstd/lib/compress/zstd_compress_literals.c +158 -0
- data/contrib/zstd/lib/compress/zstd_compress_literals.h +29 -0
- data/contrib/zstd/lib/compress/zstd_compress_sequences.c +433 -0
- data/contrib/zstd/lib/compress/zstd_compress_sequences.h +54 -0
- data/contrib/zstd/lib/compress/zstd_compress_superblock.c +849 -0
- data/contrib/zstd/lib/compress/zstd_compress_superblock.h +32 -0
- data/contrib/zstd/lib/compress/zstd_cwksp.h +561 -0
- data/contrib/zstd/lib/compress/zstd_double_fast.c +521 -0
- data/contrib/zstd/lib/compress/zstd_double_fast.h +38 -0
- data/contrib/zstd/lib/compress/zstd_fast.c +496 -0
- data/contrib/zstd/lib/compress/zstd_fast.h +37 -0
- data/contrib/zstd/lib/compress/zstd_lazy.c +1412 -0
- data/contrib/zstd/lib/compress/zstd_lazy.h +87 -0
- data/contrib/zstd/lib/compress/zstd_ldm.c +660 -0
- data/contrib/zstd/lib/compress/zstd_ldm.h +116 -0
- data/contrib/zstd/lib/compress/zstd_opt.c +1345 -0
- data/contrib/zstd/lib/compress/zstd_opt.h +56 -0
- data/contrib/zstd/lib/compress/zstdmt_compress.c +1811 -0
- data/contrib/zstd/lib/compress/zstdmt_compress.h +110 -0
- data/contrib/zstd/lib/decompress/huf_decompress.c +1350 -0
- data/contrib/zstd/lib/decompress/zstd_ddict.c +244 -0
- data/contrib/zstd/lib/decompress/zstd_ddict.h +44 -0
- data/contrib/zstd/lib/decompress/zstd_decompress.c +1930 -0
- data/contrib/zstd/lib/decompress/zstd_decompress_block.c +1540 -0
- data/contrib/zstd/lib/decompress/zstd_decompress_block.h +62 -0
- data/contrib/zstd/lib/decompress/zstd_decompress_internal.h +190 -0
- data/contrib/zstd/{common → lib/deprecated}/zbuff.h +68 -45
- data/contrib/zstd/lib/deprecated/zbuff_common.c +26 -0
- data/contrib/zstd/lib/deprecated/zbuff_compress.c +147 -0
- data/contrib/zstd/lib/deprecated/zbuff_decompress.c +75 -0
- data/contrib/zstd/lib/dictBuilder/cover.c +1245 -0
- data/contrib/zstd/lib/dictBuilder/cover.h +157 -0
- data/contrib/zstd/{dictBuilder → lib/dictBuilder}/divsufsort.c +3 -3
- data/contrib/zstd/{dictBuilder → lib/dictBuilder}/divsufsort.h +0 -0
- data/contrib/zstd/lib/dictBuilder/fastcover.c +758 -0
- data/contrib/zstd/{dictBuilder → lib/dictBuilder}/zdict.c +318 -194
- data/contrib/zstd/lib/dictBuilder/zdict.h +305 -0
- data/contrib/zstd/{legacy → lib/legacy}/zstd_legacy.h +171 -15
- data/contrib/zstd/{legacy → lib/legacy}/zstd_v01.c +191 -124
- data/contrib/zstd/{legacy → lib/legacy}/zstd_v01.h +19 -5
- data/contrib/zstd/{legacy → lib/legacy}/zstd_v02.c +125 -125
- data/contrib/zstd/{legacy → lib/legacy}/zstd_v02.h +19 -5
- data/contrib/zstd/{legacy → lib/legacy}/zstd_v03.c +125 -124
- data/contrib/zstd/{legacy → lib/legacy}/zstd_v03.h +20 -6
- data/contrib/zstd/{legacy → lib/legacy}/zstd_v04.c +151 -299
- data/contrib/zstd/{legacy → lib/legacy}/zstd_v04.h +19 -5
- data/contrib/zstd/{legacy → lib/legacy}/zstd_v05.c +237 -243
- data/contrib/zstd/{legacy → lib/legacy}/zstd_v05.h +19 -6
- data/contrib/zstd/{legacy → lib/legacy}/zstd_v06.c +130 -143
- data/contrib/zstd/{legacy → lib/legacy}/zstd_v06.h +18 -5
- data/contrib/zstd/{legacy → lib/legacy}/zstd_v07.c +158 -157
- data/contrib/zstd/{legacy → lib/legacy}/zstd_v07.h +19 -5
- data/contrib/zstd/lib/libzstd.pc.in +15 -0
- data/contrib/zstd/lib/zstd.h +2391 -0
- data/ext/depend +2 -0
- data/ext/extconf.rb +15 -6
- data/ext/extzstd.c +76 -145
- data/ext/extzstd.h +80 -31
- data/ext/extzstd_stream.c +417 -142
- data/ext/libzstd_conf.h +8 -0
- data/ext/zstd_common.c +10 -7
- data/ext/zstd_compress.c +14 -5
- data/ext/zstd_decompress.c +5 -4
- data/ext/zstd_dictbuilder.c +9 -4
- data/ext/zstd_dictbuilder_fastcover.c +3 -0
- data/ext/zstd_legacy_v01.c +3 -1
- data/ext/zstd_legacy_v02.c +3 -1
- data/ext/zstd_legacy_v03.c +3 -1
- data/ext/zstd_legacy_v04.c +3 -1
- data/ext/zstd_legacy_v05.c +3 -1
- data/ext/zstd_legacy_v06.c +3 -1
- data/ext/zstd_legacy_v07.c +3 -1
- data/gemstub.rb +10 -24
- data/lib/extzstd.rb +64 -179
- data/lib/extzstd/version.rb +6 -1
- data/test/test_basic.rb +9 -6
- metadata +113 -57
- data/HISTORY.ja +0 -5
- data/contrib/zstd/common/entropy_common.c +0 -225
- data/contrib/zstd/common/huf.h +0 -228
- data/contrib/zstd/common/zstd_common.c +0 -83
- data/contrib/zstd/common/zstd_errors.h +0 -60
- data/contrib/zstd/common/zstd_internal.h +0 -267
- data/contrib/zstd/compress/huf_compress.c +0 -533
- data/contrib/zstd/compress/zbuff_compress.c +0 -319
- data/contrib/zstd/compress/zstd_compress.c +0 -3264
- data/contrib/zstd/compress/zstd_opt.h +0 -900
- data/contrib/zstd/decompress/huf_decompress.c +0 -883
- data/contrib/zstd/decompress/zbuff_decompress.c +0 -252
- data/contrib/zstd/decompress/zstd_decompress.c +0 -1842
- data/contrib/zstd/dictBuilder/zdict.h +0 -111
- data/contrib/zstd/zstd.h +0 -640
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
|
3
|
+
* All rights reserved.
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under both the BSD-style license (found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree) and the GPLv2 (found
|
|
7
|
+
* in the COPYING file in the root directory of this source tree).
|
|
8
|
+
* You may select, at your option, one of the above-listed licenses.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
#ifndef ZSTD_COMPILER_H
|
|
12
|
+
#define ZSTD_COMPILER_H
|
|
13
|
+
|
|
14
|
+
/*-*******************************************************
|
|
15
|
+
* Compiler specifics
|
|
16
|
+
*********************************************************/
|
|
17
|
+
/* force inlining */
|
|
18
|
+
|
|
19
|
+
#if !defined(ZSTD_NO_INLINE)
|
|
20
|
+
#if (defined(__GNUC__) && !defined(__STRICT_ANSI__)) || defined(__cplusplus) || defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */
|
|
21
|
+
# define INLINE_KEYWORD inline
|
|
22
|
+
#else
|
|
23
|
+
# define INLINE_KEYWORD
|
|
24
|
+
#endif
|
|
25
|
+
|
|
26
|
+
#if defined(__GNUC__) || defined(__ICCARM__)
|
|
27
|
+
# define FORCE_INLINE_ATTR __attribute__((always_inline))
|
|
28
|
+
#elif defined(_MSC_VER)
|
|
29
|
+
# define FORCE_INLINE_ATTR __forceinline
|
|
30
|
+
#else
|
|
31
|
+
# define FORCE_INLINE_ATTR
|
|
32
|
+
#endif
|
|
33
|
+
|
|
34
|
+
#else
|
|
35
|
+
|
|
36
|
+
#define INLINE_KEYWORD
|
|
37
|
+
#define FORCE_INLINE_ATTR
|
|
38
|
+
|
|
39
|
+
#endif
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
On MSVC qsort requires that functions passed into it use the __cdecl calling conversion(CC).
|
|
43
|
+
This explictly marks such functions as __cdecl so that the code will still compile
|
|
44
|
+
if a CC other than __cdecl has been made the default.
|
|
45
|
+
*/
|
|
46
|
+
#if defined(_MSC_VER)
|
|
47
|
+
# define WIN_CDECL __cdecl
|
|
48
|
+
#else
|
|
49
|
+
# define WIN_CDECL
|
|
50
|
+
#endif
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* FORCE_INLINE_TEMPLATE is used to define C "templates", which take constant
|
|
54
|
+
* parameters. They must be inlined for the compiler to eliminate the constant
|
|
55
|
+
* branches.
|
|
56
|
+
*/
|
|
57
|
+
#define FORCE_INLINE_TEMPLATE static INLINE_KEYWORD FORCE_INLINE_ATTR
|
|
58
|
+
/**
|
|
59
|
+
* HINT_INLINE is used to help the compiler generate better code. It is *not*
|
|
60
|
+
* used for "templates", so it can be tweaked based on the compilers
|
|
61
|
+
* performance.
|
|
62
|
+
*
|
|
63
|
+
* gcc-4.8 and gcc-4.9 have been shown to benefit from leaving off the
|
|
64
|
+
* always_inline attribute.
|
|
65
|
+
*
|
|
66
|
+
* clang up to 5.0.0 (trunk) benefit tremendously from the always_inline
|
|
67
|
+
* attribute.
|
|
68
|
+
*/
|
|
69
|
+
#if !defined(__clang__) && defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 8 && __GNUC__ < 5
|
|
70
|
+
# define HINT_INLINE static INLINE_KEYWORD
|
|
71
|
+
#else
|
|
72
|
+
# define HINT_INLINE static INLINE_KEYWORD FORCE_INLINE_ATTR
|
|
73
|
+
#endif
|
|
74
|
+
|
|
75
|
+
/* UNUSED_ATTR tells the compiler it is okay if the function is unused. */
|
|
76
|
+
#if defined(__GNUC__)
|
|
77
|
+
# define UNUSED_ATTR __attribute__((unused))
|
|
78
|
+
#else
|
|
79
|
+
# define UNUSED_ATTR
|
|
80
|
+
#endif
|
|
81
|
+
|
|
82
|
+
/* force no inlining */
|
|
83
|
+
#ifdef _MSC_VER
|
|
84
|
+
# define FORCE_NOINLINE static __declspec(noinline)
|
|
85
|
+
#else
|
|
86
|
+
# if defined(__GNUC__) || defined(__ICCARM__)
|
|
87
|
+
# define FORCE_NOINLINE static __attribute__((__noinline__))
|
|
88
|
+
# else
|
|
89
|
+
# define FORCE_NOINLINE static
|
|
90
|
+
# endif
|
|
91
|
+
#endif
|
|
92
|
+
|
|
93
|
+
/* target attribute */
|
|
94
|
+
#ifndef __has_attribute
|
|
95
|
+
#define __has_attribute(x) 0 /* Compatibility with non-clang compilers. */
|
|
96
|
+
#endif
|
|
97
|
+
#if defined(__GNUC__) || defined(__ICCARM__)
|
|
98
|
+
# define TARGET_ATTRIBUTE(target) __attribute__((__target__(target)))
|
|
99
|
+
#else
|
|
100
|
+
# define TARGET_ATTRIBUTE(target)
|
|
101
|
+
#endif
|
|
102
|
+
|
|
103
|
+
/* Enable runtime BMI2 dispatch based on the CPU.
|
|
104
|
+
* Enabled for clang & gcc >=4.8 on x86 when BMI2 isn't enabled by default.
|
|
105
|
+
*/
|
|
106
|
+
#ifndef DYNAMIC_BMI2
|
|
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
|
|
117
|
+
|
|
118
|
+
/* prefetch
|
|
119
|
+
* can be disabled, by declaring NO_PREFETCH build macro */
|
|
120
|
+
#if defined(NO_PREFETCH)
|
|
121
|
+
# define PREFETCH_L1(ptr) (void)(ptr) /* disabled */
|
|
122
|
+
# define PREFETCH_L2(ptr) (void)(ptr) /* disabled */
|
|
123
|
+
#else
|
|
124
|
+
# if defined(_MSC_VER) && (defined(_M_X64) || defined(_M_I86)) /* _mm_prefetch() is not defined outside of x86/x64 */
|
|
125
|
+
# include <mmintrin.h> /* https://msdn.microsoft.com/fr-fr/library/84szxsww(v=vs.90).aspx */
|
|
126
|
+
# define PREFETCH_L1(ptr) _mm_prefetch((const char*)(ptr), _MM_HINT_T0)
|
|
127
|
+
# define PREFETCH_L2(ptr) _mm_prefetch((const char*)(ptr), _MM_HINT_T1)
|
|
128
|
+
# elif defined(__GNUC__) && ( (__GNUC__ >= 4) || ( (__GNUC__ == 3) && (__GNUC_MINOR__ >= 1) ) )
|
|
129
|
+
# define PREFETCH_L1(ptr) __builtin_prefetch((ptr), 0 /* rw==read */, 3 /* locality */)
|
|
130
|
+
# define PREFETCH_L2(ptr) __builtin_prefetch((ptr), 0 /* rw==read */, 2 /* locality */)
|
|
131
|
+
# 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)))
|
|
134
|
+
# else
|
|
135
|
+
# define PREFETCH_L1(ptr) (void)(ptr) /* disabled */
|
|
136
|
+
# define PREFETCH_L2(ptr) (void)(ptr) /* disabled */
|
|
137
|
+
# endif
|
|
138
|
+
#endif /* NO_PREFETCH */
|
|
139
|
+
|
|
140
|
+
#define CACHELINE_SIZE 64
|
|
141
|
+
|
|
142
|
+
#define PREFETCH_AREA(p, s) { \
|
|
143
|
+
const char* const _ptr = (const char*)(p); \
|
|
144
|
+
size_t const _size = (size_t)(s); \
|
|
145
|
+
size_t _pos; \
|
|
146
|
+
for (_pos=0; _pos<_size; _pos+=CACHELINE_SIZE) { \
|
|
147
|
+
PREFETCH_L2(_ptr + _pos); \
|
|
148
|
+
} \
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/* vectorization
|
|
152
|
+
* older GCC (pre gcc-4.3 picked as the cutoff) uses a different syntax */
|
|
153
|
+
#if !defined(__INTEL_COMPILER) && !defined(__clang__) && defined(__GNUC__)
|
|
154
|
+
# if (__GNUC__ == 4 && __GNUC_MINOR__ > 3) || (__GNUC__ >= 5)
|
|
155
|
+
# define DONT_VECTORIZE __attribute__((optimize("no-tree-vectorize")))
|
|
156
|
+
# else
|
|
157
|
+
# define DONT_VECTORIZE _Pragma("GCC optimize(\"no-tree-vectorize\")")
|
|
158
|
+
# endif
|
|
159
|
+
#else
|
|
160
|
+
# define DONT_VECTORIZE
|
|
161
|
+
#endif
|
|
162
|
+
|
|
163
|
+
/* Tell the compiler that a branch is likely or unlikely.
|
|
164
|
+
* Only use these macros if it causes the compiler to generate better code.
|
|
165
|
+
* If you can remove a LIKELY/UNLIKELY annotation without speed changes in gcc
|
|
166
|
+
* and clang, please do.
|
|
167
|
+
*/
|
|
168
|
+
#if defined(__GNUC__)
|
|
169
|
+
#define LIKELY(x) (__builtin_expect((x), 1))
|
|
170
|
+
#define UNLIKELY(x) (__builtin_expect((x), 0))
|
|
171
|
+
#else
|
|
172
|
+
#define LIKELY(x) (x)
|
|
173
|
+
#define UNLIKELY(x) (x)
|
|
174
|
+
#endif
|
|
175
|
+
|
|
176
|
+
/* disable warnings */
|
|
177
|
+
#ifdef _MSC_VER /* Visual Studio */
|
|
178
|
+
# include <intrin.h> /* For Visual 2005 */
|
|
179
|
+
# pragma warning(disable : 4100) /* disable: C4100: unreferenced formal parameter */
|
|
180
|
+
# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
|
|
181
|
+
# pragma warning(disable : 4204) /* disable: C4204: non-constant aggregate initializer */
|
|
182
|
+
# pragma warning(disable : 4214) /* disable: C4214: non-int bitfields */
|
|
183
|
+
# pragma warning(disable : 4324) /* disable: C4324: padded structure */
|
|
184
|
+
#endif
|
|
185
|
+
|
|
186
|
+
/*Like DYNAMIC_BMI2 but for compile time determination of BMI2 support*/
|
|
187
|
+
#ifndef STATIC_BMI2
|
|
188
|
+
# if defined(_MSC_VER) && (defined(_M_X64) || defined(_M_I86))
|
|
189
|
+
# ifdef __AVX2__ //MSVC does not have a BMI2 specific flag, but every CPU that supports AVX2 also supports BMI2
|
|
190
|
+
# define STATIC_BMI2 1
|
|
191
|
+
# endif
|
|
192
|
+
# endif
|
|
193
|
+
#endif
|
|
194
|
+
|
|
195
|
+
#ifndef STATIC_BMI2
|
|
196
|
+
#define STATIC_BMI2 0
|
|
197
|
+
#endif
|
|
198
|
+
|
|
199
|
+
/* compat. with non-clang compilers */
|
|
200
|
+
#ifndef __has_builtin
|
|
201
|
+
# define __has_builtin(x) 0
|
|
202
|
+
#endif
|
|
203
|
+
|
|
204
|
+
/* compat. with non-clang compilers */
|
|
205
|
+
#ifndef __has_feature
|
|
206
|
+
# define __has_feature(x) 0
|
|
207
|
+
#endif
|
|
208
|
+
|
|
209
|
+
/* detects whether we are being compiled under msan */
|
|
210
|
+
#ifndef ZSTD_MEMORY_SANITIZER
|
|
211
|
+
# if __has_feature(memory_sanitizer)
|
|
212
|
+
# define ZSTD_MEMORY_SANITIZER 1
|
|
213
|
+
# else
|
|
214
|
+
# define ZSTD_MEMORY_SANITIZER 0
|
|
215
|
+
# endif
|
|
216
|
+
#endif
|
|
217
|
+
|
|
218
|
+
#if ZSTD_MEMORY_SANITIZER
|
|
219
|
+
/* Not all platforms that support msan provide sanitizers/msan_interface.h.
|
|
220
|
+
* We therefore declare the functions we need ourselves, rather than trying to
|
|
221
|
+
* include the header file... */
|
|
222
|
+
#include <stddef.h> /* size_t */
|
|
223
|
+
#define ZSTD_DEPS_NEED_STDINT
|
|
224
|
+
#include "zstd_deps.h" /* intptr_t */
|
|
225
|
+
|
|
226
|
+
/* Make memory region fully initialized (without changing its contents). */
|
|
227
|
+
void __msan_unpoison(const volatile void *a, size_t size);
|
|
228
|
+
|
|
229
|
+
/* Make memory region fully uninitialized (without changing its contents).
|
|
230
|
+
This is a legacy interface that does not update origin information. Use
|
|
231
|
+
__msan_allocated_memory() instead. */
|
|
232
|
+
void __msan_poison(const volatile void *a, size_t size);
|
|
233
|
+
|
|
234
|
+
/* Returns the offset of the first (at least partially) poisoned byte in the
|
|
235
|
+
memory range, or -1 if the whole range is good. */
|
|
236
|
+
intptr_t __msan_test_shadow(const volatile void *x, size_t size);
|
|
237
|
+
#endif
|
|
238
|
+
|
|
239
|
+
/* detects whether we are being compiled under asan */
|
|
240
|
+
#ifndef ZSTD_ADDRESS_SANITIZER
|
|
241
|
+
# if __has_feature(address_sanitizer)
|
|
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
|
|
248
|
+
#endif
|
|
249
|
+
|
|
250
|
+
#if ZSTD_ADDRESS_SANITIZER
|
|
251
|
+
/* Not all platforms that support asan provide sanitizers/asan_interface.h.
|
|
252
|
+
* We therefore declare the functions we need ourselves, rather than trying to
|
|
253
|
+
* include the header file... */
|
|
254
|
+
#include <stddef.h> /* size_t */
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* Marks a memory region (<c>[addr, addr+size)</c>) as unaddressable.
|
|
258
|
+
*
|
|
259
|
+
* This memory must be previously allocated by your program. Instrumented
|
|
260
|
+
* code is forbidden from accessing addresses in this region until it is
|
|
261
|
+
* unpoisoned. This function is not guaranteed to poison the entire region -
|
|
262
|
+
* it could poison only a subregion of <c>[addr, addr+size)</c> due to ASan
|
|
263
|
+
* alignment restrictions.
|
|
264
|
+
*
|
|
265
|
+
* \note This function is not thread-safe because no two threads can poison or
|
|
266
|
+
* unpoison memory in the same memory region simultaneously.
|
|
267
|
+
*
|
|
268
|
+
* \param addr Start of memory region.
|
|
269
|
+
* \param size Size of memory region. */
|
|
270
|
+
void __asan_poison_memory_region(void const volatile *addr, size_t size);
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* Marks a memory region (<c>[addr, addr+size)</c>) as addressable.
|
|
274
|
+
*
|
|
275
|
+
* This memory must be previously allocated by your program. Accessing
|
|
276
|
+
* addresses in this region is allowed until this region is poisoned again.
|
|
277
|
+
* This function could unpoison a super-region of <c>[addr, addr+size)</c> due
|
|
278
|
+
* to ASan alignment restrictions.
|
|
279
|
+
*
|
|
280
|
+
* \note This function is not thread-safe because no two threads can
|
|
281
|
+
* poison or unpoison memory in the same memory region simultaneously.
|
|
282
|
+
*
|
|
283
|
+
* \param addr Start of memory region.
|
|
284
|
+
* \param size Size of memory region. */
|
|
285
|
+
void __asan_unpoison_memory_region(void const volatile *addr, size_t size);
|
|
286
|
+
#endif
|
|
287
|
+
|
|
288
|
+
#endif /* ZSTD_COMPILER_H */
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2018-2020, Facebook, Inc.
|
|
3
|
+
* All rights reserved.
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under both the BSD-style license (found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree) and the GPLv2 (found
|
|
7
|
+
* in the COPYING file in the root directory of this source tree).
|
|
8
|
+
* You may select, at your option, one of the above-listed licenses.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
#ifndef ZSTD_COMMON_CPU_H
|
|
12
|
+
#define ZSTD_COMMON_CPU_H
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Implementation taken from folly/CpuId.h
|
|
16
|
+
* https://github.com/facebook/folly/blob/master/folly/CpuId.h
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
#include "mem.h"
|
|
20
|
+
|
|
21
|
+
#ifdef _MSC_VER
|
|
22
|
+
#include <intrin.h>
|
|
23
|
+
#endif
|
|
24
|
+
|
|
25
|
+
typedef struct {
|
|
26
|
+
U32 f1c;
|
|
27
|
+
U32 f1d;
|
|
28
|
+
U32 f7b;
|
|
29
|
+
U32 f7c;
|
|
30
|
+
} ZSTD_cpuid_t;
|
|
31
|
+
|
|
32
|
+
MEM_STATIC ZSTD_cpuid_t ZSTD_cpuid(void) {
|
|
33
|
+
U32 f1c = 0;
|
|
34
|
+
U32 f1d = 0;
|
|
35
|
+
U32 f7b = 0;
|
|
36
|
+
U32 f7c = 0;
|
|
37
|
+
#if defined(_MSC_VER) && (defined(_M_X64) || defined(_M_IX86))
|
|
38
|
+
int reg[4];
|
|
39
|
+
__cpuid((int*)reg, 0);
|
|
40
|
+
{
|
|
41
|
+
int const n = reg[0];
|
|
42
|
+
if (n >= 1) {
|
|
43
|
+
__cpuid((int*)reg, 1);
|
|
44
|
+
f1c = (U32)reg[2];
|
|
45
|
+
f1d = (U32)reg[3];
|
|
46
|
+
}
|
|
47
|
+
if (n >= 7) {
|
|
48
|
+
__cpuidex((int*)reg, 7, 0);
|
|
49
|
+
f7b = (U32)reg[1];
|
|
50
|
+
f7c = (U32)reg[2];
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
#elif defined(__i386__) && defined(__PIC__) && !defined(__clang__) && defined(__GNUC__)
|
|
54
|
+
/* The following block like the normal cpuid branch below, but gcc
|
|
55
|
+
* reserves ebx for use of its pic register so we must specially
|
|
56
|
+
* handle the save and restore to avoid clobbering the register
|
|
57
|
+
*/
|
|
58
|
+
U32 n;
|
|
59
|
+
__asm__(
|
|
60
|
+
"pushl %%ebx\n\t"
|
|
61
|
+
"cpuid\n\t"
|
|
62
|
+
"popl %%ebx\n\t"
|
|
63
|
+
: "=a"(n)
|
|
64
|
+
: "a"(0)
|
|
65
|
+
: "ecx", "edx");
|
|
66
|
+
if (n >= 1) {
|
|
67
|
+
U32 f1a;
|
|
68
|
+
__asm__(
|
|
69
|
+
"pushl %%ebx\n\t"
|
|
70
|
+
"cpuid\n\t"
|
|
71
|
+
"popl %%ebx\n\t"
|
|
72
|
+
: "=a"(f1a), "=c"(f1c), "=d"(f1d)
|
|
73
|
+
: "a"(1));
|
|
74
|
+
}
|
|
75
|
+
if (n >= 7) {
|
|
76
|
+
__asm__(
|
|
77
|
+
"pushl %%ebx\n\t"
|
|
78
|
+
"cpuid\n\t"
|
|
79
|
+
"movl %%ebx, %%eax\n\t"
|
|
80
|
+
"popl %%ebx"
|
|
81
|
+
: "=a"(f7b), "=c"(f7c)
|
|
82
|
+
: "a"(7), "c"(0)
|
|
83
|
+
: "edx");
|
|
84
|
+
}
|
|
85
|
+
#elif defined(__x86_64__) || defined(_M_X64) || defined(__i386__)
|
|
86
|
+
U32 n;
|
|
87
|
+
__asm__("cpuid" : "=a"(n) : "a"(0) : "ebx", "ecx", "edx");
|
|
88
|
+
if (n >= 1) {
|
|
89
|
+
U32 f1a;
|
|
90
|
+
__asm__("cpuid" : "=a"(f1a), "=c"(f1c), "=d"(f1d) : "a"(1) : "ebx");
|
|
91
|
+
}
|
|
92
|
+
if (n >= 7) {
|
|
93
|
+
U32 f7a;
|
|
94
|
+
__asm__("cpuid"
|
|
95
|
+
: "=a"(f7a), "=b"(f7b), "=c"(f7c)
|
|
96
|
+
: "a"(7), "c"(0)
|
|
97
|
+
: "edx");
|
|
98
|
+
}
|
|
99
|
+
#endif
|
|
100
|
+
{
|
|
101
|
+
ZSTD_cpuid_t cpuid;
|
|
102
|
+
cpuid.f1c = f1c;
|
|
103
|
+
cpuid.f1d = f1d;
|
|
104
|
+
cpuid.f7b = f7b;
|
|
105
|
+
cpuid.f7c = f7c;
|
|
106
|
+
return cpuid;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
#define X(name, r, bit) \
|
|
111
|
+
MEM_STATIC int ZSTD_cpuid_##name(ZSTD_cpuid_t const cpuid) { \
|
|
112
|
+
return ((cpuid.r) & (1U << bit)) != 0; \
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/* cpuid(1): Processor Info and Feature Bits. */
|
|
116
|
+
#define C(name, bit) X(name, f1c, bit)
|
|
117
|
+
C(sse3, 0)
|
|
118
|
+
C(pclmuldq, 1)
|
|
119
|
+
C(dtes64, 2)
|
|
120
|
+
C(monitor, 3)
|
|
121
|
+
C(dscpl, 4)
|
|
122
|
+
C(vmx, 5)
|
|
123
|
+
C(smx, 6)
|
|
124
|
+
C(eist, 7)
|
|
125
|
+
C(tm2, 8)
|
|
126
|
+
C(ssse3, 9)
|
|
127
|
+
C(cnxtid, 10)
|
|
128
|
+
C(fma, 12)
|
|
129
|
+
C(cx16, 13)
|
|
130
|
+
C(xtpr, 14)
|
|
131
|
+
C(pdcm, 15)
|
|
132
|
+
C(pcid, 17)
|
|
133
|
+
C(dca, 18)
|
|
134
|
+
C(sse41, 19)
|
|
135
|
+
C(sse42, 20)
|
|
136
|
+
C(x2apic, 21)
|
|
137
|
+
C(movbe, 22)
|
|
138
|
+
C(popcnt, 23)
|
|
139
|
+
C(tscdeadline, 24)
|
|
140
|
+
C(aes, 25)
|
|
141
|
+
C(xsave, 26)
|
|
142
|
+
C(osxsave, 27)
|
|
143
|
+
C(avx, 28)
|
|
144
|
+
C(f16c, 29)
|
|
145
|
+
C(rdrand, 30)
|
|
146
|
+
#undef C
|
|
147
|
+
#define D(name, bit) X(name, f1d, bit)
|
|
148
|
+
D(fpu, 0)
|
|
149
|
+
D(vme, 1)
|
|
150
|
+
D(de, 2)
|
|
151
|
+
D(pse, 3)
|
|
152
|
+
D(tsc, 4)
|
|
153
|
+
D(msr, 5)
|
|
154
|
+
D(pae, 6)
|
|
155
|
+
D(mce, 7)
|
|
156
|
+
D(cx8, 8)
|
|
157
|
+
D(apic, 9)
|
|
158
|
+
D(sep, 11)
|
|
159
|
+
D(mtrr, 12)
|
|
160
|
+
D(pge, 13)
|
|
161
|
+
D(mca, 14)
|
|
162
|
+
D(cmov, 15)
|
|
163
|
+
D(pat, 16)
|
|
164
|
+
D(pse36, 17)
|
|
165
|
+
D(psn, 18)
|
|
166
|
+
D(clfsh, 19)
|
|
167
|
+
D(ds, 21)
|
|
168
|
+
D(acpi, 22)
|
|
169
|
+
D(mmx, 23)
|
|
170
|
+
D(fxsr, 24)
|
|
171
|
+
D(sse, 25)
|
|
172
|
+
D(sse2, 26)
|
|
173
|
+
D(ss, 27)
|
|
174
|
+
D(htt, 28)
|
|
175
|
+
D(tm, 29)
|
|
176
|
+
D(pbe, 31)
|
|
177
|
+
#undef D
|
|
178
|
+
|
|
179
|
+
/* cpuid(7): Extended Features. */
|
|
180
|
+
#define B(name, bit) X(name, f7b, bit)
|
|
181
|
+
B(bmi1, 3)
|
|
182
|
+
B(hle, 4)
|
|
183
|
+
B(avx2, 5)
|
|
184
|
+
B(smep, 7)
|
|
185
|
+
B(bmi2, 8)
|
|
186
|
+
B(erms, 9)
|
|
187
|
+
B(invpcid, 10)
|
|
188
|
+
B(rtm, 11)
|
|
189
|
+
B(mpx, 14)
|
|
190
|
+
B(avx512f, 16)
|
|
191
|
+
B(avx512dq, 17)
|
|
192
|
+
B(rdseed, 18)
|
|
193
|
+
B(adx, 19)
|
|
194
|
+
B(smap, 20)
|
|
195
|
+
B(avx512ifma, 21)
|
|
196
|
+
B(pcommit, 22)
|
|
197
|
+
B(clflushopt, 23)
|
|
198
|
+
B(clwb, 24)
|
|
199
|
+
B(avx512pf, 26)
|
|
200
|
+
B(avx512er, 27)
|
|
201
|
+
B(avx512cd, 28)
|
|
202
|
+
B(sha, 29)
|
|
203
|
+
B(avx512bw, 30)
|
|
204
|
+
B(avx512vl, 31)
|
|
205
|
+
#undef B
|
|
206
|
+
#define C(name, bit) X(name, f7c, bit)
|
|
207
|
+
C(prefetchwt1, 0)
|
|
208
|
+
C(avx512vbmi, 1)
|
|
209
|
+
#undef C
|
|
210
|
+
|
|
211
|
+
#undef X
|
|
212
|
+
|
|
213
|
+
#endif /* ZSTD_COMMON_CPU_H */
|