Merge inbound to mozilla-central. a=merge
authorBrindusan Cristian <cbrindusan@mozilla.com>
Mon, 09 Jul 2018 00:36:24 +0300
changeset 425484 ffb7b5015fc331bdc4c5e6ab52b9de669faa8864
parent 425482 8eab40c279038941d767790b2d2cf82b21634ff0 (current diff)
parent 425483 3c24d85af2dbe96025422dabc9ebdc5867786b03 (diff)
child 425485 78e841de1a73cc8a234810e791475d95b2956d48
child 425497 e02ce918e160e86ff76bd8e801dbabb354de9c88
push id66077
push usercbrindusan@mozilla.com
push dateSun, 08 Jul 2018 21:43:08 +0000
treeherderautoland@ffb7b5015fc3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone63.0a1
first release with
nightly linux32
ffb7b5015fc3 / 63.0a1 / 20180708220048 / files
nightly linux64
ffb7b5015fc3 / 63.0a1 / 20180708220048 / files
nightly mac
ffb7b5015fc3 / 63.0a1 / 20180708220048 / files
nightly win32
ffb7b5015fc3 / 63.0a1 / 20180708220048 / files
nightly win64
ffb7b5015fc3 / 63.0a1 / 20180708220048 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge inbound to mozilla-central. a=merge
--- a/modules/brotli/README.mozilla
+++ b/modules/brotli/README.mozilla
@@ -1,17 +1,14 @@
 This is the Brotli data compression library from
 https://github.com/google/brotli.
 
-Currently, we import only the Brotli decoder (the /dec/ subdirectory), not the
-encoder (/enc/ subdirectory).
-
 Upstream code can be viewed at
   https://github.com/google/brotli/tree/master/dec
 
 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 c6333e1e79fb62ea088443f192293f964409b04e].
+Current version: [commit b601fe817bd3217cb144bbb380a43cae8e847388].
--- a/modules/brotli/common/dictionary.c
+++ b/modules/brotli/common/dictionary.c
@@ -5878,17 +5878,17 @@ static BrotliDictionary kBrotliDictionar
     104704, 106752, 108928, 113536, 115968, 118528, 119872, 121280,
     122016, 122784, 122784, 122784, 122784, 122784, 122784, 122784
   },
 
   /* data_size ==  sizeof(kBrotliDictionaryData) */
   122784,
 
   /* data */
-#ifdef BROTLI_EXTERNAL_DICTIONARY_DATA
+#if defined(BROTLI_EXTERNAL_DICTIONARY_DATA)
   NULL
 #else
   kBrotliDictionaryData
 #endif
 };
 
 const BrotliDictionary* BrotliGetDictionary() {
   return &kBrotliDictionary;
--- a/modules/brotli/common/platform.h
+++ b/modules/brotli/common/platform.h
@@ -1,109 +1,190 @@
 /* Copyright 2016 Google Inc. All Rights Reserved.
 
    Distributed under MIT license.
    See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
 */
 
-/* Macros for compiler / platform specific features and build options. */
-
-#ifndef BROTLI_COMMON_PLATFORM_H_
-#define BROTLI_COMMON_PLATFORM_H_
-
-#include <string.h>  /* memcpy */
-#include <stdlib.h>  /* malloc, free */
-
-#include <brotli/port.h>
-#include <brotli/types.h>
-
-#if defined OS_LINUX || defined OS_CYGWIN
-#include <endian.h>
-#elif defined OS_FREEBSD
-#include <machine/endian.h>
-#elif defined OS_MACOSX
-#include <machine/endian.h>
-/* Let's try and follow the Linux convention */
-#define BROTLI_X_BYTE_ORDER BYTE_ORDER
-#define BROTLI_X_LITTLE_ENDIAN LITTLE_ENDIAN
-#define BROTLI_X_BIG_ENDIAN BIG_ENDIAN
-#endif
-
-#if defined(BROTLI_ENABLE_LOG) || defined(BROTLI_DEBUG)
-#include <assert.h>
-#include <stdio.h>
-#endif
-
 /* Macros for compiler / platform specific features and build options.
 
    Build options are:
     * BROTLI_BUILD_32_BIT disables 64-bit optimizations
     * BROTLI_BUILD_64_BIT forces to use 64-bit optimizations
     * BROTLI_BUILD_BIG_ENDIAN forces to use big-endian optimizations
     * BROTLI_BUILD_ENDIAN_NEUTRAL disables endian-aware optimizations
     * BROTLI_BUILD_LITTLE_ENDIAN forces to use little-endian optimizations
     * BROTLI_BUILD_PORTABLE disables dangerous optimizations, like unaligned
       read and overlapping memcpy; this reduces decompression speed by 5%
     * BROTLI_BUILD_NO_RBIT disables "rbit" optimization for ARM CPUs
     * BROTLI_DEBUG dumps file name and line number when decoder detects stream
       or memory error
     * BROTLI_ENABLE_LOG enables asserts and dumps various state information
 */
 
-#if BROTLI_MODERN_COMPILER || __has_attribute(always_inline)
-#define BROTLI_ATTRIBUTE_ALWAYS_INLINE __attribute__ ((always_inline))
-#else
-#define BROTLI_ATTRIBUTE_ALWAYS_INLINE
+#ifndef BROTLI_COMMON_PLATFORM_H_
+#define BROTLI_COMMON_PLATFORM_H_
+
+#include <string.h>  /* memcpy */
+#include <stdlib.h>  /* malloc, free */
+
+#include <brotli/port.h>
+#include <brotli/types.h>
+
+#if defined(OS_LINUX) || defined(OS_CYGWIN)
+#include <endian.h>
+#elif defined(OS_FREEBSD)
+#include <machine/endian.h>
+#elif defined(OS_MACOSX)
+#include <machine/endian.h>
+/* Let's try and follow the Linux convention */
+#define BROTLI_X_BYTE_ORDER BYTE_ORDER
+#define BROTLI_X_LITTLE_ENDIAN LITTLE_ENDIAN
+#define BROTLI_X_BIG_ENDIAN BIG_ENDIAN
 #endif
 
-#if defined(_WIN32) || defined(__CYGWIN__)
-#define BROTLI_ATTRIBUTE_VISIBILITY_HIDDEN
-#elif BROTLI_MODERN_COMPILER || __has_attribute(visibility)
-#define BROTLI_ATTRIBUTE_VISIBILITY_HIDDEN \
-    __attribute__ ((visibility ("hidden")))
-#else
-#define BROTLI_ATTRIBUTE_VISIBILITY_HIDDEN
-#endif
-
-#ifndef BROTLI_INTERNAL
-#define BROTLI_INTERNAL BROTLI_ATTRIBUTE_VISIBILITY_HIDDEN
+#if defined(BROTLI_ENABLE_LOG) || defined(BROTLI_DEBUG)
+#include <assert.h>
+#include <stdio.h>
 #endif
 
-#ifndef _MSC_VER
-#if defined(__cplusplus) || !defined(__STRICT_ANSI__) || \
-    (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L)
-#define BROTLI_INLINE inline BROTLI_ATTRIBUTE_ALWAYS_INLINE
+/* The following macros were borrowed from https://github.com/nemequ/hedley
+ * with permission of original author - Evan Nemerson <evan@nemerson.com> */
+
+/* >>> >>> >>> hedley macros */
+
+/* Define "BROTLI_PREDICT_TRUE" and "BROTLI_PREDICT_FALSE" macros for capable
+   compilers.
+
+To apply compiler hint, enclose the branching condition into macros, like this:
+
+  if (BROTLI_PREDICT_TRUE(zero == 0)) {
+    // main execution path
+  } else {
+    // compiler should place this code outside of main execution path
+  }
+
+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_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_INLINE
-#endif
-#else  /* _MSC_VER */
-#define BROTLI_INLINE __forceinline
-#endif  /* _MSC_VER */
-
-#if BROTLI_MODERN_COMPILER || __has_attribute(unused)
-#define BROTLI_UNUSED_FUNCTION static BROTLI_INLINE __attribute__ ((unused))
-#else
-#define BROTLI_UNUSED_FUNCTION static BROTLI_INLINE
+#define BROTLI_PREDICT_FALSE(x) (x)
+#define BROTLI_PREDICT_TRUE(x) (x)
 #endif
 
-#if !defined(__cplusplus) && !defined(c_plusplus) && \
-    (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L)
+#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \
+    !defined(__cplusplus)
 #define BROTLI_RESTRICT restrict
-#elif BROTLI_GCC_VERSION > 295 || defined(__llvm__)
+#elif BROTLI_GNUC_VERSION_CHECK(3, 1, 0) ||                         \
+    BROTLI_MSVC_VERSION_CHECK(14, 0, 0) ||                          \
+    BROTLI_INTEL_VERSION_CHECK(16, 0, 0) ||                         \
+    BROTLI_ARM_VERSION_CHECK(4, 1, 0) ||                            \
+    BROTLI_IBM_VERSION_CHECK(10, 1, 0) ||                           \
+    BROTLI_PGI_VERSION_CHECK(17, 10, 0) ||                          \
+    BROTLI_TI_VERSION_CHECK(8, 0, 0) ||                             \
+    BROTLI_IAR_VERSION_CHECK(8, 0, 0) ||                            \
+    (BROTLI_SUNPRO_VERSION_CHECK(5, 14, 0) && defined(__cplusplus))
 #define BROTLI_RESTRICT __restrict
+#elif BROTLI_SUNPRO_VERSION_CHECK(5, 3, 0) && !defined(__cplusplus)
+#define BROTLI_RESTRICT _Restrict
 #else
 #define BROTLI_RESTRICT
 #endif
 
-#if BROTLI_MODERN_COMPILER || __has_attribute(noinline)
-#define BROTLI_NOINLINE __attribute__((noinline))
+#if (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \
+    (defined(__cplusplus) && (__cplusplus >= 199711L))
+#define BROTLI_MAYBE_INLINE inline
+#elif defined(__GNUC_STDC_INLINE__) || defined(__GNUC_GNU_INLINE__) || \
+    BROTLI_ARM_VERSION_CHECK(6, 2, 0)
+#define BROTLI_MAYBE_INLINE __inline__
+#elif BROTLI_MSVC_VERSION_CHECK(12, 0, 0) || \
+    BROTLI_ARM_VERSION_CHECK(4, 1, 0) || BROTLI_TI_VERSION_CHECK(8, 0, 0)
+#define BROTLI_MAYBE_INLINE __inline
+#else
+#define BROTLI_MAYBE_INLINE
+#endif
+
+#if BROTLI_GNUC_HAS_ATTRIBUTE(always_inline, 4, 0, 0) ||                       \
+    BROTLI_INTEL_VERSION_CHECK(16, 0, 0) ||                                    \
+    BROTLI_SUNPRO_VERSION_CHECK(5, 11, 0) ||                                   \
+    BROTLI_ARM_VERSION_CHECK(4, 1, 0) ||                                       \
+    BROTLI_IBM_VERSION_CHECK(10, 1, 0) ||                                      \
+    BROTLI_TI_VERSION_CHECK(8, 0, 0) ||                                        \
+    (BROTLI_TI_VERSION_CHECK(7, 3, 0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__))
+#define BROTLI_INLINE BROTLI_MAYBE_INLINE __attribute__((__always_inline__))
+#elif BROTLI_MSVC_VERSION_CHECK(12, 0, 0)
+#define BROTLI_INLINE BROTLI_MAYBE_INLINE __forceinline
+#elif BROTLI_TI_VERSION_CHECK(7, 0, 0) && defined(__cplusplus)
+#define BROTLI_INLINE BROTLI_MAYBE_INLINE _Pragma("FUNC_ALWAYS_INLINE;")
+#elif BROTLI_IAR_VERSION_CHECK(8, 0, 0)
+#define BROTLI_INLINE BROTLI_MAYBE_INLINE _Pragma("inline=forced")
+#else
+#define BROTLI_INLINE BROTLI_MAYBE_INLINE
+#endif
+
+#if BROTLI_GNUC_HAS_ATTRIBUTE(noinline, 4, 0, 0) ||                            \
+    BROTLI_INTEL_VERSION_CHECK(16, 0, 0) ||                                    \
+    BROTLI_SUNPRO_VERSION_CHECK(5, 11, 0) ||                                   \
+    BROTLI_ARM_VERSION_CHECK(4, 1, 0) ||                                       \
+    BROTLI_IBM_VERSION_CHECK(10, 1, 0) ||                                      \
+    BROTLI_TI_VERSION_CHECK(8, 0, 0) ||                                        \
+    (BROTLI_TI_VERSION_CHECK(7, 3, 0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__))
+#define BROTLI_NOINLINE __attribute__((__noinline__))
+#elif BROTLI_MSVC_VERSION_CHECK(13, 10, 0)
+#define BROTLI_NOINLINE __declspec(noinline)
+#elif BROTLI_PGI_VERSION_CHECK(10, 2, 0)
+#define BROTLI_NOINLINE _Pragma("noinline")
+#elif BROTLI_TI_VERSION_CHECK(6, 0, 0) && defined(__cplusplus)
+#define BROTLI_NOINLINE _Pragma("FUNC_CANNOT_INLINE;")
+#elif BROTLI_IAR_VERSION_CHECK(8, 0, 0)
+#define BROTLI_NOINLINE _Pragma("inline=never")
 #else
 #define BROTLI_NOINLINE
 #endif
 
+/* BROTLI_INTERNAL could be defined to override visibility, e.g. for tests. */
+#if !defined(BROTLI_INTERNAL)
+#if defined(_WIN32) || defined(__CYGWIN__)
+#define BROTLI_INTERNAL
+#elif BROTLI_GNUC_VERSION_CHECK(3, 3, 0) ||                         \
+    BROTLI_TI_VERSION_CHECK(8, 0, 0) ||                             \
+    BROTLI_INTEL_VERSION_CHECK(16, 0, 0) ||                         \
+    BROTLI_ARM_VERSION_CHECK(4, 1, 0) ||                            \
+    BROTLI_IBM_VERSION_CHECK(13, 1, 0) ||                           \
+    BROTLI_SUNPRO_VERSION_CHECK(5, 11, 0) ||                        \
+    (BROTLI_TI_VERSION_CHECK(7, 3, 0) &&                            \
+     defined(__TI_GNU_ATTRIBUTE_SUPPORT__) && defined(__TI_EABI__))
+#define BROTLI_INTERNAL __attribute__ ((visibility ("hidden")))
+#else
+#define BROTLI_INTERNAL
+#endif
+#endif
+
+/* <<< <<< <<< end of hedley macros. */
+
+#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 (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
@@ -116,22 +197,26 @@
 #if defined(__x86_64__) || defined(_M_X64)
 #define BROTLI_TARGET_X64
 #endif
 
 #if defined(__PPC64__)
 #define BROTLI_TARGET_POWERPC64
 #endif
 
+#if defined(__riscv) && defined(__riscv_xlen) && __riscv_xlen == 64
+#define BROTLI_TARGET_RISCV64
+#endif
+
 #if defined(BROTLI_BUILD_64_BIT)
 #define BROTLI_64_BITS 1
 #elif defined(BROTLI_BUILD_32_BIT)
 #define BROTLI_64_BITS 0
 #elif defined(BROTLI_TARGET_X64) || defined(BROTLI_TARGET_ARMV8) || \
-    defined(BROTLI_TARGET_POWERPC64)
+    defined(BROTLI_TARGET_POWERPC64) || defined(BROTLI_TARGET_RISCV64)
 #define BROTLI_64_BITS 1
 #else
 #define BROTLI_64_BITS 0
 #endif
 
 #if (BROTLI_64_BITS)
 #define brotli_reg_t uint64_t
 #else
@@ -162,26 +247,27 @@
 #if !defined(BROTLI_LITTLE_ENDIAN)
 #define BROTLI_LITTLE_ENDIAN 0
 #endif
 
 #if !defined(BROTLI_BIG_ENDIAN)
 #define BROTLI_BIG_ENDIAN 0
 #endif
 
-#ifdef BROTLI_X_BYTE_ORDER
+#if defined(BROTLI_X_BYTE_ORDER)
 #undef BROTLI_X_BYTE_ORDER
 #undef BROTLI_X_LITTLE_ENDIAN
 #undef BROTLI_X_BIG_ENDIAN
 #endif
 
-#ifdef BROTLI_BUILD_PORTABLE
+#if defined(BROTLI_BUILD_PORTABLE)
 #define BROTLI_ALIGNED_READ (!!1)
 #elif defined(BROTLI_TARGET_X86) || defined(BROTLI_TARGET_X64) || \
-     defined(BROTLI_TARGET_ARMV7) || defined(BROTLI_TARGET_ARMV8)
+    defined(BROTLI_TARGET_ARMV7) || defined(BROTLI_TARGET_ARMV8) || \
+    defined(BROTLI_TARGET_RISCV64)
 /* Allow unaligned read only for white-listed CPUs. */
 #define BROTLI_ALIGNED_READ (!!0)
 #else
 #define BROTLI_ALIGNED_READ (!!1)
 #endif
 
 #if BROTLI_ALIGNED_READ
 /* Portable unaligned memory access: read / write values via memcpy. */
@@ -301,56 +387,31 @@ static BROTLI_INLINE void BROTLI_UNALIGN
   out[3] = (uint8_t)(v >> 24);
   out[4] = (uint8_t)(v >> 32);
   out[5] = (uint8_t)(v >> 40);
   out[6] = (uint8_t)(v >> 48);
   out[7] = (uint8_t)(v >> 56);
 }
 #endif  /* BROTLI_LITTLE_ENDIAN */
 
