Bug 1507525 - Update brotli to 1.0.7. r=jfkthame
authorRyan VanderMeulen <ryanvm@gmail.com>
Thu, 15 Nov 2018 20:31:53 +0000
changeset 503094 6ec9514939c0e95f123d3fcaecc05eca6d4e148c
parent 503093 cec3c30f287bdc9c1f86c4c296d99dfa13d1e195
child 503095 d459920f97a5317de3c5106e0a5f818d214dc660
push id10290
push userffxbld-merge
push dateMon, 03 Dec 2018 16:23:23 +0000
treeherdermozilla-beta@700bed2445e6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjfkthame
bugs1507525
milestone65.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1507525 - Update brotli to 1.0.7. r=jfkthame Differential Revision: https://phabricator.services.mozilla.com/D12051
modules/brotli/README.mozilla
modules/brotli/common/platform.h
modules/brotli/common/transform.c
modules/brotli/common/version.h
modules/brotli/dec/decode.c
modules/brotli/dec/huffman.c
modules/brotli/dec/huffman.h
modules/brotli/enc/backward_references_hq.c
modules/brotli/enc/backward_references_hq.h
modules/brotli/enc/backward_references_inc.h
modules/brotli/enc/encode.c
modules/brotli/enc/hash.h
modules/brotli/enc/hash_composite_inc.h
modules/brotli/enc/hash_longest_match64_inc.h
modules/brotli/enc/hash_longest_match_inc.h
modules/brotli/enc/hash_rolling_inc.h
modules/brotli/enc/hash_to_binary_tree_inc.h
modules/brotli/tools/brotli.c
modules/brotli/update.sh
--- a/modules/brotli/README.mozilla
+++ b/modules/brotli/README.mozilla
@@ -6,9 +6,9 @@ Upstream code can be viewed at
 
 and cloned by
   git clone https://github.com/google/brotli
 
 The in-tree copy is updated by running
   sh update.sh
 from within the modules/brotli directory.
 
-Current version: [commit 6eba239a5bb553fd557b7d78f7da8f0059618b9e].
+Current version: [commit d6d98957ca8ccb1ef45922e978bb10efca0ea541].
--- a/modules/brotli/common/platform.h
+++ b/modules/brotli/common/platform.h
@@ -66,17 +66,17 @@ OR:
 
   if (BROTLI_PREDICT_FALSE(something_rare_or_unexpected_happens)) {
     // compiler should place this code outside of main execution path
   }
 
 */
 #if BROTLI_GNUC_HAS_BUILTIN(__builtin_expect, 3, 0, 0) || \
     BROTLI_INTEL_VERSION_CHECK(16, 0, 0) ||               \
-    BROTLI_SUNPRO_VERSION_CHECK(5, 12, 0) ||              \
+    BROTLI_SUNPRO_VERSION_CHECK(5, 15, 0) ||              \
     BROTLI_ARM_VERSION_CHECK(4, 1, 0) ||                  \
     BROTLI_IBM_VERSION_CHECK(10, 1, 0) ||                 \
     BROTLI_TI_VERSION_CHECK(7, 3, 0) ||                   \
     BROTLI_TINYC_VERSION_CHECK(0, 9, 27)
 #define BROTLI_PREDICT_TRUE(x) (__builtin_expect(!!(x), 1))
 #define BROTLI_PREDICT_FALSE(x) (__builtin_expect(x, 0))
 #else
 #define BROTLI_PREDICT_FALSE(x) (x)
@@ -175,16 +175,22 @@ OR:
 
 #if BROTLI_GNUC_HAS_ATTRIBUTE(unused, 2, 7, 0) || \
     BROTLI_INTEL_VERSION_CHECK(16, 0, 0)
 #define BROTLI_UNUSED_FUNCTION static BROTLI_INLINE __attribute__ ((unused))
 #else
 #define BROTLI_UNUSED_FUNCTION static BROTLI_INLINE
 #endif
 
+#if BROTLI_GNUC_HAS_ATTRIBUTE(aligned, 2, 7, 0)
+#define BROTLI_ALIGNED(N) __attribute__((aligned(N)))
+#else
+#define BROTLI_ALIGNED(N)
+#endif
+
 #if (defined(__ARM_ARCH) && (__ARM_ARCH == 7)) || \
     (defined(M_ARM) && (M_ARM == 7))
 #define BROTLI_TARGET_ARMV7
 #endif  /* ARMv7 */
 
 #if (defined(__ARM_ARCH) && (__ARM_ARCH == 8)) || \
     defined(__aarch64__) || defined(__ARM64_ARCH_8__)
 #define BROTLI_TARGET_ARMV8_ANY
@@ -192,16 +198,20 @@ OR:
 #if defined(__ARM_32BIT_STATE)
 #define BROTLI_TARGET_ARMV8_32
 #elif defined(__ARM_64BIT_STATE)
 #define BROTLI_TARGET_ARMV8_64
 #endif
 
 #endif  /* ARMv8 */
 
+#if defined(__ARM_NEON__) || defined(__ARM_NEON)
+#define BROTLI_TARGET_NEON
+#endif
+
 #if defined(__i386) || defined(_M_IX86)
 #define BROTLI_TARGET_X86
 #endif
 
 #if defined(__x86_64__) || defined(_M_X64)
 #define BROTLI_TARGET_X64
 #endif
 
@@ -338,17 +348,17 @@ static BROTLI_INLINE uint64_t BrotliUnal
 static BROTLI_INLINE void BrotliUnalignedWrite64(void* p, uint64_t v) {
   *(uint64_t*)p = v;
 }
 #else  /* BROTLI_64_BITS */
 /* Avoid emitting LDRD / STRD, which require properly aligned address. */
 /* If __attribute__(aligned) is available, use that. Otherwise, memcpy. */
 
 #if BROTLI_GNUC_HAS_ATTRIBUTE(aligned, 2, 7, 0)
-typedef  __attribute__((aligned(1))) uint64_t brotli_unaligned_uint64_t;
+typedef BROTLI_ALIGNED(1) uint64_t brotli_unaligned_uint64_t;
 
 static BROTLI_INLINE uint64_t BrotliUnalignedRead64(const void* p) {
   return (uint64_t) ((brotli_unaligned_uint64_t*) p)[0];
 }
 static BROTLI_INLINE void BrotliUnalignedWrite64(void* p, uint64_t v) {
   brotli_unaligned_uint64_t* dwords = (brotli_unaligned_uint64_t*) p;
   dwords[0] = (brotli_unaligned_uint64_t) v;
 }
