Merge pull request #32 from nemequ/unaligned

Don't rely on unaligned accesses in the LZVN encoder.
This commit is contained in:
Eric Bainville 2016-08-16 09:51:18 -07:00 committed by GitHub
commit 81699de01a
2 changed files with 28 additions and 29 deletions

View File

@ -131,15 +131,15 @@ matrix:
- llvm-toolchain-precise-3.8
packages:
- clang-3.8
# - os: linux
# env: C_COMPILER=clang-3.8 SANITIZER=undefined CFLAGS="-fno-sanitize-recover=undefined,integer"
# addons:
# apt:
# sources:
# - ubuntu-toolchain-r-test
# - llvm-toolchain-precise-3.8
# packages:
# - clang-3.8
- os: linux
env: C_COMPILER=clang-3.8 SANITIZER=undefined CFLAGS="-fno-sanitize-recover=undefined,integer"
addons:
apt:
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-precise-3.8
packages:
- clang-3.8
before_install:
###

View File

@ -67,8 +67,8 @@ static inline unsigned char *emit_literal(const unsigned char *p,
x = L < 271 ? L : 271;
if (q + x + 10 >= q1)
goto OUT_FULL;
*(uint16_t *)q = 0xE0 + ((x - 16) << 8);
q += 2; // non-aligned access OK
store2(q, 0xE0 + ((x - 16) << 8));
q += 2;
L -= x;
q = lzvn_copy8(q, p, x);
p += x;
@ -100,8 +100,8 @@ static inline unsigned char *emit(const unsigned char *p, unsigned char *q,
x = L < 271 ? L : 271;
if (q + x + 10 >= q1)
goto OUT_FULL;
*(uint16_t *)q = 0xE0 + ((x - 16) << 8);
q += 2; // non-aligned access OK
store2(q, 0xE0 + ((x - 16) << 8));
q += 2;
L -= x;
q = lzvn_copy64(q, p, x);
p += x;
@ -119,8 +119,7 @@ static inline unsigned char *emit(const unsigned char *p, unsigned char *q,
x -= 3; // M = (x+3) + M' max value for x is 7-2*L
// Here L<4 literals remaining, we read them here
uint32_t literal =
*(uint32_t *)p; // read 4 literal bytes, non-aligned access OK
uint32_t literal = load4(p);
// P is not accessed after this point
// Relaxed capacity test covering all cases
@ -133,30 +132,30 @@ static inline unsigned char *emit(const unsigned char *p, unsigned char *q,
} else {
*q++ = (L << 6) + (x << 3) + 6; // LLxxx110
}
*(uint32_t *)q = literal;
q += L; // non-aligned access OK
store4(q, literal);
q += L;
} else if (D < 2048 - 2 * 256) {
// Short dist D>>8 in 0..5
*q++ = (D >> 8) + (L << 6) + (x << 3); // LLxxxDDD
*q++ = D & 0xFF;
*(uint32_t *)q = literal;
q += L; // non-aligned access OK
store4(q, literal);
q += L;
} else if (D >= (1 << 14) || M == 0 || (x + 3) + M > 34) {
// Long dist
*q++ = (L << 6) + (x << 3) + 7;
*(uint16_t *)q = D;
q += 2; // non-aligned access OK
*(uint32_t *)q = literal;
q += L; // non-aligned access OK
store2(q, D);
q += 2;
store4(q, literal);
q += L;
} else {
// Medium distance
x += M;
M = 0;
*q++ = 0xA0 + (x >> 2) + (L << 3);
*(uint16_t *)q = D << 2 | (x & 3);
q += 2; // non-aligned access OK
*(uint32_t *)q = literal;
q += L; // non-aligned access OK
store2(q, D << 2 | (x & 3));
q += 2;
store4(q, literal);
q += L;
}
// Issue remaining match
@ -164,8 +163,8 @@ static inline unsigned char *emit(const unsigned char *p, unsigned char *q,
if (q + 2 >= q1)
goto OUT_FULL;
x = M < 271 ? M : 271;
*(uint16_t *)q = 0xf0 + ((x - 16) << 8);
q += 2; // non-aligned access OK
store2(q, 0xf0 + ((x - 16) << 8));
q += 2;
M -= x;
}
if (M > 0) {