_ZN6snappy6SourceD2Ev:
   36|  1.15k|Source::~Source() = default;
_ZNK6snappy15ByteArraySource9AvailableEv:
   68|  1.15k|size_t ByteArraySource::Available() const { return left_; }
_ZN6snappy15ByteArraySource4PeekEPm:
   70|  3.78k|const char* ByteArraySource::Peek(size_t* len) {
   71|  3.78k|  *len = left_;
   72|  3.78k|  return ptr_;
   73|  3.78k|}
_ZN6snappy15ByteArraySource4SkipEm:
   75|  5.91k|void ByteArraySource::Skip(size_t n) {
   76|  5.91k|  left_ -= n;
   77|  5.91k|  ptr_ += n;
   78|  5.91k|}

_ZN6snappy15ByteArraySourceC2EPKcm:
  148|  1.15k|  ByteArraySource(const char* p, size_t n) : ptr_(p), left_(n) { }
_ZN6snappy6SourceC2Ev:
  113|  1.15k|  Source() { }

_ZN6snappy6Varint16Parse32WithLimitEPKcS2_Pj:
  457|  2.38k|                                            uint32_t* OUTPUT) {
  458|  2.38k|  const unsigned char* ptr = reinterpret_cast<const unsigned char*>(p);
  459|  2.38k|  const unsigned char* limit = reinterpret_cast<const unsigned char*>(l);
  460|  2.38k|  uint32_t b, result;
  461|  2.38k|  if (ptr >= limit) return NULL;
  ------------------
  |  Branch (461:7): [True: 0, False: 2.38k]
  ------------------
  462|  2.38k|  b = *(ptr++); result = b & 127;          if (b < 128) goto done;
  ------------------
  |  Branch (462:48): [True: 1.00k, False: 1.38k]
  ------------------
  463|  1.38k|  if (ptr >= limit) return NULL;
  ------------------
  |  Branch (463:7): [True: 8, False: 1.37k]
  ------------------
  464|  1.37k|  b = *(ptr++); result |= (b & 127) <<  7; if (b < 128) goto done;
  ------------------
  |  Branch (464:48): [True: 822, False: 550]
  ------------------
  465|    550|  if (ptr >= limit) return NULL;
  ------------------
  |  Branch (465:7): [True: 10, False: 540]
  ------------------
  466|    540|  b = *(ptr++); result |= (b & 127) << 14; if (b < 128) goto done;
  ------------------
  |  Branch (466:48): [True: 335, False: 205]
  ------------------
  467|    205|  if (ptr >= limit) return NULL;
  ------------------
  |  Branch (467:7): [True: 9, False: 196]
  ------------------
  468|    196|  b = *(ptr++); result |= (b & 127) << 21; if (b < 128) goto done;
  ------------------
  |  Branch (468:48): [True: 50, False: 146]
  ------------------
  469|    146|  if (ptr >= limit) return NULL;
  ------------------
  |  Branch (469:7): [True: 10, False: 136]
  ------------------
  470|    136|  b = *(ptr++); result |= (b & 127) << 28; if (b < 16) goto done;
  ------------------
  |  Branch (470:48): [True: 112, False: 24]
  ------------------
  471|     24|  return NULL;       // Value is too long to be a varint32
  472|  2.32k| done:
  473|  2.32k|  *OUTPUT = result;
  474|  2.32k|  return reinterpret_cast<const char*>(ptr);
  475|    136|}
_ZN6snappy12LittleEndian6Load32EPKv:
  196|   221k|  static inline uint32_t Load32(const void *ptr) {
  197|       |    // Compiles to a single mov/str on recent clang and gcc.
  198|       |#if SNAPPY_IS_BIG_ENDIAN
  199|       |    const uint8_t* const buffer = reinterpret_cast<const uint8_t*>(ptr);
  200|       |    return (static_cast<uint32_t>(buffer[0])) |
  201|       |            (static_cast<uint32_t>(buffer[1]) << 8) |
  202|       |            (static_cast<uint32_t>(buffer[2]) << 16) |
  203|       |            (static_cast<uint32_t>(buffer[3]) << 24);
  204|       |#else
  205|       |    // See Load16() for the rationale of using memcpy().
  206|   221k|    uint32_t value;
  207|   221k|    std::memcpy(&value, ptr, 4);
  208|   221k|    return value;
  209|   221k|#endif
  210|   221k|  }
_ZN6snappy28STLStringResizeUninitializedEPNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEm:
  509|  1.15k|inline void STLStringResizeUninitialized(std::string* s, size_t new_size) {
  510|  1.15k|  s->resize(new_size);
  511|  1.15k|}
_ZN6snappy15string_as_arrayEPNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEE:
  525|  1.15k|inline char* string_as_array(std::string* str) {
  526|  1.15k|  return str->empty() ? NULL : &*str->begin();
  ------------------
  |  Branch (526:10): [True: 73, False: 1.07k]
  ------------------
  527|  1.15k|}

_ZN6snappy21GetUncompressedLengthEPKcmPm:
  708|  2.38k|bool GetUncompressedLength(const char* start, size_t n, size_t* result) {
  709|  2.38k|  uint32_t v = 0;
  710|  2.38k|  const char* limit = start + n;
  711|  2.38k|  if (Varint::Parse32WithLimit(start, limit, &v) != NULL) {
  ------------------
  |  Branch (711:7): [True: 2.32k, False: 61]
  ------------------
  712|  2.32k|    *result = v;
  713|  2.32k|    return true;
  714|  2.32k|  } else {
  715|     61|    return false;
  716|     61|  }
  717|  2.38k|}
_ZN6snappy9MemCopy64EPcPKvm:
 1041|   211k|void MemCopy64(char* dst, const void* src, size_t size) {
 1042|       |  // Always copy this many bytes.  If that's below size then copy the full 64.
 1043|   211k|  constexpr int kShortMemCopy = 32;
 1044|       |
 1045|   211k|  assert(size <= 64);
 1046|      0|  assert(std::less_equal<const void*>()(static_cast<const char*>(src) + size,
 1047|   211k|                                        dst) ||
 1048|   211k|         std::less_equal<const void*>()(dst + size, src));
 1049|       |
 1050|       |  // We know that src and dst are at least size bytes apart. However, because we
 1051|       |  // might copy more than size bytes the copy still might overlap past size.
 1052|       |  // E.g. if src and dst appear consecutively in memory (src + size >= dst).
 1053|       |  // TODO: Investigate wider copies on other platforms.
 1054|       |#if defined(__x86_64__) && defined(__AVX__)
 1055|       |  assert(kShortMemCopy <= 32);
 1056|       |  __m256i data = _mm256_lddqu_si256(static_cast<const __m256i *>(src));
 1057|       |  _mm256_storeu_si256(reinterpret_cast<__m256i *>(dst), data);
 1058|       |  // Profiling shows that nearly all copies are short.
 1059|       |  if (SNAPPY_PREDICT_FALSE(size > kShortMemCopy)) {
 1060|       |    data = _mm256_lddqu_si256(static_cast<const __m256i *>(src) + 1);
 1061|       |    _mm256_storeu_si256(reinterpret_cast<__m256i *>(dst) + 1, data);
 1062|       |  }
 1063|       |#else
 1064|      0|  std::memmove(dst, src, kShortMemCopy);
 1065|       |  // Profiling shows that nearly all copies are short.
 1066|   211k|  if (SNAPPY_PREDICT_FALSE(size > kShortMemCopy)) {
  ------------------
  |  |   94|   211k|#define SNAPPY_PREDICT_FALSE(x) (__builtin_expect(x, 0))
  |  |  ------------------
  |  |  |  Branch (94:33): [True: 4.43k, False: 206k]
  |  |  ------------------
  ------------------
 1067|  4.43k|    std::memmove(dst + kShortMemCopy,
 1068|  4.43k|                 static_cast<const uint8_t*>(src) + kShortMemCopy,
 1069|  4.43k|                 64 - kShortMemCopy);
 1070|  4.43k|  }
 1071|   211k|#endif
 1072|   211k|}
_ZN6snappy13ClearDeferredEPPKvPmPh:
 1082|   212k|                   uint8_t* safe_source) {
 1083|   212k|  *deferred_src = safe_source;
 1084|   212k|  *deferred_length = 0;
 1085|   212k|}
_ZN6snappy12DeferMemCopyEPPKvPmS1_m:
 1088|  11.2k|                  const void* src, size_t length) {
 1089|  11.2k|  *deferred_src = src;
 1090|  11.2k|  *deferred_length = length;
 1091|  11.2k|}
