zstdlib 0.6.0-x64-mingw32 → 0.9.0-x64-mingw32
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 +4 -4
- data/CHANGES.md +20 -0
- data/README.md +7 -1
- data/Rakefile +38 -8
- data/ext/{zstdlib → zstdlib_c}/extconf.rb +10 -5
- data/ext/{zstdlib → zstdlib_c}/ruby/zlib-2.2/zstdlib.c +2 -2
- data/ext/{zstdlib → zstdlib_c}/ruby/zlib-2.3/zstdlib.c +2 -2
- data/ext/{zstdlib → zstdlib_c}/ruby/zlib-2.4/zstdlib.c +2 -2
- data/ext/{zstdlib → zstdlib_c}/ruby/zlib-2.5/zstdlib.c +2 -2
- data/ext/{zstdlib → zstdlib_c}/ruby/zlib-2.6/zstdlib.c +2 -2
- data/ext/{zstdlib → zstdlib_c}/ruby/zlib-2.7/zstdlib.c +2 -2
- data/ext/zstdlib_c/ruby/zlib-3.0/zstdlib.c +4994 -0
- data/ext/zstdlib_c/ruby/zlib-3.1/zstdlib.c +5076 -0
- data/ext/{zstdlib → zstdlib_c}/zlib-1.2.11/adler32.c +0 -0
- data/ext/{zstdlib → zstdlib_c}/zlib-1.2.11/compress.c +0 -0
- data/ext/{zstdlib → zstdlib_c}/zlib-1.2.11/crc32.c +0 -0
- data/ext/{zstdlib → zstdlib_c}/zlib-1.2.11/crc32.h +0 -0
- data/ext/{zstdlib → zstdlib_c}/zlib-1.2.11/deflate.c +0 -0
- data/ext/{zstdlib → zstdlib_c}/zlib-1.2.11/deflate.h +0 -0
- data/ext/{zstdlib → zstdlib_c}/zlib-1.2.11/gzclose.c +0 -0
- data/ext/{zstdlib → zstdlib_c}/zlib-1.2.11/gzguts.h +0 -0
- data/ext/{zstdlib → zstdlib_c}/zlib-1.2.11/gzlib.c +0 -0
- data/ext/{zstdlib → zstdlib_c}/zlib-1.2.11/gzread.c +0 -0
- data/ext/{zstdlib → zstdlib_c}/zlib-1.2.11/gzwrite.c +0 -0
- data/ext/{zstdlib → zstdlib_c}/zlib-1.2.11/infback.c +0 -0
- data/ext/{zstdlib → zstdlib_c}/zlib-1.2.11/inffast.c +0 -0
- data/ext/{zstdlib → zstdlib_c}/zlib-1.2.11/inffast.h +0 -0
- data/ext/{zstdlib → zstdlib_c}/zlib-1.2.11/inffixed.h +0 -0
- data/ext/{zstdlib → zstdlib_c}/zlib-1.2.11/inflate.c +0 -0
- data/ext/{zstdlib → zstdlib_c}/zlib-1.2.11/inflate.h +0 -0
- data/ext/{zstdlib → zstdlib_c}/zlib-1.2.11/inftrees.c +0 -0
- data/ext/{zstdlib → zstdlib_c}/zlib-1.2.11/inftrees.h +0 -0
- data/ext/{zstdlib → zstdlib_c}/zlib-1.2.11/trees.c +0 -0
- data/ext/{zstdlib → zstdlib_c}/zlib-1.2.11/trees.h +0 -0
- data/ext/{zstdlib → zstdlib_c}/zlib-1.2.11/uncompr.c +0 -0
- data/ext/{zstdlib → zstdlib_c}/zlib-1.2.11/zconf.h +0 -0
- data/ext/{zstdlib → zstdlib_c}/zlib-1.2.11/zlib.h +0 -0
- data/ext/{zstdlib → zstdlib_c}/zlib-1.2.11/zutil.c +0 -0
- data/ext/{zstdlib → zstdlib_c}/zlib-1.2.11/zutil.h +0 -0
- data/ext/{zstdlib → zstdlib_c}/zlib.mk +0 -0
- data/ext/{zstdlib → zstdlib_c}/zlibwrapper/zlibwrapper.c +1 -5
- data/ext/{zstdlib → zstdlib_c}/zlibwrapper.mk +0 -0
- data/ext/{zstdlib/zstd-1.4.4 → zstdlib_c/zstd-1.5.2}/lib/common/bitstream.h +75 -57
- data/ext/zstdlib_c/zstd-1.5.2/lib/common/compiler.h +335 -0
- data/ext/{zstdlib/zstd-1.4.4 → zstdlib_c/zstd-1.5.2}/lib/common/cpu.h +1 -3
- data/ext/zstdlib_c/zstd-1.5.2/lib/common/debug.c +24 -0
- data/ext/{zstdlib/zstd-1.4.4 → zstdlib_c/zstd-1.5.2}/lib/common/debug.h +22 -49
- data/ext/zstdlib_c/zstd-1.5.2/lib/common/entropy_common.c +368 -0
- data/ext/{zstdlib/zstd-1.4.4 → zstdlib_c/zstd-1.5.2}/lib/common/error_private.c +3 -1
- data/ext/zstdlib_c/zstd-1.5.2/lib/common/error_private.h +159 -0
- data/ext/{zstdlib/zstd-1.4.4 → zstdlib_c/zstd-1.5.2}/lib/common/fse.h +51 -42
- data/ext/{zstdlib/zstd-1.4.4 → zstdlib_c/zstd-1.5.2}/lib/common/fse_decompress.c +149 -57
- data/ext/{zstdlib/zstd-1.4.4 → zstdlib_c/zstd-1.5.2}/lib/common/huf.h +60 -54
- data/ext/{zstdlib/zstd-1.4.4 → zstdlib_c/zstd-1.5.2}/lib/common/mem.h +87 -98
- data/ext/{zstdlib/zstd-1.4.4 → zstdlib_c/zstd-1.5.2}/lib/common/pool.c +34 -23
- data/ext/{zstdlib/zstd-1.4.4 → zstdlib_c/zstd-1.5.2}/lib/common/pool.h +5 -5
- data/ext/zstdlib_c/zstd-1.5.2/lib/common/portability_macros.h +137 -0
- data/ext/{zstdlib/zstd-1.4.4 → zstdlib_c/zstd-1.5.2}/lib/common/threading.c +10 -8
- data/ext/{zstdlib/zstd-1.4.4 → zstdlib_c/zstd-1.5.2}/lib/common/threading.h +4 -3
- data/ext/zstdlib_c/zstd-1.5.2/lib/common/xxhash.c +24 -0
- data/ext/zstdlib_c/zstd-1.5.2/lib/common/xxhash.h +5686 -0
- data/ext/{zstdlib/zstd-1.4.4 → zstdlib_c/zstd-1.5.2}/lib/common/zstd_common.c +10 -10
- data/ext/zstdlib_c/zstd-1.5.2/lib/common/zstd_deps.h +111 -0
- data/ext/zstdlib_c/zstd-1.5.2/lib/common/zstd_internal.h +493 -0
- data/ext/zstdlib_c/zstd-1.5.2/lib/common/zstd_trace.h +163 -0
- data/ext/zstdlib_c/zstd-1.5.2/lib/compress/clevels.h +134 -0
- data/ext/{zstdlib/zstd-1.4.4 → zstdlib_c/zstd-1.5.2}/lib/compress/fse_compress.c +105 -85
- data/ext/{zstdlib/zstd-1.4.4 → zstdlib_c/zstd-1.5.2}/lib/compress/hist.c +41 -63
- data/ext/{zstdlib/zstd-1.4.4 → zstdlib_c/zstd-1.5.2}/lib/compress/hist.h +13 -33
- data/ext/zstdlib_c/zstd-1.5.2/lib/compress/huf_compress.c +1370 -0
- data/ext/zstdlib_c/zstd-1.5.2/lib/compress/zstd_compress.c +6327 -0
- data/ext/{zstdlib/zstd-1.4.4 → zstdlib_c/zstd-1.5.2}/lib/compress/zstd_compress_internal.h +537 -82
- data/ext/{zstdlib/zstd-1.4.4 → zstdlib_c/zstd-1.5.2}/lib/compress/zstd_compress_literals.c +21 -16
- data/ext/{zstdlib/zstd-1.4.4 → zstdlib_c/zstd-1.5.2}/lib/compress/zstd_compress_literals.h +4 -2
- data/ext/{zstdlib/zstd-1.4.4 → zstdlib_c/zstd-1.5.2}/lib/compress/zstd_compress_sequences.c +61 -34
- data/ext/{zstdlib/zstd-1.4.4 → zstdlib_c/zstd-1.5.2}/lib/compress/zstd_compress_sequences.h +10 -3
- data/ext/zstdlib_c/zstd-1.5.2/lib/compress/zstd_compress_superblock.c +573 -0
- data/ext/zstdlib_c/zstd-1.5.2/lib/compress/zstd_compress_superblock.h +32 -0
- data/ext/{zstdlib/zstd-1.4.4 → zstdlib_c/zstd-1.5.2}/lib/compress/zstd_cwksp.h +236 -95
- data/ext/{zstdlib/zstd-1.4.4 → zstdlib_c/zstd-1.5.2}/lib/compress/zstd_double_fast.c +321 -143
- data/ext/{zstdlib/zstd-1.4.4 → zstdlib_c/zstd-1.5.2}/lib/compress/zstd_double_fast.h +2 -2
- data/ext/{zstdlib/zstd-1.4.4 → zstdlib_c/zstd-1.5.2}/lib/compress/zstd_fast.c +328 -137
- data/ext/{zstdlib/zstd-1.4.4 → zstdlib_c/zstd-1.5.2}/lib/compress/zstd_fast.h +2 -2
- data/ext/zstdlib_c/zstd-1.5.2/lib/compress/zstd_lazy.c +2104 -0
- data/ext/zstdlib_c/zstd-1.5.2/lib/compress/zstd_lazy.h +125 -0
- data/ext/{zstdlib/zstd-1.4.4 → zstdlib_c/zstd-1.5.2}/lib/compress/zstd_ldm.c +336 -209
- data/ext/{zstdlib/zstd-1.4.4 → zstdlib_c/zstd-1.5.2}/lib/compress/zstd_ldm.h +15 -3
- data/ext/zstdlib_c/zstd-1.5.2/lib/compress/zstd_ldm_geartab.h +106 -0
- data/ext/{zstdlib/zstd-1.4.4 → zstdlib_c/zstd-1.5.2}/lib/compress/zstd_opt.c +439 -239
- data/ext/{zstdlib/zstd-1.4.4 → zstdlib_c/zstd-1.5.2}/lib/compress/zstd_opt.h +1 -1
- data/ext/{zstdlib/zstd-1.4.4 → zstdlib_c/zstd-1.5.2}/lib/compress/zstdmt_compress.c +205 -462
- data/ext/zstdlib_c/zstd-1.5.2/lib/compress/zstdmt_compress.h +113 -0
- data/ext/zstdlib_c/zstd-1.5.2/lib/decompress/huf_decompress.c +1889 -0
- data/ext/zstdlib_c/zstd-1.5.2/lib/decompress/huf_decompress_amd64.S +585 -0
- data/ext/{zstdlib/zstd-1.4.4 → zstdlib_c/zstd-1.5.2}/lib/decompress/zstd_ddict.c +20 -16
- data/ext/{zstdlib/zstd-1.4.4 → zstdlib_c/zstd-1.5.2}/lib/decompress/zstd_ddict.h +3 -3
- data/ext/{zstdlib/zstd-1.4.4 → zstdlib_c/zstd-1.5.2}/lib/decompress/zstd_decompress.c +691 -230
- data/ext/zstdlib_c/zstd-1.5.2/lib/decompress/zstd_decompress_block.c +2072 -0
- data/ext/{zstdlib/zstd-1.4.4 → zstdlib_c/zstd-1.5.2}/lib/decompress/zstd_decompress_block.h +16 -7
- data/ext/{zstdlib/zstd-1.4.4 → zstdlib_c/zstd-1.5.2}/lib/decompress/zstd_decompress_internal.h +71 -10
- data/ext/zstdlib_c/zstd-1.5.2/lib/zdict.h +452 -0
- data/ext/{zstdlib/zstd-1.4.4 → zstdlib_c/zstd-1.5.2}/lib/zstd.h +760 -234
- data/ext/{zstdlib/zstd-1.4.4/lib/common → zstdlib_c/zstd-1.5.2/lib}/zstd_errors.h +3 -1
- data/ext/{zstdlib/zstd-1.4.4 → zstdlib_c/zstd-1.5.2}/zlibWrapper/gzclose.c +0 -0
- data/ext/{zstdlib/zstd-1.4.4 → zstdlib_c/zstd-1.5.2}/zlibWrapper/gzcompatibility.h +1 -1
- data/ext/{zstdlib/zstd-1.4.4 → zstdlib_c/zstd-1.5.2}/zlibWrapper/gzguts.h +0 -0
- data/ext/{zstdlib/zstd-1.4.4 → zstdlib_c/zstd-1.5.2}/zlibWrapper/gzlib.c +0 -0
- data/ext/{zstdlib/zstd-1.4.4 → zstdlib_c/zstd-1.5.2}/zlibWrapper/gzread.c +0 -0
- data/ext/{zstdlib/zstd-1.4.4 → zstdlib_c/zstd-1.5.2}/zlibWrapper/gzwrite.c +0 -0
- data/ext/{zstdlib/zstd-1.4.4 → zstdlib_c/zstd-1.5.2}/zlibWrapper/zstd_zlibwrapper.c +133 -44
- data/ext/{zstdlib/zstd-1.4.4 → zstdlib_c/zstd-1.5.2}/zlibWrapper/zstd_zlibwrapper.h +1 -1
- data/ext/zstdlib_c/zstd.mk +15 -0
- data/lib/2.4/zstdlib_c.so +0 -0
- data/lib/2.5/zstdlib_c.so +0 -0
- data/lib/2.6/zstdlib_c.so +0 -0
- data/lib/2.7/zstdlib_c.so +0 -0
- data/lib/3.0/zstdlib_c.so +0 -0
- data/lib/zstdlib.rb +2 -2
- metadata +124 -114
- data/ext/zstdlib/zstd-1.4.4/lib/common/compiler.h +0 -159
- data/ext/zstdlib/zstd-1.4.4/lib/common/debug.c +0 -44
- data/ext/zstdlib/zstd-1.4.4/lib/common/entropy_common.c +0 -236
- data/ext/zstdlib/zstd-1.4.4/lib/common/error_private.h +0 -76
- data/ext/zstdlib/zstd-1.4.4/lib/common/xxhash.c +0 -882
- data/ext/zstdlib/zstd-1.4.4/lib/common/xxhash.h +0 -305
- data/ext/zstdlib/zstd-1.4.4/lib/common/zstd_internal.h +0 -350
- data/ext/zstdlib/zstd-1.4.4/lib/compress/huf_compress.c +0 -798
- data/ext/zstdlib/zstd-1.4.4/lib/compress/zstd_compress.c +0 -4103
- data/ext/zstdlib/zstd-1.4.4/lib/compress/zstd_lazy.c +0 -1115
- data/ext/zstdlib/zstd-1.4.4/lib/compress/zstd_lazy.h +0 -67
- data/ext/zstdlib/zstd-1.4.4/lib/compress/zstdmt_compress.h +0 -192
- data/ext/zstdlib/zstd-1.4.4/lib/decompress/huf_decompress.c +0 -1234
- data/ext/zstdlib/zstd-1.4.4/lib/decompress/zstd_decompress_block.c +0 -1323
- data/ext/zstdlib/zstd.mk +0 -14
- data/lib/2.2/zstdlib.so +0 -0
- data/lib/2.3/zstdlib.so +0 -0
- data/lib/2.4/zstdlib.so +0 -0
- data/lib/2.5/zstdlib.so +0 -0
- data/lib/2.6/zstdlib.so +0 -0
- data/lib/2.7/zstdlib.so +0 -0
| @@ -1,5 +1,5 @@ | |
| 1 1 | 
             
            /*
         | 
| 2 | 
            -
             * Copyright (c)  | 
| 2 | 
            +
             * Copyright (c) Yann Collet, Facebook, Inc.
         | 
| 3 3 | 
             
             * All rights reserved.
         | 
| 4 4 | 
             
             *
         | 
| 5 5 | 
             
             * This source code is licensed under both the BSD-style license (found in the
         | 
| @@ -14,7 +14,7 @@ | |
| 14 14 | 
             
            /*-*************************************
         | 
| 15 15 | 
             
            *  Dependencies
         | 
| 16 16 | 
             
            ***************************************/
         | 