-/* Define "BROTLI_PREDICT_TRUE" and "BROTLI_PREDICT_FALSE" macros for capable
-   compilers.
-
-To apply compiler hint, enclose the branching condition into macros, like this:
-
-  if (BROTLI_PREDICT_TRUE(zero == 0)) {
-    // main execution path
-  } else {
-    // compiler should place this code outside of main execution path
-  }
-
-OR:
-
-  if (BROTLI_PREDICT_FALSE(something_rare_or_unexpected_happens)) {
-    // compiler should place this code outside of main execution path
-  }
-
-*/
-#if BROTLI_MODERN_COMPILER || __has_builtin(__builtin_expect)
-#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)
-#define BROTLI_PREDICT_TRUE(x) (x)
-#endif
-
 /* BROTLI_IS_CONSTANT macros returns true for compile-time constants. */
-#if BROTLI_MODERN_COMPILER || __has_builtin(__builtin_constant_p)
+#if BROTLI_GNUC_HAS_BUILTIN(__builtin_constant_p, 3, 0, 1) || \
+    BROTLI_INTEL_VERSION_CHECK(16, 0, 0)
 #define BROTLI_IS_CONSTANT(x) (!!__builtin_constant_p(x))
 #else
 #define BROTLI_IS_CONSTANT(x) (!!0)
 #endif
 
 #if defined(BROTLI_TARGET_ARMV7) || defined(BROTLI_TARGET_ARMV8)
 #define BROTLI_HAS_UBFX (!!1)
 #else
 #define BROTLI_HAS_UBFX (!!0)
 #endif
 
-#ifdef BROTLI_ENABLE_LOG
+#if defined(BROTLI_ENABLE_LOG)
 #define BROTLI_DCHECK(x) assert(x)
 #define BROTLI_LOG(x) printf x
 #else
 #define BROTLI_DCHECK(x)
 #define BROTLI_LOG(x)
 #endif
 
 #if defined(BROTLI_DEBUG) || defined(BROTLI_ENABLE_LOG)
@@ -358,17 +419,18 @@ static BROTLI_INLINE void BrotliDump(con
   fprintf(stderr, "%s:%d (%s)\n", f, l, fn);
   fflush(stderr);
 }
 #define BROTLI_DUMP() BrotliDump(__FILE__, __LINE__, __FUNCTION__)
 #else
 #define BROTLI_DUMP() (void)(0)
 #endif
 
-#if (BROTLI_MODERN_COMPILER || defined(__llvm__)) && \
+/* TODO: add appropriate icc/sunpro/arm/ibm/ti checks. */
+#if (BROTLI_GNUC_VERSION_CHECK(3, 0, 0) || defined(__llvm__)) && \
     !defined(BROTLI_BUILD_NO_RBIT)
 #if defined(BROTLI_TARGET_ARMV7) || defined(BROTLI_TARGET_ARMV8)
 /* TODO: detect ARMv6T2 and enable this code for it. */
 static BROTLI_INLINE brotli_reg_t BrotliRBit(brotli_reg_t input) {
   brotli_reg_t output;
   __asm__("rbit %0, %1\n" : "=r"(output) : "r"(input));
   return output;
 }
--- a/modules/brotli/common/transform.c
+++ b/modules/brotli/common/transform.c
@@ -1,15 +1,14 @@
 /* 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 "./platform.h"
 #include "./transform.h"
 
 #if defined(__cplusplus) || defined(c_plusplus)
 extern "C" {
 #endif
 
 /* RFC 7932 transforms string data */
 static const char kPrefixSuffix[217] =
@@ -187,17 +186,17 @@ 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* BROTLI_RESTRICT transforms, int transfom_idx) {
+    const BrotliTransforms* transforms, int transfom_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);
   {
     int prefix_len = *prefix++;
     while (prefix_len--) { dst[idx++] = *prefix++; }
   }
--- 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 0x1000004
+#define BROTLI_VERSION 0x1000005
 
 /* 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 0x1004000
+#define BROTLI_ABI_VERSION 0x1005000
 
 #endif  /* BROTLI_COMMON_VERSION_H_ */
--- a/modules/brotli/dec/bit_reader.h
+++ b/modules/brotli/dec/bit_reader.h
@@ -233,17 +233,17 @@ static BROTLI_INLINE void BrotliBitReade
 }
 
 /* Reads the specified number of bits from |br| and advances the bit pos.
    Precondition: accumulator MUST contain at least |n_bits|. */
 static BROTLI_INLINE void BrotliTakeBits(
   BrotliBitReader* const br, uint32_t n_bits, uint32_t* val) {
   *val = (uint32_t)BrotliGetBitsUnmasked(br) & BitMask(n_bits);
   BROTLI_LOG(("[BrotliReadBits]  %d %d %d val: %6x\n",
-      (int)br->avail_in, (int)br->bit_pos_, n_bits, (int)*val));
+      (int)br->avail_in, (int)br->bit_pos_, (int)n_bits, (int)*val));
   BrotliDropBits(br, n_bits);
 }
 
 /* Reads the specified number of bits from |br| and advances the bit pos.
    Assumes that there is enough input to perform BrotliFillBitWindow. */
 static BROTLI_INLINE uint32_t BrotliReadBits(
     BrotliBitReader* const br, uint32_t n_bits) {
   if (BROTLI_64_BITS || (n_bits <= 16)) {
--- a/modules/brotli/dec/decode.c
+++ b/modules/brotli/dec/decode.c
@@ -1,17 +1,17 @@
 /* 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>
 
-#ifdef __ARM_NEON__
+#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"
@@ -511,17 +511,18 @@ static BROTLI_INLINE void ProcessSingleC
     uint16_t* code_length_histo, int* next_symbol) {
   *repeat = 0;
   if (code_len != 0) {  /* code_len == 1..15 */
     symbol_lists[next_symbol[code_len]] = (uint16_t)(*symbol);
     next_symbol[code_len] = (int)(*symbol);
     *prev_code_len = code_len;
     *space -= 32768U >> code_len;
     code_length_histo[code_len]++;
-    BROTLI_LOG(("[ReadHuffmanCode] code_length[%d] = %d\n", *symbol, code_len));
+    BROTLI_LOG(("[ReadHuffmanCode] code_length[%d] = %d\n",
+        (int)*symbol, (int)code_len));
   }
   (*symbol)++;
 }
 
 /* Process repeated symbol code length.
     A) Check if it is the extension of previous repeat sequence; if the decoded
        value is not BROTLI_REPEAT_PREVIOUS_CODE_LENGTH, then it is a new
        symbol-skip
@@ -556,17 +557,17 @@ static BROTLI_INLINE void ProcessRepeate
   repeat_delta = *repeat - old_repeat;
   if (*symbol + repeat_delta > alphabet_size) {
     BROTLI_DUMP();
     *symbol = alphabet_size;
     *space = 0xFFFFF;
     return;
   }
   BROTLI_LOG(("[ReadHuffmanCode] code_length[%d..%d] = %d\n",
-              *symbol, *symbol + repeat_delta - 1, *repeat_code_len));
+      (int)*symbol, (int)(*symbol + repeat_delta - 1), (int)*repeat_code_len));
   if (*repeat_code_len != 0) {
     unsigned last = *symbol + repeat_delta;
     int next = next_symbol[*repeat_code_len];
     do {
       symbol_lists[next] = (uint16_t)*symbol;
       next = (int)*symbol;
     } while (++(*symbol) != last);
     next_symbol[*repeat_code_len] = next;
@@ -827,17 +828,17 @@ static BrotliDecoderErrorCode ReadHuffma
         if (result == BROTLI_DECODER_NEEDS_MORE_INPUT) {
           result = SafeReadSymbolCodeLengths(max_symbol, s);
         }
         if (result != BROTLI_DECODER_SUCCESS) {
           return result;
         }
 
         if (s->space != 0) {
-          BROTLI_LOG(("[ReadHuffmanCode] space = %d\n", s->space));
+          BROTLI_LOG(("[ReadHuffmanCode] space = %d\n", (int)s->space));
           return BROTLI_FAILURE(BROTLI_DECODER_ERROR_FORMAT_HUFFMAN_SPACE);
         }
         table_size = BrotliBuildHuffmanTable(
             table, HUFFMAN_TABLE_BITS, s->symbol_lists, s->code_length_histo);
         if (opt_table_size) {
           *opt_table_size = table_size;
         }
         s->substate_huffman = BROTLI_STATE_HUFFMAN_NONE;
--- a/modules/brotli/dec/huffman.c
+++ b/modules/brotli/dec/huffman.c
@@ -15,17 +15,17 @@
 #include <brotli/types.h>
 
 #if defined(__cplusplus) || defined(c_plusplus)
 extern "C" {
 #endif
 
 #define BROTLI_REVERSE_BITS_MAX 8
 
-#ifdef BROTLI_RBIT
+#if defined(BROTLI_RBIT)
 #define BROTLI_REVERSE_BITS_BASE \
   ((sizeof(brotli_reg_t) << 3) - BROTLI_REVERSE_BITS_MAX)
 #else
 #define BROTLI_REVERSE_BITS_BASE 0
 static uint8_t kReverseBits[1 << BROTLI_REVERSE_BITS_MAX] = {
   0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0,
   0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
   0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8,
@@ -63,17 +63,17 @@ static uint8_t kReverseBits[1 << BROTLI_
 
 #define BROTLI_REVERSE_BITS_LOWEST \
   ((brotli_reg_t)1 << (BROTLI_REVERSE_BITS_MAX - 1 + BROTLI_REVERSE_BITS_BASE))
 
 /* Returns reverse(num >> BROTLI_REVERSE_BITS_BASE, BROTLI_REVERSE_BITS_MAX),
    where reverse(value, len) is the bit-wise reversal of the len least
    significant bits of value. */
 static BROTLI_INLINE brotli_reg_t BrotliReverseBits(brotli_reg_t num) {
-#ifdef BROTLI_RBIT
+#if defined(BROTLI_RBIT)
   return BROTLI_RBIT(num);
 #else
   return kReverseBits[num];
 #endif
 }
 
 /* Stores code in table[0], table[step], table[2*step], ..., table[end] */
 /* Assumes that end is an integer multiple of step */