_ZN6snappy18SnappyDecompressor9RefillTagEv:
 1517|  2.25k|bool SnappyDecompressor::RefillTag() {
 1518|  2.25k|  const char* ip = ip_;
 1519|  2.25k|  if (ip == ip_limit_) {
  ------------------
  |  Branch (1519:7): [True: 1.42k, False: 835]
  ------------------
 1520|       |    // Fetch a new fragment from the reader
 1521|  1.42k|    reader_->Skip(peeked_);  // All peeked bytes are used up
 1522|  1.42k|    size_t n;
 1523|  1.42k|    ip = reader_->Peek(&n);
 1524|  1.42k|    peeked_ = n;
 1525|  1.42k|    eof_ = (n == 0);
 1526|  1.42k|    if (eof_) return false;
  ------------------
  |  Branch (1526:9): [True: 337, False: 1.08k]
  ------------------
 1527|  1.08k|    ip_limit_ = ip + n;
 1528|  1.08k|  }
 1529|       |
 1530|       |  // Read the tag character
 1531|  1.92k|  assert(ip < ip_limit_);
 1532|      0|  const unsigned char c = *(reinterpret_cast<const unsigned char*>(ip));
 1533|       |  // At this point make sure that the data for the next tag is consecutive.
 1534|       |  // For copy 1 this means the next 2 bytes (tag and 1 byte offset)
 1535|       |  // For copy 2 the next 3 bytes (tag and 2 byte offset)
 1536|       |  // For copy 4 the next 5 bytes (tag and 4 byte offset)
 1537|       |  // For all small literals we only need 1 byte buf for literals 60...63 the
 1538|       |  // length is encoded in 1...4 extra bytes.
 1539|  1.92k|  const uint32_t needed = CalculateNeeded(c);
 1540|  1.92k|  assert(needed <= sizeof(scratch_));
 1541|       |
 1542|       |  // Read more bytes from reader if needed
 1543|      0|  uint32_t nbuf = ip_limit_ - ip;
 1544|  1.92k|  if (nbuf < needed) {
  ------------------
  |  Branch (1544:7): [True: 28, False: 1.89k]
  ------------------
 1545|       |    // Stitch together bytes from ip and reader to form the word
 1546|       |    // contents.  We store the needed bytes in "scratch_".  They
 1547|       |    // will be consumed immediately by the caller since we do not
 1548|       |    // read more than we need.
 1549|     28|    std::memmove(scratch_, ip, nbuf);
 1550|     28|    reader_->Skip(peeked_);  // All peeked bytes are used up
 1551|     28|    peeked_ = 0;
 1552|     28|    while (nbuf < needed) {
  ------------------
  |  Branch (1552:12): [True: 28, False: 0]
  ------------------
 1553|     28|      size_t length;
 1554|     28|      const char* src = reader_->Peek(&length);
 1555|     28|      if (length == 0) return false;
  ------------------
  |  Branch (1555:11): [True: 28, False: 0]
  ------------------
 1556|      0|      uint32_t to_add = std::min<uint32_t>(needed - nbuf, length);
 1557|      0|      std::memcpy(scratch_ + nbuf, src, to_add);
 1558|      0|      nbuf += to_add;
 1559|      0|      reader_->Skip(to_add);
 1560|      0|    }
 1561|      0|    assert(nbuf == needed);
 1562|      0|    ip_ = scratch_;
 1563|      0|    ip_limit_ = scratch_ + needed;
 1564|  1.89k|  } else if (nbuf < kMaximumTagLength) {
  ------------------
  |  Branch (1564:14): [True: 976, False: 917]
  ------------------
 1565|       |    // Have enough bytes, but move into scratch_ so that we do not
 1566|       |    // read past end of input
 1567|    976|    std::memmove(scratch_, ip, nbuf);
 1568|    976|    reader_->Skip(peeked_);  // All peeked bytes are used up
 1569|    976|    peeked_ = 0;
 1570|    976|    ip_ = scratch_;
 1571|    976|    ip_limit_ = scratch_ + nbuf;
 1572|    976|  } else {
 1573|       |    // Pass pointer to buffer returned by reader_.
 1574|    917|    ip_ = ip;
 1575|    917|  }
 1576|  1.89k|  return true;
 1577|  1.92k|}
_ZN6snappy13RawUncompressEPKcmPc:
 2028|  1.15k|                   char* uncompressed) {
 2029|  1.15k|  ByteArraySource reader(compressed, compressed_length);
 2030|  1.15k|  return RawUncompress(&reader, uncompressed);
 2031|  1.15k|}
_ZN6snappy13RawUncompressEPNS_6SourceEPc:
 2033|  1.15k|bool RawUncompress(Source* compressed, char* uncompressed) {
 2034|  1.15k|  SnappyArrayWriter output(uncompressed);
 2035|  1.15k|  return InternalUncompress(compressed, &output);
 2036|  1.15k|}
_ZN6snappy10UncompressEPKcmPNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE:
 2039|  1.15k|                std::string* uncompressed) {
 2040|  1.15k|  size_t ulength;
 2041|  1.15k|  if (!GetUncompressedLength(compressed, compressed_length, &ulength)) {
  ------------------
  |  Branch (2041:7): [True: 0, False: 1.15k]
  ------------------
 2042|      0|    return false;
 2043|      0|  }
 2044|       |  // On 32-bit builds: max_size() < kuint32max.  Check for that instead
 2045|       |  // of crashing (e.g., consider externally specified compressed data).
 2046|  1.15k|  if (ulength > uncompressed->max_size()) {
  ------------------
  |  Branch (2046:7): [True: 0, False: 1.15k]
  ------------------
 2047|      0|    return false;
 2048|      0|  }
 2049|  1.15k|  STLStringResizeUninitialized(uncompressed, ulength);
 2050|  1.15k|  return RawUncompress(compressed, compressed_length,
 2051|  1.15k|                       string_as_array(uncompressed));
 2052|  1.15k|}
snappy.cc:_ZN6snappy12_GLOBAL__N_116UnalignedCopy128EPKvPv:
  211|  2.05k|void UnalignedCopy128(const void* src, void* dst) {
  212|       |  // std::memcpy() gets vectorized when the appropriate compiler options are
  213|       |  // used. For example, x86 compilers targeting SSE2+ will optimize to an SSE2
  214|       |  // load and store.
  215|  2.05k|  char tmp[16];
  216|  2.05k|  std::memcpy(tmp, src, 16);
  217|  2.05k|  std::memcpy(dst, tmp, 16);
  218|  2.05k|}
_ZN6snappy15CalculateNeededEh:
 1498|  1.92k|constexpr uint32_t CalculateNeeded(uint8_t tag) {
 1499|  1.92k|  return ((tag & 3) == 0 && tag >= (60 * 4))
  ------------------
  |  Branch (1499:11): [True: 1.26k, False: 652]
  |  Branch (1499:29): [True: 223, False: 1.04k]
  ------------------
 1500|  1.92k|             ? (tag >> 2) - 58
 1501|  1.92k|             : (0x05030201 >> ((tag * 8) & 31)) & 0xFF;
 1502|  1.92k|}
_ZN6snappy18SnappyDecompressorC2EPNS_6SourceE:
 1334|  1.15k|      : reader_(reader), ip_(NULL), ip_limit_(NULL), peeked_(0), eof_(false) {}
_ZN6snappy18SnappyDecompressor22ReadUncompressedLengthEPj:
 1347|  1.15k|  bool ReadUncompressedLength(uint32_t* result) {
 1348|  1.15k|    assert(ip_ == NULL);  // Must not have read anything yet
 1349|       |    // Length is encoded in 1..5 bytes
 1350|      0|    *result = 0;
 1351|  1.15k|    uint32_t shift = 0;
 1352|  2.16k|    while (true) {
  ------------------
  |  Branch (1352:12): [Folded - Ignored]
  ------------------
 1353|  2.16k|      if (shift >= 32) return false;
  ------------------
  |  Branch (1353:11): [True: 0, False: 2.16k]
  ------------------
 1354|  2.16k|      size_t n;
 1355|  2.16k|      const char* ip = reader_->Peek(&n);
 1356|  2.16k|      if (n == 0) return false;
  ------------------
  |  Branch (1356:11): [True: 0, False: 2.16k]
  ------------------
 1357|  2.16k|      const unsigned char c = *(reinterpret_cast<const unsigned char*>(ip));
 1358|  2.16k|      reader_->Skip(1);
 1359|  2.16k|      uint32_t val = c & 0x7f;
 1360|  2.16k|      if (LeftShiftOverflows(static_cast<uint8_t>(val), shift)) return false;
  ------------------
  |  Branch (1360:11): [True: 0, False: 2.16k]
  ------------------
 1361|  2.16k|      *result |= val << shift;
 1362|  2.16k|      if (c < 128) {
  ------------------
  |  Branch (1362:11): [True: 1.15k, False: 1.01k]
  ------------------
 1363|  1.15k|        break;
 1364|  1.15k|      }
 1365|  1.01k|      shift += 7;
 1366|  1.01k|    }
 1367|  1.15k|    return true;
 1368|  1.15k|  }
snappy.cc:_ZN6snappyL18LeftShiftOverflowsEhj:
 1021|  2.16k|static inline bool LeftShiftOverflows(uint8_t value, uint32_t shift) {
 1022|  2.16k|  assert(shift < 32);
 1023|      0|  static const uint8_t masks[] = {
 1024|  2.16k|      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  //
 1025|  2.16k|      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  //
 1026|  2.16k|      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  //
 1027|  2.16k|      0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe};
 1028|  2.16k|  return (value & masks[shift]) != 0;
 1029|  2.16k|}
_ZN6snappy18SnappyDecompressorD2Ev:
 1336|  1.15k|  ~SnappyDecompressor() {
 1337|       |    // Advance past any bytes we peeked at from the reader
 1338|  1.15k|    reader_->Skip(peeked_);
 1339|  1.15k|  }
snappy.cc:_ZN6snappyL6ReportEPKcmm:
  945|  1.15k|                          size_t uncompressed_size) {
  946|       |  // TODO: Switch to [[maybe_unused]] when we can assume C++17.
  947|  1.15k|  (void)algorithm;
  948|  1.15k|  (void)compressed_size;
  949|  1.15k|  (void)uncompressed_size;
  950|  1.15k|}
_ZN6snappy17SnappyArrayWriterC2EPc:
 1959|  1.15k|        op_limit_min_slop_(dst) {}  // Safe default see invariant.
