Merge pull request #3789 from facebook/fix_flexArray_fse
solving flexArray issue #3785 in fse
This commit is contained in:
+3
-2
@@ -229,6 +229,7 @@ If there is an error, the function will return an error code, which can be teste
|
|||||||
|
|
||||||
#endif /* FSE_H */
|
#endif /* FSE_H */
|
||||||
|
|
||||||
|
|
||||||
#if defined(FSE_STATIC_LINKING_ONLY) && !defined(FSE_H_FSE_STATIC_LINKING_ONLY)
|
#if defined(FSE_STATIC_LINKING_ONLY) && !defined(FSE_H_FSE_STATIC_LINKING_ONLY)
|
||||||
#define FSE_H_FSE_STATIC_LINKING_ONLY
|
#define FSE_H_FSE_STATIC_LINKING_ONLY
|
||||||
|
|
||||||
@@ -464,13 +465,13 @@ MEM_STATIC void FSE_encodeSymbol(BIT_CStream_t* bitC, FSE_CState_t* statePtr, un
|
|||||||
FSE_symbolCompressionTransform const symbolTT = ((const FSE_symbolCompressionTransform*)(statePtr->symbolTT))[symbol];
|
FSE_symbolCompressionTransform const symbolTT = ((const FSE_symbolCompressionTransform*)(statePtr->symbolTT))[symbol];
|
||||||
const U16* const stateTable = (const U16*)(statePtr->stateTable);
|
const U16* const stateTable = (const U16*)(statePtr->stateTable);
|
||||||
U32 const nbBitsOut = (U32)((statePtr->value + symbolTT.deltaNbBits) >> 16);
|
U32 const nbBitsOut = (U32)((statePtr->value + symbolTT.deltaNbBits) >> 16);
|
||||||
BIT_addBits(bitC, statePtr->value, nbBitsOut);
|
BIT_addBits(bitC, (size_t)statePtr->value, nbBitsOut);
|
||||||
statePtr->value = stateTable[ (statePtr->value >> nbBitsOut) + symbolTT.deltaFindState];
|
statePtr->value = stateTable[ (statePtr->value >> nbBitsOut) + symbolTT.deltaFindState];
|
||||||
}
|
}
|
||||||
|
|
||||||
MEM_STATIC void FSE_flushCState(BIT_CStream_t* bitC, const FSE_CState_t* statePtr)
|
MEM_STATIC void FSE_flushCState(BIT_CStream_t* bitC, const FSE_CState_t* statePtr)
|
||||||
{
|
{
|
||||||
BIT_addBits(bitC, statePtr->value, statePtr->stateLog);
|
BIT_addBits(bitC, (size_t)statePtr->value, statePtr->stateLog);
|
||||||
BIT_flushBits(bitC);
|
BIT_flushBits(bitC);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+19
-17
@@ -22,8 +22,7 @@
|
|||||||
#define FSE_STATIC_LINKING_ONLY
|
#define FSE_STATIC_LINKING_ONLY
|
||||||
#include "fse.h"
|
#include "fse.h"
|
||||||
#include "error_private.h"
|
#include "error_private.h"
|
||||||
#define ZSTD_DEPS_NEED_MALLOC
|
#include "zstd_deps.h" /* ZSTD_memcpy */
|
||||||
#include "zstd_deps.h"
|
|
||||||
#include "bits.h" /* ZSTD_highbit32 */
|
#include "bits.h" /* ZSTD_highbit32 */
|
||||||
|
|
||||||
|
|
||||||
@@ -84,7 +83,7 @@ static size_t FSE_buildDTable_internal(FSE_DTable* dt, const short* normalizedCo
|
|||||||
symbolNext[s] = 1;
|
symbolNext[s] = 1;
|
||||||
} else {
|
} else {
|
||||||
if (normalizedCounter[s] >= largeLimit) DTableH.fastMode=0;
|
if (normalizedCounter[s] >= largeLimit) DTableH.fastMode=0;
|
||||||
symbolNext[s] = normalizedCounter[s];
|
symbolNext[s] = (U16)normalizedCounter[s];
|
||||||
} } }
|
} } }
|
||||||
ZSTD_memcpy(dt, &DTableH, sizeof(DTableH));
|
ZSTD_memcpy(dt, &DTableH, sizeof(DTableH));
|
||||||
}
|
}
|
||||||
@@ -99,8 +98,7 @@ static size_t FSE_buildDTable_internal(FSE_DTable* dt, const short* normalizedCo
|
|||||||
* all symbols have counts <= 8. We ensure we have 8 bytes at the end of
|
* all symbols have counts <= 8. We ensure we have 8 bytes at the end of
|
||||||
* our buffer to handle the over-write.
|
* our buffer to handle the over-write.
|
||||||
*/
|
*/
|
||||||
{
|
{ U64 const add = 0x0101010101010101ull;
|
||||||
U64 const add = 0x0101010101010101ull;
|
|
||||||
size_t pos = 0;
|
size_t pos = 0;
|
||||||
U64 sv = 0;
|
U64 sv = 0;
|
||||||
U32 s;
|
U32 s;
|
||||||
@@ -111,9 +109,8 @@ static size_t FSE_buildDTable_internal(FSE_DTable* dt, const short* normalizedCo
|
|||||||
for (i = 8; i < n; i += 8) {
|
for (i = 8; i < n; i += 8) {
|
||||||
MEM_write64(spread + pos + i, sv);
|
MEM_write64(spread + pos + i, sv);
|
||||||
}
|
}
|
||||||
pos += n;
|
pos += (size_t)n;
|
||||||
}
|
} }
|
||||||
}
|
|
||||||
/* Now we spread those positions across the table.
|
/* Now we spread those positions across the table.
|
||||||
* The benefit of doing it in two stages is that we avoid the
|
* The benefit of doing it in two stages is that we avoid the
|
||||||
* variable size inner loop, which caused lots of branch misses.
|
* variable size inner loop, which caused lots of branch misses.
|
||||||
@@ -232,12 +229,12 @@ FORCE_INLINE_TEMPLATE size_t FSE_decompress_usingDTable_generic(
|
|||||||
break;
|
break;
|
||||||
} }
|
} }
|
||||||
|
|
||||||
return op-ostart;
|
assert(op >= ostart);
|
||||||
|
return (size_t)(op-ostart);
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
short ncount[FSE_MAX_SYMBOL_VALUE + 1];
|
short ncount[FSE_MAX_SYMBOL_VALUE + 1];
|
||||||
FSE_DTable dtable[1]; /* Dynamically sized */
|
|
||||||
} FSE_DecompressWksp;
|
} FSE_DecompressWksp;
|
||||||
|
|
||||||
|
|
||||||
@@ -252,13 +249,18 @@ FORCE_INLINE_TEMPLATE size_t FSE_decompress_wksp_body(
|
|||||||
unsigned tableLog;
|
unsigned tableLog;
|
||||||
unsigned maxSymbolValue = FSE_MAX_SYMBOL_VALUE;
|
unsigned maxSymbolValue = FSE_MAX_SYMBOL_VALUE;
|
||||||
FSE_DecompressWksp* const wksp = (FSE_DecompressWksp*)workSpace;
|
FSE_DecompressWksp* const wksp = (FSE_DecompressWksp*)workSpace;
|
||||||
|
size_t const dtablePos = sizeof(FSE_DecompressWksp) / sizeof(FSE_DTable);
|
||||||
|
FSE_DTable* const dtable = (FSE_DTable*)workSpace + dtablePos;
|
||||||
|
|
||||||
DEBUG_STATIC_ASSERT((FSE_MAX_SYMBOL_VALUE + 1) % 2 == 0);
|
FSE_STATIC_ASSERT((FSE_MAX_SYMBOL_VALUE + 1) % 2 == 0);
|
||||||
if (wkspSize < sizeof(*wksp)) return ERROR(GENERIC);
|
if (wkspSize < sizeof(*wksp)) return ERROR(GENERIC);
|
||||||
|
|
||||||
|
/* correct offset to dtable depends on this property */
|
||||||
|
FSE_STATIC_ASSERT(sizeof(FSE_DecompressWksp) % sizeof(FSE_DTable) == 0);
|
||||||
|
|
||||||
/* normal FSE decoding mode */
|
/* normal FSE decoding mode */
|
||||||
{
|
{ size_t const NCountLength =
|
||||||
size_t const NCountLength = FSE_readNCount_bmi2(wksp->ncount, &maxSymbolValue, &tableLog, istart, cSrcSize, bmi2);
|
FSE_readNCount_bmi2(wksp->ncount, &maxSymbolValue, &tableLog, istart, cSrcSize, bmi2);
|
||||||
if (FSE_isError(NCountLength)) return NCountLength;
|
if (FSE_isError(NCountLength)) return NCountLength;
|
||||||
if (tableLog > maxLog) return ERROR(tableLog_tooLarge);
|
if (tableLog > maxLog) return ERROR(tableLog_tooLarge);
|
||||||
assert(NCountLength <= cSrcSize);
|
assert(NCountLength <= cSrcSize);
|
||||||
@@ -271,16 +273,16 @@ FORCE_INLINE_TEMPLATE size_t FSE_decompress_wksp_body(
|
|||||||
workSpace = (BYTE*)workSpace + sizeof(*wksp) + FSE_DTABLE_SIZE(tableLog);
|
workSpace = (BYTE*)workSpace + sizeof(*wksp) + FSE_DTABLE_SIZE(tableLog);
|
||||||
wkspSize -= sizeof(*wksp) + FSE_DTABLE_SIZE(tableLog);
|
wkspSize -= sizeof(*wksp) + FSE_DTABLE_SIZE(tableLog);
|
||||||
|
|
||||||
CHECK_F( FSE_buildDTable_internal(wksp->dtable, wksp->ncount, maxSymbolValue, tableLog, workSpace, wkspSize) );
|
CHECK_F( FSE_buildDTable_internal(dtable, wksp->ncount, maxSymbolValue, tableLog, workSpace, wkspSize) );
|
||||||
|
|
||||||
{
|
{
|
||||||
const void* ptr = wksp->dtable;
|
const void* ptr = dtable;
|
||||||
const FSE_DTableHeader* DTableH = (const FSE_DTableHeader*)ptr;
|
const FSE_DTableHeader* DTableH = (const FSE_DTableHeader*)ptr;
|
||||||
const U32 fastMode = DTableH->fastMode;
|
const U32 fastMode = DTableH->fastMode;
|
||||||
|
|
||||||
/* select fast mode (static) */
|
/* select fast mode (static) */
|
||||||
if (fastMode) return FSE_decompress_usingDTable_generic(dst, dstCapacity, ip, cSrcSize, wksp->dtable, 1);
|
if (fastMode) return FSE_decompress_usingDTable_generic(dst, dstCapacity, ip, cSrcSize, dtable, 1);
|
||||||
return FSE_decompress_usingDTable_generic(dst, dstCapacity, ip, cSrcSize, wksp->dtable, 0);
|
return FSE_decompress_usingDTable_generic(dst, dstCapacity, ip, cSrcSize, dtable, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -225,8 +225,8 @@ size_t FSE_NCountWriteBound(unsigned maxSymbolValue, unsigned tableLog)
|
|||||||
size_t const maxHeaderSize = (((maxSymbolValue+1) * tableLog
|
size_t const maxHeaderSize = (((maxSymbolValue+1) * tableLog
|
||||||
+ 4 /* bitCount initialized at 4 */
|
+ 4 /* bitCount initialized at 4 */
|
||||||
+ 2 /* first two symbols may use one additional bit each */) / 8)
|
+ 2 /* first two symbols may use one additional bit each */) / 8)
|
||||||
+ 1 /* round up to whole nb bytes */
|
+ 1 /* round up to whole nb bytes */
|
||||||
+ 2 /* additional two bytes for bitstream flush */;
|
+ 2 /* additional two bytes for bitstream flush */;
|
||||||
return maxSymbolValue ? maxHeaderSize : FSE_NCOUNTBOUND; /* maxSymbolValue==0 ? use default */
|
return maxSymbolValue ? maxHeaderSize : FSE_NCOUNTBOUND; /* maxSymbolValue==0 ? use default */
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -255,7 +255,7 @@ FSE_writeNCount_generic (void* header, size_t headerBufferSize,
|
|||||||
/* Init */
|
/* Init */
|
||||||
remaining = tableSize+1; /* +1 for extra accuracy */
|
remaining = tableSize+1; /* +1 for extra accuracy */
|
||||||
threshold = tableSize;
|
threshold = tableSize;
|
||||||
nbBits = tableLog+1;
|
nbBits = (int)tableLog+1;
|
||||||
|
|
||||||
while ((symbol < alphabetSize) && (remaining>1)) { /* stops at 1 */
|
while ((symbol < alphabetSize) && (remaining>1)) { /* stops at 1 */
|
||||||
if (previousIs0) {
|
if (previousIs0) {
|
||||||
@@ -274,7 +274,7 @@ FSE_writeNCount_generic (void* header, size_t headerBufferSize,
|
|||||||
}
|
}
|
||||||
while (symbol >= start+3) {
|
while (symbol >= start+3) {
|
||||||
start+=3;
|
start+=3;
|
||||||
bitStream += 3 << bitCount;
|
bitStream += 3U << bitCount;
|
||||||
bitCount += 2;
|
bitCount += 2;
|
||||||
}
|
}
|
||||||
bitStream += (symbol-start) << bitCount;
|
bitStream += (symbol-start) << bitCount;
|
||||||
@@ -294,7 +294,7 @@ FSE_writeNCount_generic (void* header, size_t headerBufferSize,
|
|||||||
count++; /* +1 for extra accuracy */
|
count++; /* +1 for extra accuracy */
|
||||||
if (count>=threshold)
|
if (count>=threshold)
|
||||||
count += max; /* [0..max[ [max..threshold[ (...) [threshold+max 2*threshold[ */
|
count += max; /* [0..max[ [max..threshold[ (...) [threshold+max 2*threshold[ */
|
||||||
bitStream += count << bitCount;
|
bitStream += (U32)count << bitCount;
|
||||||
bitCount += nbBits;
|
bitCount += nbBits;
|
||||||
bitCount -= (count<max);
|
bitCount -= (count<max);
|
||||||
previousIs0 = (count==1);
|
previousIs0 = (count==1);
|
||||||
@@ -322,7 +322,8 @@ FSE_writeNCount_generic (void* header, size_t headerBufferSize,
|
|||||||
out[1] = (BYTE)(bitStream>>8);
|
out[1] = (BYTE)(bitStream>>8);
|
||||||
out+= (bitCount+7) /8;
|
out+= (bitCount+7) /8;
|
||||||
|
|
||||||
return (out-ostart);
|
assert(out >= ostart);
|
||||||
|
return (size_t)(out-ostart);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user