extzstd 0.3.3 → 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 +39 -2
- data/contrib/zstd/CONTRIBUTING.md +3 -3
- data/contrib/zstd/Makefile +34 -20
- data/contrib/zstd/README.md +6 -2
- data/contrib/zstd/SECURITY.md +15 -0
- data/contrib/zstd/lib/Makefile +40 -28
- data/contrib/zstd/lib/README.md +14 -1
- data/contrib/zstd/lib/common/allocations.h +1 -1
- data/contrib/zstd/lib/common/bitstream.h +49 -29
- data/contrib/zstd/lib/common/compiler.h +114 -22
- data/contrib/zstd/lib/common/cpu.h +36 -0
- data/contrib/zstd/lib/common/debug.c +6 -0
- data/contrib/zstd/lib/common/debug.h +20 -11
- data/contrib/zstd/lib/common/error_private.h +45 -36
- data/contrib/zstd/lib/common/fse.h +3 -2
- data/contrib/zstd/lib/common/fse_decompress.c +19 -17
- data/contrib/zstd/lib/common/huf.h +14 -1
- data/contrib/zstd/lib/common/mem.h +0 -9
- data/contrib/zstd/lib/common/pool.c +1 -1
- data/contrib/zstd/lib/common/pool.h +1 -1
- data/contrib/zstd/lib/common/portability_macros.h +2 -0
- data/contrib/zstd/lib/common/threading.c +8 -2
- data/contrib/zstd/lib/common/xxhash.c +5 -11
- data/contrib/zstd/lib/common/xxhash.h +2341 -1007
- data/contrib/zstd/lib/common/zstd_internal.h +5 -5
- data/contrib/zstd/lib/compress/fse_compress.c +8 -7
- data/contrib/zstd/lib/compress/huf_compress.c +54 -25
- data/contrib/zstd/lib/compress/zstd_compress.c +282 -161
- data/contrib/zstd/lib/compress/zstd_compress_internal.h +29 -27
- data/contrib/zstd/lib/compress/zstd_compress_superblock.c +224 -113
- data/contrib/zstd/lib/compress/zstd_cwksp.h +19 -13
- data/contrib/zstd/lib/compress/zstd_double_fast.c +17 -5
- data/contrib/zstd/lib/compress/zstd_double_fast.h +11 -0
- data/contrib/zstd/lib/compress/zstd_fast.c +14 -6
- data/contrib/zstd/lib/compress/zstd_lazy.c +129 -87
- data/contrib/zstd/lib/compress/zstd_lazy.h +103 -28
- data/contrib/zstd/lib/compress/zstd_ldm.c +8 -2
- data/contrib/zstd/lib/compress/zstd_opt.c +216 -112
- data/contrib/zstd/lib/compress/zstd_opt.h +31 -7
- data/contrib/zstd/lib/compress/zstdmt_compress.c +94 -79
- data/contrib/zstd/lib/decompress/huf_decompress.c +188 -126
- data/contrib/zstd/lib/decompress/huf_decompress_amd64.S +38 -19
- data/contrib/zstd/lib/decompress/zstd_decompress.c +84 -32
- data/contrib/zstd/lib/decompress/zstd_decompress_block.c +231 -208
- data/contrib/zstd/lib/decompress/zstd_decompress_block.h +1 -1
- data/contrib/zstd/lib/decompress/zstd_decompress_internal.h +2 -0
- data/contrib/zstd/lib/dictBuilder/cover.c +16 -12
- data/contrib/zstd/lib/dictBuilder/cover.h +2 -8
- data/contrib/zstd/lib/dictBuilder/fastcover.c +2 -2
- data/contrib/zstd/lib/dictBuilder/zdict.c +12 -6
- data/contrib/zstd/lib/legacy/zstd_legacy.h +30 -0
- data/contrib/zstd/lib/legacy/zstd_v01.c +2 -0
- data/contrib/zstd/lib/legacy/zstd_v02.c +4 -16
- data/contrib/zstd/lib/legacy/zstd_v03.c +4 -16
- data/contrib/zstd/lib/legacy/zstd_v04.c +4 -11
- data/contrib/zstd/lib/legacy/zstd_v05.c +1 -0
- data/contrib/zstd/lib/legacy/zstd_v06.c +2 -9
- data/contrib/zstd/lib/legacy/zstd_v07.c +2 -10
- data/contrib/zstd/lib/libzstd.mk +34 -11
- data/contrib/zstd/lib/zstd.h +129 -60
- data/ext/extconf.rb +19 -1
- data/ext/extzstd.c +38 -14
- data/ext/extzstd.h +33 -6
- data/ext/extzstd_stream.c +74 -31
- metadata +4 -5
- data/contrib/zstd/appveyor.yml +0 -205
- data/ext/depend +0 -2
@@ -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
|
|
@@ -22,8 +22,7 @@
|
|
22
22
|
#define FSE_STATIC_LINKING_ONLY
|
23
23
|
#include "fse.h"
|
24
24
|
#include "error_private.h"
|
25
|
-
#
|
26
|
-
#include "zstd_deps.h"
|
25
|
+
#include "zstd_deps.h" /* ZSTD_memcpy */
|
27
26
|
#include "bits.h" /* ZSTD_highbit32 */
|
28
27
|
|
29
28
|
|
@@ -84,7 +83,7 @@ static size_t FSE_buildDTable_internal(FSE_DTable* dt, const short* normalizedCo
|
|
84
83
|
symbolNext[s] = 1;
|
85
84
|
} else {
|
86
85
|
if (normalizedCounter[s] >= largeLimit) DTableH.fastMode=0;
|
87
|
-
symbolNext[s] = normalizedCounter[s];
|
86
|
+
symbolNext[s] = (U16)normalizedCounter[s];
|
88
87
|
} } }
|
89
88
|
ZSTD_memcpy(dt, &DTableH, sizeof(DTableH));
|
90
89
|
}
|
@@ -99,8 +98,7 @@ static size_t FSE_buildDTable_internal(FSE_DTable* dt, const short* normalizedCo
|
|
99
98
|
* all symbols have counts <= 8. We ensure we have 8 bytes at the end of
|
100
99
|
* our buffer to handle the over-write.
|
101
100
|
*/
|
102
|
-
{
|
103
|
-
U64 const add = 0x0101010101010101ull;
|
101
|
+
{ U64 const add = 0x0101010101010101ull;
|
104
102
|
size_t pos = 0;
|
105
103
|
U64 sv = 0;
|
106
104
|
U32 s;
|
@@ -111,9 +109,8 @@ static size_t FSE_buildDTable_internal(FSE_DTable* dt, const short* normalizedCo
|
|
111
109
|
for (i = 8; i < n; i += 8) {
|
112
110
|
MEM_write64(spread + pos + i, sv);
|
113
111
|
}
|
114
|
-
pos += n;
|
115
|
-
|
116
|
-
}
|
112
|
+
pos += (size_t)n;
|
113
|
+
} }
|
117
114
|
/* Now we spread those positions across the table.
|
118
115
|
* The benefit of doing it in two stages is that we avoid the
|
119
116
|
* variable size inner loop, which caused lots of branch misses.
|
@@ -232,12 +229,12 @@ FORCE_INLINE_TEMPLATE size_t FSE_decompress_usingDTable_generic(
|
|
232
229
|
break;
|
233
230
|
} }
|
234
231
|
|
235
|
-
|
232
|
+
assert(op >= ostart);
|
233
|
+
return (size_t)(op-ostart);
|
236
234
|
}
|
237
235
|
|
238
236
|
typedef struct {
|
239
237
|
short ncount[FSE_MAX_SYMBOL_VALUE + 1];
|
240
|
-
FSE_DTable dtable[1]; /* Dynamically sized */
|
241
238
|
} FSE_DecompressWksp;
|
242
239
|
|
243
240
|
|
@@ -252,13 +249,18 @@ FORCE_INLINE_TEMPLATE size_t FSE_decompress_wksp_body(
|
|
252
249
|
unsigned tableLog;
|
253
250
|
unsigned maxSymbolValue = FSE_MAX_SYMBOL_VALUE;
|
254
251
|
FSE_DecompressWksp* const wksp = (FSE_DecompressWksp*)workSpace;
|
252
|
+
size_t const dtablePos = sizeof(FSE_DecompressWksp) / sizeof(FSE_DTable);
|
253
|
+
FSE_DTable* const dtable = (FSE_DTable*)workSpace + dtablePos;
|
255
254
|
|
256
|
-
|
255
|
+
FSE_STATIC_ASSERT((FSE_MAX_SYMBOL_VALUE + 1) % 2 == 0);
|
257
256
|
if (wkspSize < sizeof(*wksp)) return ERROR(GENERIC);
|
258
257
|
|
258
|
+
/* correct offset to dtable depends on this property */
|
259
|
+
FSE_STATIC_ASSERT(sizeof(FSE_DecompressWksp) % sizeof(FSE_DTable) == 0);
|
260
|
+
|
259
261
|
/* normal FSE decoding mode */
|
260
|
-
{
|
261
|
-
|
262
|
+
{ size_t const NCountLength =
|
263
|
+
FSE_readNCount_bmi2(wksp->ncount, &maxSymbolValue, &tableLog, istart, cSrcSize, bmi2);
|
262
264
|
if (FSE_isError(NCountLength)) return NCountLength;
|
263
265
|
if (tableLog > maxLog) return ERROR(tableLog_tooLarge);
|
264
266
|
assert(NCountLength <= cSrcSize);
|
@@ -271,16 +273,16 @@ FORCE_INLINE_TEMPLATE size_t FSE_decompress_wksp_body(
|
|
271
273
|
workSpace = (BYTE*)workSpace + sizeof(*wksp) + FSE_DTABLE_SIZE(tableLog);
|
272
274
|
wkspSize -= sizeof(*wksp) + FSE_DTABLE_SIZE(tableLog);
|
273
275
|
|
274
|
-
CHECK_F( FSE_buildDTable_internal(
|
276
|
+
CHECK_F( FSE_buildDTable_internal(dtable, wksp->ncount, maxSymbolValue, tableLog, workSpace, wkspSize) );
|
275
277
|
|
276
278
|
{
|
277
|
-
const void* ptr =
|
279
|
+
const void* ptr = dtable;
|
278
280
|
const FSE_DTableHeader* DTableH = (const FSE_DTableHeader*)ptr;
|
279
281
|
const U32 fastMode = DTableH->fastMode;
|
280
282
|
|
281
283
|
/* select fast mode (static) */
|
282
|
-
if (fastMode) return FSE_decompress_usingDTable_generic(dst, dstCapacity, ip, cSrcSize,
|
283
|
-
return FSE_decompress_usingDTable_generic(dst, dstCapacity, ip, cSrcSize,
|
284
|
+
if (fastMode) return FSE_decompress_usingDTable_generic(dst, dstCapacity, ip, cSrcSize, dtable, 1);
|
285
|
+
return FSE_decompress_usingDTable_generic(dst, dstCapacity, ip, cSrcSize, dtable, 0);
|
284
286
|
}
|
285
287
|
}
|
286
288
|
|
@@ -197,9 +197,22 @@ size_t HUF_readCTable (HUF_CElt* CTable, unsigned* maxSymbolValuePtr, const void
|
|
197
197
|
|
198
198
|
/** HUF_getNbBitsFromCTable() :
|
199
199
|
* Read nbBits from CTable symbolTable, for symbol `symbolValue` presumed <= HUF_SYMBOLVALUE_MAX
|
200
|
-
* Note 1 :
|
200
|
+
* Note 1 : If symbolValue > HUF_readCTableHeader(symbolTable).maxSymbolValue, returns 0
|
201
|
+
* Note 2 : is not inlined, as HUF_CElt definition is private
|
202
|
+
*/
|
201
203
|
U32 HUF_getNbBitsFromCTable(const HUF_CElt* symbolTable, U32 symbolValue);
|
202
204
|
|
205
|
+
typedef struct {
|
206
|
+
BYTE tableLog;
|
207
|
+
BYTE maxSymbolValue;
|
208
|
+
BYTE unused[sizeof(size_t) - 2];
|
209
|
+
} HUF_CTableHeader;
|
210
|
+
|
211
|
+
/** HUF_readCTableHeader() :
|
212
|
+
* @returns The header from the CTable specifying the tableLog and the maxSymbolValue.
|
213
|
+
*/
|
214
|
+
HUF_CTableHeader HUF_readCTableHeader(HUF_CElt const* ctable);
|
215
|
+
|
203
216
|
/*
|
204
217
|
* HUF_decompress() does the following:
|
205
218
|
* 1. select the decompression algorithm (X1, X2) based on pre-computed heuristics
|
@@ -31,15 +31,6 @@ extern "C" {
|
|
31
31
|
# include <stdlib.h> /* _byteswap_ulong */
|
32
32
|
# include <intrin.h> /* _byteswap_* */
|
33
33
|
#endif
|
34
|
-
#if defined(__GNUC__)
|
35
|
-
# define MEM_STATIC static __inline __attribute__((unused))
|
36
|
-
#elif defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */)
|
37
|
-
# define MEM_STATIC static inline
|
38
|
-
#elif defined(_MSC_VER)
|
39
|
-
# define MEM_STATIC static __inline
|
40
|
-
#else
|
41
|
-
# define MEM_STATIC static /* this version may generate warnings for unused static functions; disable the relevant warning */
|
42
|
-
#endif
|
43
34
|
|
44
35
|
/*-**************************************************************
|
45
36
|
* Basic Types
|
@@ -223,7 +223,7 @@ static int POOL_resize_internal(POOL_ctx* ctx, size_t numThreads)
|
|
223
223
|
{ ZSTD_pthread_t* const threadPool = (ZSTD_pthread_t*)ZSTD_customCalloc(numThreads * sizeof(ZSTD_pthread_t), ctx->customMem);
|
224
224
|
if (!threadPool) return 1;
|
225
225
|
/* replace existing thread pool */
|
226
|
-
ZSTD_memcpy(threadPool, ctx->threads, ctx->threadCapacity * sizeof(
|
226
|
+
ZSTD_memcpy(threadPool, ctx->threads, ctx->threadCapacity * sizeof(ZSTD_pthread_t));
|
227
227
|
ZSTD_customFree(ctx->threads, ctx->customMem);
|
228
228
|
ctx->threads = threadPool;
|
229
229
|
/* Initialize additional threads */
|
@@ -47,7 +47,7 @@ void POOL_joinJobs(POOL_ctx* ctx);
|
|
47
47
|
/*! POOL_resize() :
|
48
48
|
* Expands or shrinks pool's number of threads.
|
49
49
|
* This is more efficient than releasing + creating a new context,
|
50
|
-
* since it tries to preserve and
|
50
|
+
* since it tries to preserve and reuse existing threads.
|
51
51
|
* `numThreads` must be at least 1.
|
52
52
|
* @return : 0 when resize was successful,
|
53
53
|
* !0 (typically 1) if there is an error.
|
@@ -68,6 +68,8 @@
|
|
68
68
|
/* Mark the internal assembly functions as hidden */
|
69
69
|
#ifdef __ELF__
|
70
70
|
# define ZSTD_HIDE_ASM_FUNCTION(func) .hidden func
|
71
|
+
#elif defined(__APPLE__)
|
72
|
+
# define ZSTD_HIDE_ASM_FUNCTION(func) .private_extern func
|
71
73
|
#else
|
72
74
|
# define ZSTD_HIDE_ASM_FUNCTION(func)
|
73
75
|
#endif
|
@@ -73,10 +73,12 @@ int ZSTD_pthread_create(ZSTD_pthread_t* thread, const void* unused,
|
|
73
73
|
ZSTD_thread_params_t thread_param;
|
74
74
|
(void)unused;
|
75
75
|
|
76
|
+
if (thread==NULL) return -1;
|
77
|
+
*thread = NULL;
|
78
|
+
|
76
79
|
thread_param.start_routine = start_routine;
|
77
80
|
thread_param.arg = arg;
|
78
81
|
thread_param.initialized = 0;
|
79
|
-
*thread = NULL;
|
80
82
|
|
81
83
|
/* Setup thread initialization synchronization */
|
82
84
|
if(ZSTD_pthread_cond_init(&thread_param.initialized_cond, NULL)) {
|
@@ -91,7 +93,7 @@ int ZSTD_pthread_create(ZSTD_pthread_t* thread, const void* unused,
|
|
91
93
|
|
92
94
|
/* Spawn thread */
|
93
95
|
*thread = (HANDLE)_beginthreadex(NULL, 0, worker, &thread_param, 0, NULL);
|
94
|
-
if (
|
96
|
+
if (*thread==NULL) {
|
95
97
|
ZSTD_pthread_mutex_destroy(&thread_param.initialized_mutex);
|
96
98
|
ZSTD_pthread_cond_destroy(&thread_param.initialized_cond);
|
97
99
|
return errno;
|
@@ -137,6 +139,7 @@ int ZSTD_pthread_join(ZSTD_pthread_t thread)
|
|
137
139
|
|
138
140
|
int ZSTD_pthread_mutex_init(ZSTD_pthread_mutex_t* mutex, pthread_mutexattr_t const* attr)
|
139
141
|
{
|
142
|
+
assert(mutex != NULL);
|
140
143
|
*mutex = (pthread_mutex_t*)ZSTD_malloc(sizeof(pthread_mutex_t));
|
141
144
|
if (!*mutex)
|
142
145
|
return 1;
|
@@ -145,6 +148,7 @@ int ZSTD_pthread_mutex_init(ZSTD_pthread_mutex_t* mutex, pthread_mutexattr_t con
|
|
145
148
|
|
146
149
|
int ZSTD_pthread_mutex_destroy(ZSTD_pthread_mutex_t* mutex)
|
147
150
|
{
|
151
|
+
assert(mutex != NULL);
|
148
152
|
if (!*mutex)
|
149
153
|
return 0;
|
150
154
|
{
|
@@ -156,6 +160,7 @@ int ZSTD_pthread_mutex_destroy(ZSTD_pthread_mutex_t* mutex)
|
|
156
160
|
|
157
161
|
int ZSTD_pthread_cond_init(ZSTD_pthread_cond_t* cond, pthread_condattr_t const* attr)
|
158
162
|
{
|
163
|
+
assert(cond != NULL);
|
159
164
|
*cond = (pthread_cond_t*)ZSTD_malloc(sizeof(pthread_cond_t));
|
160
165
|
if (!*cond)
|
161
166
|
return 1;
|
@@ -164,6 +169,7 @@ int ZSTD_pthread_cond_init(ZSTD_pthread_cond_t* cond, pthread_condattr_t const*
|
|
164
169
|
|
165
170
|
int ZSTD_pthread_cond_destroy(ZSTD_pthread_cond_t* cond)
|
166
171
|
{
|
172
|
+
assert(cond != NULL);
|
167
173
|
if (!*cond)
|
168
174
|
return 0;
|
169
175
|
{
|