_ZN6snappy18SnappyDecompressor10ResetLimitEPKc:
 1327|  3.04k|  void ResetLimit(const char* ip) {
 1328|  3.04k|    ip_limit_min_maxtaglen_ =
 1329|  3.04k|        ip_limit_ - std::min<ptrdiff_t>(ip_limit_ - ip, kMaximumTagLength - 1);
 1330|  3.04k|  }
_ZN6snappy20DecompressBranchlessIPcEENSt3__14pairIPKhlEES5_S5_lT_l:
 1196|  12.6k|    ptrdiff_t op_limit_min_slop) {
 1197|       |  // If deferred_src is invalid point it here.
 1198|  12.6k|  uint8_t safe_source[64];
 1199|  12.6k|  const void* deferred_src;
 1200|  12.6k|  size_t deferred_length;
 1201|  12.6k|  ClearDeferred(&deferred_src, &deferred_length, safe_source);
 1202|       |
 1203|       |  // We unroll the inner loop twice so we need twice the spare room.
 1204|  12.6k|  op_limit_min_slop -= kSlopBytes;
 1205|  12.6k|  if (2 * (kSlopBytes + 1) < ip_limit - ip && op < op_limit_min_slop) {
  ------------------
  |  Branch (1205:7): [True: 4.07k, False: 8.61k]
  |  Branch (1205:47): [True: 2.65k, False: 1.42k]
  ------------------
 1206|  2.65k|    const uint8_t* const ip_limit_min_slop = ip_limit - 2 * kSlopBytes - 1;
 1207|  2.65k|    ip++;
 1208|       |    // ip points just past the tag and we are touching at maximum kSlopBytes
 1209|       |    // in an iteration.
 1210|  2.65k|    size_t tag = ip[-1];
 1211|       |#if defined(__clang__) && defined(__aarch64__)
 1212|       |    // Workaround for https://bugs.llvm.org/show_bug.cgi?id=51317
 1213|       |    // when loading 1 byte, clang for aarch64 doesn't realize that it(ldrb)
 1214|       |    // comes with free zero-extension, so clang generates another
 1215|       |    // 'and xn, xm, 0xff' before it use that as the offset. This 'and' is
 1216|       |    // redundant and can be removed by adding this dummy asm, which gives
 1217|       |    // clang a hint that we're doing the zero-extension at the load.
 1218|       |    asm("" ::"r"(tag));
 1219|       |#endif
 1220|   106k|    do {
 1221|       |      // The throughput is limited by instructions, unrolling the inner loop
 1222|       |      // twice reduces the amount of instructions checking limits and also
 1223|       |      // leads to reduced mov's.
 1224|       |
 1225|   106k|      SNAPPY_PREFETCH(ip + 128);
  ------------------
  |  |  109|   106k|#define SNAPPY_PREFETCH(ptr) __builtin_prefetch(ptr, 0, 3)
  ------------------
 1226|   316k|      for (int i = 0; i < 2; i++) {
  ------------------
  |  Branch (1226:23): [True: 212k, False: 104k]
  ------------------
 1227|   212k|        const uint8_t* old_ip = ip;
 1228|   212k|        assert(tag == ip[-1]);
 1229|       |        // For literals tag_type = 0, hence we will always obtain 0 from
 1230|       |        // ExtractLowBytes. For literals offset will thus be kLiteralOffset.
 1231|      0|        ptrdiff_t len_minus_offset = kLengthMinusOffset[tag];
 1232|   212k|        uint32_t next;
 1233|       |#if defined(__aarch64__)
 1234|       |        size_t tag_type = AdvanceToNextTagARMOptimized(&ip, &tag);
 1235|       |        // We never need more than 16 bits. Doing a Load16 allows the compiler
 1236|       |        // to elide the masking operation in ExtractOffset.
 1237|       |        next = LittleEndian::Load16(old_ip);
 1238|       |#else
 1239|   212k|        size_t tag_type = AdvanceToNextTagX86Optimized(&ip, &tag);
 1240|   212k|        next = LittleEndian::Load32(old_ip);
 1241|   212k|#endif
 1242|   212k|        size_t len = len_minus_offset & 0xFF;
 1243|   212k|        ptrdiff_t extracted = ExtractOffset(next, tag_type);
 1244|   212k|        ptrdiff_t len_min_offset = len_minus_offset - extracted;
 1245|   212k|        if (SNAPPY_PREDICT_FALSE(len_minus_offset > extracted)) {
  ------------------
  |  |   94|   212k|#define SNAPPY_PREDICT_FALSE(x) (__builtin_expect(x, 0))
  |  |  ------------------
  |  |  |  Branch (94:33): [True: 200k, False: 11.2k]
  |  |  ------------------
  ------------------
 1246|   200k|          if (SNAPPY_PREDICT_FALSE(len & 0x80)) {
  ------------------
  |  |   94|   200k|#define SNAPPY_PREDICT_FALSE(x) (__builtin_expect(x, 0))
  |  |  ------------------
  |  |  |  Branch (94:33): [True: 2.30k, False: 198k]
  |  |  ------------------
  ------------------
 1247|       |            // Exceptional case (long literal or copy 4).
 1248|       |            // Actually doing the copy here is negatively impacting the main
 1249|       |            // loop due to compiler incorrectly allocating a register for
 1250|       |            // this fallback. Hence we just break.
 1251|  2.38k|          break_loop:
 1252|  2.38k|            ip = old_ip;
 1253|  2.38k|            goto exit;
 1254|  2.30k|          }
 1255|       |          // Only copy-1 or copy-2 tags can get here.
 1256|   198k|          assert(tag_type == 1 || tag_type == 2);
 1257|      0|          std::ptrdiff_t delta = (op + deferred_length) + len_min_offset - len;
 1258|       |          // Guard against copies before the buffer start.
 1259|       |          // Execute any deferred MemCopy since we write to dst here.
 1260|   198k|          MemCopy64(op_base + op, deferred_src, deferred_length);
 1261|   198k|          op += deferred_length;
 1262|   198k|          ClearDeferred(&deferred_src, &deferred_length, safe_source);
 1263|   198k|          if (SNAPPY_PREDICT_FALSE(delta < 0 ||
  ------------------
  |  |   94|   396k|#define SNAPPY_PREDICT_FALSE(x) (__builtin_expect(x, 0))
  |  |  ------------------
  |  |  |  Branch (94:33): [True: 29, False: 198k]
  |  |  |  Branch (94:51): [True: 13, False: 198k]
  |  |  |  Branch (94:51): [True: 16, False: 198k]
  |  |  ------------------
  ------------------
 1264|   198k|                                  !Copy64BytesWithPatternExtension(
 1265|   198k|                                      op_base + op, len - len_min_offset))) {
 1266|     29|            goto break_loop;
 1267|     29|          }
 1268|       |          // We aren't deferring this copy so add length right away.
 1269|   198k|          op += len;
 1270|   198k|          continue;
 1271|   198k|        }
 1272|  11.2k|        std::ptrdiff_t delta = (op + deferred_length) + len_min_offset - len;
 1273|  11.2k|        if (SNAPPY_PREDICT_FALSE(delta < 0)) {
  ------------------
  |  |   94|  11.2k|#define SNAPPY_PREDICT_FALSE(x) (__builtin_expect(x, 0))
  |  |  ------------------
  |  |  |  Branch (94:33): [True: 2.05k, False: 9.23k]
  |  |  ------------------
  ------------------
 1274|       |          // Due to the spurious offset in literals have this will trigger
 1275|       |          // at the start of a block when op is still smaller than 256.
 1276|  2.05k|          if (tag_type != 0) goto break_loop;
  ------------------
  |  Branch (1276:15): [True: 53, False: 2.00k]
  ------------------
 1277|  2.00k|          MemCopy64(op_base + op, deferred_src, deferred_length);
 1278|  2.00k|          op += deferred_length;
 1279|  2.00k|          DeferMemCopy(&deferred_src, &deferred_length, old_ip, len);
 1280|  2.00k|          continue;
 1281|  2.05k|        }
 1282|       |
 1283|       |        // For copies we need to copy from op_base + delta, for literals
 1284|       |        // we need to copy from ip instead of from the stream.
 1285|  9.23k|        const void* from =
 1286|  9.23k|            tag_type ? reinterpret_cast<void*>(op_base + delta) : old_ip;
  ------------------
  |  Branch (1286:13): [True: 5.97k, False: 3.26k]
  ------------------
 1287|  9.23k|        MemCopy64(op_base + op, deferred_src, deferred_length);
 1288|  9.23k|        op += deferred_length;
 1289|  9.23k|        DeferMemCopy(&deferred_src, &deferred_length, from, len);
 1290|  9.23k|      }
 1291|   106k|    } while (ip < ip_limit_min_slop &&
  ------------------
  |  Branch (1291:14): [True: 104k, False: 257]
  ------------------
 1292|   104k|             (op + deferred_length) < op_limit_min_slop);
  ------------------
  |  Branch (1292:14): [True: 104k, False: 11]
  ------------------
 1293|  2.65k|  exit:
 1294|  2.65k|    ip--;
 1295|  2.65k|    assert(ip <= ip_limit);
 1296|  2.65k|  }
 1297|       |  // If we deferred a copy then we can perform.  If we are up to date then we
 1298|       |  // might not have enough slop bytes and could run past the end.
 1299|  12.6k|  if (deferred_length) {
  ------------------
  |  Branch (1299:7): [True: 1.42k, False: 11.2k]
  ------------------
 1300|  1.42k|    MemCopy64(op_base + op, deferred_src, deferred_length);
 1301|  1.42k|    op += deferred_length;
 1302|  1.42k|    ClearDeferred(&deferred_src, &deferred_length, safe_source);
 1303|  1.42k|  }
 1304|  12.6k|  return {ip, op};
 1305|  12.6k|}