| 17 | 
            -
            #include "zstd_internal.h"
         | 
| 17 | 
            +
            #include "../common/zstd_internal.h"
         | 
| 18 18 |  | 
| 19 19 | 
             
            #if defined (__cplusplus)
         | 
| 20 20 | 
             
            extern "C" {
         | 
| @@ -24,16 +24,6 @@ extern "C" { | |
| 24 24 | 
             
            *  Constants
         | 
| 25 25 | 
             
            ***************************************/
         | 
| 26 26 |  | 
| 27 | 
            -
            /* define "workspace is too large" as this number of times larger than needed */
         | 
| 28 | 
            -
            #define ZSTD_WORKSPACETOOLARGE_FACTOR 3
         | 
| 29 | 
            -
             | 
| 30 | 
            -
            /* when workspace is continuously too large
         | 
| 31 | 
            -
             * during at least this number of times,
         | 
| 32 | 
            -
             * context's memory usage is considered wasteful,
         | 
| 33 | 
            -
             * because it's sized to handle a worst case scenario which rarely happens.
         | 
| 34 | 
            -
             * In which case, resize it down to free some memory */
         | 
| 35 | 
            -
            #define ZSTD_WORKSPACETOOLARGE_MAXDURATION 128
         | 
| 36 | 
            -
             | 
| 37 27 | 
             
            /* Since the workspace is effectively its own little malloc implementation /
         | 
| 38 28 | 
             
             * arena, when we run under ASAN, we should similarly insert redzones between
         | 
| 39 29 | 
             
             * each internal element of the workspace, so ASAN will catch overruns that
         | 
| @@ -45,6 +35,10 @@ extern "C" { | |
| 45 35 | 
             
            #define ZSTD_CWKSP_ASAN_REDZONE_SIZE 128
         | 
| 46 36 | 
             
            #endif
         | 
| 47 37 |  | 
| 38 | 
            +
             | 
| 39 | 
            +
            /* Set our tables and aligneds to align by 64 bytes */
         | 
| 40 | 
            +
            #define ZSTD_CWKSP_ALIGNMENT_BYTES 64
         | 
| 41 | 
            +
             | 
| 48 42 | 
             
            /*-*************************************
         | 
| 49 43 | 
             
            *  Structures
         | 
| 50 44 | 
             
            ***************************************/
         | 
| @@ -54,6 +48,16 @@ typedef enum { | |
| 54 48 | 
             
                ZSTD_cwksp_alloc_aligned
         | 
| 55 49 | 
             
            } ZSTD_cwksp_alloc_phase_e;
         | 
| 56 50 |  | 
| 51 | 
            +
            /**
         | 
| 52 | 
            +
             * Used to describe whether the workspace is statically allocated (and will not
         | 
| 53 | 
            +
             * necessarily ever be freed), or if it's dynamically allocated and we can
         | 
| 54 | 
            +
             * expect a well-formed caller to free this.
         | 
| 55 | 
            +
             */
         | 
| 56 | 
            +
            typedef enum {
         | 
| 57 | 
            +
                ZSTD_cwksp_dynamic_alloc,
         | 
| 58 | 
            +
                ZSTD_cwksp_static_alloc
         | 
| 59 | 
            +
            } ZSTD_cwksp_static_alloc_e;
         | 
| 60 | 
            +
             | 
| 57 61 | 
             
            /**
         | 
| 58 62 | 
             
             * Zstd fits all its internal datastructures into a single continuous buffer,
         | 
| 59 63 | 
             
             * so that it only needs to perform a single OS allocation (or so that a buffer
         | 
| @@ -102,7 +106,7 @@ typedef enum { | |
| 102 106 | 
             
             *
         | 
| 103 107 | 
             
             * - Static objects: this is optionally the enclosing ZSTD_CCtx or ZSTD_CDict,
         | 
| 104 108 | 
             
             *   so that literally everything fits in a single buffer. Note: if present,
         | 
| 105 | 
            -
             *   this must be the first object in the workspace, since  | 
| 109 | 
            +
             *   this must be the first object in the workspace, since ZSTD_customFree{CCtx,
         | 
| 106 110 | 
             
             *   CDict}() rely on a pointer comparison to see whether one or two frees are
         | 
| 107 111 | 
             
             *   required.
         | 
| 108 112 | 
             
             *
         | 
| @@ -117,10 +121,11 @@ typedef enum { | |
| 117 121 | 
             
             * - Tables: these are any of several different datastructures (hash tables,
         | 
| 118 122 | 
             
             *   chain tables, binary trees) that all respect a common format: they are
         | 
| 119 123 | 
             
             *   uint32_t arrays, all of whose values are between 0 and (nextSrc - base).
         | 
| 120 | 
            -
             *   Their sizes depend on the cparams.
         | 
| 124 | 
            +
             *   Their sizes depend on the cparams. These tables are 64-byte aligned.
         | 
| 121 125 | 
             
             *
         | 
| 122 126 | 
             
             * - Aligned: these buffers are used for various purposes that require 4 byte
         | 
| 123 | 
            -
             *   alignment, but don't require any initialization before they're used.
         | 
| 127 | 
            +
             *   alignment, but don't require any initialization before they're used. These
         | 
| 128 | 
            +
             *   buffers are each aligned to 64 bytes.
         | 
| 124 129 | 
             
             *
         | 
| 125 130 | 
             
             * - Buffers: these buffers are used for various purposes that don't require
         | 
| 126 131 | 
             
             *   any alignment or initialization before they're used. This means they can
         | 
| @@ -133,8 +138,7 @@ typedef enum { | |
| 133 138 | 
             
             *
         | 
| 134 139 | 
             
             * 1. Objects
         | 
| 135 140 | 
             
             * 2. Buffers
         | 
| 136 | 
            -
             * 3. Aligned
         | 
| 137 | 
            -
             * 4. Tables
         | 
| 141 | 
            +
             * 3. Aligned/Tables
         | 
| 138 142 | 
             
             *
         | 
| 139 143 | 
             
             * Attempts to reserve objects of different types out of order will fail.
         | 
| 140 144 | 
             
             */
         | 
| @@ -147,9 +151,10 @@ typedef struct { | |
| 147 151 | 
             
                void* tableValidEnd;
         | 
| 148 152 | 
             
                void* allocStart;
         | 
| 149 153 |  | 
| 150 | 
            -
                 | 
| 154 | 
            +
                BYTE allocFailed;
         | 
| 151 155 | 
             
                int workspaceOversizedDuration;
         | 
| 152 156 | 
             
                ZSTD_cwksp_alloc_phase_e phase;
         | 
| 157 | 
            +
                ZSTD_cwksp_static_alloc_e isStatic;
         | 
| 153 158 | 
             
            } ZSTD_cwksp;
         | 
| 154 159 |  | 
| 155 160 | 
             
            /*-*************************************
         | 
| @@ -186,82 +191,166 @@ MEM_STATIC size_t ZSTD_cwksp_align(size_t size, size_t const align) { | |
| 186 191 | 
             
             * Since tables aren't currently redzoned, you don't need to call through this
         | 
| 187 192 | 
             
             * to figure out how much space you need for the matchState tables. Everything
         | 
| 188 193 | 
             
             * else is though.
         | 
| 194 | 
            +
             *
         | 
| 195 | 
            +
             * Do not use for sizing aligned buffers. Instead, use ZSTD_cwksp_aligned_alloc_size().
         | 
| 189 196 | 
             
             */
         | 
| 190 197 | 
             
            MEM_STATIC size_t ZSTD_cwksp_alloc_size(size_t size) {
         | 
| 191 | 
            -
             | 
| 198 | 
            +
                if (size == 0)
         | 
| 199 | 
            +
                    return 0;
         | 
| 200 | 
            +
            #if ZSTD_ADDRESS_SANITIZER && !defined (ZSTD_ASAN_DONT_POISON_WORKSPACE)
         | 
| 192 201 | 
             
                return size + 2 * ZSTD_CWKSP_ASAN_REDZONE_SIZE;
         | 
| 193 202 | 
             
            #else
         | 
| 194 203 | 
             
                return size;
         | 
| 195 204 | 
             
            #endif
         | 
| 196 205 | 
             
            }
         | 
| 197 206 |  | 
| 198 | 
            -
             | 
| 199 | 
            -
             | 
| 207 | 
            +
            /**
         | 
| 208 | 
            +
             * Returns an adjusted alloc size that is the nearest larger multiple of 64 bytes.
         | 
| 209 | 
            +
             * Used to determine the number of bytes required for a given "aligned".
         | 
| 210 | 
            +
             */
         | 
| 211 | 
            +
            MEM_STATIC size_t ZSTD_cwksp_aligned_alloc_size(size_t size) {
         | 
| 212 | 
            +
                return ZSTD_cwksp_alloc_size(ZSTD_cwksp_align(size, ZSTD_CWKSP_ALIGNMENT_BYTES));
         | 
| 213 | 
            +
            }
         | 
| 214 | 
            +
             | 
| 215 | 
            +
            /**
         | 
| 216 | 
            +
             * Returns the amount of additional space the cwksp must allocate
         | 
| 217 | 
            +
             * for internal purposes (currently only alignment).
         | 
| 218 | 
            +
             */
         | 
| 219 | 
            +
            MEM_STATIC size_t ZSTD_cwksp_slack_space_required(void) {
         | 
| 220 | 
            +
                /* For alignment, the wksp will always allocate an additional n_1=[1, 64] bytes
         | 
| 221 | 
            +
                 * to align the beginning of tables section, as well as another n_2=[0, 63] bytes
         | 
| 222 | 
            +
                 * to align the beginning of the aligned section.
         | 
| 223 | 
            +
                 *
         | 
| 224 | 
            +
                 * n_1 + n_2 == 64 bytes if the cwksp is freshly allocated, due to tables and
         | 
| 225 | 
            +
                 * aligneds being sized in multiples of 64 bytes.
         | 
| 226 | 
            +
                 */
         | 
| 227 | 
            +
                size_t const slackSpace = ZSTD_CWKSP_ALIGNMENT_BYTES;
         | 
| 228 | 
            +
                return slackSpace;
         | 
| 229 | 
            +
            }
         | 
| 230 | 
            +
             | 
| 231 | 
            +
             | 
| 232 | 
            +
            /**
         | 
| 233 | 
            +
             * Return the number of additional bytes required to align a pointer to the given number of bytes.
         | 
| 234 | 
            +
             * alignBytes must be a power of two.
         | 
| 235 | 
            +
             */
         | 
| 236 | 
            +
            MEM_STATIC size_t ZSTD_cwksp_bytes_to_align_ptr(void* ptr, const size_t alignBytes) {
         | 
| 237 | 
            +
                size_t const alignBytesMask = alignBytes - 1;
         | 
| 238 | 
            +
                size_t const bytes = (alignBytes - ((size_t)ptr & (alignBytesMask))) & alignBytesMask;
         | 
| 239 | 
            +
                assert((alignBytes & alignBytesMask) == 0);
         | 
| 240 | 
            +
                assert(bytes != ZSTD_CWKSP_ALIGNMENT_BYTES);
         | 
| 241 | 
            +
                return bytes;
         | 
| 242 | 
            +
            }
         | 
| 243 | 
            +
             | 
| 244 | 
            +
            /**
         | 
| 245 | 
            +
             * Internal function. Do not use directly.
         | 
| 246 | 
            +
             * Reserves the given number of bytes within the aligned/buffer segment of the wksp,
         | 
| 247 | 
            +
             * which counts from the end of the wksp (as opposed to the object/table segment).
         | 
| 248 | 
            +
             *
         | 
| 249 | 
            +
             * Returns a pointer to the beginning of that space.
         | 
| 250 | 
            +
             */
         | 
| 251 | 
            +
            MEM_STATIC void*
         | 
| 252 | 
            +
            ZSTD_cwksp_reserve_internal_buffer_space(ZSTD_cwksp* ws, size_t const bytes)
         | 
| 253 | 
            +
            {
         | 
| 254 | 
            +
                void* const alloc = (BYTE*)ws->allocStart - bytes;
         | 
| 255 | 
            +
                void* const bottom = ws->tableEnd;
         | 
| 256 | 
            +
                DEBUGLOG(5, "cwksp: reserving %p %zd bytes, %zd bytes remaining",
         | 
| 257 | 
            +
                    alloc, bytes, ZSTD_cwksp_available_space(ws) - bytes);
         | 
| 258 | 
            +
                ZSTD_cwksp_assert_internal_consistency(ws);
         | 
| 259 | 
            +
                assert(alloc >= bottom);
         | 
| 260 | 
            +
                if (alloc < bottom) {
         | 
| 261 | 
            +
                    DEBUGLOG(4, "cwksp: alloc failed!");
         | 
| 262 | 
            +
                    ws->allocFailed = 1;
         | 
| 263 | 
            +
                    return NULL;
         | 
| 264 | 
            +
                }
         | 
| 265 | 
            +
                /* the area is reserved from the end of wksp.
         | 
| 266 | 
            +
                 * If it overlaps with tableValidEnd, it voids guarantees on values' range */
         | 
| 267 | 
            +
                if (alloc < ws->tableValidEnd) {
         | 
| 268 | 
            +
                    ws->tableValidEnd = alloc;
         | 
| 269 | 
            +
                }
         | 
| 270 | 
            +
                ws->allocStart = alloc;
         | 
| 271 | 
            +
                return alloc;
         | 
| 272 | 
            +
            }
         | 
| 273 | 
            +
             | 
| 274 | 
            +
            /**
         | 
| 275 | 
            +
             * Moves the cwksp to the next phase, and does any necessary allocations.
         | 
| 276 | 
            +
             * cwksp initialization must necessarily go through each phase in order.
         | 
| 277 | 
            +
             * Returns a 0 on success, or zstd error
         | 
| 278 | 
            +
             */
         | 
| 279 | 
            +
            MEM_STATIC size_t
         | 
| 280 | 
            +
            ZSTD_cwksp_internal_advance_phase(ZSTD_cwksp* ws, ZSTD_cwksp_alloc_phase_e phase)
         | 
| 281 | 
            +
            {
         | 
| 200 282 | 
             
                assert(phase >= ws->phase);
         | 
| 201 283 | 
             
                if (phase > ws->phase) {
         | 
| 284 | 
            +
                    /* Going from allocating objects to allocating buffers */
         | 
| 202 285 | 
             
                    if (ws->phase < ZSTD_cwksp_alloc_buffers &&
         | 
| 203 286 | 
             
                            phase >= ZSTD_cwksp_alloc_buffers) {
         | 
| 204 287 | 
             
                        ws->tableValidEnd = ws->objectEnd;
         | 
| 205 288 | 
             
                    }
         | 
| 289 | 
            +
             | 
| 290 | 
            +
                    /* Going from allocating buffers to allocating aligneds/tables */
         | 
| 206 291 | 
             
                    if (ws->phase < ZSTD_cwksp_alloc_aligned &&
         | 
| 207 292 | 
             
                            phase >= ZSTD_cwksp_alloc_aligned) {
         | 
| 208 | 
            -
                        /*  | 
| 209 | 
            -
             | 
| 210 | 
            -
             | 
| 211 | 
            -
             | 
| 212 | 
            -
             | 
| 213 | 
            -
             | 
| 214 | 
            -
             | 
| 215 | 
            -
                        ws->allocStart = (BYTE*)ws->allocStart - ((size_t)ws->allocStart & (sizeof(U32)-1));
         | 
| 216 | 
            -
                        if (ws->allocStart < ws->tableValidEnd) {
         | 
| 217 | 
            -
                            ws->tableValidEnd = ws->allocStart;
         | 
| 293 | 
            +
                        {   /* Align the start of the "aligned" to 64 bytes. Use [1, 64] bytes. */
         | 
| 294 | 
            +
                            size_t const bytesToAlign =
         | 
| 295 | 
            +
                                ZSTD_CWKSP_ALIGNMENT_BYTES - ZSTD_cwksp_bytes_to_align_ptr(ws->allocStart, ZSTD_CWKSP_ALIGNMENT_BYTES);
         | 
| 296 | 
            +
                            DEBUGLOG(5, "reserving aligned alignment addtl space: %zu", bytesToAlign);
         | 
| 297 | 
            +
                            ZSTD_STATIC_ASSERT((ZSTD_CWKSP_ALIGNMENT_BYTES & (ZSTD_CWKSP_ALIGNMENT_BYTES - 1)) == 0); /* power of 2 */
         | 
| 298 | 
            +
                            RETURN_ERROR_IF(!ZSTD_cwksp_reserve_internal_buffer_space(ws, bytesToAlign),
         | 
| 299 | 
            +
                                            memory_allocation, "aligned phase - alignment initial allocation failed!");
         | 
| 218 300 | 
             
                        }
         | 
| 219 | 
            -
             | 
| 301 | 
            +
                        {   /* Align the start of the tables to 64 bytes. Use [0, 63] bytes */
         | 
| 302 | 
            +
                            void* const alloc = ws->objectEnd;
         | 
| 303 | 
            +
                            size_t const bytesToAlign = ZSTD_cwksp_bytes_to_align_ptr(alloc, ZSTD_CWKSP_ALIGNMENT_BYTES);
         | 
| 304 | 
            +
                            void* const objectEnd = (BYTE*)alloc + bytesToAlign;
         | 
| 305 | 
            +
                            DEBUGLOG(5, "reserving table alignment addtl space: %zu", bytesToAlign);
         | 
| 306 | 
            +
                            RETURN_ERROR_IF(objectEnd > ws->workspaceEnd, memory_allocation,
         | 
| 307 | 
            +
                                            "table phase - alignment initial allocation failed!");
         | 
| 308 | 
            +
                            ws->objectEnd = objectEnd;
         | 
| 309 | 
            +
                            ws->tableEnd = objectEnd;  /* table area starts being empty */
         | 
| 310 | 
            +
                            if (ws->tableValidEnd < ws->tableEnd) {
         | 
| 311 | 
            +
                                ws->tableValidEnd = ws->tableEnd;
         | 
| 312 | 
            +
                    }   }   }
         | 
| 220 313 | 
             
                    ws->phase = phase;
         | 
| 314 | 
            +
                    ZSTD_cwksp_assert_internal_consistency(ws);
         | 
| 221 315 | 
             
                }
         | 
| 316 | 
            +
                return 0;
         | 
| 222 317 | 
             
            }
         | 
| 223 318 |  | 
| 224 319 | 
             
            /**
         | 
| 225 320 | 
             
             * Returns whether this object/buffer/etc was allocated in this workspace.
         | 
| 226 321 | 
             
             */
         | 
| 227 | 
            -
            MEM_STATIC int ZSTD_cwksp_owns_buffer(const ZSTD_cwksp* ws, const void* ptr) | 
| 322 | 
            +
            MEM_STATIC int ZSTD_cwksp_owns_buffer(const ZSTD_cwksp* ws, const void* ptr)
         | 
| 323 | 
            +
            {
         | 
| 228 324 | 
             
                return (ptr != NULL) && (ws->workspace <= ptr) && (ptr <= ws->workspaceEnd);
         | 
| 229 325 | 
             
            }
         | 
| 230 326 |  | 
| 231 327 | 
             
            /**
         | 
| 232 328 | 
             
             * Internal function. Do not use directly.
         | 
| 233 329 | 
             
             */
         | 
| 234 | 
            -
            MEM_STATIC void* | 
| 235 | 
            -
             | 
| 330 | 
            +
            MEM_STATIC void*
         | 
| 331 | 
            +
            ZSTD_cwksp_reserve_internal(ZSTD_cwksp* ws, size_t bytes, ZSTD_cwksp_alloc_phase_e phase)
         | 
| 332 | 
            +
            {
         | 
| 236 333 | 
             
                void* alloc;
         | 
| 237 | 
            -
                 | 
| 238 | 
            -
             | 
| 239 | 
            -
                 | 
| 334 | 
            +
                if (ZSTD_isError(ZSTD_cwksp_internal_advance_phase(ws, phase)) || bytes == 0) {
         | 
| 335 | 
            +
                    return NULL;
         | 
| 336 | 
            +
                }
         | 
| 240 337 |  | 
| 241 | 
            -
            #if  | 
| 338 | 
            +
            #if ZSTD_ADDRESS_SANITIZER && !defined (ZSTD_ASAN_DONT_POISON_WORKSPACE)
         | 
| 242 339 | 
             
                /* over-reserve space */
         | 
| 243 | 
            -
                 | 
| 340 | 
            +
                bytes += 2 * ZSTD_CWKSP_ASAN_REDZONE_SIZE;
         | 
| 244 341 | 
             
            #endif
         | 
| 245 342 |  | 
| 246 | 
            -
                 | 
| 247 | 
            -
                    alloc, bytes, ZSTD_cwksp_available_space(ws) - bytes);
         | 
| 248 | 
            -
                ZSTD_cwksp_assert_internal_consistency(ws);
         | 
| 249 | 
            -
                assert(alloc >= bottom);
         | 
| 250 | 
            -
                if (alloc < bottom) {
         | 
| 251 | 
            -
                    DEBUGLOG(4, "cwksp: alloc failed!");
         | 
| 252 | 
            -
                    ws->allocFailed = 1;
         | 
| 253 | 
            -
                    return NULL;
         | 
| 254 | 
            -
                }
         | 
| 255 | 
            -
                if (alloc < ws->tableValidEnd) {
         | 
| 256 | 
            -
                    ws->tableValidEnd = alloc;
         | 
| 257 | 
            -
                }
         | 
| 258 | 
            -
                ws->allocStart = alloc;
         | 
| 343 | 
            +
                alloc = ZSTD_cwksp_reserve_internal_buffer_space(ws, bytes);
         | 
| 259 344 |  | 
| 260 | 
            -
            #if  | 
| 345 | 
            +
            #if ZSTD_ADDRESS_SANITIZER && !defined (ZSTD_ASAN_DONT_POISON_WORKSPACE)
         | 
| 261 346 | 
             
                /* Move alloc so there's ZSTD_CWKSP_ASAN_REDZONE_SIZE unused space on
         | 
| 262 347 | 
             
                 * either size. */
         | 
| 263 | 
            -
                 | 
| 264 | 
            -
             | 
| 348 | 
            +
                if (alloc) {
         | 
| 349 | 
            +
                    alloc = (BYTE *)alloc + ZSTD_CWKSP_ASAN_REDZONE_SIZE;
         | 
| 350 | 
            +
                    if (ws->isStatic == ZSTD_cwksp_dynamic_alloc) {
         | 
| 351 | 
            +
                        __asan_unpoison_memory_region(alloc, bytes);
         | 
| 352 | 
            +
                    }
         | 
| 353 | 
            +
                }
         | 
| 265 354 | 
             
            #endif
         | 
| 266 355 |  | 
| 267 356 | 
             
                return alloc;
         | 
| @@ -270,33 +359,44 @@ MEM_STATIC void* ZSTD_cwksp_reserve_internal( | |
| 270 359 | 
             
            /**
         | 
| 271 360 | 
             
             * Reserves and returns unaligned memory.
         | 
| 272 361 | 
             
             */
         | 
| 273 | 
            -
            MEM_STATIC BYTE* ZSTD_cwksp_reserve_buffer(ZSTD_cwksp* ws, size_t bytes) | 
| 362 | 
            +
            MEM_STATIC BYTE* ZSTD_cwksp_reserve_buffer(ZSTD_cwksp* ws, size_t bytes)
         | 
| 363 | 
            +
            {
         | 
| 274 364 | 
             
                return (BYTE*)ZSTD_cwksp_reserve_internal(ws, bytes, ZSTD_cwksp_alloc_buffers);
         | 
| 275 365 | 
             
            }
         | 
| 276 366 |  | 
| 277 367 | 
             
            /**
         | 
| 278 | 
            -
             * Reserves and returns memory sized on and aligned on  | 
| 368 | 
            +
             * Reserves and returns memory sized on and aligned on ZSTD_CWKSP_ALIGNMENT_BYTES (64 bytes).
         | 
| 279 369 | 
             
             */
         | 
| 280 | 
            -
            MEM_STATIC void* ZSTD_cwksp_reserve_aligned(ZSTD_cwksp* ws, size_t bytes) | 
| 281 | 
            -
             | 
| 282 | 
            -
                 | 
| 370 | 
            +
            MEM_STATIC void* ZSTD_cwksp_reserve_aligned(ZSTD_cwksp* ws, size_t bytes)
         | 
| 371 | 
            +
            {
         | 
| 372 | 
            +
                void* ptr = ZSTD_cwksp_reserve_internal(ws, ZSTD_cwksp_align(bytes, ZSTD_CWKSP_ALIGNMENT_BYTES),
         | 
| 373 | 
            +
                                                        ZSTD_cwksp_alloc_aligned);
         | 
| 374 | 
            +
                assert(((size_t)ptr & (ZSTD_CWKSP_ALIGNMENT_BYTES-1))== 0);
         | 
| 375 | 
            +
                return ptr;
         | 
| 283 376 | 
             
            }
         | 
| 284 377 |  | 
| 285 378 | 
             
            /**
         | 
| 286 | 
            -
             * Aligned on  | 
| 379 | 
            +
             * Aligned on 64 bytes. These buffers have the special property that
         | 
| 287 380 | 
             
             * their values remain constrained, allowing us to re-use them without
         | 
| 288 381 | 
             
             * memset()-ing them.
         | 
| 289 382 | 
             
             */
         | 
| 290 | 
            -
            MEM_STATIC void* ZSTD_cwksp_reserve_table(ZSTD_cwksp* ws, size_t bytes) | 
| 383 | 
            +
            MEM_STATIC void* ZSTD_cwksp_reserve_table(ZSTD_cwksp* ws, size_t bytes)
         | 
| 384 | 
            +
            {
         | 
| 291 385 | 
             
                const ZSTD_cwksp_alloc_phase_e phase = ZSTD_cwksp_alloc_aligned;
         | 
| 292 | 
            -
                void* alloc | 
| 293 | 
            -
                void* end | 
| 294 | 
            -
                void* top | 
| 386 | 
            +
                void* alloc;
         | 
| 387 | 
            +
                void* end;
         | 
| 388 | 
            +
                void* top;
         | 
| 389 | 
            +
             | 
| 390 | 
            +
                if (ZSTD_isError(ZSTD_cwksp_internal_advance_phase(ws, phase))) {
         | 
| 391 | 
            +
                    return NULL;
         | 
| 392 | 
            +
                }
         | 
| 393 | 
            +
                alloc = ws->tableEnd;
         | 
| 394 | 
            +
                end = (BYTE *)alloc + bytes;
         | 
| 395 | 
            +
                top = ws->allocStart;
         | 
| 295 396 |  | 
| 296 397 | 
             
                DEBUGLOG(5, "cwksp: reserving %p table %zd bytes, %zd bytes remaining",
         | 
| 297 398 | 
             
                    alloc, bytes, ZSTD_cwksp_available_space(ws) - bytes);
         | 
| 298 399 | 
             
                assert((bytes & (sizeof(U32)-1)) == 0);
         | 
| 299 | 
            -
                ZSTD_cwksp_internal_advance_phase(ws, phase);
         | 
| 300 400 | 
             
                ZSTD_cwksp_assert_internal_consistency(ws);
         | 
| 301 401 | 
             
                assert(end <= top);
         | 
| 302 402 | 
             
                if (end > top) {
         | 
| @@ -306,35 +406,41 @@ MEM_STATIC void* ZSTD_cwksp_reserve_table(ZSTD_cwksp* ws, size_t bytes) { | |
| 306 406 | 
             
                }
         | 
| 307 407 | 
             
                ws->tableEnd = end;
         | 
| 308 408 |  | 
| 309 | 
            -
            #if  | 
| 310 | 
            -
                 | 
| 409 | 
            +
            #if ZSTD_ADDRESS_SANITIZER && !defined (ZSTD_ASAN_DONT_POISON_WORKSPACE)
         | 
| 410 | 
            +
                if (ws->isStatic == ZSTD_cwksp_dynamic_alloc) {
         | 
| 411 | 
            +
                    __asan_unpoison_memory_region(alloc, bytes);
         | 
| 412 | 
            +
                }
         | 
| 311 413 | 
             
            #endif
         | 
| 312 414 |  | 
| 415 | 
            +
                assert((bytes & (ZSTD_CWKSP_ALIGNMENT_BYTES-1)) == 0);
         | 
| 416 | 
            +
                assert(((size_t)alloc & (ZSTD_CWKSP_ALIGNMENT_BYTES-1))== 0);
         | 
| 313 417 | 
             
                return alloc;
         | 
| 314 418 | 
             
            }
         | 
| 315 419 |  | 
| 316 420 | 
             
            /**
         | 
| 317 421 | 
             
             * Aligned on sizeof(void*).
         | 
| 422 | 
            +
             * Note : should happen only once, at workspace first initialization
         | 
| 318 423 | 
             
             */
         | 
| 319 | 
            -
            MEM_STATIC void* ZSTD_cwksp_reserve_object(ZSTD_cwksp* ws, size_t bytes) | 
| 320 | 
            -
             | 
| 424 | 
            +
            MEM_STATIC void* ZSTD_cwksp_reserve_object(ZSTD_cwksp* ws, size_t bytes)
         | 
| 425 | 
            +
            {
         | 
| 426 | 
            +
                size_t const roundedBytes = ZSTD_cwksp_align(bytes, sizeof(void*));
         | 
| 321 427 | 
             
                void* alloc = ws->objectEnd;
         | 
| 322 428 | 
             
                void* end = (BYTE*)alloc + roundedBytes;
         | 
| 323 429 |  | 
| 324 | 
            -
            #if  | 
| 430 | 
            +
            #if ZSTD_ADDRESS_SANITIZER && !defined (ZSTD_ASAN_DONT_POISON_WORKSPACE)
         | 
| 325 431 | 
             
                /* over-reserve space */
         | 
| 326 432 | 
             
                end = (BYTE *)end + 2 * ZSTD_CWKSP_ASAN_REDZONE_SIZE;
         | 
| 327 433 | 
             
            #endif
         | 
| 328 434 |  | 
| 329 | 
            -
                DEBUGLOG( | 
| 435 | 
            +
                DEBUGLOG(4,
         | 
| 330 436 | 
             
                    "cwksp: reserving %p object %zd bytes (rounded to %zd), %zd bytes remaining",
         | 
| 331 437 | 
             
                    alloc, bytes, roundedBytes, ZSTD_cwksp_available_space(ws) - roundedBytes);
         | 
| 332 | 
            -
                assert(( | 
| 333 | 
            -
                assert( | 
| 438 | 
            +
                assert((size_t)alloc % ZSTD_ALIGNOF(void*) == 0);
         | 
| 439 | 
            +
                assert(bytes % ZSTD_ALIGNOF(void*) == 0);
         | 
| 334 440 | 
             
                ZSTD_cwksp_assert_internal_consistency(ws);
         | 
| 335 441 | 
             
                /* we must be in the first phase, no advance is possible */
         | 
| 336 442 | 
             
                if (ws->phase != ZSTD_cwksp_alloc_objects || end > ws->workspaceEnd) {
         | 
| 337 | 
            -
                    DEBUGLOG( | 
| 443 | 
            +
                    DEBUGLOG(3, "cwksp: object alloc failed!");
         | 
| 338 444 | 
             
                    ws->allocFailed = 1;
         | 
| 339 445 | 
             
                    return NULL;
         | 
| 340 446 | 
             
                }
         | 
| @@ -342,20 +448,23 @@ MEM_STATIC void* ZSTD_cwksp_reserve_object(ZSTD_cwksp* ws, size_t bytes) { | |
| 342 448 | 
             
                ws->tableEnd = end;
         | 
| 343 449 | 
             
                ws->tableValidEnd = end;
         | 
| 344 450 |  | 
| 345 | 
            -
            #if  | 
| 451 | 
            +
            #if ZSTD_ADDRESS_SANITIZER && !defined (ZSTD_ASAN_DONT_POISON_WORKSPACE)
         | 
| 346 452 | 
             
                /* Move alloc so there's ZSTD_CWKSP_ASAN_REDZONE_SIZE unused space on
         | 
| 347 453 | 
             
                 * either size. */
         | 
| 348 | 
            -
                alloc = (BYTE | 
| 349 | 
            -
                 | 
| 454 | 
            +
                alloc = (BYTE*)alloc + ZSTD_CWKSP_ASAN_REDZONE_SIZE;
         | 
| 455 | 
            +
                if (ws->isStatic == ZSTD_cwksp_dynamic_alloc) {
         | 
| 456 | 
            +
                    __asan_unpoison_memory_region(alloc, bytes);
         | 
| 457 | 
            +
                }
         | 
| 350 458 | 
             
            #endif
         | 
| 351 459 |  | 
| 352 460 | 
             
                return alloc;
         | 
| 353 461 | 
             
            }
         | 
| 354 462 |  | 
| 355 | 
            -
            MEM_STATIC void ZSTD_cwksp_mark_tables_dirty(ZSTD_cwksp* ws) | 
| 463 | 
            +
            MEM_STATIC void ZSTD_cwksp_mark_tables_dirty(ZSTD_cwksp* ws)
         | 
| 464 | 
            +
            {
         | 
| 356 465 | 
             
                DEBUGLOG(4, "cwksp: ZSTD_cwksp_mark_tables_dirty");
         | 
| 357 466 |  | 
| 358 | 
            -
            #if  | 
| 467 | 
            +
            #if ZSTD_MEMORY_SANITIZER && !defined (ZSTD_MSAN_DONT_POISON_WORKSPACE)
         | 
| 359 468 | 
             
                /* To validate that the table re-use logic is sound, and that we don't
         | 
| 360 469 | 
             
                 * access table space that we haven't cleaned, we re-"poison" the table
         | 
| 361 470 | 
             
                 * space every time we mark it dirty. */
         | 
| @@ -390,7 +499,7 @@ MEM_STATIC void ZSTD_cwksp_clean_tables(ZSTD_cwksp* ws) { | |
| 390 499 | 
             
                assert(ws->tableValidEnd >= ws->objectEnd);
         | 
| 391 500 | 
             
                assert(ws->tableValidEnd <= ws->allocStart);
         | 
| 392 501 | 
             
                if (ws->tableValidEnd < ws->tableEnd) {
         | 
| 393 | 
            -
                     | 
| 502 | 
            +
                    ZSTD_memset(ws->tableValidEnd, 0, (BYTE*)ws->tableEnd - (BYTE*)ws->tableValidEnd);
         | 
| 394 503 | 
             
                }
         | 
| 395 504 | 
             
                ZSTD_cwksp_mark_tables_clean(ws);
         | 
| 396 505 | 
             
            }
         | 
| @@ -402,8 +511,12 @@ MEM_STATIC void ZSTD_cwksp_clean_tables(ZSTD_cwksp* ws) { | |
| 402 511 | 
             
            MEM_STATIC void ZSTD_cwksp_clear_tables(ZSTD_cwksp* ws) {
         | 
| 403 512 | 
             
                DEBUGLOG(4, "cwksp: clearing tables!");
         | 
| 404 513 |  | 
| 405 | 
            -
            #if  | 
| 406 | 
            -
                 | 
| 514 | 
            +
            #if ZSTD_ADDRESS_SANITIZER && !defined (ZSTD_ASAN_DONT_POISON_WORKSPACE)
         | 
| 515 | 
            +
                /* We don't do this when the workspace is statically allocated, because
         | 
| 516 | 
            +
                 * when that is the case, we have no capability to hook into the end of the
         | 
| 517 | 
            +
                 * workspace's lifecycle to unpoison the memory.
         | 
| 518 | 
            +
                 */
         | 
| 519 | 
            +
                if (ws->isStatic == ZSTD_cwksp_dynamic_alloc) {
         | 
| 407 520 | 
             
                    size_t size = (BYTE*)ws->tableValidEnd - (BYTE*)ws->objectEnd;
         | 
| 408 521 | 
             
                    __asan_poison_memory_region(ws->objectEnd, size);
         | 
| 409 522 | 
             
                }
         | 
| @@ -420,7 +533,7 @@ MEM_STATIC void ZSTD_cwksp_clear_tables(ZSTD_cwksp* ws) { | |
| 420 533 | 
             
            MEM_STATIC void ZSTD_cwksp_clear(ZSTD_cwksp* ws) {
         | 
| 421 534 | 
             
                DEBUGLOG(4, "cwksp: clearing!");
         | 
| 422 535 |  | 
| 423 | 
            -
            #if  | 
| 536 | 
            +
            #if ZSTD_MEMORY_SANITIZER && !defined (ZSTD_MSAN_DONT_POISON_WORKSPACE)
         | 
| 424 537 | 
             
                /* To validate that the context re-use logic is sound, and that we don't
         | 
| 425 538 | 
             
                 * access stuff that this compression hasn't initialized, we re-"poison"
         | 
| 426 539 | 
             
                 * the workspace (or at least the non-static, non-table parts of it)
         | 
| @@ -431,8 +544,12 @@ MEM_STATIC void ZSTD_cwksp_clear(ZSTD_cwksp* ws) { | |
| 431 544 | 
             
                }
         | 
| 432 545 | 
             
            #endif
         | 
| 433 546 |  | 
| 434 | 
            -
            #if  | 
| 435 | 
            -
                 | 
| 547 | 
            +
            #if ZSTD_ADDRESS_SANITIZER && !defined (ZSTD_ASAN_DONT_POISON_WORKSPACE)
         | 
| 548 | 
            +
                /* We don't do this when the workspace is statically allocated, because
         | 
| 549 | 
            +
                 * when that is the case, we have no capability to hook into the end of the
         | 
| 550 | 
            +
                 * workspace's lifecycle to unpoison the memory.
         | 
| 551 | 
            +
                 */
         | 
| 552 | 
            +
                if (ws->isStatic == ZSTD_cwksp_dynamic_alloc) {
         | 
| 436 553 | 
             
                    size_t size = (BYTE*)ws->workspaceEnd - (BYTE*)ws->objectEnd;
         | 
| 437 554 | 
             
                    __asan_poison_memory_region(ws->objectEnd, size);
         | 
| 438 555 | 
             
                }
         | 
| @@ -452,7 +569,7 @@ MEM_STATIC void ZSTD_cwksp_clear(ZSTD_cwksp* ws) { | |
| 452 569 | 
             
             * Any existing values in the workspace are ignored (the previously managed
         | 
| 453 570 | 
             
             * buffer, if present, must be separately freed).
         | 
| 454 571 | 
             
             */
         | 
| 455 | 
            -
            MEM_STATIC void ZSTD_cwksp_init(ZSTD_cwksp* ws, void* start, size_t size) {
         | 
| 572 | 
            +
            MEM_STATIC void ZSTD_cwksp_init(ZSTD_cwksp* ws, void* start, size_t size, ZSTD_cwksp_static_alloc_e isStatic) {
         | 
| 456 573 | 
             
                DEBUGLOG(4, "cwksp: init'ing workspace with %zd bytes", size);
         | 
| 457 574 | 
             
                assert(((size_t)start & (sizeof(void*)-1)) == 0); /* ensure correct alignment */
         | 
| 458 575 | 
             
                ws->workspace = start;
         | 
| @@ -460,39 +577,45 @@ MEM_STATIC void ZSTD_cwksp_init(ZSTD_cwksp* ws, void* start, size_t size) { | |
| 460 577 | 
             
                ws->objectEnd = ws->workspace;
         | 
| 461 578 | 
             
                ws->tableValidEnd = ws->objectEnd;
         | 
| 462 579 | 
             
                ws->phase = ZSTD_cwksp_alloc_objects;
         | 
| 580 | 
            +
                ws->isStatic = isStatic;
         | 
| 463 581 | 
             
                ZSTD_cwksp_clear(ws);
         | 
| 464 582 | 
             
                ws->workspaceOversizedDuration = 0;
         | 
| 465 583 | 
             
                ZSTD_cwksp_assert_internal_consistency(ws);
         | 
| 466 584 | 
             
            }
         | 
| 467 585 |  | 
| 468 586 | 
             
            MEM_STATIC size_t ZSTD_cwksp_create(ZSTD_cwksp* ws, size_t size, ZSTD_customMem customMem) {
         | 
| 469 | 
            -
                void* workspace =  | 
| 587 | 
            +
                void* workspace = ZSTD_customMalloc(size, customMem);
         | 
| 470 588 | 
             
                DEBUGLOG(4, "cwksp: creating new workspace with %zd bytes", size);
         | 
| 471 | 
            -
                RETURN_ERROR_IF(workspace == NULL, memory_allocation);
         | 
| 472 | 
            -
                ZSTD_cwksp_init(ws, workspace, size);
         | 
| 589 | 
            +
                RETURN_ERROR_IF(workspace == NULL, memory_allocation, "NULL pointer!");
         | 
| 590 | 
            +
                ZSTD_cwksp_init(ws, workspace, size, ZSTD_cwksp_dynamic_alloc);
         | 
| 473 591 | 
             
                return 0;
         | 
| 474 592 | 
             
            }
         | 
| 475 593 |  | 
| 476 594 | 
             
            MEM_STATIC void ZSTD_cwksp_free(ZSTD_cwksp* ws, ZSTD_customMem customMem) {
         | 
| 477 595 | 
             
                void *ptr = ws->workspace;
         | 
| 478 596 | 
             
                DEBUGLOG(4, "cwksp: freeing workspace");
         | 
| 479 | 
            -
                 | 
| 480 | 
            -
                 | 
| 597 | 
            +
                ZSTD_memset(ws, 0, sizeof(ZSTD_cwksp));
         | 
| 598 | 
            +
                ZSTD_customFree(ptr, customMem);
         | 
| 481 599 | 
             
            }
         | 
| 482 600 |  | 
| 483 601 | 
             
            /**
         | 
| 484 602 | 
             
             * Moves the management of a workspace from one cwksp to another. The src cwksp
         | 
| 485 | 
            -
             * is left in an invalid state (src must be re-init()'ed before  | 
| 603 | 
            +
             * is left in an invalid state (src must be re-init()'ed before it's used again).
         | 
| 486 604 | 
             
             */
         | 
| 487 605 | 
             
            MEM_STATIC void ZSTD_cwksp_move(ZSTD_cwksp* dst, ZSTD_cwksp* src) {
         | 
| 488 606 | 
             
                *dst = *src;
         | 
| 489 | 
            -
                 | 
| 607 | 
            +
                ZSTD_memset(src, 0, sizeof(ZSTD_cwksp));
         | 
| 490 608 | 
             
            }
         | 
| 491 609 |  | 
| 492 610 | 
             
            MEM_STATIC size_t ZSTD_cwksp_sizeof(const ZSTD_cwksp* ws) {
         | 
| 493 611 | 
             
                return (size_t)((BYTE*)ws->workspaceEnd - (BYTE*)ws->workspace);
         | 
| 494 612 | 
             
            }
         | 
| 495 613 |  | 
| 614 | 
            +
            MEM_STATIC size_t ZSTD_cwksp_used(const ZSTD_cwksp* ws) {
         | 
| 615 | 
            +
                return (size_t)((BYTE*)ws->tableEnd - (BYTE*)ws->workspace)
         | 
| 616 | 
            +
                     + (size_t)((BYTE*)ws->workspaceEnd - (BYTE*)ws->allocStart);
         | 
| 617 | 
            +
            }
         | 
| 618 | 
            +
             | 
| 496 619 | 
             
            MEM_STATIC int ZSTD_cwksp_reserve_failed(const ZSTD_cwksp* ws) {
         | 
| 497 620 | 
             
                return ws->allocFailed;
         | 
| 498 621 | 
             
            }
         | 
| @@ -501,6 +624,24 @@ MEM_STATIC int ZSTD_cwksp_reserve_failed(const ZSTD_cwksp* ws) { | |
| 501 624 | 
             
            *  Functions Checking Free Space
         | 
| 502 625 | 
             
            ***************************************/
         | 
| 503 626 |  | 
| 627 | 
            +
            /* ZSTD_alignmentSpaceWithinBounds() :
         | 
| 628 | 
            +
             * Returns if the estimated space needed for a wksp is within an acceptable limit of the
         | 
| 629 | 
            +
             * actual amount of space used.
         | 
| 630 | 
            +
             */
         | 
| 631 | 
            +
            MEM_STATIC int ZSTD_cwksp_estimated_space_within_bounds(const ZSTD_cwksp* const ws,
         | 
| 632 | 
            +
                                                                    size_t const estimatedSpace, int resizedWorkspace) {
         | 
| 633 | 
            +
                if (resizedWorkspace) {
         | 
| 634 | 
            +
                    /* Resized/newly allocated wksp should have exact bounds */
         | 
| 635 | 
            +
                    return ZSTD_cwksp_used(ws) == estimatedSpace;
         | 
| 636 | 
            +
                } else {
         | 
| 637 | 
            +
                    /* Due to alignment, when reusing a workspace, we can actually consume 63 fewer or more bytes
         | 
| 638 | 
            +
                     * than estimatedSpace. See the comments in zstd_cwksp.h for details.
         | 
| 639 | 
            +
                     */
         | 
| 640 | 
            +
                    return (ZSTD_cwksp_used(ws) >= estimatedSpace - 63) && (ZSTD_cwksp_used(ws) <= estimatedSpace + 63);
         | 
| 641 | 
            +
                }
         | 
| 642 | 
            +
            }
         | 
| 643 | 
            +
             | 
| 644 | 
            +
             | 
| 504 645 | 
             
            MEM_STATIC size_t ZSTD_cwksp_available_space(ZSTD_cwksp* ws) {
         | 
| 505 646 | 
             
                return (size_t)((BYTE*)ws->allocStart - (BYTE*)ws->tableEnd);
         | 
| 506 647 | 
             
            }
         |