--- a/modules/brotli/enc/backward_references.c
+++ b/modules/brotli/enc/backward_references.c
@@ -92,16 +92,31 @@ static BROTLI_INLINE size_t ComputeDista
 #include "./backward_references_inc.h"
 #undef HASHER
 
 #define HASHER() H54
 /* NOLINTNEXTLINE(build/include) */
 #include "./backward_references_inc.h"
 #undef HASHER
 
+#define HASHER() H35
+/* NOLINTNEXTLINE(build/include) */
+#include "./backward_references_inc.h"
+#undef HASHER
+
+#define HASHER() H55
+/* NOLINTNEXTLINE(build/include) */
+#include "./backward_references_inc.h"
+#undef HASHER
+
+#define HASHER() H65
+/* NOLINTNEXTLINE(build/include) */
+#include "./backward_references_inc.h"
+#undef HASHER
+
 #undef PREFIX
 
 #undef EXPORT_FN
 #undef FN
 #undef CAT
 #undef EXPAND_CAT
 
 void BrotliCreateBackwardReferences(
--- a/modules/brotli/enc/brotli_bit_stream.h
+++ b/modules/brotli/enc/brotli_bit_stream.h
@@ -68,16 +68,17 @@ BROTLI_INTERNAL void BrotliStoreMetaBloc
     const Command* commands, size_t n_commands,
     size_t* storage_ix, uint8_t* storage);
 
 /* This is for storing uncompressed blocks (simple raw storage of
    bytes-as-bytes).
    REQUIRES: length > 0
    REQUIRES: length <= (1 << 24) */
 BROTLI_INTERNAL void BrotliStoreUncompressedMetaBlock(
-    BROTLI_BOOL is_final_block, const uint8_t* input, size_t position,
-    size_t mask, size_t len, size_t* storage_ix, uint8_t* storage);
+    BROTLI_BOOL is_final_block, const uint8_t* BROTLI_RESTRICT input,
+    size_t position, size_t mask, size_t len,
+    size_t* BROTLI_RESTRICT storage_ix, uint8_t* BROTLI_RESTRICT storage);
 
 #if defined(__cplusplus) || defined(c_plusplus)
 }  /* extern "C" */
 #endif
 
 #endif  /* BROTLI_ENC_BROTLI_BIT_STREAM_H_ */