_ZN6snappy28AdvanceToNextTagX86OptimizedEPPKhPm:
 1117|   212k|inline size_t AdvanceToNextTagX86Optimized(const uint8_t** ip_p, size_t* tag) {
 1118|   212k|  const uint8_t*& ip = *ip_p;
 1119|       |  // This section is crucial for the throughput of the decompression loop.
 1120|       |  // The latency of an iteration is fundamentally constrained by the
 1121|       |  // following data chain on ip.
 1122|       |  // ip -> c = Load(ip) -> ip1 = ip + 1 + (c & 3) -> ip = ip1 or ip2
 1123|       |  //                       ip2 = ip + 2 + (c >> 2)
 1124|       |  // This amounts to 8 cycles.
 1125|       |  // 5 (load) + 1 (c & 3) + 1 (lea ip1, [ip + (c & 3) + 1]) + 1 (cmov)
 1126|   212k|  size_t literal_len = *tag >> 2;
 1127|   212k|  size_t tag_type = *tag;
 1128|   212k|  bool is_literal;
 1129|   212k|#if defined(__GCC_ASM_FLAG_OUTPUTS__) && defined(__x86_64__)
 1130|       |  // TODO clang misses the fact that the (c & 3) already correctly
 1131|       |  // sets the zero flag.
 1132|   212k|  asm("and $3, %k[tag_type]\n\t"
 1133|   212k|      : [tag_type] "+r"(tag_type), "=@ccz"(is_literal)
 1134|   212k|      :: "cc");
 1135|       |#else
 1136|       |  tag_type &= 3;
 1137|       |  is_literal = (tag_type == 0);
 1138|       |#endif
 1139|       |  // TODO
 1140|       |  // This is code is subtle. Loading the values first and then cmov has less
 1141|       |  // latency then cmov ip and then load. However clang would move the loads
 1142|       |  // in an optimization phase, volatile prevents this transformation.
 1143|       |  // Note that we have enough slop bytes (64) that the loads are always valid.
 1144|   212k|  size_t tag_literal =
 1145|   212k|      static_cast<const volatile uint8_t*>(ip)[1 + literal_len];
 1146|   212k|  size_t tag_copy = static_cast<const volatile uint8_t*>(ip)[tag_type];
 1147|   212k|  *tag = is_literal ? tag_literal : tag_copy;
  ------------------
  |  Branch (1147:10): [True: 6.71k, False: 205k]
  ------------------
 1148|   212k|  const uint8_t* ip_copy = ip + 1 + tag_type;
 1149|   212k|  const uint8_t* ip_literal = ip + 2 + literal_len;
 1150|   212k|  ip = is_literal ? ip_literal : ip_copy;
  ------------------
  |  Branch (1150:8): [True: 6.71k, False: 205k]
  ------------------
 1151|   212k|#if defined(__GNUC__) && defined(__x86_64__)
 1152|       |  // TODO Clang is "optimizing" zero-extension (a totally free
 1153|       |  // operation) this means that after the cmov of tag, it emits another movzb
 1154|       |  // tag, byte(tag). It really matters as it's on the core chain. This dummy
 1155|       |  // asm, persuades clang to do the zero-extension at the load (it's automatic)
 1156|       |  // removing the expensive movzb.
 1157|   212k|  asm("" ::"r"(tag_copy));
 1158|   212k|#endif
 1159|   212k|  return tag_type;
 1160|   212k|}
_ZN6snappy13ExtractOffsetEjm:
 1163|   212k|inline uint32_t ExtractOffset(uint32_t val, size_t tag_type) {
 1164|       |  // For x86 non-static storage works better. For ARM static storage is better.
 1165|       |  // TODO: Once the array is recognized as a register, improve the
 1166|       |  // readability for x86.
 1167|   212k|#if defined(__x86_64__)
 1168|   212k|  constexpr uint64_t kExtractMasksCombined = 0x0000FFFF00FF0000ull;
 1169|   212k|  uint16_t result;
 1170|   212k|  memcpy(&result,
 1171|   212k|         reinterpret_cast<const char*>(&kExtractMasksCombined) + 2 * tag_type,
 1172|   212k|         sizeof(result));
 1173|   212k|  return val & result;
 1174|       |#elif defined(__aarch64__)
 1175|       |  constexpr uint64_t kExtractMasksCombined = 0x0000FFFF00FF0000ull;
 1176|       |  return val & static_cast<uint32_t>(
 1177|       |      (kExtractMasksCombined >> (tag_type * 16)) & 0xFFFF);
 1178|       |#else
 1179|       |  static constexpr uint32_t kExtractMasks[4] = {0, 0xFF, 0xFFFF, 0};
 1180|       |  return val & kExtractMasks[tag_type];
 1181|       |#endif
 1182|   212k|};
snappy.cc:_ZN6snappy12_GLOBAL__N_131Copy64BytesWithPatternExtensionEPcm:
  338|   198k|static inline bool Copy64BytesWithPatternExtension(char* dst, size_t offset) {
  339|       |#if SNAPPY_HAVE_VECTOR_BYTE_SHUFFLE
  340|       |  if (SNAPPY_PREDICT_TRUE(offset <= 16)) {
  341|       |    switch (offset) {
  342|       |      case 0:
  343|       |        return false;
  344|       |      case 1: {
  345|       |        // TODO: Ideally we should memset, move back once the
  346|       |        // codegen issues are fixed.
  347|       |        V128 pattern = V128_DupChar(dst[-1]);
  348|       |        for (int i = 0; i < 4; i++) {
  349|       |          V128_StoreU(reinterpret_cast<V128*>(dst + 16 * i), pattern);
  350|       |        }
  351|       |        return true;
  352|       |      }
  353|       |      case 2:
  354|       |      case 4:
  355|       |      case 8:
  356|       |      case 16: {
  357|       |        V128 pattern = LoadPattern(dst - offset, offset);
  358|       |        for (int i = 0; i < 4; i++) {
  359|       |          V128_StoreU(reinterpret_cast<V128*>(dst + 16 * i), pattern);
  360|       |        }
  361|       |        return true;
  362|       |      }
  363|       |      default: {
  364|       |        auto pattern_and_reshuffle_mask =
  365|       |            LoadPatternAndReshuffleMask(dst - offset, offset);
  366|       |        V128 pattern = pattern_and_reshuffle_mask.first;
  367|       |        V128 reshuffle_mask = pattern_and_reshuffle_mask.second;
  368|       |        for (int i = 0; i < 4; i++) {
  369|       |          V128_StoreU(reinterpret_cast<V128*>(dst + 16 * i), pattern);
  370|       |          pattern = V128_Shuffle(pattern, reshuffle_mask);
  371|       |        }
  372|       |        return true;
  373|       |      }
  374|       |    }
  375|       |  }
  376|       |#else
  377|   198k|  if (SNAPPY_PREDICT_TRUE(offset < 16)) {
  ------------------
  |  |   95|   198k|#define SNAPPY_PREDICT_TRUE(x) (__builtin_expect(!!(x), 1))
  |  |  ------------------
  |  |  |  Branch (95:32): [True: 175k, False: 23.0k]
  |  |  ------------------
  ------------------
  378|   175k|    if (SNAPPY_PREDICT_FALSE(offset == 0)) return false;
  ------------------
  |  |   94|   175k|#define SNAPPY_PREDICT_FALSE(x) (__builtin_expect(x, 0))
  |  |  ------------------
  |  |  |  Branch (94:33): [True: 16, False: 175k]
  |  |  ------------------
  ------------------
  379|       |    // Extend the pattern to the first 16 bytes.
  380|       |    // The simpler formulation of `dst[i - offset]` induces undefined behavior.
  381|  2.98M|    for (int i = 0; i < 16; i++) dst[i] = (dst - offset)[i];
  ------------------
  |  Branch (381:21): [True: 2.80M, False: 175k]
  ------------------
  382|       |    // Find a multiple of pattern >= 16.
  383|   175k|    static std::array<uint8_t, 16> pattern_sizes = []() {
  384|   175k|      std::array<uint8_t, 16> res;
  385|   175k|      for (int i = 1; i < 16; i++) res[i] = (16 / i + 1) * i;
  386|   175k|      return res;
  387|   175k|    }();
  388|   175k|    offset = pattern_sizes[offset];
  389|   701k|    for (int i = 1; i < 4; i++) {
  ------------------
  |  Branch (389:21): [True: 526k, False: 175k]
  ------------------
  390|   526k|      std::memcpy(dst + i * 16, dst + i * 16 - offset, 16);
  391|   526k|    }
  392|   175k|    return true;
  393|   175k|  }
  394|  23.0k|#endif  // SNAPPY_HAVE_VECTOR_BYTE_SHUFFLE
  395|       |
  396|       |  // Very rare.
  397|   115k|  for (int i = 0; i < 4; i++) {
  ------------------
  |  Branch (397:19): [True: 92.1k, False: 23.0k]
  ------------------
  398|  92.1k|    std::memcpy(dst + i * 16, dst + i * 16 - offset, 16);
  399|  92.1k|  }
  400|  23.0k|  return true;
  401|   198k|}