--- a/modules/brotli/common/transform.c
+++ b/modules/brotli/common/transform.c
@@ -186,21 +186,21 @@ static int ToUpperCase(uint8_t* p) {
     return 2;
   }
   /* An arbitrary transform for three byte characters. */
   p[2] ^= 5;
   return 3;
 }
 
 int BrotliTransformDictionaryWord(uint8_t* dst, const uint8_t* word, int len,
-    const BrotliTransforms* transforms, int transfom_idx) {
+    const BrotliTransforms* transforms, int transform_idx) {
   int idx = 0;
-  const uint8_t* prefix = BROTLI_TRANSFORM_PREFIX(transforms, transfom_idx);
-  uint8_t type = BROTLI_TRANSFORM_TYPE(transforms, transfom_idx);
-  const uint8_t* suffix = BROTLI_TRANSFORM_SUFFIX(transforms, transfom_idx);
+  const uint8_t* prefix = BROTLI_TRANSFORM_PREFIX(transforms, transform_idx);
+  uint8_t type = BROTLI_TRANSFORM_TYPE(transforms, transform_idx);
+  const uint8_t* suffix = BROTLI_TRANSFORM_SUFFIX(transforms, transform_idx);
   {
     int prefix_len = *prefix++;
     while (prefix_len--) { dst[idx++] = *prefix++; }
   }
   {
     const int t = type;
     int i = 0;
     if (t <= BROTLI_TRANSFORM_OMIT_LAST_9) {
--- a/modules/brotli/common/version.h
+++ b/modules/brotli/common/version.h
@@ -9,18 +9,18 @@
 #ifndef BROTLI_COMMON_VERSION_H_
 #define BROTLI_COMMON_VERSION_H_
 
 /* This macro should only be used when library is compiled together with client.
    If library is dynamically linked, use BrotliDecoderVersion and
    BrotliEncoderVersion methods. */
 
 /* Semantic version, calculated as (MAJOR << 24) | (MINOR << 12) | PATCH */
-#define BROTLI_VERSION 0x1000006
+#define BROTLI_VERSION 0x1000007
 
 /* This macro is used by build system to produce Libtool-friendly soname. See
    https://www.gnu.org/software/libtool/manual/html_node/Libtool-versioning.html
  */
 
 /* ABI version, calculated as (CURRENT << 24) | (REVISION << 12) | AGE */
-#define BROTLI_ABI_VERSION 0x1006000
+#define BROTLI_ABI_VERSION 0x1007000
 
 #endif  /* BROTLI_COMMON_VERSION_H_ */
--- a/modules/brotli/dec/decode.c
+++ b/modules/brotli/dec/decode.c
@@ -1,34 +1,34 @@
 /* Copyright 2013 Google Inc. All Rights Reserved.
 
    Distributed under MIT license.
    See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
 */
 
 #include <brotli/decode.h>
 
-#if defined(__ARM_NEON__)
-#include <arm_neon.h>
-#endif
-
 #include <stdlib.h>  /* free, malloc */
 #include <string.h>  /* memcpy, memset */
 
 #include "../common/constants.h"
 #include "../common/context.h"
 #include "../common/dictionary.h"
 #include "../common/platform.h"
 #include "../common/transform.h"
 #include "../common/version.h"
 #include "./bit_reader.h"
 #include "./huffman.h"
 #include "./prefix.h"
 #include "./state.h"
 
+#if defined(BROTLI_TARGET_NEON)
+#include <arm_neon.h>
+#endif
+
 #if defined(__cplusplus) || defined(c_plusplus)
 extern "C" {
 #endif
 
 #define BROTLI_FAILURE(CODE) (BROTLI_DUMP(), CODE)
 
 #define BROTLI_LOG_UINT(name)                                       \
   BROTLI_LOG(("[%s] %s = %lu\n", __func__, #name, (unsigned long)(name)))
@@ -162,17 +162,17 @@ static BrotliDecoderErrorCode DecodeWind
     s->window_bits = 8 + n;
     return BROTLI_DECODER_SUCCESS;
   }
   s->window_bits = 17;
   return BROTLI_DECODER_SUCCESS;
 }
 
 static BROTLI_INLINE void memmove16(uint8_t* dst, uint8_t* src) {
-#if defined(__ARM_NEON__)
+#if defined(BROTLI_TARGET_NEON)
   vst1q_u8(dst, vld1q_u8(src));
 #else
   uint32_t buffer[4];
   memcpy(buffer, src, 16);
   memcpy(dst, buffer, 16);
 #endif
 }
 
@@ -342,72 +342,75 @@ static BrotliDecoderErrorCode BROTLI_NOI
 
 /* Decodes the Huffman code.
    This method doesn't read data from the bit reader, BUT drops the amount of
    bits that correspond to the decoded symbol.
    bits MUST contain at least 15 (BROTLI_HUFFMAN_MAX_CODE_LENGTH) valid bits. */
 static BROTLI_INLINE uint32_t DecodeSymbol(uint32_t bits,
                                            const HuffmanCode* table,
                                            BrotliBitReader* br) {
-  table += bits & HUFFMAN_TABLE_MASK;
-  if (table->bits > HUFFMAN_TABLE_BITS) {
-    uint32_t nbits = table->bits - HUFFMAN_TABLE_BITS;
+  BROTLI_HC_MARK_TABLE_FOR_FAST_LOAD(table);
+  BROTLI_HC_ADJUST_TABLE_INDEX(table, bits & HUFFMAN_TABLE_MASK);
+  if (BROTLI_HC_FAST_LOAD_BITS(table) > HUFFMAN_TABLE_BITS) {
+    uint32_t nbits = BROTLI_HC_FAST_LOAD_BITS(table) - HUFFMAN_TABLE_BITS;
     BrotliDropBits(br, HUFFMAN_TABLE_BITS);
-    table += table->value;
-    table += (bits >> HUFFMAN_TABLE_BITS) & BitMask(nbits);
+    BROTLI_HC_ADJUST_TABLE_INDEX(table,
+        BROTLI_HC_FAST_LOAD_VALUE(table) +
+        ((bits >> HUFFMAN_TABLE_BITS) & BitMask(nbits)));
   }
-  BrotliDropBits(br, table->bits);
-  return table->value;
+  BrotliDropBits(br, BROTLI_HC_FAST_LOAD_BITS(table));
+  return BROTLI_HC_FAST_LOAD_VALUE(table);
 }
 
 /* Reads and decodes the next Huffman code from bit-stream.
    This method peeks 16 bits of input and drops 0 - 15 of them. */
 static BROTLI_INLINE uint32_t ReadSymbol(const HuffmanCode* table,
                                          BrotliBitReader* br) {
   return DecodeSymbol(BrotliGet16BitsUnmasked(br), table, br);
 }
 
 /* Same as DecodeSymbol, but it is known that there is less than 15 bits of
    input are currently available. */
 static BROTLI_NOINLINE BROTLI_BOOL SafeDecodeSymbol(
     const HuffmanCode* table, BrotliBitReader* br, uint32_t* result) {
   uint32_t val;
   uint32_t available_bits = BrotliGetAvailableBits(br);
+  BROTLI_HC_MARK_TABLE_FOR_FAST_LOAD(table);
   if (available_bits == 0) {
-    if (table->bits == 0) {
-      *result = table->value;
+    if (BROTLI_HC_FAST_LOAD_BITS(table) == 0) {
+      *result = BROTLI_HC_FAST_LOAD_VALUE(table);
       return BROTLI_TRUE;
     }
     return BROTLI_FALSE;  /* No valid bits at all. */
   }
   val = (uint32_t)BrotliGetBitsUnmasked(br);
-  table += val & HUFFMAN_TABLE_MASK;
-  if (table->bits <= HUFFMAN_TABLE_BITS) {
-    if (table->bits <= available_bits) {
-      BrotliDropBits(br, table->bits);
-      *result = table->value;
+  BROTLI_HC_ADJUST_TABLE_INDEX(table, val & HUFFMAN_TABLE_MASK);
+  if (BROTLI_HC_FAST_LOAD_BITS(table) <= HUFFMAN_TABLE_BITS) {
+    if (BROTLI_HC_FAST_LOAD_BITS(table) <= available_bits) {
+      BrotliDropBits(br, BROTLI_HC_FAST_LOAD_BITS(table));
+      *result = BROTLI_HC_FAST_LOAD_VALUE(table);
       return BROTLI_TRUE;
     } else {
       return BROTLI_FALSE;  /* Not enough bits for the first level. */
     }
   }
   if (available_bits <= HUFFMAN_TABLE_BITS) {
     return BROTLI_FALSE;  /* Not enough bits to move to the second level. */
   }
 
   /* Speculatively drop HUFFMAN_TABLE_BITS. */
-  val = (val & BitMask(table->bits)) >> HUFFMAN_TABLE_BITS;
+  val = (val & BitMask(BROTLI_HC_FAST_LOAD_BITS(table))) >> HUFFMAN_TABLE_BITS;
   available_bits -= HUFFMAN_TABLE_BITS;
-  table += table->value + val;
-  if (available_bits < table->bits) {
+  BROTLI_HC_ADJUST_TABLE_INDEX(table, BROTLI_HC_FAST_LOAD_VALUE(table) + val);
+  if (available_bits < BROTLI_HC_FAST_LOAD_BITS(table)) {
     return BROTLI_FALSE;  /* Not enough bits for the second level. */
   }
 
-  BrotliDropBits(br, HUFFMAN_TABLE_BITS + table->bits);
-  *result = table->value;
+  BrotliDropBits(br, HUFFMAN_TABLE_BITS + BROTLI_HC_FAST_LOAD_BITS(table));
+  *result = BROTLI_HC_FAST_LOAD_VALUE(table);
   return BROTLI_TRUE;
 }
 
 static BROTLI_INLINE BROTLI_BOOL SafeReadSymbol(
     const HuffmanCode* table, BrotliBitReader* br, uint32_t* result) {
   uint32_t val;
   if (BROTLI_PREDICT_TRUE(BrotliSafeGetBits(br, 15, &val))) {
     *result = DecodeSymbol(val, table, br);
@@ -420,36 +423,38 @@ static BROTLI_INLINE BROTLI_BOOL SafeRea
 static BROTLI_INLINE void PreloadSymbol(int safe,
                                         const HuffmanCode* table,
                                         BrotliBitReader* br,
                                         uint32_t* bits,
                                         uint32_t* value) {
   if (safe) {
     return;
   }
-  table += BrotliGetBits(br, HUFFMAN_TABLE_BITS);
-  *bits = table->bits;
-  *value = table->value;
+  BROTLI_HC_MARK_TABLE_FOR_FAST_LOAD(table);
+  BROTLI_HC_ADJUST_TABLE_INDEX(table, BrotliGetBits(br, HUFFMAN_TABLE_BITS));
+  *bits = BROTLI_HC_FAST_LOAD_BITS(table);
+  *value = BROTLI_HC_FAST_LOAD_VALUE(table);
 }
 
 /* Decodes the next Huffman code using data prepared by PreloadSymbol.
    Reads 0 - 15 bits. Also peeks 8 following bits. */
 static BROTLI_INLINE uint32_t ReadPreloadedSymbol(const HuffmanCode* table,
                                                   BrotliBitReader* br,
                                                   uint32_t* bits,
                                                   uint32_t* value) {
   uint32_t result = *value;
   if (BROTLI_PREDICT_FALSE(*bits > HUFFMAN_TABLE_BITS)) {
     uint32_t val = BrotliGet16BitsUnmasked(br);
     const HuffmanCode* ext = table + (val & HUFFMAN_TABLE_MASK) + *value;
     uint32_t mask = BitMask((*bits - HUFFMAN_TABLE_BITS));
+    BROTLI_HC_MARK_TABLE_FOR_FAST_LOAD(ext);
     BrotliDropBits(br, HUFFMAN_TABLE_BITS);
-    ext += (val >> HUFFMAN_TABLE_BITS) & mask;
-    BrotliDropBits(br, ext->bits);
-    result = ext->value;
+    BROTLI_HC_ADJUST_TABLE_INDEX(ext, (val >> HUFFMAN_TABLE_BITS) & mask);
+    BrotliDropBits(br, BROTLI_HC_FAST_LOAD_BITS(ext));
+    result = BROTLI_HC_FAST_LOAD_VALUE(ext);
   } else {
     BrotliDropBits(br, *bits);
   }
   PreloadSymbol(0, table, br, bits, value);
   return result;
 }
 
 static BROTLI_INLINE uint32_t Log2Floor(uint32_t x) {
@@ -592,29 +597,30 @@ static BrotliDecoderErrorCode ReadSymbol
   uint16_t* code_length_histo = s->code_length_histo;
   int* next_symbol = s->next_symbol;
   if (!BrotliWarmupBitReader(br)) {
     return BROTLI_DECODER_NEEDS_MORE_INPUT;
   }
   while (symbol < alphabet_size && space > 0) {
     const HuffmanCode* p = s->table;
     uint32_t code_len;
+    BROTLI_HC_MARK_TABLE_FOR_FAST_LOAD(p);
     if (!BrotliCheckInputAmount(br, BROTLI_SHORT_FILL_BIT_WINDOW_READ)) {
       s->symbol = symbol;
       s->repeat = repeat;
       s->prev_code_len = prev_code_len;
       s->repeat_code_len = repeat_code_len;
       s->space = space;
       return BROTLI_DECODER_NEEDS_MORE_INPUT;
     }
     BrotliFillBitWindow16(br);
-    p += BrotliGetBitsUnmasked(br) &
-        BitMask(BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH);
-    BrotliDropBits(br, p->bits);  /* Use 1..5 bits. */
-    code_len = p->value;  /* code_len == 0..17 */
+    BROTLI_HC_ADJUST_TABLE_INDEX(p, BrotliGetBitsUnmasked(br) &
+        BitMask(BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH));
+    BrotliDropBits(br, BROTLI_HC_FAST_LOAD_BITS(p));  /* Use 1..5 bits. */
+    code_len = BROTLI_HC_FAST_LOAD_VALUE(p);  /* code_len == 0..17 */
     if (code_len < BROTLI_REPEAT_PREVIOUS_CODE_LENGTH) {
       ProcessSingleCodeLength(code_len, &symbol, &repeat, &space,
           &prev_code_len, symbol_lists, code_length_histo, next_symbol);
     } else {  /* code_len == 16..17, extra_bits == 2..3 */
       uint32_t extra_bits =
           (code_len == BROTLI_REPEAT_PREVIOUS_CODE_LENGTH) ? 2 : 3;
       uint32_t repeat_delta =
           (uint32_t)BrotliGetBitsUnmasked(br) & BitMask(extra_bits);
@@ -632,41 +638,44 @@ static BrotliDecoderErrorCode SafeReadSy
     uint32_t alphabet_size, BrotliDecoderState* s) {
   BrotliBitReader* br = &s->br;
   BROTLI_BOOL get_byte = BROTLI_FALSE;
   while (s->symbol < alphabet_size && s->space > 0) {
     const HuffmanCode* p = s->table;
     uint32_t code_len;
     uint32_t available_bits;
     uint32_t bits = 0;
+    BROTLI_HC_MARK_TABLE_FOR_FAST_LOAD(p);
     if (get_byte && !BrotliPullByte(br)) return BROTLI_DECODER_NEEDS_MORE_INPUT;
     get_byte = BROTLI_FALSE;
     available_bits = BrotliGetAvailableBits(br);
     if (available_bits != 0) {
       bits = (uint32_t)BrotliGetBitsUnmasked(br);
     }
-    p += bits & BitMask(BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH);
-    if (p->bits > available_bits) {
+    BROTLI_HC_ADJUST_TABLE_INDEX(p,
+        bits & BitMask(BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH));
+    if (BROTLI_HC_FAST_LOAD_BITS(p) > available_bits) {
       get_byte = BROTLI_TRUE;
       continue;
     }
-    code_len = p->value;  /* code_len == 0..17 */
+    code_len = BROTLI_HC_FAST_LOAD_VALUE(p);  /* code_len == 0..17 */
     if (code_len < BROTLI_REPEAT_PREVIOUS_CODE_LENGTH) {
-      BrotliDropBits(br, p->bits);
+      BrotliDropBits(br, BROTLI_HC_FAST_LOAD_BITS(p));
       ProcessSingleCodeLength(code_len, &s->symbol, &s->repeat, &s->space,
           &s->prev_code_len, s->symbol_lists, s->code_length_histo,
           s->next_symbol);
     } else {  /* code_len == 16..17, extra_bits == 2..3 */
       uint32_t extra_bits = code_len - 14U;
-      uint32_t repeat_delta = (bits >> p->bits) & BitMask(extra_bits);
-      if (available_bits < p->bits + extra_bits) {
+      uint32_t repeat_delta = (bits >> BROTLI_HC_FAST_LOAD_BITS(p)) &
+          BitMask(extra_bits);
+      if (available_bits < BROTLI_HC_FAST_LOAD_BITS(p) + extra_bits) {
         get_byte = BROTLI_TRUE;
         continue;
       }
-      BrotliDropBits(br, p->bits + extra_bits);
+      BrotliDropBits(br, BROTLI_HC_FAST_LOAD_BITS(p) + extra_bits);
       ProcessRepeatedCodeLength(code_len, repeat_delta, alphabet_size,
           &s->symbol, &s->repeat, &s->space, &s->prev_code_len,
           &s->repeat_code_len, s->symbol_lists, s->code_length_histo,
           s->next_symbol);
     }
   }
   return BROTLI_DECODER_SUCCESS;
 }
--- a/modules/brotli/dec/huffman.c
+++ b/modules/brotli/dec/huffman.c
@@ -137,34 +137,32 @@ void BrotliBuildCodeLengthsHuffmanTable(
       sorted[offset[code_lengths[symbol]]--] = symbol;
     });
   } while (symbol != 0);
 
   table_size = 1 << BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH;
 
   /* Special case: all symbols but one have 0 code length. */
   if (offset[0] == 0) {
-    code.bits = 0;
-    code.value = (uint16_t)sorted[0];
+    code = ConstructHuffmanCode(0, (uint16_t)sorted[0]);
     for (key = 0; key < (brotli_reg_t)table_size; ++key) {
       table[key] = code;
     }
     return;
   }
 
   /* Fill in table. */
   key = 0;
   key_step = BROTLI_REVERSE_BITS_LOWEST;
   symbol = 0;
   bits = 1;
   step = 2;
   do {
-    code.bits = (uint8_t)bits;
     for (bits_count = count[bits]; bits_count != 0; --bits_count) {
-      code.value = (uint16_t)sorted[symbol++];
+      code = ConstructHuffmanCode((uint8_t)bits, (uint16_t)sorted[symbol++]);
       ReplicateValue(&table[BrotliReverseBits(key)], step, table_size, code);
       key += key_step;
     }
     step <<= 1;
     key_step >>= 1;
   } while (++bits <= BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH);
 }
 
@@ -206,21 +204,20 @@ uint32_t BrotliBuildHuffmanTable(Huffman
     table_bits = max_length;
     table_size = 1 << table_bits;
   }
   key = 0;
   key_step = BROTLI_REVERSE_BITS_LOWEST;
   bits = 1;
   step = 2;
   do {
-    code.bits = (uint8_t)bits;
     symbol = bits - (BROTLI_HUFFMAN_MAX_CODE_LENGTH + 1);
     for (bits_count = count[bits]; bits_count != 0; --bits_count) {
       symbol = symbol_lists[symbol];
-      code.value = (uint16_t)symbol;
+      code = ConstructHuffmanCode((uint8_t)bits, (uint16_t)symbol);
       ReplicateValue(&table[BrotliReverseBits(key)], step, table_size, code);
       key += key_step;
     }
     step <<= 1;
     key_step >>= 1;
   } while (++bits <= table_bits);
 
   /* If root_bits != table_bits then replicate to fill the remaining slots. */
@@ -239,24 +236,23 @@ uint32_t BrotliBuildHuffmanTable(Huffman
     for (; count[len] != 0; --count[len]) {
       if (sub_key == (BROTLI_REVERSE_BITS_LOWEST << 1U)) {
         table += table_size;
         table_bits = NextTableBitSize(count, len, root_bits);
         table_size = 1 << table_bits;
         total_size += table_size;
         sub_key = BrotliReverseBits(key);
         key += key_step;
-        root_table[sub_key].bits = (uint8_t)(table_bits + root_bits);
-        root_table[sub_key].value =
-            (uint16_t)(((size_t)(table - root_table)) - sub_key);
+        root_table[sub_key] = ConstructHuffmanCode(
+            (uint8_t)(table_bits + root_bits),
+            (uint16_t)(((size_t)(table - root_table)) - sub_key));
         sub_key = 0;
       }
-      code.bits = (uint8_t)(len - root_bits);
       symbol = symbol_lists[symbol];
-      code.value = (uint16_t)symbol;
+      code = ConstructHuffmanCode((uint8_t)(len - root_bits), (uint16_t)symbol);
       ReplicateValue(
           &table[BrotliReverseBits(sub_key)], step, table_size, code);
       sub_key += sub_key_step;
     }
     step <<= 1;
     sub_key_step >>= 1;
   }
   return (uint32_t)total_size;
@@ -265,85 +261,72 @@ uint32_t BrotliBuildHuffmanTable(Huffman
 uint32_t BrotliBuildSimpleHuffmanTable(HuffmanCode* table,
                                        int root_bits,
                                        uint16_t* val,
                                        uint32_t num_symbols) {
   uint32_t table_size = 1;
   const uint32_t goal_size = 1U << root_bits;
   switch (num_symbols) {
     case 0:
-      table[0].bits = 0;
-      table[0].value = val[0];
+      table[0] = ConstructHuffmanCode(0, val[0]);
       break;
     case 1:
-      table[0].bits = 1;
-      table[1].bits = 1;
       if (val[1] > val[0]) {
-        table[0].value = val[0];
-        table[1].value = val[1];
+        table[0] = ConstructHuffmanCode(1, val[0]);
+        table[1] = ConstructHuffmanCode(1, val[1]);
       } else {
-        table[0].value = val[1];
-        table[1].value = val[0];
+        table[0] = ConstructHuffmanCode(1, val[1]);
+        table[1] = ConstructHuffmanCode(1, val[0]);
       }
       table_size = 2;
       break;
     case 2:
-      table[0].bits = 1;
-      table[0].value = val[0];
-      table[2].bits = 1;
-      table[2].value = val[0];
+      table[0] = ConstructHuffmanCode(1, val[0]);
+      table[2] = ConstructHuffmanCode(1, val[0]);
       if (val[2] > val[1]) {
-        table[1].value = val[1];
-        table[3].value = val[2];
+        table[1] = ConstructHuffmanCode(2, val[1]);
+        table[3] = ConstructHuffmanCode(2, val[2]);
       } else {
-        table[1].value = val[2];
-        table[3].value = val[1];
+        table[1] = ConstructHuffmanCode(2, val[2]);
+        table[3] = ConstructHuffmanCode(2, val[1]);
       }
-      table[1].bits = 2;
-      table[3].bits = 2;
       table_size = 4;
       break;
     case 3: {
       int i, k;
       for (i = 0; i < 3; ++i) {
         for (k = i + 1; k < 4; ++k) {
           if (val[k] < val[i]) {
             uint16_t t = val[k];
             val[k] = val[i];
             val[i] = t;
           }
         }
       }
-      for (i = 0; i < 4; ++i) {
-        table[i].bits = 2;
-      }
-      table[0].value = val[0];
-      table[2].value = val[1];
-      table[1].value = val[2];
-      table[3].value = val[3];
+      table[0] = ConstructHuffmanCode(2, val[0]);
+      table[2] = ConstructHuffmanCode(2, val[1]);
+      table[1] = ConstructHuffmanCode(2, val[2]);
+      table[3] = ConstructHuffmanCode(2, val[3]);
       table_size = 4;
       break;
     }
     case 4: {
-      int i;
       if (val[3] < val[2]) {
         uint16_t t = val[3];
         val[3] = val[2];
         val[2] = t;
       }
-      for (i = 0; i < 7; ++i) {
-        table[i].value = val[0];
-        table[i].bits = (uint8_t)(1 + (i & 1));
-      }
-      table[1].value = val[1];
-      table[3].value = val[2];
-      table[5].value = val[1];
-      table[7].value = val[3];
-      table[3].bits = 3;
-      table[7].bits = 3;
+      table[0] = ConstructHuffmanCode(1, val[0]);
+      table[1] = ConstructHuffmanCode(2, val[1]);
+      table[2] = ConstructHuffmanCode(1, val[0]);
+      table[3] = ConstructHuffmanCode(3, val[2]);
+      table[4] = ConstructHuffmanCode(1, val[0]);
+      table[5] = ConstructHuffmanCode(2, val[1]);
+      table[6] = ConstructHuffmanCode(1, val[0]);
+      table[7] = ConstructHuffmanCode(3, val[3]);
       table_size = 8;
       break;
     }
   }
   while (table_size != goal_size) {
     memcpy(&table[table_size], &table[0],
            (size_t)table_size * sizeof(table[0]));
     table_size <<= 1;
--- a/modules/brotli/dec/huffman.h
+++ b/modules/brotli/dec/huffman.h
@@ -28,21 +28,76 @@ static const uint16_t kMaxHuffmanTableSi
 #define BROTLI_HUFFMAN_MAX_SIZE_26 396
 /* BROTLI_MAX_BLOCK_TYPE_SYMBOLS == 258 */
 #define BROTLI_HUFFMAN_MAX_SIZE_258 632
 /* BROTLI_MAX_CONTEXT_MAP_SYMBOLS == 272 */
 #define BROTLI_HUFFMAN_MAX_SIZE_272 646
 
 #define BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH 5
 
+#if ((defined(BROTLI_TARGET_ARMV7) || defined(BROTLI_TARGET_ARMV8_32)) && \
+  BROTLI_GNUC_HAS_ATTRIBUTE(aligned, 2, 7, 0))
+#define BROTLI_HUFFMAN_CODE_FAST_LOAD
+#endif
+
+#if !defined(BROTLI_HUFFMAN_CODE_FAST_LOAD)
+/* Do not create this struct directly - use the ConstructHuffmanCode
+ * constructor below! */
 typedef struct {
   uint8_t bits;    /* number of bits used for this symbol */
   uint16_t value;  /* symbol value or table offset */
 } HuffmanCode;
 
+static BROTLI_INLINE HuffmanCode ConstructHuffmanCode(const uint8_t bits,
+    const uint16_t value) {
+  HuffmanCode h;
+  h.bits = bits;
+  h.value = value;
+  return h;
+}
+
+/* Please use the following macros to optimize HuffmanCode accesses in hot
+ * paths.
+ *
+ * For example, assuming |table| contains a HuffmanCode pointer:
+ *
+ *   BROTLI_HC_MARK_TABLE_FOR_FAST_LOAD(table);
+ *   BROTLI_HC_ADJUST_TABLE_INDEX(table, index_into_table);
+ *   *bits = BROTLI_HC_GET_BITS(table);
+ *   *value = BROTLI_HC_GET_VALUE(table);
+ *   BROTLI_HC_ADJUST_TABLE_INDEX(table, offset);
+ *   *bits2 = BROTLI_HC_GET_BITS(table);
+ *   *value2 = BROTLI_HC_GET_VALUE(table);
+ *
+ */
+
+#define BROTLI_HC_MARK_TABLE_FOR_FAST_LOAD(H)
+#define BROTLI_HC_ADJUST_TABLE_INDEX(H, V) H += (V)
+
+/* These must be given a HuffmanCode pointer! */
+#define BROTLI_HC_FAST_LOAD_BITS(H) (H->bits)
+#define BROTLI_HC_FAST_LOAD_VALUE(H) (H->value)
+
+#else /* BROTLI_HUFFMAN_CODE_FAST_LOAD */
+
+typedef BROTLI_ALIGNED(4) uint32_t HuffmanCode;
+
+static BROTLI_INLINE HuffmanCode ConstructHuffmanCode(const uint8_t bits,
+    const uint16_t value) {
+  return ((value & 0xFFFF) << 16) | (bits & 0xFF);
+}
+
+#define BROTLI_HC_MARK_TABLE_FOR_FAST_LOAD(H) uint32_t __fastload_##H = (*H)
+#define BROTLI_HC_ADJUST_TABLE_INDEX(H, V) H += (V); __fastload_##H = (*H)
+
+/* These must be given a HuffmanCode pointer! */
+#define BROTLI_HC_FAST_LOAD_BITS(H) ((__fastload_##H) & 0xFF)
+#define BROTLI_HC_FAST_LOAD_VALUE(H) ((__fastload_##H) >> 16)
+#endif /* BROTLI_HUFFMAN_CODE_FAST_LOAD */
+
 /* Builds Huffman lookup table assuming code lengths are in symbol order. */
 BROTLI_INTERNAL void BrotliBuildCodeLengthsHuffmanTable(HuffmanCode* root_table,
     const uint8_t* const code_lengths, uint16_t* count);
 
 /* Builds Huffman lookup table assuming code lengths are in symbol order.
    Returns size of resulting table. */
 BROTLI_INTERNAL uint32_t BrotliBuildHuffmanTable(HuffmanCode* root_table,
     int root_bits, const uint16_t* const symbol_lists, uint16_t* count_arg);
--- a/modules/brotli/enc/backward_references_hq.c
+++ b/modules/brotli/enc/backward_references_hq.c
@@ -325,31 +325,31 @@ static size_t ComputeMinimumCopyLength(c
   }
   return len;
 }
 
 /* REQUIRES: nodes[pos].cost < kInfinity
    REQUIRES: nodes[0..pos] satisfies that "ZopfliNode array invariant". */
 static uint32_t ComputeDistanceShortcut(const size_t block_start,
                                         const size_t pos,
-                                        const size_t max_backward,
+                                        const size_t max_backward_limit,
                                         const size_t gap,
                                         const ZopfliNode* nodes) {
   const size_t clen = ZopfliNodeCopyLength(&nodes[pos]);
   const size_t ilen = nodes[pos].dcode_insert_length & 0x7FFFFFF;
   const size_t dist = ZopfliNodeCopyDistance(&nodes[pos]);
   /* Since |block_start + pos| is the end position of the command, the copy part
      starts from |block_start + pos - clen|. Distances that are greater than
-     this or greater than |max_backward| are static dictionary references, and
-     do not update the last distances. Also distance code 0 (last distance)
-     does not update the last distances. */
+     this or greater than |max_backward_limit| + |gap| are static dictionary
+     references, and do not update the last distances.
+     Also distance code 0 (last distance) does not update the last distances. */
   if (pos == 0) {
     return 0;
   } else if (dist + clen <= block_start + pos + gap &&
-             dist <= max_backward + gap &&
+             dist <= max_backward_limit + gap &&
              ZopfliNodeDistanceCode(&nodes[pos]) > 0) {
     return (uint32_t)pos;
   } else {
     return nodes[pos - clen - ilen].u.shortcut;
   }
 }
 
 /* Fills in dist_cache[0..3] with the last four distances (as defined by
@@ -449,19 +449,21 @@ static size_t UpdateNodes(
           (size_t)(posdata->distance_cache[idx] + kDistanceCacheOffset[j]);
       size_t prev_ix = cur_ix - backward;
       size_t len = 0;
       uint8_t continuation = ringbuffer[cur_ix_masked + best_len];
       if (cur_ix_masked + best_len > ringbuffer_mask) {
         break;
       }
       if (BROTLI_PREDICT_FALSE(backward > max_distance + gap)) {
+        /* Word dictionary -> ignore. */
         continue;
       }
       if (backward <= max_distance) {
+        /* Regular backward reference. */
         if (prev_ix >= cur_ix) {
           continue;
         }
 
         prev_ix &= ringbuffer_mask;
         if (prev_ix + best_len > ringbuffer_mask ||
             continuation != ringbuffer[prev_ix + best_len]) {
           continue;
@@ -559,24 +561,20 @@ static size_t ComputeShortestPathFromNod
     nodes[index].u.next = (uint32_t)len;
     num_commands++;
   }
   return num_commands;
 }
 
 /* REQUIRES: nodes != NULL and len(nodes) >= num_bytes + 1 */
 void BrotliZopfliCreateCommands(const size_t num_bytes,
-                                const size_t block_start,
-                                const size_t max_backward_limit,
-                                const ZopfliNode* nodes,
-                                int* dist_cache,
-                                size_t* last_insert_len,
-                                const BrotliEncoderParams* params,
-                                Command* commands,
-                                size_t* num_literals) {
+    const size_t block_start, const ZopfliNode* nodes, int* dist_cache,
+    size_t* last_insert_len, const BrotliEncoderParams* params,
+    Command* commands, size_t* num_literals) {
+  const size_t max_backward_limit = BROTLI_MAX_BACKWARD_LIMIT(params->lgwin);
   size_t pos = 0;
   uint32_t offset = nodes[0].u.next;
   size_t i;
   size_t gap = 0;
   for (i = 0; offset != BROTLI_UINT32_MAX; i++) {
     const ZopfliNode* next = &nodes[pos + offset];
     size_t copy_length = ZopfliNodeCopyLength(next);
     size_t insert_length = next->dcode_insert_length & 0x7FFFFFF;
@@ -605,28 +603,22 @@ void BrotliZopfliCreateCommands(const si
     }
 
     *num_literals += insert_length;
     pos += copy_length;
   }
   *last_insert_len += num_bytes - pos;
 }
 
-static size_t ZopfliIterate(size_t num_bytes,
-                            size_t position,
-                            const uint8_t* ringbuffer,
-                            size_t ringbuffer_mask,
-                            const BrotliEncoderParams* params,
-                            const size_t max_backward_limit,
-                            const size_t gap,
-                            const int* dist_cache,
-                            const ZopfliCostModel* model,
-                            const uint32_t* num_matches,
-                            const BackwardMatch* matches,
-                            ZopfliNode* nodes) {
+static size_t ZopfliIterate(size_t num_bytes, size_t position,
+    const uint8_t* ringbuffer, size_t ringbuffer_mask,
+    const BrotliEncoderParams* params, const size_t gap, const int* dist_cache,
+    const ZopfliCostModel* model, const uint32_t* num_matches,
+    const BackwardMatch* matches, ZopfliNode* nodes) {
+  const size_t max_backward_limit = BROTLI_MAX_BACKWARD_LIMIT(params->lgwin);
   const size_t max_zopfli_len = MaxZopfliLen(params);
   StartPosQueue queue;
   size_t cur_match_pos = 0;
   size_t i;
   nodes[0].length = 0;
   nodes[0].u.cost = 0;
   InitStartPosQueue(&queue);
   for (i = 0; i + 3 < num_bytes; i++) {
@@ -640,32 +632,32 @@ static size_t ZopfliIterate(size_t num_b
       skip = BROTLI_MAX(size_t,
           BackwardMatchLength(&matches[cur_match_pos - 1]), skip);
     }
     if (skip > 1) {
       skip--;
       while (skip) {
         i++;
         if (i + 3 >= num_bytes) break;
-        EvaluateNode(position, i, max_backward_limit, gap, dist_cache, model,
-            &queue, nodes);
+        EvaluateNode(position, i, max_backward_limit, gap,
+            dist_cache, model, &queue, nodes);
         cur_match_pos += num_matches[i];
         skip--;
       }
     }
   }
   return ComputeShortestPathFromNodes(num_bytes, nodes);
 }
 
 /* REQUIRES: nodes != NULL and len(nodes) >= num_bytes + 1 */
-size_t BrotliZopfliComputeShortestPath(MemoryManager* m,
-    size_t num_bytes, size_t position, const uint8_t* ringbuffer,
-    size_t ringbuffer_mask, const BrotliEncoderParams* params,
-    const size_t max_backward_limit, const int* dist_cache, HasherHandle hasher,
-    ZopfliNode* nodes) {
+size_t BrotliZopfliComputeShortestPath(MemoryManager* m, size_t num_bytes,
+    size_t position, const uint8_t* ringbuffer, size_t ringbuffer_mask,
+    const BrotliEncoderParams* params,
+    const int* dist_cache, HasherHandle hasher, ZopfliNode* nodes) {
+  const size_t max_backward_limit = BROTLI_MAX_BACKWARD_LIMIT(params->lgwin);
   const size_t max_zopfli_len = MaxZopfliLen(params);
   ZopfliCostModel model;
   StartPosQueue queue;
   BackwardMatch matches[2 * (MAX_NUM_MATCHES_H10 + 64)];
   const size_t store_end = num_bytes >= StoreLookaheadH10() ?
       position + num_bytes - StoreLookaheadH10() + 1 : position;
   size_t i;
   size_t gap = 0;
@@ -676,19 +668,21 @@ size_t BrotliZopfliComputeShortestPath(M
   if (BROTLI_IS_OOM(m)) return 0;
   ZopfliCostModelSetFromLiteralCosts(
       &model, position, ringbuffer, ringbuffer_mask);
   InitStartPosQueue(&queue);
   for (i = 0; i + HashTypeLengthH10() - 1 < num_bytes; i++) {
     const size_t pos = position + i;
     const size_t max_distance = BROTLI_MIN(size_t, pos, max_backward_limit);
     size_t skip;
-    size_t num_matches = FindAllMatchesH10(hasher, &params->dictionary,
-        ringbuffer, ringbuffer_mask, pos, num_bytes - i, max_distance, gap,
-        params, &matches[lz_matches_offset]);
+    size_t num_matches;
+    num_matches = FindAllMatchesH10(hasher,
+        &params->dictionary,
+        ringbuffer, ringbuffer_mask, pos, num_bytes - i, max_distance,
+        gap, params, &matches[lz_matches_offset]);
     if (num_matches > 0 &&
         BackwardMatchLength(&matches[num_matches - 1]) > max_zopfli_len) {
       matches[0] = matches[num_matches - 1];
       num_matches = 1;
     }
     skip = UpdateNodes(num_bytes, position, i, ringbuffer, ringbuffer_mask,
         params, max_backward_limit, dist_cache, num_matches, matches, &model,
         &queue, nodes);
@@ -699,48 +693,47 @@ size_t BrotliZopfliComputeShortestPath(M
     if (skip > 1) {
       /* Add the tail of the copy to the hasher. */
       StoreRangeH10(hasher, ringbuffer, ringbuffer_mask, pos + 1, BROTLI_MIN(
           size_t, pos + skip, store_end));
       skip--;
       while (skip) {
         i++;
         if (i + HashTypeLengthH10() - 1 >= num_bytes) break;
-        EvaluateNode(position, i, max_backward_limit, gap, dist_cache, &model,
-            &queue, nodes);
+        EvaluateNode(position, i, max_backward_limit, gap,
+            dist_cache, &model, &queue, nodes);
         skip--;
       }
     }
   }
   CleanupZopfliCostModel(m, &model);
   return ComputeShortestPathFromNodes(num_bytes, nodes);
 }
 
-void BrotliCreateZopfliBackwardReferences(MemoryManager* m,
-    size_t num_bytes, size_t position, const uint8_t* ringbuffer,
-    size_t ringbuffer_mask, const BrotliEncoderParams* params,
+void BrotliCreateZopfliBackwardReferences(MemoryManager* m, size_t num_bytes,
+    size_t position, const uint8_t* ringbuffer, size_t ringbuffer_mask,
+    const BrotliEncoderParams* params,
     HasherHandle hasher, int* dist_cache, size_t* last_insert_len,
     Command* commands, size_t* num_commands, size_t* num_literals) {
-  const size_t max_backward_limit = BROTLI_MAX_BACKWARD_LIMIT(params->lgwin);
   ZopfliNode* nodes;
   nodes = BROTLI_ALLOC(m, ZopfliNode, num_bytes + 1);
   if (BROTLI_IS_OOM(m)) return;
   BrotliInitZopfliNodes(nodes, num_bytes + 1);
-  *num_commands += BrotliZopfliComputeShortestPath(m,
-      num_bytes, position, ringbuffer, ringbuffer_mask,
-      params, max_backward_limit, dist_cache, hasher, nodes);
+  *num_commands += BrotliZopfliComputeShortestPath(m, num_bytes,
+      position, ringbuffer, ringbuffer_mask, params,
+      dist_cache, hasher, nodes);
   if (BROTLI_IS_OOM(m)) return;
-  BrotliZopfliCreateCommands(num_bytes, position, max_backward_limit, nodes,
-      dist_cache, last_insert_len, params, commands, num_literals);
+  BrotliZopfliCreateCommands(num_bytes, position, nodes, dist_cache,
+      last_insert_len, params, commands, num_literals);
   BROTLI_FREE(m, nodes);
 }
 
-void BrotliCreateHqZopfliBackwardReferences(MemoryManager* m,
-    size_t num_bytes, size_t position, const uint8_t* ringbuffer,
-    size_t ringbuffer_mask, const BrotliEncoderParams* params,
+void BrotliCreateHqZopfliBackwardReferences(MemoryManager* m, size_t num_bytes,
+    size_t position, const uint8_t* ringbuffer, size_t ringbuffer_mask,
+    const BrotliEncoderParams* params,
     HasherHandle hasher, int* dist_cache, size_t* last_insert_len,
     Command* commands, size_t* num_commands, size_t* num_literals) {
   const size_t max_backward_limit = BROTLI_MAX_BACKWARD_LIMIT(params->lgwin);
   uint32_t* num_matches = BROTLI_ALLOC(m, uint32_t, num_bytes);
   size_t matches_size = 4 * num_bytes;
   const size_t store_end = num_bytes >= StoreLookaheadH10() ?
       position + num_bytes - StoreLookaheadH10() + 1 : position;
   size_t cur_match_pos = 0;
@@ -762,18 +755,20 @@ void BrotliCreateHqZopfliBackwardReferen
     size_t num_found_matches;
     size_t cur_match_end;
     size_t j;
     /* Ensure that we have enough free slots. */
     BROTLI_ENSURE_CAPACITY(m, BackwardMatch, matches, matches_size,
         cur_match_pos + MAX_NUM_MATCHES_H10 + shadow_matches);
     if (BROTLI_IS_OOM(m)) return;
     num_found_matches = FindAllMatchesH10(hasher,
-        &params->dictionary, ringbuffer, ringbuffer_mask, pos, max_length,
-        max_distance, gap, params, &matches[cur_match_pos + shadow_matches]);
+        &params->dictionary,
+        ringbuffer, ringbuffer_mask, pos, max_length,
+        max_distance, gap, params,
+        &matches[cur_match_pos + shadow_matches]);
     cur_match_end = cur_match_pos + num_found_matches;
     for (j = cur_match_pos; j + 1 < cur_match_end; ++j) {
       BROTLI_DCHECK(BackwardMatchLength(&matches[j]) <=
           BackwardMatchLength(&matches[j + 1]));
     }
     num_matches[i] = (uint32_t)num_found_matches;
     if (num_found_matches > 0) {
       const size_t match_len = BackwardMatchLength(&matches[cur_match_end - 1]);
@@ -809,20 +804,20 @@ void BrotliCreateHqZopfliBackwardReferen
           ringbuffer_mask, commands, *num_commands - orig_num_commands,
           orig_last_insert_len);
     }
     *num_commands = orig_num_commands;
     *num_literals = orig_num_literals;
     *last_insert_len = orig_last_insert_len;
     memcpy(dist_cache, orig_dist_cache, 4 * sizeof(dist_cache[0]));
     *num_commands += ZopfliIterate(num_bytes, position, ringbuffer,
-        ringbuffer_mask, params, max_backward_limit, gap, dist_cache,
-        &model, num_matches, matches, nodes);
-    BrotliZopfliCreateCommands(num_bytes, position, max_backward_limit,
-        nodes, dist_cache, last_insert_len, params, commands, num_literals);
+        ringbuffer_mask, params, gap, dist_cache, &model, num_matches, matches,
+        nodes);
+    BrotliZopfliCreateCommands(num_bytes, position, nodes, dist_cache,
+        last_insert_len, params, commands, num_literals);
   }
   CleanupZopfliCostModel(m, &model);
   BROTLI_FREE(m, nodes);
   BROTLI_FREE(m, matches);
   BROTLI_FREE(m, num_matches);
 }
 
 #if defined(__cplusplus) || defined(c_plusplus)
--- a/modules/brotli/enc/backward_references_hq.h
+++ b/modules/brotli/enc/backward_references_hq.h
@@ -69,25 +69,24 @@ BROTLI_INTERNAL void BrotliInitZopfliNod
    Note that the sum of the lengths of all commands can be less than num_bytes.
 
    On return, the nodes[0..num_bytes] array will have the following
    "ZopfliNode array invariant":
    For each i in [1..num_bytes], if nodes[i].cost < kInfinity, then
      (1) nodes[i].copy_length() >= 2
      (2) nodes[i].command_length() <= i and
      (3) nodes[i - nodes[i].command_length()].cost < kInfinity */
-BROTLI_INTERNAL size_t BrotliZopfliComputeShortestPath(MemoryManager* m,
-    size_t num_bytes, size_t position, const uint8_t* ringbuffer,
-    size_t ringbuffer_mask, const BrotliEncoderParams* params,
-    const size_t max_backward_limit, const int* dist_cache, HasherHandle hasher,
-    ZopfliNode* nodes);
+BROTLI_INTERNAL size_t BrotliZopfliComputeShortestPath(
+    MemoryManager* m, size_t num_bytes,
+    size_t position, const uint8_t* ringbuffer, size_t ringbuffer_mask,
+    const BrotliEncoderParams* params,
+    const int* dist_cache, HasherHandle hasher, ZopfliNode* nodes);
 
 BROTLI_INTERNAL void BrotliZopfliCreateCommands(
-    const size_t num_bytes, const size_t block_start,
-    const size_t max_backward_limit, const ZopfliNode* nodes,
+    const size_t num_bytes, const size_t block_start, const ZopfliNode* nodes,
     int* dist_cache, size_t* last_insert_len, const BrotliEncoderParams* params,
     Command* commands, size_t* num_literals);
 
 #if defined(__cplusplus) || defined(c_plusplus)
 }  /* extern "C" */
 #endif
 
 #endif  /* BROTLI_ENC_BACKWARD_REFERENCES_HQ_H_ */
--- a/modules/brotli/enc/backward_references_inc.h
+++ b/modules/brotli/enc/backward_references_inc.h
@@ -5,19 +5,19 @@
    See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
 */
 
 /* template parameters: EXPORT_FN, FN */
 
 static BROTLI_NOINLINE void EXPORT_FN(CreateBackwardReferences)(
     size_t num_bytes, size_t position,
     const uint8_t* ringbuffer, size_t ringbuffer_mask,
-    const BrotliEncoderParams* params, HasherHandle hasher, int* dist_cache,
-    size_t* last_insert_len, Command* commands, size_t* num_commands,
-    size_t* num_literals) {
+    const BrotliEncoderParams* params,
+    HasherHandle hasher, int* dist_cache, size_t* last_insert_len,
+    Command* commands, size_t* num_commands, size_t* num_literals) {
   /* Set maximum distance, see section 9.1. of the spec. */
   const size_t max_backward_limit = BROTLI_MAX_BACKWARD_LIMIT(params->lgwin);
 
   const Command* const orig_commands = commands;
   size_t insert_length = *last_insert_len;
   const size_t pos_end = position + num_bytes;
   const size_t store_end = num_bytes >= FN(StoreLookahead)() ?
       position + num_bytes - FN(StoreLookahead)() + 1 : position;
@@ -37,33 +37,33 @@ static BROTLI_NOINLINE void EXPORT_FN(Cr
     size_t max_length = pos_end - position;
     size_t max_distance = BROTLI_MIN(size_t, position, max_backward_limit);
     HasherSearchResult sr;
     sr.len = 0;
     sr.len_code_delta = 0;
     sr.distance = 0;
     sr.score = kMinScore;
     FN(FindLongestMatch)(hasher, &params->dictionary,
-                         ringbuffer, ringbuffer_mask, dist_cache, position,
-                         max_length, max_distance, gap,
-                         params->dist.max_distance, &sr);
+        ringbuffer, ringbuffer_mask, dist_cache, position, max_length,
+        max_distance, gap, params->dist.max_distance, &sr);
     if (sr.score > kMinScore) {
       /* Found a match. Let's look for something even better ahead. */
       int delayed_backward_references_in_row = 0;
       --max_length;
       for (;; --max_length) {
         const score_t cost_diff_lazy = 175;
         HasherSearchResult sr2;
         sr2.len = params->quality < MIN_QUALITY_FOR_EXTENSIVE_REFERENCE_SEARCH ?
             BROTLI_MIN(size_t, sr.len - 1, max_length) : 0;
         sr2.len_code_delta = 0;
         sr2.distance = 0;
         sr2.score = kMinScore;
         max_distance = BROTLI_MIN(size_t, position + 1, max_backward_limit);
-        FN(FindLongestMatch)(hasher, &params->dictionary,
+        FN(FindLongestMatch)(hasher,
+            &params->dictionary,
             ringbuffer, ringbuffer_mask, dist_cache, position + 1, max_length,
             max_distance, gap, params->dist.max_distance, &sr2);
         if (sr2.score >= sr.score + cost_diff_lazy) {
           /* Ok, let's just write one byte for now and start a match from the
              next byte. */
           ++position;
           ++insert_length;
           sr = sr2;
@@ -75,18 +75,18 @@ static BROTLI_NOINLINE void EXPORT_FN(Cr
         break;
       }
       apply_random_heuristics =
           position + 2 * sr.len + random_heuristics_window_size;
       max_distance = BROTLI_MIN(size_t, position, max_backward_limit);
       {
         /* The first 16 codes are special short-codes,
            and the minimum offset is 1. */
-        size_t distance_code =
-            ComputeDistanceCode(sr.distance, max_distance + gap, dist_cache);
+        size_t distance_code = ComputeDistanceCode(
+            sr.distance, max_distance + gap, dist_cache);
         if ((sr.distance <= (max_distance + gap)) && distance_code > 0) {
           dist_cache[3] = dist_cache[2];
           dist_cache[2] = dist_cache[1];
           dist_cache[1] = dist_cache[0];
           dist_cache[0] = (int)sr.distance;
           FN(PrepareDistanceCache)(hasher, dist_cache);
         }
         InitCommand(commands++, &params->dist, insert_length,
--- a/modules/brotli/enc/encode.c
+++ b/modules/brotli/enc/encode.c
@@ -491,16 +491,18 @@ static void DecideOverLiteralContextMode
     ChooseContextMap(quality, &bigram_prefix_histo[0], num_literal_contexts,
                      literal_context_map);
   }
 }
 
 static BROTLI_BOOL ShouldCompress(
     const uint8_t* data, const size_t mask, const uint64_t last_flush_pos,
     const size_t bytes, const size_t num_literals, const size_t num_commands) {
+  /* TODO: find more precise minimal block overhead. */
+  if (bytes <= 2) return BROTLI_FALSE;
   if (num_commands < (bytes >> 8) + 2) {
     if (num_literals > 0.99 * (double)bytes) {
       uint32_t literal_histo[256] = { 0 };
       static const uint32_t kSampleRate = 13;
       static const double kMinEntropy = 7.92;
       const double bit_cost_threshold =
           (double)bytes * kMinEntropy / kSampleRate;
       size_t t = (bytes + kSampleRate - 1) / kSampleRate;
@@ -669,22 +671,24 @@ static void ChooseDistanceParams(BrotliE
   BrotliInitDistanceParams(
       params, distance_postfix_bits, num_direct_distance_codes);
 }
 
 static BROTLI_BOOL EnsureInitialized(BrotliEncoderState* s) {
   if (BROTLI_IS_OOM(&s->memory_manager_)) return BROTLI_FALSE;
   if (s->is_initialized_) return BROTLI_TRUE;
 
+  s->last_bytes_bits_ = 0;
+  s->last_bytes_ = 0;
+  s->remaining_metadata_bytes_ = BROTLI_UINT32_MAX;
+
   SanitizeParams(&s->params);
   s->params.lgblock = ComputeLgBlock(&s->params);
   ChooseDistanceParams(&s->params);
 
-  s->remaining_metadata_bytes_ = BROTLI_UINT32_MAX;
-
   RingBufferSetup(&s->params, &s->ringbuffer_);
 
   /* Initialize last byte with stream header. */
   {
     int lgwin = s->params.lgwin;
     if (s->params.quality == FAST_ONE_PASS_COMPRESSION_QUALITY ||
         s->params.quality == FAST_TWO_PASS_COMPRESSION_QUALITY) {
       lgwin = BROTLI_MAX(int, lgwin, 18);
@@ -1024,33 +1028,30 @@ static BROTLI_BOOL EncodeData(
   if (BROTLI_IS_OOM(m)) return BROTLI_FALSE;
 
   if (s->num_commands_ && s->last_insert_len_ == 0) {
     ExtendLastCommand(s, &bytes, &wrapped_last_processed_pos);
   }
 
   if (s->params.quality == ZOPFLIFICATION_QUALITY) {
     BROTLI_DCHECK(s->params.hasher.type == 10);
-    BrotliCreateZopfliBackwardReferences(m,
-        bytes, wrapped_last_processed_pos,
+    BrotliCreateZopfliBackwardReferences(m, bytes, wrapped_last_processed_pos,
         data, mask, &s->params, s->hasher_, s->dist_cache_,
         &s->last_insert_len_, &s->commands_[s->num_commands_],
         &s->num_commands_, &s->num_literals_);
     if (BROTLI_IS_OOM(m)) return BROTLI_FALSE;
   } else if (s->params.quality == HQ_ZOPFLIFICATION_QUALITY) {
     BROTLI_DCHECK(s->params.hasher.type == 10);
-    BrotliCreateHqZopfliBackwardReferences(m,
-        bytes, wrapped_last_processed_pos,
+    BrotliCreateHqZopfliBackwardReferences(m, bytes, wrapped_last_processed_pos,
         data, mask, &s->params, s->hasher_, s->dist_cache_,
         &s->last_insert_len_, &s->commands_[s->num_commands_],
         &s->num_commands_, &s->num_literals_);
     if (BROTLI_IS_OOM(m)) return BROTLI_FALSE;
   } else {
-    BrotliCreateBackwardReferences(
-        bytes, wrapped_last_processed_pos,
+    BrotliCreateBackwardReferences(bytes, wrapped_last_processed_pos,
         data, mask, &s->params, s->hasher_, s->dist_cache_,
         &s->last_insert_len_, &s->commands_[s->num_commands_],
         &s->num_commands_, &s->num_literals_);
   }
 
   {
     const size_t max_length = MaxMetablockSize(&s->params);
     const size_t max_literals = max_length / 8;
@@ -1161,28 +1162,27 @@ static size_t WriteMetadataHeader(
 
 static BROTLI_BOOL BrotliCompressBufferQuality10(
     int lgwin, size_t input_size, const uint8_t* input_buffer,
     size_t* encoded_size, uint8_t* encoded_buffer) {
   MemoryManager memory_manager;
   MemoryManager* m = &memory_manager;
 
   const size_t mask = BROTLI_SIZE_MAX >> 1;
-  const size_t max_backward_limit = BROTLI_MAX_BACKWARD_LIMIT(lgwin);
   int dist_cache[4] = { 4, 11, 15, 16 };
   int saved_dist_cache[4] = { 4, 11, 15, 16 };
   BROTLI_BOOL ok = BROTLI_TRUE;
   const size_t max_out_size = *encoded_size;
   size_t total_out_size = 0;
   uint16_t last_bytes;
   uint8_t last_bytes_bits;
   HasherHandle hasher = NULL;
 
-  const size_t hasher_eff_size =
-      BROTLI_MIN(size_t, input_size, max_backward_limit + BROTLI_WINDOW_GAP);
+  const size_t hasher_eff_size = BROTLI_MIN(size_t,
+      input_size, BROTLI_MAX_BACKWARD_LIMIT(lgwin) + BROTLI_WINDOW_GAP);
 
   BrotliEncoderParams params;
 
   const int lgmetablock = BROTLI_MIN(int, 24, lgwin + 1);
   size_t max_block_size;
   const size_t max_metablock_size = (size_t)1 << lgmetablock;
   const size_t max_literals_per_metablock = max_metablock_size / 8;
   const size_t max_commands_per_metablock = max_metablock_size / 8;
@@ -1233,19 +1233,19 @@ static BROTLI_BOOL BrotliCompressBufferQ
           BROTLI_MIN(size_t, metablock_end - block_start, max_block_size);
       ZopfliNode* nodes = BROTLI_ALLOC(m, ZopfliNode, block_size + 1);
       size_t path_size;
       size_t new_cmd_alloc_size;
       if (BROTLI_IS_OOM(m)) goto oom;
       BrotliInitZopfliNodes(nodes, block_size + 1);
       StitchToPreviousBlockH10(hasher, block_size, block_start,
                                input_buffer, mask);
-      path_size = BrotliZopfliComputeShortestPath(m,
-          block_size, block_start, input_buffer, mask, &params,
-          max_backward_limit, dist_cache, hasher, nodes);
+      path_size = BrotliZopfliComputeShortestPath(m, block_size, block_start,
+          input_buffer, mask, &params, dist_cache, hasher,
+          nodes);
       if (BROTLI_IS_OOM(m)) goto oom;
       /* We allocate a command buffer in the first iteration of this loop that
          will be likely big enough for the whole metablock, so that for most
          inputs we will not have to reallocate in later iterations. We do the
          allocation here and not before the loop, because if the input is small,
          this will be allocated after the Zopfli cost model is freed, so this
          will not increase peak memory usage.
          TODO: If the first allocation is too small, increase command
@@ -1257,20 +1257,18 @@ static BROTLI_BOOL BrotliCompressBufferQ
         if (BROTLI_IS_OOM(m)) goto oom;
         cmd_alloc_size = new_cmd_alloc_size;
         if (commands) {
           memcpy(new_commands, commands, sizeof(Command) * num_commands);
           BROTLI_FREE(m, commands);
         }
         commands = new_commands;
       }
-      BrotliZopfliCreateCommands(block_size, block_start, max_backward_limit,
-                                 &nodes[0], dist_cache, &last_insert_len,
-                                 &params, &commands[num_commands],
-                                 &num_literals);
+      BrotliZopfliCreateCommands(block_size, block_start, &nodes[0], dist_cache,
+          &last_insert_len, &params, &commands[num_commands], &num_literals);
       num_commands += path_size;
       block_start += block_size;
       metablock_size += block_size;
       BROTLI_FREE(m, nodes);
       if (num_literals > max_literals_per_metablock ||
           num_commands > max_commands_per_metablock) {
         break;
       }
--- a/modules/brotli/enc/hash.h
+++ b/modules/brotli/enc/hash.h
@@ -144,19 +144,19 @@ static BROTLI_INLINE score_t BackwardRef
 }
 
 static BROTLI_INLINE score_t BackwardReferencePenaltyUsingLastDistance(
     size_t distance_short_code) {
   return (score_t)39 + ((0x1CA10 >> (distance_short_code & 0xE)) & 0xE);
 }
 
 static BROTLI_INLINE BROTLI_BOOL TestStaticDictionaryItem(
-    const BrotliEncoderDictionary* dictionary, size_t item, const uint8_t* data,
-    size_t max_length, size_t max_backward, size_t max_distance,
-    HasherSearchResult* out) {
+    const BrotliEncoderDictionary* dictionary, size_t item,
+    const uint8_t* data, size_t max_length, size_t max_backward,
+    size_t max_distance, HasherSearchResult* out) {
   size_t len;
   size_t word_idx;
   size_t offset;
   size_t matchlen;
   size_t backward;
   score_t score;
   len = item & 0x1F;
   word_idx = item >> 5;
@@ -203,17 +203,18 @@ static BROTLI_INLINE void SearchInStatic
     return;
   }
   key = Hash14(data) << 1;
   for (i = 0; i < (shallow ? 1u : 2u); ++i, ++key) {
     size_t item = dictionary->hash_table[key];
     self->dict_num_lookups++;
     if (item != 0) {
       BROTLI_BOOL item_matches = TestStaticDictionaryItem(
-          dictionary, item, data, max_length, max_backward, max_distance, out);
+          dictionary, item, data,
+          max_length, max_backward, max_distance, out);
       if (item_matches) {
         self->dict_num_matches++;
       }
     }
   }
 }
 
 typedef struct BackwardMatch {
--- a/modules/brotli/enc/hash_composite_inc.h
+++ b/modules/brotli/enc/hash_composite_inc.h
@@ -116,18 +116,21 @@ static BROTLI_INLINE void FN(PrepareDist
   FN_A(PrepareDistanceCache)(self->ha, distance_cache);
   FN_B(PrepareDistanceCache)(self->hb, distance_cache);
 }
 
 static BROTLI_INLINE void FN(FindLongestMatch)(HasherHandle handle,
     const BrotliEncoderDictionary* dictionary,
     const uint8_t* BROTLI_RESTRICT data, const size_t ring_buffer_mask,
     const int* BROTLI_RESTRICT distance_cache, const size_t cur_ix,
-    const size_t max_length, const size_t max_backward, const size_t gap,
-    const size_t max_distance, HasherSearchResult* BROTLI_RESTRICT out) {
+    const size_t max_length, const size_t max_backward,
+    const size_t gap, const size_t max_distance,
+    HasherSearchResult* BROTLI_RESTRICT out) {
   HashComposite* self = FN(Self)(handle);
   FN_A(FindLongestMatch)(self->ha, dictionary, data, ring_buffer_mask,
-      distance_cache, cur_ix, max_length, max_backward, gap, max_distance, out);
+      distance_cache, cur_ix, max_length, max_backward, gap,
+      max_distance, out);
   FN_B(FindLongestMatch)(self->hb, dictionary, data, ring_buffer_mask,
-      distance_cache, cur_ix, max_length, max_backward, gap, max_distance, out);
+      distance_cache, cur_ix, max_length, max_backward, gap,
+      max_distance, out);
 }
 
 #undef HashComposite
--- a/modules/brotli/enc/hash_longest_match64_inc.h
+++ b/modules/brotli/enc/hash_longest_match64_inc.h
@@ -156,18 +156,19 @@ static BROTLI_INLINE void FN(PrepareDist
    Does not look for matches longer than max_length.
    Does not look for matches further away than max_backward.
    Writes the best match into |out|.
    |out|->score is updated only if a better match is found. */
 static BROTLI_INLINE void FN(FindLongestMatch)(HasherHandle handle,
     const BrotliEncoderDictionary* dictionary,
     const uint8_t* BROTLI_RESTRICT data, const size_t ring_buffer_mask,
     const int* BROTLI_RESTRICT distance_cache, const size_t cur_ix,
-    const size_t max_length, const size_t max_backward, const size_t gap,
-    const size_t max_distance, HasherSearchResult* BROTLI_RESTRICT out) {
+    const size_t max_length, const size_t max_backward,
+    const size_t gap, const size_t max_distance,
+    HasherSearchResult* BROTLI_RESTRICT out) {
   HasherCommon* common = GetHasherCommon(handle);
   HashLongestMatch* self = FN(Self)(handle);
   uint16_t* num = FN(Num)(self);
   uint32_t* buckets = FN(Buckets)(self);
   const size_t cur_ix_masked = cur_ix & ring_buffer_mask;
   /* Don't accept a short copy from far away. */
   score_t min_score = out->score;
   score_t best_score = out->score;
--- a/modules/brotli/enc/hash_longest_match_inc.h
+++ b/modules/brotli/enc/hash_longest_match_inc.h
@@ -149,18 +149,19 @@ static BROTLI_INLINE void FN(PrepareDist
    Does not look for matches longer than max_length.
    Does not look for matches further away than max_backward.
    Writes the best match into |out|.
    |out|->score is updated only if a better match is found. */
 static BROTLI_INLINE void FN(FindLongestMatch)(HasherHandle handle,
     const BrotliEncoderDictionary* dictionary,
     const uint8_t* BROTLI_RESTRICT data, const size_t ring_buffer_mask,
     const int* BROTLI_RESTRICT distance_cache, const size_t cur_ix,
-    const size_t max_length, const size_t max_backward, const size_t gap,
-    const size_t max_distance, HasherSearchResult* BROTLI_RESTRICT out) {
+    const size_t max_length, const size_t max_backward,
+    const size_t gap, const size_t max_distance,
+    HasherSearchResult* BROTLI_RESTRICT out) {
   HasherCommon* common = GetHasherCommon(handle);
   HashLongestMatch* self = FN(Self)(handle);
   uint16_t* num = FN(Num)(self);
   uint32_t* buckets = FN(Buckets)(self);
   const size_t cur_ix_masked = cur_ix & ring_buffer_mask;
   /* Don't accept a short copy from far away. */
   score_t min_score = out->score;
   score_t best_score = out->score;
--- a/modules/brotli/enc/hash_rolling_inc.h
+++ b/modules/brotli/enc/hash_rolling_inc.h
@@ -150,18 +150,19 @@ static BROTLI_INLINE void FN(PrepareDist
   BROTLI_UNUSED(handle);
   BROTLI_UNUSED(distance_cache);
 }
 
 static BROTLI_INLINE void FN(FindLongestMatch)(HasherHandle handle,
     const BrotliEncoderDictionary* dictionary,
     const uint8_t* BROTLI_RESTRICT data, const size_t ring_buffer_mask,
     const int* BROTLI_RESTRICT distance_cache, const size_t cur_ix,
-    const size_t max_length, const size_t max_backward, const size_t gap,
-    const size_t max_distance, HasherSearchResult* BROTLI_RESTRICT out) {
+    const size_t max_length, const size_t max_backward,
+    const size_t gap, const size_t max_distance,
+    HasherSearchResult* BROTLI_RESTRICT out) {
   HashRolling* self = FN(Self)(handle);
   const size_t cur_ix_masked = cur_ix & ring_buffer_mask;
   size_t pos = self->next_ix;
 
   if ((cur_ix & (JUMP - 1)) != 0) return;
 
   /* Not enough lookahead */
   if (max_length < CHUNKLEN) return;
--- a/modules/brotli/enc/hash_to_binary_tree_inc.h
+++ b/modules/brotli/enc/hash_to_binary_tree_inc.h
@@ -197,18 +197,19 @@ static BROTLI_INLINE BackwardMatch* FN(S
 
    Sets *num_matches to the number of matches found, and stores the found
    matches in matches[0] to matches[*num_matches - 1]. The matches will be
    sorted by strictly increasing length and (non-strictly) increasing
    distance. */
 static BROTLI_INLINE size_t FN(FindAllMatches)(HasherHandle handle,
     const BrotliEncoderDictionary* dictionary, const uint8_t* data,
     const size_t ring_buffer_mask, const size_t cur_ix,
-    const size_t max_length, const size_t max_backward, const size_t gap,
-    const BrotliEncoderParams* params, BackwardMatch* matches) {
+    const size_t max_length, const size_t max_backward,
+    const size_t gap, const BrotliEncoderParams* params,
+    BackwardMatch* matches) {
   BackwardMatch* const orig_matches = matches;
   const size_t cur_ix_masked = cur_ix & ring_buffer_mask;
   size_t best_len = 1;
   const size_t short_match_max_backward =
       params->quality != HQ_ZOPFLIFICATION_QUALITY ? 16 : 64;
   size_t stop = cur_ix - short_match_max_backward;
   uint32_t dict_matches[BROTLI_MAX_STATIC_DICTIONARY_MATCH_LEN + 1];
   size_t i;
--- a/modules/brotli/tools/brotli.c
+++ b/modules/brotli/tools/brotli.c
@@ -938,20 +938,19 @@ static BROTLI_BOOL CompressFiles(Context
       }
       BrotliEncoderSetParameter(s,
           BROTLI_PARAM_LGWIN, (uint32_t)context->lgwin);
     } else {
       /* 0, or not specified by user; could be chosen by compressor. */
       uint32_t lgwin = DEFAULT_LGWIN;
       /* Use file size to limit lgwin. */
       if (context->input_file_length >= 0) {
-        int32_t size = 1 << BROTLI_MIN_WINDOW_BITS;
         lgwin = BROTLI_MIN_WINDOW_BITS;
-        while (size < context->input_file_length) {
-          size <<= 1;
+        while (BROTLI_MAX_BACKWARD_LIMIT(lgwin) <
+               (uint64_t)context->input_file_length) {
           lgwin++;
           if (lgwin == BROTLI_MAX_WINDOW_BITS) break;
         }
       }
       BrotliEncoderSetParameter(s, BROTLI_PARAM_LGWIN, lgwin);
     }
     if (context->input_file_length > 0) {
       uint32_t size_hint = context->input_file_length < (1 << 30) ?
--- a/modules/brotli/update.sh
+++ b/modules/brotli/update.sh
@@ -1,17 +1,17 @@
 #!/bin/sh
 
 # Script to update the mozilla in-tree copy of the Brotli library.
 # Run this within the /modules/brotli directory of the source tree.
 
 MY_TEMP_DIR=`mktemp -d -t brotli_update.XXXXXX` || exit 1
 
 git clone https://github.com/google/brotli ${MY_TEMP_DIR}/brotli
-git -C ${MY_TEMP_DIR}/brotli checkout v1.0.6
+git -C ${MY_TEMP_DIR}/brotli checkout v1.0.7
 
 COMMIT=$(git -C ${MY_TEMP_DIR}/brotli rev-parse HEAD)
 perl -p -i -e "s/\[commit [0-9a-f]{40}\]/[commit ${COMMIT}]/" README.mozilla;
 
 DIRS="common dec enc include tools"
 
 for d in $DIRS; do
 	rm -rf $d