--- a/modules/brotli/enc/command.h
+++ b/modules/brotli/enc/command.h
@@ -57,31 +57,31 @@ static BROTLI_INLINE uint16_t GetCopyLen
   } else {
     return 23u;
   }
 }
 
 static BROTLI_INLINE uint16_t CombineLengthCodes(
     uint16_t inscode, uint16_t copycode, BROTLI_BOOL use_last_distance) {
   uint16_t bits64 =
-      (uint16_t)((copycode & 0x7u) | ((inscode & 0x7u) << 3));
-  if (use_last_distance && inscode < 8 && copycode < 16) {
-    return (copycode < 8) ? bits64 : (bits64 | 64);
+      (uint16_t)((copycode & 0x7u) | ((inscode & 0x7u) << 3u));
+  if (use_last_distance && inscode < 8u && copycode < 16u) {
+    return (copycode < 8u) ? bits64 : (bits64 | 64u);
   } else {
     /* Specification: 5 Encoding of ... (last table) */
     /* offset = 2 * index, where index is in range [0..8] */
-    int offset = 2 * ((copycode >> 3) + 3 * (inscode >> 3));
+    uint32_t offset = 2u * ((copycode >> 3u) + 3u * (inscode >> 3u));
     /* All values in specification are K * 64,
        where   K = [2, 3, 6, 4, 5, 8, 7, 9, 10],
            i + 1 = [1, 2, 3, 4, 5, 6, 7, 8,  9],
        K - i - 1 = [1, 1, 3, 0, 0, 2, 0, 1,  2] = D.
        All values in D require only 2 bits to encode.
        Magic constant is shifted 6 bits left, to avoid final multiplication. */
-    offset = (offset << 5) + 0x40 + ((0x520D40 >> offset) & 0xC0);
-    return (uint16_t)offset | bits64;
+    offset = (offset << 5u) + 0x40u + ((0x520D40u >> offset) & 0xC0u);
+    return (uint16_t)(offset | bits64);
   }
 }
 
 static BROTLI_INLINE void GetLengthCode(size_t insertlen, size_t copylen,
                                         BROTLI_BOOL use_last_distance,
                                         uint16_t* code) {
   uint16_t inscode = GetInsertLengthCode(insertlen);
   uint16_t copycode = GetCopyLengthCode(copylen);
--- a/modules/brotli/enc/compress_fragment.c
+++ b/modules/brotli/enc/compress_fragment.c
@@ -197,34 +197,34 @@ static BROTLI_INLINE void EmitInsertLen(
     const uint32_t nbits = Log2FloorNonZero(tail);
     const size_t code = nbits + 50;
     BrotliWriteBits(depth[code], bits[code], storage_ix, storage);
     BrotliWriteBits(nbits, tail - ((size_t)1 << nbits), storage_ix, storage);
     ++histo[code];
   } else {
     BrotliWriteBits(depth[61], bits[61], storage_ix, storage);
     BrotliWriteBits(12, insertlen - 2114, storage_ix, storage);
-    ++histo[21];
+    ++histo[61];
   }
 }
 
 static BROTLI_INLINE void EmitLongInsertLen(size_t insertlen,
                                             const uint8_t depth[128],
                                             const uint16_t bits[128],
                                             uint32_t histo[128],
                                             size_t* storage_ix,
                                             uint8_t* storage) {
   if (insertlen < 22594) {
     BrotliWriteBits(depth[62], bits[62], storage_ix, storage);
     BrotliWriteBits(14, insertlen - 6210, storage_ix, storage);
-    ++histo[22];
+    ++histo[62];
   } else {
     BrotliWriteBits(depth[63], bits[63], storage_ix, storage);
     BrotliWriteBits(24, insertlen - 22594, storage_ix, storage);
-    ++histo[23];
+    ++histo[63];
   }
 }
 
 static BROTLI_INLINE void EmitCopyLen(size_t copylen,
                                       const uint8_t depth[128],
                                       const uint16_t bits[128],
                                       uint32_t histo[128],
                                       size_t* storage_ix,
@@ -246,17 +246,17 @@ static BROTLI_INLINE void EmitCopyLen(si
     const uint32_t nbits = Log2FloorNonZero(tail);
     const size_t code = nbits + 28;
     BrotliWriteBits(depth[code], bits[code], storage_ix, storage);
     BrotliWriteBits(nbits, tail - ((size_t)1 << nbits), storage_ix, storage);
     ++histo[code];
   } else {
     BrotliWriteBits(depth[39], bits[39], storage_ix, storage);
     BrotliWriteBits(24, copylen - 2118, storage_ix, storage);
-    ++histo[47];
+    ++histo[39];
   }
 }
 
 static BROTLI_INLINE void EmitCopyLenLastDistance(size_t copylen,
                                                   const uint8_t depth[128],
                                                   const uint16_t bits[128],
                                                   uint32_t histo[128],
                                                   size_t* storage_ix,
@@ -288,17 +288,17 @@ static BROTLI_INLINE void EmitCopyLenLas
     BrotliWriteBits(nbits, tail - ((size_t)1 << nbits), storage_ix, storage);
     BrotliWriteBits(depth[64], bits[64], storage_ix, storage);
     ++histo[code];
     ++histo[64];
   } else {
     BrotliWriteBits(depth[39], bits[39], storage_ix, storage);
     BrotliWriteBits(24, copylen - 2120, storage_ix, storage);
     BrotliWriteBits(depth[64], bits[64], storage_ix, storage);
-    ++histo[47];
+    ++histo[39];
     ++histo[64];
   }
 }
 
 static BROTLI_INLINE void EmitDistance(size_t distance,
                                        const uint8_t depth[128],
                                        const uint16_t bits[128],
                                        uint32_t histo[128],
--- a/modules/brotli/enc/compress_fragment_two_pass.c
+++ b/modules/brotli/enc/compress_fragment_two_pass.c
@@ -34,36 +34,39 @@ extern "C" {
 /* kHashMul32 multiplier has these properties:
    * The multiplier must be odd. Otherwise we may lose the highest bit.
    * No long streaks of ones or zeros.
    * There is no effort to ensure that it is a prime, the oddity is enough
      for this use.
    * The number has been tuned heuristically against compression benchmarks. */
 static const uint32_t kHashMul32 = 0x1E35A7BD;
 
-static BROTLI_INLINE uint32_t Hash(const uint8_t* p, size_t shift) {
-  const uint64_t h = (BROTLI_UNALIGNED_LOAD64LE(p) << 16) * kHashMul32;
+static BROTLI_INLINE uint32_t Hash(const uint8_t* p,
+    size_t shift, size_t length) {
+  const uint64_t h =
+      (BROTLI_UNALIGNED_LOAD64LE(p) << ((8 - length) * 8)) * kHashMul32;
   return (uint32_t)(h >> shift);
 }
 
-static BROTLI_INLINE uint32_t HashBytesAtOffset(
-    uint64_t v, int offset, size_t shift) {
-  BROTLI_DCHECK(offset >= 0);
-  BROTLI_DCHECK(offset <= 2);
+static BROTLI_INLINE uint32_t HashBytesAtOffset(uint64_t v, size_t offset,
+    size_t shift, size_t length) {
+  BROTLI_DCHECK(offset <= 8 - length);
   {
-    const uint64_t h = ((v >> (8 * offset)) << 16) * kHashMul32;
+    const uint64_t h = ((v >> (8 * offset)) << ((8 - length) * 8)) * kHashMul32;
     return (uint32_t)(h >> shift);
   }
 }
 
-static BROTLI_INLINE BROTLI_BOOL IsMatch(const uint8_t* p1, const uint8_t* p2) {
-  return TO_BROTLI_BOOL(
-      BrotliUnalignedRead32(p1) == BrotliUnalignedRead32(p2) &&
-      p1[4] == p2[4] &&
-      p1[5] == p2[5]);
+static BROTLI_INLINE BROTLI_BOOL IsMatch(const uint8_t* p1, const uint8_t* p2,
+    size_t length) {
+  if (BrotliUnalignedRead32(p1) == BrotliUnalignedRead32(p2)) {
+    if (length == 4) return BROTLI_TRUE;
+    return TO_BROTLI_BOOL(p1[4] == p2[4] && p1[5] == p2[5]);
+  }
+  return BROTLI_FALSE;
 }
 
 /* Builds a command and distance prefix code (each 64 symbols) into "depth" and
    "bits" based on "histogram" and stores it into the bit stream. */
 static void BuildAndStoreCommandPrefixCode(
     const uint32_t histogram[128],
     uint8_t depth[128], uint16_t bits[128],
     size_t* storage_ix, uint8_t* storage) {
@@ -230,41 +233,41 @@ static void BrotliStoreMetaBlockHeader(
   BrotliWriteBits(2, nibbles - 4, storage_ix, storage);
   BrotliWriteBits(nibbles * 4, len - 1, storage_ix, storage);
   /* ISUNCOMPRESSED */
   BrotliWriteBits(1, (uint64_t)is_uncompressed, storage_ix, storage);
 }
 
 static BROTLI_INLINE void CreateCommands(const uint8_t* input,
     size_t block_size, size_t input_size, const uint8_t* base_ip, int* table,
-    size_t table_bits, uint8_t** literals, uint32_t** commands) {
+    size_t table_bits, size_t min_match,
+    uint8_t** literals, uint32_t** commands) {
   /* "ip" is the input pointer. */
   const uint8_t* ip = input;
   const size_t shift = 64u - table_bits;
   const uint8_t* ip_end = input + block_size;
   /* "next_emit" is a pointer to the first byte that is not covered by a
      previous copy. Bytes between "next_emit" and the start of the next copy or
      the end of the input will be emitted as literal bytes. */
   const uint8_t* next_emit = input;
 
   int last_distance = -1;
   const size_t kInputMarginBytes = BROTLI_WINDOW_GAP;
-  const size_t kMinMatchLen = 6;
 
   if (BROTLI_PREDICT_TRUE(block_size >= kInputMarginBytes)) {
     /* For the last block, we need to keep a 16 bytes margin so that we can be
        sure that all distances are at most window size - 16.
        For all other blocks, we only need to keep a margin of 5 bytes so that
        we don't go over the block size with a copy. */
-    const size_t len_limit = BROTLI_MIN(size_t, block_size - kMinMatchLen,
+    const size_t len_limit = BROTLI_MIN(size_t, block_size - min_match,
                                         input_size - kInputMarginBytes);
     const uint8_t* ip_limit = input + len_limit;
 
     uint32_t next_hash;
-    for (next_hash = Hash(++ip, shift); ; ) {
+    for (next_hash = Hash(++ip, shift, min_match); ; ) {
       /* Step 1: Scan forward in the input looking for a 6-byte-long match.
          If we get close to exhausting the input then goto emit_remainder.
 
          Heuristic match skipping: If 32 bytes are scanned with no matches
          found, start looking only at every other byte. If 32 more bytes are
          scanned, look at every third byte, etc.. When a match is found,
          immediately go back to looking at every byte. This is a small loss
          (~5% performance, ~0.1% density) for compressible data due to more
@@ -281,51 +284,52 @@ static BROTLI_INLINE void CreateCommands
       const uint8_t* candidate;
 
       BROTLI_DCHECK(next_emit < ip);
 trawl:
       do {
         uint32_t hash = next_hash;
         uint32_t bytes_between_hash_lookups = skip++ >> 5;
         ip = next_ip;
-        BROTLI_DCHECK(hash == Hash(ip, shift));
+        BROTLI_DCHECK(hash == Hash(ip, shift, min_match));
         next_ip = ip + bytes_between_hash_lookups;
         if (BROTLI_PREDICT_FALSE(next_ip > ip_limit)) {
           goto emit_remainder;
         }
-        next_hash = Hash(next_ip, shift);
+        next_hash = Hash(next_ip, shift, min_match);
         candidate = ip - last_distance;
-        if (IsMatch(ip, candidate)) {
+        if (IsMatch(ip, candidate, min_match)) {
           if (BROTLI_PREDICT_TRUE(candidate < ip)) {
             table[hash] = (int)(ip - base_ip);
             break;
           }
         }
         candidate = base_ip + table[hash];
         BROTLI_DCHECK(candidate >= base_ip);
         BROTLI_DCHECK(candidate < ip);
 
         table[hash] = (int)(ip - base_ip);
-      } while (BROTLI_PREDICT_TRUE(!IsMatch(ip, candidate)));
+      } while (BROTLI_PREDICT_TRUE(!IsMatch(ip, candidate, min_match)));
 
       /* Check copy distance. If candidate is not feasible, continue search.
          Checking is done outside of hot loop to reduce overhead. */
       if (ip - candidate > MAX_DISTANCE) goto trawl;
 
       /* Step 2: Emit the found match together with the literal bytes from
          "next_emit", and then see if we can find a next match immediately
          afterwards. Repeat until we find no match for the input
          without emitting some literal bytes. */
 
       {
         /* We have a 6-byte match at ip, and we need to emit bytes in
            [next_emit, ip). */
         const uint8_t* base = ip;
-        size_t matched = 6 + FindMatchLengthWithLimit(
-            candidate + 6, ip + 6, (size_t)(ip_end - ip) - 6);
+        size_t matched = min_match + FindMatchLengthWithLimit(
+            candidate + min_match, ip + min_match,
+            (size_t)(ip_end - ip) - min_match);
         int distance = (int)(base - candidate);  /* > 0 */
         int insert = (int)(base - next_emit);
         ip += matched;
         BROTLI_DCHECK(0 == memcmp(base, candidate, matched));
         EmitInsertLen((uint32_t)insert, commands);
         memcpy(*literals, next_emit, (size_t)insert);
         *literals += insert;
         if (distance == last_distance) {
@@ -340,77 +344,105 @@ trawl:
         next_emit = ip;
         if (BROTLI_PREDICT_FALSE(ip >= ip_limit)) {
           goto emit_remainder;
         }
         {
           /* We could immediately start working at ip now, but to improve
              compression we first update "table" with the hashes of some
              positions within the last copy. */
-          uint64_t input_bytes = BROTLI_UNALIGNED_LOAD64LE(ip - 5);
-          uint32_t prev_hash = HashBytesAtOffset(input_bytes, 0, shift);
+          uint64_t input_bytes;
           uint32_t cur_hash;
-          table[prev_hash] = (int)(ip - base_ip - 5);
-          prev_hash = HashBytesAtOffset(input_bytes, 1, shift);
-          table[prev_hash] = (int)(ip - base_ip - 4);
-          prev_hash = HashBytesAtOffset(input_bytes, 2, shift);
-          table[prev_hash] = (int)(ip - base_ip - 3);
-          input_bytes = BROTLI_UNALIGNED_LOAD64LE(ip - 2);
-          cur_hash = HashBytesAtOffset(input_bytes, 2, shift);
-          prev_hash = HashBytesAtOffset(input_bytes, 0, shift);
-          table[prev_hash] = (int)(ip - base_ip - 2);
-          prev_hash = HashBytesAtOffset(input_bytes, 1, shift);
-          table[prev_hash] = (int)(ip - base_ip - 1);
+          uint32_t prev_hash;
+          if (min_match == 4) {
+            input_bytes = BROTLI_UNALIGNED_LOAD64LE(ip - 3);
+            cur_hash = HashBytesAtOffset(input_bytes, 3, shift, min_match);
+            prev_hash = HashBytesAtOffset(input_bytes, 0, shift, min_match);
+            table[prev_hash] = (int)(ip - base_ip - 3);
+            prev_hash = HashBytesAtOffset(input_bytes, 1, shift, min_match);
+            table[prev_hash] = (int)(ip - base_ip - 2);
+            prev_hash = HashBytesAtOffset(input_bytes, 0, shift, min_match);
+            table[prev_hash] = (int)(ip - base_ip - 1);
+          } else {
+            input_bytes = BROTLI_UNALIGNED_LOAD64LE(ip - 5);
+            prev_hash = HashBytesAtOffset(input_bytes, 0, shift, min_match);
+            table[prev_hash] = (int)(ip - base_ip - 5);
+            prev_hash = HashBytesAtOffset(input_bytes, 1, shift, min_match);
+            table[prev_hash] = (int)(ip - base_ip - 4);
+            prev_hash = HashBytesAtOffset(input_bytes, 2, shift, min_match);
+            table[prev_hash] = (int)(ip - base_ip - 3);
+            input_bytes = BROTLI_UNALIGNED_LOAD64LE(ip - 2);
+            cur_hash = HashBytesAtOffset(input_bytes, 2, shift, min_match);
+            prev_hash = HashBytesAtOffset(input_bytes, 0, shift, min_match);
+            table[prev_hash] = (int)(ip - base_ip - 2);
+            prev_hash = HashBytesAtOffset(input_bytes, 1, shift, min_match);
+            table[prev_hash] = (int)(ip - base_ip - 1);
+          }
 
           candidate = base_ip + table[cur_hash];
           table[cur_hash] = (int)(ip - base_ip);
         }
       }
 
-      while (ip - candidate <= MAX_DISTANCE && IsMatch(ip, candidate)) {
+      while (ip - candidate <= MAX_DISTANCE &&
+          IsMatch(ip, candidate, min_match)) {
         /* We have a 6-byte match at ip, and no need to emit any
            literal bytes prior to ip. */
         const uint8_t* base = ip;
-        size_t matched = 6 + FindMatchLengthWithLimit(
-            candidate + 6, ip + 6, (size_t)(ip_end - ip) - 6);
+        size_t matched = min_match + FindMatchLengthWithLimit(
+            candidate + min_match, ip + min_match,
+            (size_t)(ip_end - ip) - min_match);
         ip += matched;
         last_distance = (int)(base - candidate);  /* > 0 */
         BROTLI_DCHECK(0 == memcmp(base, candidate, matched));
         EmitCopyLen(matched, commands);
         EmitDistance((uint32_t)last_distance, commands);
 
         next_emit = ip;
         if (BROTLI_PREDICT_FALSE(ip >= ip_limit)) {
           goto emit_remainder;
         }
         {
           /* We could immediately start working at ip now, but to improve
              compression we first update "table" with the hashes of some
              positions within the last copy. */
-          uint64_t input_bytes = BROTLI_UNALIGNED_LOAD64LE(ip - 5);
-          uint32_t prev_hash = HashBytesAtOffset(input_bytes, 0, shift);
+          uint64_t input_bytes;
           uint32_t cur_hash;
-          table[prev_hash] = (int)(ip - base_ip - 5);
-          prev_hash = HashBytesAtOffset(input_bytes, 1, shift);
-          table[prev_hash] = (int)(ip - base_ip - 4);
-          prev_hash = HashBytesAtOffset(input_bytes, 2, shift);
-          table[prev_hash] = (int)(ip - base_ip - 3);
-          input_bytes = BROTLI_UNALIGNED_LOAD64LE(ip - 2);
-          cur_hash = HashBytesAtOffset(input_bytes, 2, shift);
-          prev_hash = HashBytesAtOffset(input_bytes, 0, shift);
-          table[prev_hash] = (int)(ip - base_ip - 2);
-          prev_hash = HashBytesAtOffset(input_bytes, 1, shift);
-          table[prev_hash] = (int)(ip - base_ip - 1);
+          uint32_t prev_hash;
+          if (min_match == 4) {
+            input_bytes = BROTLI_UNALIGNED_LOAD64LE(ip - 3);
+            cur_hash = HashBytesAtOffset(input_bytes, 3, shift, min_match);
+            prev_hash = HashBytesAtOffset(input_bytes, 0, shift, min_match);
+            table[prev_hash] = (int)(ip - base_ip - 3);
+            prev_hash = HashBytesAtOffset(input_bytes, 1, shift, min_match);
+            table[prev_hash] = (int)(ip - base_ip - 2);
+            prev_hash = HashBytesAtOffset(input_bytes, 2, shift, min_match);
+            table[prev_hash] = (int)(ip - base_ip - 1);
+          } else {
+            input_bytes = BROTLI_UNALIGNED_LOAD64LE(ip - 5);
+            prev_hash = HashBytesAtOffset(input_bytes, 0, shift, min_match);
+            table[prev_hash] = (int)(ip - base_ip - 5);
+            prev_hash = HashBytesAtOffset(input_bytes, 1, shift, min_match);
+            table[prev_hash] = (int)(ip - base_ip - 4);
+            prev_hash = HashBytesAtOffset(input_bytes, 2, shift, min_match);
+            table[prev_hash] = (int)(ip - base_ip - 3);
+            input_bytes = BROTLI_UNALIGNED_LOAD64LE(ip - 2);
+            cur_hash = HashBytesAtOffset(input_bytes, 2, shift, min_match);
+            prev_hash = HashBytesAtOffset(input_bytes, 0, shift, min_match);
+            table[prev_hash] = (int)(ip - base_ip - 2);
+            prev_hash = HashBytesAtOffset(input_bytes, 1, shift, min_match);
+            table[prev_hash] = (int)(ip - base_ip - 1);
+          }
 
           candidate = base_ip + table[cur_hash];
           table[cur_hash] = (int)(ip - base_ip);
         }
       }
 
-      next_hash = Hash(++ip, shift);
+      next_hash = Hash(++ip, shift, min_match);
     }
   }
 
 emit_remainder:
   BROTLI_DCHECK(next_emit <= ip_end);
   /* Emit the remaining bytes as literals. */
   if (next_emit < ip_end) {
     const uint32_t insert = (uint32_t)(ip_end - next_emit);
@@ -520,30 +552,31 @@ static void EmitUncompressedMetaBlock(co
   memcpy(&storage[*storage_ix >> 3], input, input_size);
   *storage_ix += input_size << 3;
   storage[*storage_ix >> 3] = 0;
 }
 
 static BROTLI_INLINE void BrotliCompressFragmentTwoPassImpl(
     MemoryManager* m, const uint8_t* input, size_t input_size,
     BROTLI_BOOL is_last, uint32_t* command_buf, uint8_t* literal_buf,
-    int* table, size_t table_bits, size_t* storage_ix, uint8_t* storage) {
+    int* table, size_t table_bits, size_t min_match,
+    size_t* storage_ix, uint8_t* storage) {
   /* Save the start of the first block for position and distance computations.
   */
   const uint8_t* base_ip = input;
   BROTLI_UNUSED(is_last);
 
   while (input_size > 0) {
     size_t block_size =
         BROTLI_MIN(size_t, input_size, kCompressFragmentTwoPassBlockSize);
     uint32_t* commands = command_buf;
     uint8_t* literals = literal_buf;
     size_t num_literals;
-    CreateCommands(input, block_size, input_size, base_ip, table, table_bits,
-                   &literals, &commands);
+    CreateCommands(input, block_size, input_size, base_ip, table,
+                   table_bits, min_match, &literals, &commands);
     num_literals = (size_t)(literals - literal_buf);
     if (ShouldCompress(input, block_size, num_literals)) {
       const size_t num_commands = (size_t)(commands - command_buf);
       BrotliStoreMetaBlockHeader(block_size, 0, storage_ix, storage);
       /* No block splits, no contexts. */
       BrotliWriteBits(13, 0, storage_ix, storage);
       StoreCommands(m, literal_buf, num_literals, command_buf, num_commands,
                     storage_ix, storage);
@@ -562,18 +595,19 @@ static BROTLI_INLINE void BrotliCompress
 #define FOR_TABLE_BITS_(X) \
   X(8) X(9) X(10) X(11) X(12) X(13) X(14) X(15) X(16) X(17)
 
 #define BAKE_METHOD_PARAM_(B)                                                  \
 static BROTLI_NOINLINE void BrotliCompressFragmentTwoPassImpl ## B(            \
     MemoryManager* m, const uint8_t* input, size_t input_size,                 \
     BROTLI_BOOL is_last, uint32_t* command_buf, uint8_t* literal_buf,          \
     int* table, size_t* storage_ix, uint8_t* storage) {                        \
+  size_t min_match = (B <= 15) ? 4 : 6;                                        \
   BrotliCompressFragmentTwoPassImpl(m, input, input_size, is_last, command_buf,\
-      literal_buf, table, B, storage_ix, storage);                             \
+      literal_buf, table, B, min_match, storage_ix, storage);                  \
 }
 FOR_TABLE_BITS_(BAKE_METHOD_PARAM_)
 #undef BAKE_METHOD_PARAM_
 
 void BrotliCompressFragmentTwoPass(
     MemoryManager* m, const uint8_t* input, size_t input_size,
     BROTLI_BOOL is_last, uint32_t* command_buf, uint8_t* literal_buf,
     int* table, size_t table_size, size_t* storage_ix, uint8_t* storage) {
--- a/modules/brotli/enc/encode.c
+++ b/modules/brotli/enc/encode.c
@@ -112,17 +112,16 @@ typedef struct BrotliEncoderStateStruct 
 
   BROTLI_BOOL is_last_block_emitted_;
   BROTLI_BOOL is_initialized_;
 } BrotliEncoderStateStruct;
 
 static BROTLI_BOOL EnsureInitialized(BrotliEncoderState* s);
 
 static size_t InputBlockSize(BrotliEncoderState* s) {
-  if (!EnsureInitialized(s)) return 0;
   return (size_t)1 << s->params.lgblock;
 }
 
 static uint64_t UnprocessedInputSize(BrotliEncoderState* s) {
   return s->input_pos_ - s->last_processed_pos_;
 }
 
 static size_t RemainingInputBlockSize(BrotliEncoderState* s) {
@@ -812,17 +811,16 @@ void BrotliEncoderDestroyInstance(Brotli
    accumulated input. At most input_block_size() bytes of input data can be
    copied to the ring buffer, otherwise the next WriteBrotliData() will fail.
  */
 static void CopyInputToRingBuffer(BrotliEncoderState* s,
                                   const size_t input_size,
                                   const uint8_t* input_buffer) {
   RingBuffer* ringbuffer_ = &s->ringbuffer_;
   MemoryManager* m = &s->memory_manager_;
-  if (!EnsureInitialized(s)) return;
   RingBufferWrite(m, input_buffer, input_size, ringbuffer_);
   if (BROTLI_IS_OOM(m)) return;
   s->input_pos_ += input_size;
 
   /* TL;DR: If needed, initialize 7 more bytes in the ring buffer to make the
      hashing not depend on uninitialized data. This makes compression
      deterministic and it prevents uninitialized memory warnings in Valgrind.
      Even without erasing, the output would be valid (but nondeterministic).
@@ -877,17 +875,18 @@ static BROTLI_BOOL UpdateLastProcessedPo
   return TO_BROTLI_BOOL(wrapped_input_pos < wrapped_last_processed_pos);
 }
 
 static void ExtendLastCommand(BrotliEncoderState* s, uint32_t* bytes,
                               uint32_t* wrapped_last_processed_pos) {
   Command* last_command = &s->commands_[s->num_commands_ - 1];
   const uint8_t* data = s->ringbuffer_.buffer_;
   const uint32_t mask = s->ringbuffer_.mask_;
-  uint64_t max_backward_distance = (1u << s->params.lgwin) - BROTLI_WINDOW_GAP;
+  uint64_t max_backward_distance =
+      (((uint64_t)1) << s->params.lgwin) - BROTLI_WINDOW_GAP;
   uint64_t last_copy_len = last_command->copy_len_ & 0x1FFFFFF;
   uint64_t last_processed_pos = s->last_processed_pos_ - last_copy_len;
   uint64_t max_distance = last_processed_pos < max_backward_distance ?
       last_processed_pos : max_backward_distance;
   uint64_t cmd_dist = (uint64_t)s->dist_cache_[0];
   uint32_t distance_code = CommandRestoreDistanceCode(last_command,
                                                       &s->params.dist);
   if (distance_code < BROTLI_NUM_DISTANCE_SHORT_CODES ||
@@ -927,17 +926,16 @@ static BROTLI_BOOL EncodeData(
   const uint64_t delta = UnprocessedInputSize(s);
   uint32_t bytes = (uint32_t)delta;
   uint32_t wrapped_last_processed_pos = WrapPosition(s->last_processed_pos_);
   uint8_t* data;
   uint32_t mask;
   MemoryManager* m = &s->memory_manager_;
   ContextType literal_context_mode;
 
-  if (!EnsureInitialized(s)) return BROTLI_FALSE;
   data = s->ringbuffer_.buffer_;
   mask = s->ringbuffer_.mask_;
 
   /* Adding more blocks after "last" block is forbidden. */
   if (s->is_last_block_emitted_) return BROTLI_FALSE;
   if (is_last) s->is_last_block_emitted_ = BROTLI_TRUE;
 
   if (delta > InputBlockSize(s)) {
--- a/modules/brotli/enc/encoder_dict.h
+++ b/modules/brotli/enc/encoder_dict.h
@@ -29,14 +29,13 @@ typedef struct BrotliEncoderDictionary {
 
   /* from static_dict_lut.h, for slow encoder */
   const uint16_t* buckets;
   const DictWord* dict_words;
 } BrotliEncoderDictionary;
 
 BROTLI_INTERNAL void BrotliInitEncoderDictionary(BrotliEncoderDictionary* dict);
 
-
 #if defined(__cplusplus) || defined(c_plusplus)
 }  /* extern "C" */
 #endif
 
 #endif  /* BROTLI_ENC_ENCODER_DICT_H_ */
--- a/modules/brotli/enc/fast_log.h
+++ b/modules/brotli/enc/fast_log.h
@@ -14,17 +14,19 @@
 #include "../common/platform.h"
 #include <brotli/types.h>
 
 #if defined(__cplusplus) || defined(c_plusplus)
 extern "C" {
 #endif
 
 static BROTLI_INLINE uint32_t Log2FloorNonZero(size_t n) {
-#if BROTLI_MODERN_COMPILER || __has_builtin(__builtin_clz)
+  /* TODO: generalize and move to platform.h */
+#if BROTLI_GNUC_HAS_BUILTIN(__builtin_clz, 3, 4, 0) || \
+    BROTLI_INTEL_VERSION_CHECK(16, 0, 0)
   return 31u ^ (uint32_t)__builtin_clz((uint32_t)n);
 #else
   uint32_t result = 0;
   while (n >>= 1) result++;
   return result;
 #endif
 }
 
--- a/modules/brotli/enc/hash.h
+++ b/modules/brotli/enc/hash.h
@@ -31,18 +31,20 @@ extern "C" {
  *
  * Excluding initialization and destruction, hasher can be passed as
  * HasherHandle by value.
  *
  * Typically hasher data consists of 3 sections:
  * * HasherCommon structure
  * * private structured hasher data, depending on hasher type
  * * private dynamic hasher data, depending on hasher type and parameters
- */
-typedef uint8_t* HasherHandle;
+ *
+ * Using "define" instead of "typedef", because on MSVC __restrict does not work
+ * on typedef pointer types. */
+#define HasherHandle uint8_t*
 
 typedef struct {
   BrotliHasherParams params;
 
   /* False if hasher needs to be "prepared" before use. */
   BROTLI_BOOL is_prepared_;
 
   size_t dict_num_lookups;
@@ -146,38 +148,38 @@ static BROTLI_INLINE score_t BackwardRef
   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) {
   size_t len;
-  size_t dist;
+  size_t word_idx;
   size_t offset;
   size_t matchlen;
   size_t backward;
   score_t score;
   len = item & 0x1F;
-  dist = item >> 5;
-  offset = dictionary->words->offsets_by_length[len] + len * dist;
+  word_idx = item >> 5;
+  offset = dictionary->words->offsets_by_length[len] + len * word_idx;
   if (len > max_length) {
     return BROTLI_FALSE;
   }
 
   matchlen =
       FindMatchLengthWithLimit(data, &dictionary->words->data[offset], len);
   if (matchlen + dictionary->cutoffTransformsCount <= len || matchlen == 0) {
     return BROTLI_FALSE;
   }
   {
     size_t cut = len - matchlen;
     size_t transform_id = (cut << 2) +
         (size_t)((dictionary->cutoffTransforms >> (cut * 6)) & 0x3F);
-    backward = max_backward + dist + 1 +
+    backward = max_backward + 1 + word_idx +
         (transform_id << dictionary->words->size_bits_by_length[len]);
   }
   if (backward > max_distance) {
     return BROTLI_FALSE;
   }
   score = BackwardReferenceScore(matchlen, backward);
   if (score < out->score) {
     return BROTLI_FALSE;
@@ -336,21 +338,67 @@ static BROTLI_INLINE size_t BackwardMatc
 #define USE_DICTIONARY 0
 #include "./hash_longest_match_quickly_inc.h"  /* NOLINT(build/include) */
 #undef USE_DICTIONARY
 #undef HASH_LEN
 #undef BUCKET_SWEEP
 #undef BUCKET_BITS
 #undef HASHER
 
+/* fast large window hashers */
+
+#define HASHER() HROLLING_FAST
+#define CHUNKLEN 32
+#define JUMP 4
+#define NUMBUCKETS 16777216
+#define MASK ((NUMBUCKETS * 64) - 1)
+#include "./hash_rolling_inc.h"  /* NOLINT(build/include) */
+#undef JUMP
+#undef HASHER
+
+
+#define HASHER() HROLLING
+#define JUMP 1
+#include "./hash_rolling_inc.h"  /* NOLINT(build/include) */
+#undef MASK
+#undef NUMBUCKETS
+#undef JUMP
+#undef CHUNKLEN
+#undef HASHER
+
+#define HASHER() H35
+#define HASHER_A H3
+#define HASHER_B HROLLING_FAST
+#include "./hash_composite_inc.h"  /* NOLINT(build/include) */
+#undef HASHER_A
+#undef HASHER_B
+#undef HASHER
+
+#define HASHER() H55
+#define HASHER_A H54
+#define HASHER_B HROLLING_FAST
+#include "./hash_composite_inc.h"  /* NOLINT(build/include) */
+#undef HASHER_A
+#undef HASHER_B
+#undef HASHER
+
+#define HASHER() H65
+#define HASHER_A H6
+#define HASHER_B HROLLING
+#include "./hash_composite_inc.h"  /* NOLINT(build/include) */
+#undef HASHER_A
+#undef HASHER_B
+#undef HASHER
+
 #undef FN
 #undef CAT
 #undef EXPAND_CAT
 
-#define FOR_GENERIC_HASHERS(H) H(2) H(3) H(4) H(5) H(6) H(40) H(41) H(42) H(54)
+#define FOR_GENERIC_HASHERS(H) H(2) H(3) H(4) H(5) H(6) H(40) H(41) H(42) H(54)\
+                               H(35) H(55) H(65)
 #define FOR_ALL_HASHERS(H) FOR_GENERIC_HASHERS(H) H(10)
 
 static BROTLI_INLINE void DestroyHasher(
     MemoryManager* m, HasherHandle* handle) {
   if (*handle == NULL) return;
   BROTLI_FREE(m, *handle);
 }
 
new file mode 100644
--- /dev/null
+++ b/modules/brotli/enc/hash_composite_inc.h
@@ -0,0 +1,133 @@
+/* NOLINT(build/header_guard) */
+/* Copyright 2018 Google Inc. All Rights Reserved.
+
+   Distributed under MIT license.
+   See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
+*/
+
+/* template parameters: FN, HASHER_A, HASHER_B */
+
+/* Composite hasher: This hasher allows to combine two other hashers, HASHER_A
+   and HASHER_B. */
+
+#define HashComposite HASHER()
+
+#define FN_A(X) EXPAND_CAT(X, HASHER_A)
+#define FN_B(X) EXPAND_CAT(X, HASHER_B)
+
+static BROTLI_INLINE size_t FN(HashTypeLength)(void) {
+  size_t a =  FN_A(HashTypeLength)();
+  size_t b =  FN_B(HashTypeLength)();
+  return a > b ? a : b;
+}
+
+static BROTLI_INLINE size_t FN(StoreLookahead)(void) {
+  size_t a =  FN_A(StoreLookahead)();
+  size_t b =  FN_B(StoreLookahead)();
+  return a > b ? a : b;
+}
+
+typedef struct HashComposite {
+  HasherHandle ha;
+  HasherHandle hb;
+  const BrotliEncoderParams* params;
+} HashComposite;
+
+static BROTLI_INLINE HashComposite* FN(Self)(HasherHandle handle) {
+  return (HashComposite*)&(GetHasherCommon(handle)[1]);
+}
+
+static void FN(Initialize)(
+    HasherHandle handle, const BrotliEncoderParams* params) {
+  HashComposite* self = FN(Self)(handle);
+  self->ha = 0;
+  self->hb = 0;
+  self->params = params;
+  /* TODO: Initialize of the hashers is defered to Prepare (and params
+     remembered here) because we don't get the one_shot and input_size params
+     here that are needed to know the memory size of them. Instead provide
+     those params to all hashers FN(Initialize) */
+}
+
+static void FN(Prepare)(HasherHandle handle, BROTLI_BOOL one_shot,
+    size_t input_size, const uint8_t* data) {
+  HashComposite* self = FN(Self)(handle);
+  if (!self->ha) {
+    HasherCommon* common_a;
+    HasherCommon* common_b;
+
+    self->ha = handle + sizeof(HasherCommon) + sizeof(HashComposite);
+    common_a = (HasherCommon*)self->ha;
+    common_a->params = self->params->hasher;
+    common_a->is_prepared_ = BROTLI_FALSE;
+    common_a->dict_num_lookups = 0;
+    common_a->dict_num_matches = 0;
+    FN_A(Initialize)(self->ha, self->params);
+
+    self->hb = self->ha + sizeof(HasherCommon) + FN_A(HashMemAllocInBytes)(
+        self->params, one_shot, input_size);
+    common_b = (HasherCommon*)self->hb;
+    common_b->params = self->params->hasher;
+    common_b->is_prepared_ = BROTLI_FALSE;
+    common_b->dict_num_lookups = 0;
+    common_b->dict_num_matches = 0;
+    FN_B(Initialize)(self->hb, self->params);
+  }
+  FN_A(Prepare)(self->ha, one_shot, input_size, data);
+  FN_B(Prepare)(self->hb, one_shot, input_size, data);
+}
+
+static BROTLI_INLINE size_t FN(HashMemAllocInBytes)(
+    const BrotliEncoderParams* params, BROTLI_BOOL one_shot,
+    size_t input_size) {
+  return sizeof(HashComposite) + 2 * sizeof(HasherCommon) +
+      FN_A(HashMemAllocInBytes)(params, one_shot, input_size) +
+      FN_B(HashMemAllocInBytes)(params, one_shot, input_size);
+}
+
+static BROTLI_INLINE void FN(Store)(HasherHandle BROTLI_RESTRICT handle,
+    const uint8_t* BROTLI_RESTRICT data, const size_t mask, const size_t ix) {
+  HashComposite* self = FN(Self)(handle);
+  FN_A(Store)(self->ha, data, mask, ix);
+  FN_B(Store)(self->hb, data, mask, ix);
+}
+
+static BROTLI_INLINE void FN(StoreRange)(HasherHandle handle,
+    const uint8_t* data, const size_t mask, const size_t ix_start,
+    const size_t ix_end) {
+  HashComposite* self = FN(Self)(handle);
+  FN_A(StoreRange)(self->ha, data, mask, ix_start, ix_end);
+  FN_B(StoreRange)(self->hb, data, mask, ix_start, ix_end);
+}
+
+static BROTLI_INLINE void FN(StitchToPreviousBlock)(HasherHandle handle,
+    size_t num_bytes, size_t position, const uint8_t* ringbuffer,
+    size_t ring_buffer_mask) {
+  HashComposite* self = FN(Self)(handle);
+  FN_A(StitchToPreviousBlock)(self->ha, num_bytes, position, ringbuffer,
+      ring_buffer_mask);
+  FN_B(StitchToPreviousBlock)(self->hb, num_bytes, position, ringbuffer,
+      ring_buffer_mask);
+}
+
+static BROTLI_INLINE void FN(PrepareDistanceCache)(
+    HasherHandle handle, int* BROTLI_RESTRICT distance_cache) {
+  HashComposite* self = FN(Self)(handle);
+  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) {
+  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);
+  FN_B(FindLongestMatch)(self->hb, dictionary, data, ring_buffer_mask,
+      distance_cache, cur_ix, max_length, max_backward, gap, max_distance, out);
+}
+
+#undef HashComposite
new file mode 100644
--- /dev/null
+++ b/modules/brotli/enc/hash_rolling_inc.h
@@ -0,0 +1,215 @@
+/* NOLINT(build/header_guard) */
+/* Copyright 2018 Google Inc. All Rights Reserved.
+
+   Distributed under MIT license.
+   See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
+*/
+
+/* template parameters: FN, JUMP, NUMBUCKETS, MASK, CHUNKLEN */
+/* NUMBUCKETS / (MASK + 1) = probability of storing and using hash code. */
+/* JUMP = skip bytes for speedup */
+
+/* Rolling hash for long distance long string matches. Stores one position
+   per bucket, bucket key is computed over a long region. */
+
+#define HashRolling HASHER()
+
+static const uint32_t FN(kRollingHashMul32) = 69069;
+static const uint32_t FN(kInvalidPos) = 0xffffffff;
+
+/* This hasher uses a longer forward length, but returning a higher value here
+   will hurt compression by the main hasher when combined with a composite
+   hasher. The hasher tests for forward itself instead. */
+static BROTLI_INLINE size_t FN(HashTypeLength)(void) { return 4; }
+static BROTLI_INLINE size_t FN(StoreLookahead)(void) { return 4; }
+
+/* Computes a code from a single byte. A lookup table of 256 values could be
+   used, but simply adding 1 works about as good. */
+static uint32_t FN(HashByte)(uint8_t byte) {
+  return (uint32_t)byte + 1u;
+}
+
+static uint32_t FN(HashRollingFunctionInitial)(uint32_t state, uint8_t add,
+                                               uint32_t factor) {
+  return (uint32_t)(factor * state + FN(HashByte)(add));
+}
+
+static uint32_t FN(HashRollingFunction)(uint32_t state, uint8_t add,
+                                        uint8_t rem, uint32_t factor,
+                                        uint32_t factor_remove) {
+  return (uint32_t)(factor * state +
+      FN(HashByte)(add) - factor_remove * FN(HashByte)(rem));
+}
+
+typedef struct HashRolling {
+  uint32_t state;
+  uint32_t* table;
+  size_t next_ix;
+
+  uint32_t chunk_len;
+  uint32_t factor;
+  uint32_t factor_remove;
+} HashRolling;
+
+static BROTLI_INLINE HashRolling* FN(Self)(HasherHandle handle) {
+  return (HashRolling*)&(GetHasherCommon(handle)[1]);
+}
+
+static void FN(Initialize)(
+    HasherHandle handle, const BrotliEncoderParams* params) {
+  HashRolling* self = FN(Self)(handle);
+  size_t i;
+  self->state = 0;
+  self->next_ix = 0;
+
+  self->factor = FN(kRollingHashMul32);
+
+  /* Compute the factor of the oldest byte to remove: factor**steps modulo
+     0xffffffff (the multiplications rely on 32-bit overflow) */
+  self->factor_remove = 1;
+  for (i = 0; i < CHUNKLEN; i += JUMP) {
+    self->factor_remove *= self->factor;
+  }
+
+  self->table = (uint32_t*)((HasherHandle)self + sizeof(HashRolling));
+  for (i = 0; i < NUMBUCKETS; i++) {
+    self->table[i] = FN(kInvalidPos);
+  }
+
+  BROTLI_UNUSED(params);
+}
+
+static void FN(Prepare)(HasherHandle handle, BROTLI_BOOL one_shot,
+    size_t input_size, const uint8_t* data) {
+  HashRolling* self = FN(Self)(handle);
+  size_t i;
+  /* Too small size, cannot use this hasher. */
+  if (input_size < CHUNKLEN) return;
+  self->state = 0;
+  for (i = 0; i < CHUNKLEN; i += JUMP) {
+    self->state = FN(HashRollingFunctionInitial)(
+        self->state, data[i], self->factor);
+  }
+  BROTLI_UNUSED(one_shot);
+}
+
+static BROTLI_INLINE size_t FN(HashMemAllocInBytes)(
+    const BrotliEncoderParams* params, BROTLI_BOOL one_shot,
+    size_t input_size) {
+  return sizeof(HashRolling) + NUMBUCKETS * sizeof(uint32_t);
+  BROTLI_UNUSED(params);
+  BROTLI_UNUSED(one_shot);
+  BROTLI_UNUSED(input_size);
+}
+
+static BROTLI_INLINE void FN(Store)(HasherHandle BROTLI_RESTRICT handle,
+    const uint8_t* BROTLI_RESTRICT data, const size_t mask, const size_t ix) {
+  BROTLI_UNUSED(handle);
+  BROTLI_UNUSED(data);
+  BROTLI_UNUSED(mask);
+  BROTLI_UNUSED(ix);
+}
+
+static BROTLI_INLINE void FN(StoreRange)(HasherHandle handle,
+    const uint8_t* data, const size_t mask, const size_t ix_start,
+    const size_t ix_end) {
+  BROTLI_UNUSED(handle);
+  BROTLI_UNUSED(data);
+  BROTLI_UNUSED(mask);
+  BROTLI_UNUSED(ix_start);
+  BROTLI_UNUSED(ix_end);
+}
+
+static BROTLI_INLINE void FN(StitchToPreviousBlock)(HasherHandle handle,
+    size_t num_bytes, size_t position, const uint8_t* ringbuffer,
+    size_t ring_buffer_mask) {
+  /* In this case we must re-initialize the hasher from scratch from the
+     current position. */
+  HashRolling* self = FN(Self)(handle);
+  size_t position_masked;
+  size_t available = num_bytes;
+  if ((position & (JUMP - 1)) != 0) {
+    size_t diff = JUMP - (position & (JUMP - 1));
+    available = (diff > available) ? 0 : (available - diff);
+    position += diff;
+  }
+  position_masked = position & ring_buffer_mask;
+  /* wrapping around ringbuffer not handled. */
+  if (available > ring_buffer_mask - position_masked) {
+    available = ring_buffer_mask - position_masked;
+  }
+
+  FN(Prepare)(handle, BROTLI_FALSE, available,
+      ringbuffer + (position & ring_buffer_mask));
+  self->next_ix = position;
+  BROTLI_UNUSED(num_bytes);
+}
+
+static BROTLI_INLINE void FN(PrepareDistanceCache)(
+    HasherHandle handle, int* BROTLI_RESTRICT distance_cache) {
+  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) {
+  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;
+
+  for (pos = self->next_ix; pos <= cur_ix; pos += JUMP) {
+    uint32_t code = self->state & MASK;
+
+    uint8_t rem = data[pos & ring_buffer_mask];
+    uint8_t add = data[(pos + CHUNKLEN) & ring_buffer_mask];
+    size_t found_ix = FN(kInvalidPos);
+
+    self->state = FN(HashRollingFunction)(
+        self->state, add, rem, self->factor, self->factor_remove);
+
+    if (code < NUMBUCKETS) {
+      found_ix = self->table[code];
+      self->table[code] = (uint32_t)pos;
+      if (pos == cur_ix && found_ix != FN(kInvalidPos)) {
+        /* The cast to 32-bit makes backward distances up to 4GB work even
+           if cur_ix is above 4GB, despite using 32-bit values in the table. */
+        size_t backward = (uint32_t)(cur_ix - found_ix);
+        if (backward <= max_backward) {
+          const size_t found_ix_masked = found_ix & ring_buffer_mask;
+          const size_t len = FindMatchLengthWithLimit(&data[found_ix_masked],
+                                                      &data[cur_ix_masked],
+                                                      max_length);
+          if (len >= 4 && len > out->len) {
+            score_t score = BackwardReferenceScore(len, backward);
+            if (score > out->score) {
+              out->len = len;
+              out->distance = backward;
+              out->score = score;
+              out->len_code_delta = 0;
+            }
+          }
+        }
+      }
+    }
+  }
+
+  self->next_ix = cur_ix + JUMP;
+
+  /* NOTE: this hasher does not search in the dictionary. It is used as
+     backup-hasher, the main hasher already searches in it. */
+  BROTLI_UNUSED(dictionary);
+  BROTLI_UNUSED(distance_cache);
+  BROTLI_UNUSED(gap);
+  BROTLI_UNUSED(max_distance);
+}
+
+#undef HashRolling
--- a/modules/brotli/enc/quality.h
+++ b/modules/brotli/enc/quality.h
@@ -137,11 +137,29 @@ static BROTLI_INLINE void ChooseHasher(c
         params->quality < 7 ? 4 : params->quality < 9 ? 10 : 16;
   } else {
     hparams->type = 5;
     hparams->block_bits = params->quality - 1;
     hparams->bucket_bits = params->quality < 7 ? 14 : 15;
     hparams->num_last_distances_to_check =
         params->quality < 7 ? 4 : params->quality < 9 ? 10 : 16;
   }
+
+  if (params->lgwin > 24) {
+    /* Different hashers for large window brotli: not for qualities <= 2,
+       these are too fast for large window. Not for qualities >= 10: their
+       hasher already works well with large window. So the changes are:
+       H3 --> H35: for quality 3.
+       H54 --> H55: for quality 4 with size hint > 1MB
+       H6 --> H65: for qualities 5, 6, 7, 8, 9. */
+    if (hparams->type == 3) {
+      hparams->type = 35;
+    }
+    if (hparams->type == 54) {
+      hparams->type = 55;
+    }
+    if (hparams->type == 6) {
+      hparams->type = 65;
+    }
+  }
 }
 
 #endif  /* BROTLI_ENC_QUALITY_H_ */
--- a/modules/brotli/enc/static_dict.c
+++ b/modules/brotli/enc/static_dict.c
@@ -11,21 +11,16 @@
 #include "../common/transform.h"
 #include "./encoder_dict.h"
 #include "./find_match_length.h"
 
 #if defined(__cplusplus) || defined(c_plusplus)
 extern "C" {
 #endif
 
-/* TODO: use BrotliTransforms.cutOffTransforms instead. */
-static const uint8_t kOmitLastNTransforms[10] = {
-  0, 12, 27, 23, 42, 63, 56, 48, 59, 64,
-};
-
 static BROTLI_INLINE uint32_t Hash(const uint8_t* data) {
   uint32_t h = BROTLI_UNALIGNED_LOAD32LE(data) * kDictHashMul32;
   /* The higher bits contain more mixture from the multiplication,
      so we take our results from there. */
   return h >> (32 - kDictNumBits);
 }
 
 static BROTLI_INLINE void AddMatch(size_t distance, size_t len, size_t len_code,
@@ -116,17 +111,20 @@ BROTLI_BOOL BrotliFindAllStaticDictionar
           }
           has_found_match = BROTLI_TRUE;
         }
         /* Transform "" + BROTLI_TRANSFORM_OMIT_LAST_# + "" (# = 2 .. 9) */
         minlen = min_length;
         if (l > 9) minlen = BROTLI_MAX(size_t, minlen, l - 9);
         maxlen = BROTLI_MIN(size_t, matchlen, l - 2);
         for (len = minlen; len <= maxlen; ++len) {
-          AddMatch(id + kOmitLastNTransforms[l - len] * n, len, l, matches);
+          size_t cut = l - len;
+          size_t transform_id = (cut << 2) +
+              (size_t)((dictionary->cutoffTransforms >> (cut * 6)) & 0x3F);
+          AddMatch(id + transform_id * n, len, l, matches);
           has_found_match = BROTLI_TRUE;
         }
         if (matchlen < l || l + 6 >= max_length) {
           continue;
         }
         s = &data[l];
         /* Transforms "" + BROTLI_TRANSFORM_IDENTITY + <suffix> */
         if (s[0] == ' ') {
--- a/modules/brotli/enc/write_bits.h
+++ b/modules/brotli/enc/write_bits.h
@@ -32,17 +32,17 @@ extern "C" {
    and OR'ing to BYTE-0.
 
    For n bits, we take the last 5 bits, OR that with high bits in BYTE-0,
    and locate the rest in BYTE+1, BYTE+2, etc. */
 static BROTLI_INLINE void BrotliWriteBits(size_t n_bits,
                                           uint64_t bits,
                                           size_t* BROTLI_RESTRICT pos,
                                           uint8_t* BROTLI_RESTRICT array) {
-#ifdef BROTLI_LITTLE_ENDIAN
+#if defined(BROTLI_LITTLE_ENDIAN)
   /* This branch of the code can write up to 56 bits at a time,
      7 bits are lost by being perhaps already in *p and at least
      1 bit is needed to initialize the bit-stream ahead (i.e. if 7
      bits are in *p and we write 57 bits, then the next write will
      access a byte that was never initialized). */
   uint8_t* p = &array[*pos >> 3];
   uint64_t v = (uint64_t)(*p);  /* Zero-extend 8 to 64 bits. */
   BROTLI_LOG(("WriteBits  %2d  0x%08x%08x  %10d\n", (int)n_bits,
--- a/modules/brotli/include/brotli/port.h
+++ b/modules/brotli/include/brotli/port.h
@@ -1,78 +1,274 @@
 /* Copyright 2016 Google Inc. All Rights Reserved.
 
    Distributed under MIT license.
    See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
 */
 
-/* Macros for compiler / platform specific features and build options.
-
-   Build options are:
-    * BROTLI_BUILD_MODERN_COMPILER forces to use modern compilers built-ins,
-      features and attributes
- */
+/* Macros for compiler / platform specific API declarations. */
 
 #ifndef BROTLI_COMMON_PORT_H_
 #define BROTLI_COMMON_PORT_H_
 
-/* Compatibility with non-clang compilers. */
-#ifndef __has_builtin
-#define __has_builtin(x) 0
+/* The following macros were borrowed from https://github.com/nemequ/hedley
+ * with permission of original author - Evan Nemerson <evan@nemerson.com> */
+
+/* >>> >>> >>> hedley macros */
+
+#define BROTLI_MAKE_VERSION(major, minor, revision) \
+  (((major) * 1000000) + ((minor) * 1000) + (revision))
+
+#if defined(__GNUC__) && defined(__GNUC_PATCHLEVEL__)
+#define BROTLI_GNUC_VERSION \
+  BROTLI_MAKE_VERSION(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
+#elif defined(__GNUC__)
+#define BROTLI_GNUC_VERSION BROTLI_MAKE_VERSION(__GNUC__, __GNUC_MINOR__, 0)
+#endif
+
+#if defined(BROTLI_GNUC_VERSION)
+#define BROTLI_GNUC_VERSION_CHECK(major, minor, patch) \
+  (BROTLI_GNUC_VERSION >= BROTLI_MAKE_VERSION(major, minor, patch))
+#else
+#define BROTLI_GNUC_VERSION_CHECK(major, minor, patch) (0)
+#endif
+
+#if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 140000000)
+#define BROTLI_MSVC_VERSION                                \
+  BROTLI_MAKE_VERSION((_MSC_FULL_VER / 10000000),          \
+                      (_MSC_FULL_VER % 10000000) / 100000, \
+                      (_MSC_FULL_VER % 100000) / 100)
+#elif defined(_MSC_FULL_VER)
+#define BROTLI_MSVC_VERSION                              \
+  BROTLI_MAKE_VERSION((_MSC_FULL_VER / 1000000),         \
+                      (_MSC_FULL_VER % 1000000) / 10000, \
+                      (_MSC_FULL_VER % 10000) / 10)
+#elif defined(_MSC_VER)
+#define BROTLI_MSVC_VERSION \
+  BROTLI_MAKE_VERSION(_MSC_VER / 100, _MSC_VER % 100, 0)
+#endif
+
+#if !defined(_MSC_VER)
+#define BROTLI_MSVC_VERSION_CHECK(major, minor, patch) (0)
+#elif defined(_MSC_VER) && (_MSC_VER >= 1400)
+#define BROTLI_MSVC_VERSION_CHECK(major, minor, patch) \
+  (_MSC_FULL_VER >= ((major * 10000000) + (minor * 100000) + (patch)))
+#elif defined(_MSC_VER) && (_MSC_VER >= 1200)
+#define BROTLI_MSVC_VERSION_CHECK(major, minor, patch) \
+  (_MSC_FULL_VER >= ((major * 1000000) + (minor * 10000) + (patch)))
+#else
+#define BROTLI_MSVC_VERSION_CHECK(major, minor, patch) \
+  (_MSC_VER >= ((major * 100) + (minor)))
 #endif
 
-#ifndef __has_attribute
-#define __has_attribute(x) 0
+#if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE)
+#define BROTLI_INTEL_VERSION                   \
+  BROTLI_MAKE_VERSION(__INTEL_COMPILER / 100,  \
+                      __INTEL_COMPILER % 100,  \
+                      __INTEL_COMPILER_UPDATE)
+#elif defined(__INTEL_COMPILER)
+#define BROTLI_INTEL_VERSION \
+  BROTLI_MAKE_VERSION(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, 0)
+#endif
+
+#if defined(BROTLI_INTEL_VERSION)
+#define BROTLI_INTEL_VERSION_CHECK(major, minor, patch) \
+  (BROTLI_INTEL_VERSION >= BROTLI_MAKE_VERSION(major, minor, patch))
+#else
+#define BROTLI_INTEL_VERSION_CHECK(major, minor, patch) (0)
+#endif
+
+#if defined(__PGI) && \
+    defined(__PGIC__) && defined(__PGIC_MINOR__) && defined(__PGIC_PATCHLEVEL__)
+#define BROTLI_PGI_VERSION \
+  BROTLI_MAKE_VERSION(__PGIC__, __PGIC_MINOR__, __PGIC_PATCHLEVEL__)
+#endif
+
+#if defined(BROTLI_PGI_VERSION)
+#define BROTLI_PGI_VERSION_CHECK(major, minor, patch) \
+  (BROTLI_PGI_VERSION >= BROTLI_MAKE_VERSION(major, minor, patch))
+#else
+#define BROTLI_PGI_VERSION_CHECK(major, minor, patch) (0)
 #endif
 
-#ifndef __has_feature
-#define __has_feature(x) 0
+#if defined(__SUNPRO_C) && (__SUNPRO_C > 0x1000)
+#define BROTLI_SUNPRO_VERSION                                       \
+  BROTLI_MAKE_VERSION(                                              \
+    (((__SUNPRO_C >> 16) & 0xf) * 10) + ((__SUNPRO_C >> 12) & 0xf), \
+    (((__SUNPRO_C >> 8) & 0xf) * 10) + ((__SUNPRO_C >> 4) & 0xf),   \
+    (__SUNPRO_C & 0xf) * 10)
+#elif defined(__SUNPRO_C)
+#define BROTLI_SUNPRO_VERSION                  \
+  BROTLI_MAKE_VERSION((__SUNPRO_C >> 8) & 0xf, \
+                      (__SUNPRO_C >> 4) & 0xf, \
+                      (__SUNPRO_C) & 0xf)
+#elif defined(__SUNPRO_CC) && (__SUNPRO_CC > 0x1000)
+#define BROTLI_SUNPRO_VERSION                                         \
+  BROTLI_MAKE_VERSION(                                                \
+    (((__SUNPRO_CC >> 16) & 0xf) * 10) + ((__SUNPRO_CC >> 12) & 0xf), \
+    (((__SUNPRO_CC >> 8) & 0xf) * 10) + ((__SUNPRO_CC >> 4) & 0xf),   \
+    (__SUNPRO_CC & 0xf) * 10)
+#elif defined(__SUNPRO_CC)
+#define BROTLI_SUNPRO_VERSION                   \
+  BROTLI_MAKE_VERSION((__SUNPRO_CC >> 8) & 0xf, \
+                      (__SUNPRO_CC >> 4) & 0xf, \
+                      (__SUNPRO_CC) & 0xf)
+#endif
+
+#if defined(BROTLI_SUNPRO_VERSION)
+#define BROTLI_SUNPRO_VERSION_CHECK(major, minor, patch) \
+  (BROTLI_SUNPRO_VERSION >= BROTLI_MAKE_VERSION(major, minor, patch))
+#else
+#define BROTLI_SUNPRO_VERSION_CHECK(major, minor, patch) (0)
 #endif
 
-#if defined(__GNUC__) && defined(__GNUC_MINOR__)
-#define BROTLI_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
+#if defined(__CC_ARM) && defined(__ARMCOMPILER_VERSION)
+#define BROTLI_ARM_VERSION                                       \
+  BROTLI_MAKE_VERSION((__ARMCOMPILER_VERSION / 1000000),         \
+                      (__ARMCOMPILER_VERSION % 1000000) / 10000, \
+                      (__ARMCOMPILER_VERSION % 10000) / 100)
+#elif defined(__CC_ARM) && defined(__ARMCC_VERSION)
+#define BROTLI_ARM_VERSION                                 \
+  BROTLI_MAKE_VERSION((__ARMCC_VERSION / 1000000),         \
+                      (__ARMCC_VERSION % 1000000) / 10000, \
+                      (__ARMCC_VERSION % 10000) / 100)
+#endif
+
+#if defined(BROTLI_ARM_VERSION)
+#define BROTLI_ARM_VERSION_CHECK(major, minor, patch) \
+  (BROTLI_ARM_VERSION >= BROTLI_MAKE_VERSION(major, minor, patch))
 #else
-#define BROTLI_GCC_VERSION 0
+#define BROTLI_ARM_VERSION_CHECK(major, minor, patch) (0)
+#endif
+
+#if defined(__ibmxl__)
+#define BROTLI_IBM_VERSION                    \
+  BROTLI_MAKE_VERSION(__ibmxl_version__,      \
+                      __ibmxl_release__,      \
+                      __ibmxl_modification__)
+#elif defined(__xlC__) && defined(__xlC_ver__)
+#define BROTLI_IBM_VERSION \
+  BROTLI_MAKE_VERSION(__xlC__ >> 8, __xlC__ & 0xff, (__xlC_ver__ >> 8) & 0xff)
+#elif defined(__xlC__)
+#define BROTLI_IBM_VERSION BROTLI_MAKE_VERSION(__xlC__ >> 8, __xlC__ & 0xff, 0)
+#endif
+
+#if defined(BROTLI_IBM_VERSION)
+#define BROTLI_IBM_VERSION_CHECK(major, minor, patch) \
+  (BROTLI_IBM_VERSION >= BROTLI_MAKE_VERSION(major, minor, patch))
+#else
+#define BROTLI_IBM_VERSION_CHECK(major, minor, patch) (0)
+#endif
+
+#if defined(__TI_COMPILER_VERSION__)
+#define BROTLI_TI_VERSION                                         \
+  BROTLI_MAKE_VERSION((__TI_COMPILER_VERSION__ / 1000000),        \
+                      (__TI_COMPILER_VERSION__ % 1000000) / 1000, \
+                      (__TI_COMPILER_VERSION__ % 1000))
+#endif
+
+#if defined(BROTLI_TI_VERSION)
+#define BROTLI_TI_VERSION_CHECK(major, minor, patch) \
+  (BROTLI_TI_VERSION >= BROTLI_MAKE_VERSION(major, minor, patch))
+#else
+#define BROTLI_TI_VERSION_CHECK(major, minor, patch) (0)
+#endif
+
+#if defined(__IAR_SYSTEMS_ICC__)
+#if __VER__ > 1000
+#define BROTLI_IAR_VERSION                     \
+  BROTLI_MAKE_VERSION((__VER__ / 1000000),     \
+                      (__VER__ / 1000) % 1000, \
+                      (__VER__ % 1000))
+#else
+#define BROTLI_IAR_VERSION BROTLI_MAKE_VERSION(VER / 100, __VER__ % 100, 0)
+#endif
 #endif
 
-#if defined(__ICC)
-#define BROTLI_ICC_VERSION __ICC
+#if defined(BROTLI_IAR_VERSION)
+#define BROTLI_IAR_VERSION_CHECK(major, minor, patch) \
+  (BROTLI_IAR_VERSION >= BROTLI_MAKE_VERSION(major, minor, patch))
 #else
-#define BROTLI_ICC_VERSION 0
+#define BROTLI_IAR_VERSION_CHECK(major, minor, patch) (0)
+#endif
+
+#if defined(__TINYC__)
+#define BROTLI_TINYC_VERSION \
+  BROTLI_MAKE_VERSION(__TINYC__ / 1000, (__TINYC__ / 100) % 10, __TINYC__ % 100)
+#endif
+
+#if defined(BROTLI_TINYC_VERSION)
+#define BROTLI_TINYC_VERSION_CHECK(major, minor, patch) \
+  (BROTLI_TINYC_VERSION >= BROTLI_MAKE_VERSION(major, minor, patch))
+#else
+#define BROTLI_TINYC_VERSION_CHECK(major, minor, patch) (0)
+#endif
+
+#if defined(__has_attribute)
+#define BROTLI_GNUC_HAS_ATTRIBUTE(attribute, major, minor, patch) \
+  __has_attribute(attribute)
+#else
+#define BROTLI_GNUC_HAS_ATTRIBUTE(attribute, major, minor, patch) \
+  BROTLI_GNUC_VERSION_CHECK(major, minor, patch)
 #endif
 
-#if defined(BROTLI_BUILD_MODERN_COMPILER)
-#define BROTLI_MODERN_COMPILER 1
-#elif BROTLI_GCC_VERSION >= 304 || BROTLI_ICC_VERSION >= 1600
-#define BROTLI_MODERN_COMPILER 1
+#if defined(__has_builtin)
+#define BROTLI_GNUC_HAS_BUILTIN(builtin, major, minor, patch) \
+  __has_builtin(builtin)
 #else
-#define BROTLI_MODERN_COMPILER 0
+#define BROTLI_GNUC_HAS_BUILTIN(builtin, major, minor, patch) \
+  BROTLI_GNUC_VERSION_CHECK(major, minor, patch)
 #endif
 
-#if defined(BROTLI_SHARED_COMPILATION) && defined(_WIN32)
+#if defined(_WIN32) || defined(__CYGWIN__)
+#define BROTLI_PUBLIC
+#elif BROTLI_GNUC_VERSION_CHECK(3, 3, 0) ||                         \
+    BROTLI_TI_VERSION_CHECK(8, 0, 0) ||                             \
+    BROTLI_INTEL_VERSION_CHECK(16, 0, 0) ||                         \
+    BROTLI_ARM_VERSION_CHECK(4, 1, 0) ||                            \
+    BROTLI_IBM_VERSION_CHECK(13, 1, 0) ||                           \
+    BROTLI_SUNPRO_VERSION_CHECK(5, 11, 0) ||                        \
+    (BROTLI_TI_VERSION_CHECK(7, 3, 0) &&                            \
+     defined(__TI_GNU_ATTRIBUTE_SUPPORT__) && defined(__TI_EABI__))
+#define BROTLI_PUBLIC __attribute__ ((visibility ("default")))
+#else
+#define BROTLI_PUBLIC
+#endif
+
+#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \
+    !defined(__STDC_NO_VLA__) && !defined(__cplusplus) &&         \
+    !defined(__PGI) && !defined(__PGIC__) && !defined(__TINYC__)
+#define BROTLI_ARRAY_PARAM(name) (name)
+#else
+#define BROTLI_ARRAY_PARAM(name)
+#endif
+
+/* <<< <<< <<< end of hedley macros. */
+
+#if defined(BROTLI_SHARED_COMPILATION)
+#if defined(_WIN32)
 #if defined(BROTLICOMMON_SHARED_COMPILATION)
 #define BROTLI_COMMON_API __declspec(dllexport)
 #else
 #define BROTLI_COMMON_API __declspec(dllimport)
 #endif  /* BROTLICOMMON_SHARED_COMPILATION */
 #if defined(BROTLIDEC_SHARED_COMPILATION)
 #define BROTLI_DEC_API __declspec(dllexport)
 #else
 #define BROTLI_DEC_API __declspec(dllimport)
 #endif  /* BROTLIDEC_SHARED_COMPILATION */
 #if defined(BROTLIENC_SHARED_COMPILATION)
 #define BROTLI_ENC_API __declspec(dllexport)
 #else
 #define BROTLI_ENC_API __declspec(dllimport)
 #endif  /* BROTLIENC_SHARED_COMPILATION */
-#else  /* BROTLI_SHARED_COMPILATION && _WIN32 */
+#else  /* _WIN32 */
+#define BROTLI_COMMON_API BROTLI_PUBLIC
+#define BROTLI_DEC_API BROTLI_PUBLIC
+#define BROTLI_ENC_API BROTLI_PUBLIC
+#endif  /* _WIN32 */
+#else  /* BROTLI_SHARED_COMPILATION */
 #define BROTLI_COMMON_API
 #define BROTLI_DEC_API
 #define BROTLI_ENC_API
 #endif
 
-#if BROTLI_MODERN_COMPILER || __has_attribute(deprecated)
-#define BROTLI_DEPRECATED __attribute__((deprecated))
-#else
-#define BROTLI_DEPRECATED
-#endif
-
 #endif  /* BROTLI_COMMON_PORT_H_ */
--- a/modules/brotli/include/brotli/types.h
+++ b/modules/brotli/include/brotli/types.h
@@ -75,16 +75,9 @@ typedef void* (*brotli_alloc_func)(void*
  *
  * This function @b SHOULD do nothing if @p address is @c 0.
  *
  * @param opaque custom memory manager handle provided by client
  * @param address memory region pointer returned by ::brotli_alloc_func, or @c 0
  */
 typedef void (*brotli_free_func)(void* opaque, void* address);
 
-#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \
-    !defined(__cplusplus) && !defined(__PGI)
-#define BROTLI_ARRAY_PARAM(L) L
-#else
-#define BROTLI_ARRAY_PARAM(L)
-#endif
-
 #endif  /* BROTLI_COMMON_TYPES_H_ */
--- a/modules/brotli/tools/brotli.c
+++ b/modules/brotli/tools/brotli.c
@@ -775,17 +775,17 @@ static BROTLI_BOOL CloseFiles(Context* c
   }
 
   context->fin = NULL;
   context->fout = NULL;
 
   return is_ok;
 }
 
-static const size_t kFileBufferSize = 1 << 16;
+static const size_t kFileBufferSize = 1 << 19;
 
 static void InitializeBuffers(Context* context) {
   context->available_in = 0;
   context->next_in = NULL;
   context->available_out = kFileBufferSize;
   context->next_out = context->output;
 }
 
--- a/modules/brotli/update.sh
+++ b/modules/brotli/update.sh
@@ -1,27 +1,27 @@
 #!/bin/sh
 
-# Script to update the mozilla in-tree copy of the Brotli decompressor.
+# 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.4
+git -C ${MY_TEMP_DIR}/brotli checkout v1.0.5
 
 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
 	mv ${MY_TEMP_DIR}/brotli/c/$d $d
 done
 rm -rf ${MY_TEMP_DIR}
 
 hg addremove $DIRS
 
 echo "###"
-echo "### Updated brotli/dec to $COMMIT."
+echo "### Updated brotli to $COMMIT."
 echo "### Remember to verify and commit the changes to source control!"
 echo "###"