snappy.cc:_ZZN6snappy12_GLOBAL__N_131Copy64BytesWithPatternExtensionEPcmENKUlvE_clEv:
  383|      1|    static std::array<uint8_t, 16> pattern_sizes = []() {
  384|      1|      std::array<uint8_t, 16> res;
  385|     16|      for (int i = 1; i < 16; i++) res[i] = (16 / i + 1) * i;
  ------------------
  |  Branch (385:23): [True: 15, False: 1]
  ------------------
  386|      1|      return res;
  387|      1|    }();
snappy.cc:_ZN6snappyL15ExtractLowBytesERKji:
 1008|  8.43k|static inline uint32_t ExtractLowBytes(const uint32_t& v, int n) {
 1009|  8.43k|  assert(n >= 0);
 1010|      0|  assert(n <= 4);
 1011|       |#if SNAPPY_HAVE_BMI2
 1012|       |  return _bzhi_u32(v, 8 * n);
 1013|       |#else
 1014|       |  // This needs to be wider than uint32_t otherwise `mask << 32` will be
 1015|       |  // undefined.
 1016|      0|  uint64_t mask = 0xffffffff;
 1017|  8.43k|  return v & ~(mask << (8 * n));
 1018|  8.43k|#endif
 1019|  8.43k|}
snappy.cc:_ZN6snappy12_GLOBAL__N_115IncrementalCopyEPKcPcS3_S3_:
  407|  5.61k|                             char* const buf_limit) {
  408|       |#if SNAPPY_HAVE_VECTOR_BYTE_SHUFFLE
  409|       |  constexpr int big_pattern_size_lower_bound = 16;
  410|       |#else
  411|  5.61k|  constexpr int big_pattern_size_lower_bound = 8;
  412|  5.61k|#endif
  413|       |
  414|       |  // Terminology:
  415|       |  //
  416|       |  // slop = buf_limit - op
  417|       |  // pat  = op - src
  418|       |  // len  = op_limit - op
  419|  5.61k|  assert(src < op);
  420|      0|  assert(op < op_limit);
  421|      0|  assert(op_limit <= buf_limit);
  422|       |  // NOTE: The copy tags use 3 or 6 bits to store the copy length, so len <= 64.
  423|      0|  assert(op_limit - op <= 64);
  424|       |  // NOTE: In practice the compressor always emits len >= 4, so it is ok to
  425|       |  // assume that to optimize this function, but this is not guaranteed by the
  426|       |  // compression format, so we have to also handle len < 4 in case the input
  427|       |  // does not satisfy these conditions.
  428|       |
  429|      0|  size_t pattern_size = op - src;
  430|       |  // The cases are split into different branches to allow the branch predictor,
  431|       |  // FDO, and static prediction hints to work better. For each input we list the
  432|       |  // ratio of invocations that match each condition.
  433|       |  //
  434|       |  // input        slop < 16   pat < 8  len > 16
  435|       |  // ------------------------------------------
  436|       |  // html|html4|cp   0%         1.01%    27.73%
  437|       |  // urls            0%         0.88%    14.79%
  438|       |  // jpg             0%        64.29%     7.14%
  439|       |  // pdf             0%         2.56%    58.06%
  440|       |  // txt[1-4]        0%         0.23%     0.97%
  441|       |  // pb              0%         0.96%    13.88%
  442|       |  // bin             0.01%     22.27%    41.17%
  443|       |  //
  444|       |  // It is very rare that we don't have enough slop for doing block copies. It
  445|       |  // is also rare that we need to expand a pattern. Small patterns are common
  446|       |  // for incompressible formats and for those we are plenty fast already.
  447|       |  // Lengths are normally not greater than 16 but they vary depending on the
  448|       |  // input. In general if we always predict len <= 16 it would be an ok
  449|       |  // prediction.
  450|       |  //
  451|       |  // In order to be fast we want a pattern >= 16 bytes (or 8 bytes in non-SSE)
  452|       |  // and an unrolled loop copying 1x 16 bytes (or 2x 8 bytes in non-SSE) at a
  453|       |  // time.
  454|       |
  455|       |  // Handle the uncommon case where pattern is less than 16 (or 8 in non-SSE)
  456|       |  // bytes.
  457|  5.61k|  if (pattern_size < big_pattern_size_lower_bound) {
  ------------------
  |  Branch (457:7): [True: 4.28k, False: 1.33k]
  ------------------
  458|       |#if SNAPPY_HAVE_VECTOR_BYTE_SHUFFLE
  459|       |    // Load the first eight bytes into an 128-bit XMM register, then use PSHUFB
  460|       |    // to permute the register's contents in-place into a repeating sequence of
  461|       |    // the first "pattern_size" bytes.
  462|       |    // For example, suppose:
  463|       |    //    src       == "abc"
  464|       |    //    op        == op + 3
  465|       |    // After V128_Shuffle(), "pattern" will have five copies of "abc"
  466|       |    // followed by one byte of slop: abcabcabcabcabca.
  467|       |    //
  468|       |    // The non-SSE fallback implementation suffers from store-forwarding stalls
  469|       |    // because its loads and stores partly overlap. By expanding the pattern
  470|       |    // in-place, we avoid the penalty.
  471|       |
  472|       |    // Typically, the op_limit is the gating factor so try to simplify the loop
  473|       |    // based on that.
  474|       |    if (SNAPPY_PREDICT_TRUE(op_limit <= buf_limit - 15)) {
  475|       |      auto pattern_and_reshuffle_mask =
  476|       |          LoadPatternAndReshuffleMask(src, pattern_size);
  477|       |      V128 pattern = pattern_and_reshuffle_mask.first;
  478|       |      V128 reshuffle_mask = pattern_and_reshuffle_mask.second;
  479|       |
  480|       |      // There is at least one, and at most four 16-byte blocks. Writing four
  481|       |      // conditionals instead of a loop allows FDO to layout the code with
  482|       |      // respect to the actual probabilities of each length.
  483|       |      // TODO: Replace with loop with trip count hint.
  484|       |      V128_StoreU(reinterpret_cast<V128*>(op), pattern);
  485|       |
  486|       |      if (op + 16 < op_limit) {
  487|       |        pattern = V128_Shuffle(pattern, reshuffle_mask);
  488|       |        V128_StoreU(reinterpret_cast<V128*>(op + 16), pattern);
  489|       |      }
  490|       |      if (op + 32 < op_limit) {
  491|       |        pattern = V128_Shuffle(pattern, reshuffle_mask);
  492|       |        V128_StoreU(reinterpret_cast<V128*>(op + 32), pattern);
  493|       |      }
  494|       |      if (op + 48 < op_limit) {
  495|       |        pattern = V128_Shuffle(pattern, reshuffle_mask);
  496|       |        V128_StoreU(reinterpret_cast<V128*>(op + 48), pattern);
  497|       |      }
  498|       |      return op_limit;
  499|       |    }
  500|       |    char* const op_end = buf_limit - 15;
  501|       |    if (SNAPPY_PREDICT_TRUE(op < op_end)) {
  502|       |      auto pattern_and_reshuffle_mask =
  503|       |          LoadPatternAndReshuffleMask(src, pattern_size);
  504|       |      V128 pattern = pattern_and_reshuffle_mask.first;
  505|       |      V128 reshuffle_mask = pattern_and_reshuffle_mask.second;
  506|       |
  507|       |      // This code path is relatively cold however so we save code size
  508|       |      // by avoiding unrolling and vectorizing.
  509|       |      //
  510|       |      // TODO: Remove pragma when when cold regions don't get
  511|       |      // vectorized or unrolled.
  512|       |#ifdef __clang__
  513|       |#pragma clang loop unroll(disable)
  514|       |#endif
  515|       |      do {
  516|       |        V128_StoreU(reinterpret_cast<V128*>(op), pattern);
  517|       |        pattern = V128_Shuffle(pattern, reshuffle_mask);
  518|       |        op += 16;
  519|       |      } while (SNAPPY_PREDICT_TRUE(op < op_end));
  520|       |    }
  521|       |    return IncrementalCopySlow(op - pattern_size, op, op_limit);
  522|       |#else   // !SNAPPY_HAVE_VECTOR_BYTE_SHUFFLE
  523|       |    // If plenty of buffer space remains, expand the pattern to at least 8
  524|       |    // bytes. The way the following loop is written, we need 8 bytes of buffer
  525|       |    // space if pattern_size >= 4, 11 bytes if pattern_size is 1 or 3, and 10
  526|       |    // bytes if pattern_size is 2.  Precisely encoding that is probably not
  527|       |    // worthwhile; instead, invoke the slow path if we cannot write 11 bytes
  528|       |    // (because 11 are required in the worst case).
  529|  4.28k|    if (SNAPPY_PREDICT_TRUE(op <= buf_limit - 11)) {
  ------------------
  |  |   95|  4.28k|#define SNAPPY_PREDICT_TRUE(x) (__builtin_expect(!!(x), 1))
  |  |  ------------------
  |  |  |  Branch (95:32): [True: 4.23k, False: 50]
  |  |  ------------------
  ------------------
  530|  15.7k|      while (pattern_size < 8) {
  ------------------
  |  Branch (530:14): [True: 11.5k, False: 4.23k]
  ------------------
  531|  11.5k|        UnalignedCopy64(src, op);
  532|  11.5k|        op += pattern_size;
  533|  11.5k|        pattern_size *= 2;
  534|  11.5k|      }
  535|  4.23k|      if (SNAPPY_PREDICT_TRUE(op >= op_limit)) return op_limit;
  ------------------
  |  |   95|  4.23k|#define SNAPPY_PREDICT_TRUE(x) (__builtin_expect(!!(x), 1))
  |  |  ------------------
  |  |  |  Branch (95:32): [True: 905, False: 3.32k]
  |  |  ------------------
  ------------------
  536|  4.23k|    } else {
  537|     50|      return IncrementalCopySlow(src, op, op_limit);
  538|     50|    }
  539|  4.28k|#endif  // SNAPPY_HAVE_VECTOR_BYTE_SHUFFLE
  540|  4.28k|  }
  541|  4.66k|  assert(pattern_size >= big_pattern_size_lower_bound);
  542|      0|  constexpr bool use_16bytes_chunk = big_pattern_size_lower_bound == 16;
  543|       |
  544|       |  // Copy 1x 16 bytes (or 2x 8 bytes in non-SSE) at a time. Because op - src can
  545|       |  // be < 16 in non-SSE, a single UnalignedCopy128 might overwrite data in op.
  546|       |  // UnalignedCopy64 is safe because expanding the pattern to at least 8 bytes
  547|       |  // guarantees that op - src >= 8.
  548|       |  //
  549|       |  // Typically, the op_limit is the gating factor so try to simplify the loop
  550|       |  // based on that.
  551|  4.66k|  if (SNAPPY_PREDICT_TRUE(op_limit <= buf_limit - 15)) {
  ------------------
  |  |   95|  4.66k|#define SNAPPY_PREDICT_TRUE(x) (__builtin_expect(!!(x), 1))
  |  |  ------------------
  |  |  |  Branch (95:32): [True: 4.53k, False: 131]
  |  |  ------------------
  ------------------
  552|       |    // There is at least one, and at most four 16-byte blocks. Writing four
  553|       |    // conditionals instead of a loop allows FDO to layout the code with respect
  554|       |    // to the actual probabilities of each length.
  555|       |    // TODO: Replace with loop with trip count hint.
  556|  4.53k|    ConditionalUnalignedCopy128<use_16bytes_chunk>(src, op);
  557|  4.53k|    if (op + 16 < op_limit) {
  ------------------
  |  Branch (557:9): [True: 3.67k, False: 857]
  ------------------
  558|  3.67k|      ConditionalUnalignedCopy128<use_16bytes_chunk>(src + 16, op + 16);
  559|  3.67k|    }
  560|  4.53k|    if (op + 32 < op_limit) {
  ------------------
  |  Branch (560:9): [True: 3.65k, False: 876]
  ------------------
  561|  3.65k|      ConditionalUnalignedCopy128<use_16bytes_chunk>(src + 32, op + 32);
  562|  3.65k|    }
  563|  4.53k|    if (op + 48 < op_limit) {
  ------------------
  |  Branch (563:9): [True: 3.64k, False: 884]
  ------------------
  564|  3.64k|      ConditionalUnalignedCopy128<use_16bytes_chunk>(src + 48, op + 48);
  565|  3.64k|    }
  566|  4.53k|    return op_limit;
  567|  4.53k|  }
  568|       |
  569|       |  // Fall back to doing as much as we can with the available slop in the
  570|       |  // buffer. This code path is relatively cold however so we save code size by
  571|       |  // avoiding unrolling and vectorizing.
  572|       |  //
  573|       |  // TODO: Remove pragma when when cold regions don't get vectorized
  574|       |  // or unrolled.
  575|  4.66k|#ifdef __clang__
  576|  4.66k|#pragma clang loop unroll(disable)
  577|    131|#endif
  578|    196|  for (char* op_end = buf_limit - 16; op < op_end; op += 16, src += 16) {
  ------------------
  |  Branch (578:39): [True: 65, False: 131]
  ------------------
  579|     65|    ConditionalUnalignedCopy128<use_16bytes_chunk>(src, op);
  580|     65|  }
  581|    131|  if (op >= op_limit) return op_limit;
  ------------------
  |  Branch (581:7): [True: 17, False: 114]
  ------------------
  582|       |
  583|       |  // We only take this branch if we didn't have enough slop and we can do a
  584|       |  // single 8 byte copy.
  585|    114|  if (SNAPPY_PREDICT_FALSE(op <= buf_limit - 8)) {
  ------------------
  |  |   94|    114|#define SNAPPY_PREDICT_FALSE(x) (__builtin_expect(x, 0))
  |  |  ------------------
  |  |  |  Branch (94:33): [True: 69, False: 45]
  |  |  ------------------
  ------------------
  586|     69|    UnalignedCopy64(src, op);
  587|     69|    src += 8;
  588|     69|    op += 8;
  589|     69|  }
  590|    114|  return IncrementalCopySlow(src, op, op_limit);
  591|    131|}
snappy.cc:_ZN6snappy12_GLOBAL__N_115UnalignedCopy64EPKvPv:
  205|  42.7k|void UnalignedCopy64(const void* src, void* dst) {
  206|  42.7k|  char tmp[8];
  207|  42.7k|  std::memcpy(tmp, src, 8);
  208|  42.7k|  std::memcpy(dst, tmp, 8);
  209|  42.7k|}
snappy.cc:_ZN6snappy12_GLOBAL__N_119IncrementalCopySlowEPKcPcS3_:
  242|    164|                                 char* const op_limit) {
  243|       |  // TODO: Remove pragma when LLVM is aware this
  244|       |  // function is only called in cold regions and when cold regions don't get
  245|       |  // vectorized or unrolled.
  246|    164|#ifdef __clang__
  247|    164|#pragma clang loop unroll(disable)
  248|    164|#endif
  249|    408|  while (op < op_limit) {
  ------------------
  |  Branch (249:10): [True: 244, False: 164]
  ------------------
  250|    244|    *op++ = *src++;
  251|    244|  }
  252|    164|  return op_limit;
  253|    164|}
snappy.cc:_ZN6snappy12_GLOBAL__N_127ConditionalUnalignedCopy128ILb0EEEvPKcPc:
  221|  15.5k|inline void ConditionalUnalignedCopy128(const char* src, char* dst) {
  222|  15.5k|  if (use_16bytes_chunk) {
  ------------------
  |  Branch (222:7): [Folded - Ignored]
  ------------------
  223|      0|    UnalignedCopy128(src, dst);
  224|  15.5k|  } else {
  225|  15.5k|    UnalignedCopy64(src, dst);
  226|  15.5k|    UnalignedCopy64(src + 8, dst + 8);
  227|  15.5k|  }
  228|  15.5k|}
_ZNK6snappy18SnappyDecompressor3eofEv:
 1342|  1.15k|  bool eof() const { return eof_; }
snappy.cc:_ZN6snappyL18InternalUncompressINS_17SnappyArrayWriterEEEbPNS_6SourceEPT_:
 1580|  1.15k|static bool InternalUncompress(Source* r, Writer* writer) {
 1581|       |  // Read the uncompressed length from the front of the compressed input
 1582|  1.15k|  SnappyDecompressor decompressor(r);
 1583|  1.15k|  uint32_t uncompressed_len = 0;
 1584|  1.15k|  if (!decompressor.ReadUncompressedLength(&uncompressed_len)) return false;
  ------------------
  |  Branch (1584:7): [True: 0, False: 1.15k]
  ------------------
 1585|       |
 1586|  1.15k|  return InternalUncompressAllTags(&decompressor, writer, r->Available(),
 1587|  1.15k|                                   uncompressed_len);
 1588|  1.15k|}
snappy.cc:_ZN6snappyL25InternalUncompressAllTagsINS_17SnappyArrayWriterEEEbPNS_18SnappyDecompressorEPT_jj:
 1593|  1.15k|                                      uint32_t uncompressed_len) {
 1594|  1.15k|  Report("snappy_uncompress", compressed_len, uncompressed_len);
 1595|       |
 1596|  1.15k|  writer->SetExpectedLength(uncompressed_len);
 1597|       |
 1598|       |  // Process the entire input
 1599|  1.15k|  decompressor->DecompressAllTags(writer);
 1600|  1.15k|  writer->Flush();
 1601|  1.15k|  return (decompressor->eof() && writer->CheckLength());
  ------------------
  |  Branch (1601:11): [True: 337, False: 815]
  |  Branch (1601:34): [True: 14, False: 323]
  ------------------
 1602|  1.15k|}
_ZN6snappy17SnappyArrayWriter17SetExpectedLengthEm:
 1961|  1.15k|  inline void SetExpectedLength(size_t len) {
 1962|  1.15k|    op_limit_ = op_ + len;
 1963|       |    // Prevent pointer from being past the buffer.
 1964|  1.15k|    op_limit_min_slop_ = op_limit_ - std::min<size_t>(kSlopBytes - 1, len);
 1965|  1.15k|  }
_ZN6snappy18SnappyDecompressor17DecompressAllTagsINS_17SnappyArrayWriterEEEvPT_:
 1377|  1.15k|  DecompressAllTags(Writer* writer) {
 1378|  1.15k|    const char* ip = ip_;
 1379|  1.15k|    ResetLimit(ip);
 1380|  1.15k|    auto op = writer->GetOutputPtr();
 1381|       |    // We could have put this refill fragment only at the beginning of the loop.
 1382|       |    // However, duplicating it at the end of each branch gives the compiler more
 1383|       |    // scope to optimize the <ip_limit_ - ip> expression based on the local
 1384|       |    // context, which overall increases speed.
 1385|  1.15k|#define MAYBE_REFILL()                                      \
 1386|  1.15k|  if (SNAPPY_PREDICT_FALSE(ip >= ip_limit_min_maxtaglen_)) { \
 1387|  1.15k|    ip_ = ip;                                               \
 1388|  1.15k|    if (SNAPPY_PREDICT_FALSE(!RefillTag())) goto exit;       \
 1389|  1.15k|    ip = ip_;                                               \
 1390|  1.15k|    ResetLimit(ip);                                         \
 1391|  1.15k|  }                                                         \
 1392|  1.15k|  preload = static_cast<uint8_t>(*ip)
 1393|       |
 1394|       |    // At the start of the for loop below the least significant byte of preload
 1395|       |    // contains the tag.
 1396|  1.15k|    uint32_t preload;
 1397|  1.15k|    MAYBE_REFILL();
  ------------------
  |  | 1386|  1.15k|  if (SNAPPY_PREDICT_FALSE(ip >= ip_limit_min_maxtaglen_)) { \
  |  |  ------------------
  |  |  |  |   94|  1.15k|#define SNAPPY_PREDICT_FALSE(x) (__builtin_expect(x, 0))
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (94:33): [True: 1.15k, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  |  | 1387|  1.15k|    ip_ = ip;                                               \
  |  | 1388|  1.15k|    if (SNAPPY_PREDICT_FALSE(!RefillTag())) goto exit;       \
  |  |  ------------------
  |  |  |  |   94|  1.15k|#define SNAPPY_PREDICT_FALSE(x) (__builtin_expect(x, 0))
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (94:33): [True: 71, False: 1.08k]
  |  |  |  |  ------------------
  |  |  ------------------
  |  | 1389|  1.15k|    ip = ip_;                                               \
  |  | 1390|  1.08k|    ResetLimit(ip);                                         \
  |  | 1391|  1.08k|  }                                                         \
  |  | 1392|  1.15k|  preload = static_cast<uint8_t>(*ip)
  ------------------
 1398|  12.9k|    for (;;) {
 1399|  12.9k|      {
 1400|  12.9k|        ptrdiff_t op_limit_min_slop;
 1401|  12.9k|        auto op_base = writer->GetBase(&op_limit_min_slop);
 1402|  12.9k|        if (op_base) {
  ------------------
  |  Branch (1402:13): [True: 12.6k, False: 288]
  ------------------
 1403|  12.6k|          auto res =
 1404|  12.6k|              DecompressBranchless(reinterpret_cast<const uint8_t*>(ip),
 1405|  12.6k|                                   reinterpret_cast<const uint8_t*>(ip_limit_),
 1406|  12.6k|                                   op - op_base, op_base, op_limit_min_slop);
 1407|  12.6k|          ip = reinterpret_cast<const char*>(res.first);
 1408|  12.6k|          op = op_base + res.second;
 1409|  12.6k|          MAYBE_REFILL();
  ------------------
  |  | 1386|  12.6k|  if (SNAPPY_PREDICT_FALSE(ip >= ip_limit_min_maxtaglen_)) { \
  |  |  ------------------
  |  |  |  |   94|  12.6k|#define SNAPPY_PREDICT_FALSE(x) (__builtin_expect(x, 0))
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (94:33): [True: 476, False: 12.2k]
  |  |  |  |  ------------------
  |  |  ------------------
  |  | 1387|    476|    ip_ = ip;                                               \
  |  | 1388|    476|    if (SNAPPY_PREDICT_FALSE(!RefillTag())) goto exit;       \
  |  |  ------------------
  |  |  |  |   94|    476|#define SNAPPY_PREDICT_FALSE(x) (__builtin_expect(x, 0))
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (94:33): [True: 0, False: 476]
  |  |  |  |  ------------------
  |  |  ------------------
  |  | 1389|    476|    ip = ip_;                                               \
  |  | 1390|    476|    ResetLimit(ip);                                         \
  |  | 1391|    476|  }                                                         \
  |  | 1392|  12.6k|  preload = static_cast<uint8_t>(*ip)
  ------------------
 1410|  12.6k|        }
 1411|  12.9k|      }
 1412|  12.9k|      const uint8_t c = static_cast<uint8_t>(preload);
 1413|  12.9k|      ip++;
 1414|       |
 1415|       |      // Ratio of iterations that have LITERAL vs non-LITERAL for different
 1416|       |      // inputs.
 1417|       |      //
 1418|       |      // input          LITERAL  NON_LITERAL
 1419|       |      // -----------------------------------
 1420|       |      // html|html4|cp   23%        77%
 1421|       |      // urls            36%        64%
 1422|       |      // jpg             47%        53%
 1423|       |      // pdf             19%        81%
 1424|       |      // txt[1-4]        25%        75%
 1425|       |      // pb              24%        76%
 1426|       |      // bin             24%        76%
 1427|  12.9k|      if (SNAPPY_PREDICT_FALSE((c & 0x3) == LITERAL)) {
  ------------------
  |  |   94|  12.9k|#define SNAPPY_PREDICT_FALSE(x) (__builtin_expect(x, 0))
  |  |  ------------------
  |  |  |  Branch (94:33): [True: 5.43k, False: 7.54k]
  |  |  ------------------
  ------------------
 1428|  5.43k|        size_t literal_length = (c >> 2) + 1u;
 1429|  5.43k|        if (writer->TryFastAppend(ip, ip_limit_ - ip, literal_length, &op)) {
  ------------------
  |  Branch (1429:13): [True: 2.05k, False: 3.37k]
  ------------------
 1430|  2.05k|          assert(literal_length < 61);
 1431|      0|          ip += literal_length;
 1432|       |          // NOTE: There is no MAYBE_REFILL() here, as TryFastAppend()
 1433|       |          // will not return true unless there's already at least five spare
 1434|       |          // bytes in addition to the literal.
 1435|  2.05k|          preload = static_cast<uint8_t>(*ip);
 1436|  2.05k|          continue;
 1437|  2.05k|        }
 1438|  3.37k|        if (SNAPPY_PREDICT_FALSE(literal_length >= 61)) {
  ------------------
  |  |   94|  3.37k|#define SNAPPY_PREDICT_FALSE(x) (__builtin_expect(x, 0))
  |  |  ------------------
  |  |  |  Branch (94:33): [True: 2.40k, False: 979]
  |  |  ------------------
  ------------------
 1439|       |          // Long literal.
 1440|  2.40k|          const size_t literal_length_length = literal_length - 60;
 1441|  2.40k|          literal_length =
 1442|  2.40k|              ExtractLowBytes(LittleEndian::Load32(ip), literal_length_length) +
 1443|  2.40k|              1;
 1444|  2.40k|          ip += literal_length_length;
 1445|  2.40k|        }
 1446|       |
 1447|  3.37k|        size_t avail = ip_limit_ - ip;
 1448|  3.37k|        while (avail < literal_length) {
  ------------------
  |  Branch (1448:16): [True: 187, False: 3.19k]
  ------------------
 1449|    187|          if (!writer->Append(ip, avail, &op)) goto exit;
  ------------------
  |  Branch (1449:15): [True: 17, False: 170]
  ------------------
 1450|    170|          literal_length -= avail;
 1451|    170|          reader_->Skip(peeked_);
 1452|    170|          size_t n;
 1453|    170|          ip = reader_->Peek(&n);
 1454|    170|          avail = n;
 1455|    170|          peeked_ = avail;
 1456|    170|          if (avail == 0) goto exit;
  ------------------
  |  Branch (1456:15): [True: 170, False: 0]
  ------------------
 1457|      0|          ip_limit_ = ip + avail;
 1458|      0|          ResetLimit(ip);
 1459|      0|        }
 1460|  3.19k|        if (!writer->Append(ip, literal_length, &op)) goto exit;
  ------------------
  |  Branch (1460:13): [True: 49, False: 3.14k]
  ------------------
 1461|  3.14k|        ip += literal_length;
 1462|  3.14k|        MAYBE_REFILL();
  ------------------
  |  | 1386|  3.14k|  if (SNAPPY_PREDICT_FALSE(ip >= ip_limit_min_maxtaglen_)) { \
  |  |  ------------------
  |  |  |  |   94|  3.14k|#define SNAPPY_PREDICT_FALSE(x) (__builtin_expect(x, 0))
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (94:33): [True: 193, False: 2.95k]
  |  |  |  |  ------------------
  |  |  ------------------
  |  | 1387|    193|    ip_ = ip;                                               \
  |  | 1388|    193|    if (SNAPPY_PREDICT_FALSE(!RefillTag())) goto exit;       \
  |  |  ------------------
  |  |  |  |   94|    193|#define SNAPPY_PREDICT_FALSE(x) (__builtin_expect(x, 0))
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (94:33): [True: 59, False: 134]
  |  |  |  |  ------------------
  |  |  ------------------
  |  | 1389|    193|    ip = ip_;                                               \
  |  | 1390|    134|    ResetLimit(ip);                                         \
  |  | 1391|    134|  }                                                         \
  |  | 1392|  3.14k|  preload = static_cast<uint8_t>(*ip)
  ------------------
 1463|  7.54k|      } else {
 1464|  7.54k|        if (SNAPPY_PREDICT_FALSE((c & 3) == COPY_4_BYTE_OFFSET)) {
  ------------------
  |  |   94|  7.54k|#define SNAPPY_PREDICT_FALSE(x) (__builtin_expect(x, 0))
  |  |  ------------------
  |  |  |  Branch (94:33): [True: 1.50k, False: 6.03k]
  |  |  ------------------
  ------------------
 1465|  1.50k|          const size_t copy_offset = LittleEndian::Load32(ip);
 1466|  1.50k|          const size_t length = (c >> 2) + 1;
 1467|  1.50k|          ip += 4;
 1468|       |
 1469|  1.50k|          if (!writer->AppendFromSelf(copy_offset, length, &op)) goto exit;
  ------------------
  |  Branch (1469:15): [True: 227, False: 1.27k]
  ------------------
 1470|  6.03k|        } else {
 1471|  6.03k|          const ptrdiff_t entry = kLengthMinusOffset[c];
 1472|  6.03k|          preload = LittleEndian::Load32(ip);
 1473|  6.03k|          const uint32_t trailer = ExtractLowBytes(preload, c & 3);
 1474|  6.03k|          const uint32_t length = entry & 0xff;
 1475|  6.03k|          assert(length > 0);
 1476|       |
 1477|       |          // copy_offset/256 is encoded in bits 8..10.  By just fetching
 1478|       |          // those bits, we get copy_offset (since the bit-field starts at
 1479|       |          // bit 8).
 1480|      0|          const uint32_t copy_offset = trailer - entry + length;
 1481|  6.03k|          if (!writer->AppendFromSelf(copy_offset, length, &op)) goto exit;
  ------------------
  |  Branch (1481:15): [True: 324, False: 5.71k]
  ------------------
 1482|       |
 1483|  5.71k|          ip += (c & 3);
 1484|       |          // By using the result of the previous load we reduce the critical
 1485|       |          // dependency chain of ip to 4 cycles.
 1486|  5.71k|          preload >>= (c & 3) * 8;
 1487|  5.71k|          if (ip < ip_limit_min_maxtaglen_) continue;
  ------------------
  |  Branch (1487:15): [True: 5.35k, False: 355]
  ------------------
 1488|  5.71k|        }
 1489|  3.03k|        MAYBE_REFILL();
  ------------------
  |  | 1386|  1.63k|  if (SNAPPY_PREDICT_FALSE(ip >= ip_limit_min_maxtaglen_)) { \
  |  |  ------------------
  |  |  |  |   94|  1.63k|#define SNAPPY_PREDICT_FALSE(x) (__builtin_expect(x, 0))
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (94:33): [True: 437, False: 1.19k]
  |  |  |  |  ------------------
  |  |  ------------------
  |  | 1387|    437|    ip_ = ip;                                               \
  |  | 1388|    437|    if (SNAPPY_PREDICT_FALSE(!RefillTag())) goto exit;       \
  |  |  ------------------
  |  |  |  |   94|    437|#define SNAPPY_PREDICT_FALSE(x) (__builtin_expect(x, 0))
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (94:33): [True: 235, False: 202]
  |  |  |  |  ------------------
  |  |  ------------------
  |  | 1389|    437|    ip = ip_;                                               \
  |  | 1390|    202|    ResetLimit(ip);                                         \
  |  | 1391|    202|  }                                                         \
  |  | 1392|  1.63k|  preload = static_cast<uint8_t>(*ip)
  ------------------
 1490|  3.03k|      }
 1491|  12.9k|    }
 1492|      0|#undef MAYBE_REFILL
 1493|  1.15k|  exit:
 1494|  1.15k|    writer->SetOutputPtr(op);
 1495|  1.15k|  }
_ZN6snappy17SnappyArrayWriter12GetOutputPtrEv:
 1969|  1.15k|  char* GetOutputPtr() { return op_; }
_ZN6snappy17SnappyArrayWriter7GetBaseEPl:
 1970|  12.9k|  char* GetBase(ptrdiff_t* op_limit_min_slop) {
 1971|  12.9k|    *op_limit_min_slop = op_limit_min_slop_ - base_;
 1972|  12.9k|    return base_;
 1973|  12.9k|  }
_ZN6snappy17SnappyArrayWriter13TryFastAppendEPKcmmPPc:
 1986|  5.43k|                            char** op_p) {
 1987|  5.43k|    char* op = *op_p;
 1988|  5.43k|    const size_t space_left = op_limit_ - op;
 1989|  5.43k|    if (len <= 16 && available >= 16 + kMaximumTagLength && space_left >= 16) {
  ------------------
  |  Branch (1989:9): [True: 2.91k, False: 2.51k]
  |  Branch (1989:22): [True: 2.34k, False: 576]
  |  Branch (1989:61): [True: 2.05k, False: 291]
  ------------------
 1990|       |      // Fast path, used for the majority (about 95%) of invocations.
 1991|  2.05k|      UnalignedCopy128(ip, op);
 1992|  2.05k|      *op_p = op + len;
 1993|  2.05k|      return true;
 1994|  3.37k|    } else {
 1995|  3.37k|      return false;
 1996|  3.37k|    }
 1997|  5.43k|  }
_ZN6snappy17SnappyArrayWriter6AppendEPKcmPPc:
 1976|  3.37k|  inline bool Append(const char* ip, size_t len, char** op_p) {
 1977|  3.37k|    char* op = *op_p;
 1978|  3.37k|    const size_t space_left = op_limit_ - op;
 1979|  3.37k|    if (space_left < len) return false;
  ------------------
  |  Branch (1979:9): [True: 66, False: 3.31k]
  ------------------
 1980|  3.31k|    std::memcpy(op, ip, len);
 1981|  3.31k|    *op_p = op + len;
 1982|  3.31k|    return true;
 1983|  3.37k|  }
_ZN6snappy17SnappyArrayWriter14AppendFromSelfEmmPPc:
 2000|  7.54k|  inline bool AppendFromSelf(size_t offset, size_t len, char** op_p) {
 2001|  7.54k|    assert(len > 0);
 2002|      0|    char* const op = *op_p;
 2003|  7.54k|    assert(op >= base_);
 2004|      0|    char* const op_end = op + len;
 2005|       |
 2006|       |    // Check if we try to append from before the start of the buffer.
 2007|  7.54k|    if (SNAPPY_PREDICT_FALSE(static_cast<size_t>(op - base_) < offset))
  ------------------
  |  |   94|  7.54k|#define SNAPPY_PREDICT_FALSE(x) (__builtin_expect(x, 0))
  |  |  ------------------
  |  |  |  Branch (94:33): [True: 412, False: 7.13k]
  |  |  ------------------
  ------------------
 2008|    412|      return false;
 2009|       |
 2010|  7.13k|    if (SNAPPY_PREDICT_FALSE((kSlopBytes < 64 && len > kSlopBytes) ||
  ------------------
  |  |   94|  34.9k|#define SNAPPY_PREDICT_FALSE(x) (__builtin_expect(x, 0))
  |  |  ------------------
  |  |  |  Branch (94:33): [True: 5.75k, False: 1.37k]
  |  |  |  Branch (94:51): [Folded - Ignored]
  |  |  |  Branch (94:51): [True: 0, False: 0]
  |  |  |  Branch (94:51): [True: 680, False: 6.45k]
  |  |  |  Branch (94:51): [True: 5.07k, False: 1.37k]
  |  |  ------------------
  ------------------
 2011|  7.13k|                            op >= op_limit_min_slop_ || offset < len)) {
 2012|  5.75k|      if (op_end > op_limit_ || offset == 0) return false;
  ------------------
  |  Branch (2012:11): [True: 20, False: 5.73k]
  |  Branch (2012:33): [True: 119, False: 5.61k]
  ------------------
 2013|  5.61k|      *op_p = IncrementalCopy(op - offset, op, op_end, op_limit_);
 2014|  5.61k|      return true;
 2015|  5.75k|    }
 2016|  1.37k|    std::memmove(op, op - offset, kSlopBytes);
 2017|  1.37k|    *op_p = op_end;
 2018|  1.37k|    return true;
 2019|  7.13k|  }
_ZN6snappy17SnappyArrayWriter12SetOutputPtrEPc:
 1974|  1.15k|  void SetOutputPtr(char* op) { op_ = op; }
_ZN6snappy17SnappyArrayWriter5FlushEv:
 2024|  1.15k|  inline void Flush() {}
_ZNK6snappy17SnappyArrayWriter11CheckLengthEv:
 1967|    337|  inline bool CheckLength() const { return op_ == op_limit_; }

LLVMFuzzerTestOneInput:
   40|  1.23k|extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
   41|  1.23k|  std::string input(reinterpret_cast<const char*>(data), size);
   42|       |
   43|       |  // Avoid self-crafted decompression bombs.
   44|  1.23k|  size_t uncompressed_size;
   45|  1.23k|  constexpr size_t kMaxUncompressedSize = 1 << 20;
   46|  1.23k|  bool get_uncompressed_length_succeeded = snappy::GetUncompressedLength(
   47|  1.23k|      input.data(), input.size(), &uncompressed_size);
   48|  1.23k|  if (!get_uncompressed_length_succeeded ||
  ------------------
  |  Branch (48:7): [True: 61, False: 1.17k]
  ------------------
   49|  1.23k|      (uncompressed_size > kMaxUncompressedSize)) {
  ------------------
  |  Branch (49:7): [True: 19, False: 1.15k]
  ------------------
   50|     80|    return 0;
   51|     80|  }
   52|       |
   53|  1.15k|  std::string uncompressed;
   54|       |  // The return value of snappy::Uncompress() is ignored because decompression
   55|       |  // will fail on invalid inputs.
   56|  1.15k|  snappy::Uncompress(input.data(), input.size(), &uncompressed);
   57|  1.15k|  return 0;
   58|  1.23k|}

