LLVMFuzzerTestOneInput:
   19|    689|extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
   20|       |
   21|       |  // since this check is expensive, only do it once
   22|    689|  static const auto implementations=get_runtime_supported_implementations();
   23|       |
   24|    689|    using Buffer=std::vector<uint8_t>;
   25|    689|    auto minify=[Data,Size](const simdjson::implementation* impl) -> Buffer {
   26|    689|        Buffer ret(Size);
   27|    689|        std::size_t retsize=0;
   28|    689|        auto err=impl->minify(Data,Size,ret.data(),retsize);
   29|    689|        if(err) {
   30|    689|            std::string tmp = error_message(err);
   31|    689|            ret.assign(tmp.begin(),tmp.end());
   32|    689|        } else {
   33|    689|            assert(retsize<=Size && "size should not grow by minimize()!");
   34|    689|            ret.resize(retsize);
   35|    689|        }
   36|    689|        return ret;
   37|    689|    };
   38|       |
   39|    689|    auto const first = implementations.begin();
   40|    689|    auto const last = implementations.end();
   41|       |
   42|    689|    const auto reference=minify(*first);
   43|       |
   44|    689|    bool failed=false;
   45|  2.06k|    for(auto it=first+1;it != last; ++it) {
  ------------------
  |  Branch (45:25): [True: 1.37k, False: 689]
  ------------------
   46|  1.37k|        const auto current=minify(*it);
   47|  1.37k|        if(current!=reference) {
  ------------------
  |  Branch (47:12): [True: 0, False: 1.37k]
  ------------------
   48|      0|            failed=true;
   49|      0|        }
   50|  1.37k|    }
   51|       |
   52|    689|    if(failed) {
  ------------------
  |  Branch (52:8): [True: 0, False: 689]
  ------------------
   53|      0|        std::cerr<<std::boolalpha<<"Mismatch between implementations of minify() found:\n";
   54|      0|        for(const auto& e:implementations) {
  ------------------
  |  Branch (54:26): [True: 0, False: 0]
  ------------------
   55|      0|            const auto current=minify(e);
   56|      0|            std::string tmp(current.begin(),current.end());
   57|      0|            std::cerr<<e->name()<<" returns "<<tmp<<std::endl;
   58|      0|        }
   59|      0|        std::abort();
   60|      0|    }
   61|       |
   62|       |    //all is well
   63|    689|    return 0;
   64|    689|}
fuzz_minifyimpl.cpp:_ZZ22LLVMFuzzerTestOneInputENK3$_0clEPKN8simdjson14implementationE:
   25|  2.06k|    auto minify=[Data,Size](const simdjson::implementation* impl) -> Buffer {
   26|  2.06k|        Buffer ret(Size);
   27|  2.06k|        std::size_t retsize=0;
   28|  2.06k|        auto err=impl->minify(Data,Size,ret.data(),retsize);
   29|  2.06k|        if(err) {
  ------------------
  |  Branch (29:12): [True: 393, False: 1.67k]
  ------------------
   30|    393|            std::string tmp = error_message(err);
   31|    393|            ret.assign(tmp.begin(),tmp.end());
   32|  1.67k|        } else {
   33|  1.67k|            assert(retsize<=Size && "size should not grow by minimize()!");
   34|  1.67k|            ret.resize(retsize);
   35|  1.67k|        }
   36|  2.06k|        return ret;
   37|  2.06k|    };

_Z37get_runtime_supported_implementationsv:
   18|      1|get_runtime_supported_implementations() {
   19|      1|    std::vector<const simdjson::implementation*> ret;
   20|      4|    for(auto& e: simdjson::get_available_implementations()) {
  ------------------
  |  Branch (20:16): [True: 4, False: 1]
  ------------------
   21|      4|        if(e->supported_by_runtime_system()) {
  ------------------
  |  Branch (21:12): [True: 3, False: 1]
  ------------------
   22|      3|            ret.emplace_back(e);
   23|      3|        }
   24|      4|    }
   25|      1|    if(ret.empty()) {
  ------------------
  |  Branch (25:8): [True: 0, False: 1]
  ------------------
   26|       |        // No implementations available, not even fallback, weird.
   27|      0|        std::abort();
   28|      0|    }
   29|      1|    return ret;
   30|      1|}

_ZN8simdjson13error_messageENS_10error_codeE:
   25|    393|inline const char *error_message(error_code error) noexcept {
   26|       |  // If you're using error_code, we're trusting you got it from the enum.
   27|    393|  return internal::error_codes[int(error)].message;
   28|    393|}

_ZN8simdjson8fallback14implementationC2Ev:
   17|      1|  simdjson_inline implementation() : simdjson::implementation(
   18|      1|      "fallback",
   19|      1|      "Generic fallback implementation",
   20|      1|      0
   21|      1|  ) {}

simdjson.cpp:_ZN8simdjson7haswell12_GLOBAL__N_110count_onesEm:
   51|  1.90M|simdjson_inline long long int count_ones(uint64_t input_num) {
   52|  1.90M|  return _popcnt64(input_num);
   53|  1.90M|}

simdjson.cpp:_ZN8simdjson7haswell12_GLOBAL__N_110prefix_xorEm:
   18|   476k|simdjson_inline uint64_t prefix_xor(const uint64_t bitmask) {
   19|       |  // There should be no such thing with a processor supporting avx2
   20|       |  // but not clmul.
   21|   476k|  __m128i all_ones = _mm_set1_epi8('\xFF');
   22|   476k|  __m128i result = _mm_clmulepi64_si128(_mm_set_epi64x(0ULL, bitmask), all_ones, 0);
   23|   476k|  return _mm_cvtsi128_si64(result);
   24|   476k|}

_ZN8simdjson7haswell14implementationC2Ev:
   19|      1|  simdjson_inline implementation() : simdjson::implementation(
   20|      1|      "haswell",
   21|      1|      "Intel/AMD AVX2",
   22|      1|      internal::instruction_set::AVX2 | internal::instruction_set::PCLMULQDQ | internal::instruction_set::BMI1 | internal::instruction_set::BMI2
   23|      1|  ) {}

simdjson.cpp:_ZN8simdjson7haswell12_GLOBAL__N_14simd8simd8x64IhEC2EPKh:
  309|   476k|    simdjson_inline simd8x64(const T ptr[64]) : chunks{simd8<T>::load(ptr), simd8<T>::load(ptr+32)} {}
simdjson.cpp:_ZN8simdjson7haswell12_GLOBAL__N_14simd13base8_numericIhE4loadEPKh:
   82|   953k|    static simdjson_inline simd8<T> load(const T values[32]) {
   83|   953k|      return _mm256_loadu_si256(reinterpret_cast<const __m256i *>(values));
   84|   953k|    }
simdjson.cpp:_ZN8simdjson7haswell12_GLOBAL__N_14simd5simd8IhEC2EDv4_x:
  232|  6.67M|    simdjson_inline simd8(const __m256i _value) : base8_numeric<uint8_t>(_value) {}
simdjson.cpp:_ZN8simdjson7haswell12_GLOBAL__N_14simd13base8_numericIhEC2EDv4_x:
   99|  6.67M|    simdjson_inline base8_numeric(const __m256i _value) : base8<T>(_value) {}
simdjson.cpp:_ZN8simdjson7haswell12_GLOBAL__N_14simd5base8IhNS2_5simd8IbEEEC2EDv4_x:
   51|  6.67M|    simdjson_inline base8(const __m256i _value) : base<simd8<T>>(_value) {}
simdjson.cpp:_ZN8simdjson7haswell12_GLOBAL__N_14simd4baseINS2_5simd8IhEEEC2EDv4_x:
   25|  6.67M|    simdjson_inline base(const __m256i _value) : value(_value) {}
simdjson.cpp:_ZNK8simdjson7haswell12_GLOBAL__N_14simd4baseINS2_5simd8IhEEEorES5_:
   32|   953k|    simdjson_inline Child operator|(const Child other) const { return _mm256_or_si256(*this, other); }
simdjson.cpp:_ZNK8simdjson7haswell12_GLOBAL__N_14simd4baseINS2_5simd8IhEEEcvRKDv4_xEv:
   28|  14.2M|    simdjson_inline operator const __m256i&() const { return this->value; }
simdjson.cpp:_ZN8simdjson7haswell12_GLOBAL__N_14simd5simd8IhE9repeat_16Ehhhhhhhhhhhhhhhh:
  253|   953k|    ) {
  254|   953k|      return simd8<uint8_t>(
  255|   953k|        v0, v1, v2, v3, v4, v5, v6, v7,
  256|   953k|        v8, v9, v10,v11,v12,v13,v14,v15,
  257|   953k|        v0, v1, v2, v3, v4, v5, v6, v7,
  258|   953k|        v8, v9, v10,v11,v12,v13,v14,v15
  259|   953k|      );
  260|   953k|    }
simdjson.cpp:_ZN8simdjson7haswell12_GLOBAL__N_14simd5simd8IhEC2Ehhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh:
  243|   953k|    ) : simd8(_mm256_setr_epi8(
  244|   953k|      v0, v1, v2, v3, v4, v5, v6, v7,
  245|   953k|      v8, v9, v10,v11,v12,v13,v14,v15,
  246|   953k|      v16,v17,v18,v19,v20,v21,v22,v23,
  247|   953k|      v24,v25,v26,v27,v28,v29,v30,v31
  248|   953k|    )) {}
simdjson.cpp:_ZN8simdjson7haswell12_GLOBAL__N_14simd5simd8IhEC2Eh:
  234|   953k|    simdjson_inline simd8(uint8_t _value) : simd8(splat(_value)) {}
simdjson.cpp:_ZN8simdjson7haswell12_GLOBAL__N_14simd13base8_numericIhE5splatEh:
   80|  1.90M|    static simdjson_inline simd8<T> splat(T _value) { return _mm256_set1_epi8(_value); }
simdjson.cpp:_ZN8simdjson7haswell12_GLOBAL__N_14simdeqENS2_5simd8IhEES4_:
   53|  3.81M|    friend simdjson_really_inline Mask operator==(const simd8<T> lhs, const simd8<T> rhs) { return _mm256_cmpeq_epi8(lhs, rhs); }
simdjson.cpp:_ZN8simdjson7haswell12_GLOBAL__N_14simd5simd8IbEC2EDv4_x:
   69|  3.81M|    simdjson_inline simd8(const __m256i _value) : base8<bool>(_value) {}
simdjson.cpp:_ZN8simdjson7haswell12_GLOBAL__N_14simd5base8IbNS2_5simd8IbEEEC2EDv4_x:
   51|  3.81M|    simdjson_inline base8(const __m256i _value) : base<simd8<T>>(_value) {}
simdjson.cpp:_ZN8simdjson7haswell12_GLOBAL__N_14simd4baseINS2_5simd8IbEEEC2EDv4_x:
   25|  3.81M|    simdjson_inline base(const __m256i _value) : value(_value) {}
simdjson.cpp:_ZNK8simdjson7haswell12_GLOBAL__N_14simd5simd8IbE10to_bitmaskEv:
   73|  3.81M|    simdjson_inline int to_bitmask() const { return _mm256_movemask_epi8(*this); }
simdjson.cpp:_ZNK8simdjson7haswell12_GLOBAL__N_14simd4baseINS2_5simd8IbEEEcvRKDv4_xEv:
   28|  3.81M|    simdjson_inline operator const __m256i&() const { return this->value; }
simdjson.cpp:_ZNK8simdjson7haswell12_GLOBAL__N_14simd8simd8x64IhE2eqEh:
  342|   953k|    simdjson_inline uint64_t eq(const T m) const {
  343|   953k|      const simd8<T> mask = simd8<T>::splat(m);
  344|   953k|      return  simd8x64<bool>(
  345|   953k|        this->chunks[0] == mask,
  346|   953k|        this->chunks[1] == mask
  347|   953k|      ).to_bitmask();
  348|   953k|    }
simdjson.cpp:_ZN8simdjson7haswell12_GLOBAL__N_14simd8simd8x64IbEC2ENS2_5simd8IbEES6_:
  308|  1.90M|    simdjson_inline simd8x64(const simd8<T> chunk0, const simd8<T> chunk1) : chunks{chunk0, chunk1} {}
simdjson.cpp:_ZNK8simdjson7haswell12_GLOBAL__N_14simd8simd8x64IbE10to_bitmaskEv:
  324|  1.90M|    simdjson_inline uint64_t to_bitmask() const {
  325|  1.90M|      uint64_t r_lo = uint32_t(this->chunks[0].to_bitmask());
  326|  1.90M|      uint64_t r_hi =                       this->chunks[1].to_bitmask();
  327|  1.90M|      return r_lo | (r_hi << 32);
  328|  1.90M|    }
simdjson.cpp:_ZNK8simdjson7haswell12_GLOBAL__N_14simd8simd8x64IhE2eqERKS4_:
  350|   953k|    simdjson_inline uint64_t eq(const simd8x64<uint8_t> &other) const {
  351|   953k|      return  simd8x64<bool>(
  352|   953k|        this->chunks[0] == other.chunks[0],
  353|   953k|        this->chunks[1] == other.chunks[1]
  354|   953k|      ).to_bitmask();
  355|   953k|    }
simdjson.cpp:_ZN8simdjson7haswell12_GLOBAL__N_14simd8simd8x64IhEC2ENS2_5simd8IhEES6_:
  308|  1.42M|    simdjson_inline simd8x64(const simd8<T> chunk0, const simd8<T> chunk1) : chunks{chunk0, chunk1} {}
simdjson.cpp:_ZNK8simdjson7haswell12_GLOBAL__N_14simd8simd8x64IhE8compressEmPh:
  311|   476k|    simdjson_inline uint64_t compress(uint64_t mask, T * output) const {
  312|   476k|      uint32_t mask1 = uint32_t(mask);
  313|   476k|      uint32_t mask2 = uint32_t(mask >> 32);
  314|   476k|      this->chunks[0].compress(mask1, output);
  315|   476k|      this->chunks[1].compress(mask2, output + 32 - count_ones(mask1));
  316|   476k|      return 64 - count_ones(mask);
  317|   476k|    }
simdjson.cpp:_ZNK8simdjson7haswell12_GLOBAL__N_14simd13base8_numericIhE8compressIhEEvjPT_:
  127|   953k|    simdjson_inline void compress(uint32_t mask, L * output) const {
  128|   953k|      using internal::thintable_epi8;
  129|   953k|      using internal::BitsSetTable256mul2;
  130|   953k|      using internal::pshufb_combine_table;
  131|       |      // this particular implementation was inspired by work done by @animetosho
  132|       |      // we do it in four steps, first 8 bytes and then second 8 bytes...
  133|   953k|      uint8_t mask1 = uint8_t(mask); // least significant 8 bits
  134|   953k|      uint8_t mask2 = uint8_t(mask >> 8); // second least significant 8 bits
  135|   953k|      uint8_t mask3 = uint8_t(mask >> 16); // ...
  136|   953k|      uint8_t mask4 = uint8_t(mask >> 24); // ...
  137|       |      // next line just loads the 64-bit values thintable_epi8[mask1] and
  138|       |      // thintable_epi8[mask2] into a 128-bit register, using only
  139|       |      // two instructions on most compilers.
  140|   953k|      __m256i shufmask =  _mm256_set_epi64x(thintable_epi8[mask4], thintable_epi8[mask3],
  141|   953k|        thintable_epi8[mask2], thintable_epi8[mask1]);
  142|       |      // we increment by 0x08 the second half of the mask and so forth
  143|   953k|      shufmask =
  144|   953k|      _mm256_add_epi8(shufmask, _mm256_set_epi32(0x18181818, 0x18181818,
  145|   953k|         0x10101010, 0x10101010, 0x08080808, 0x08080808, 0, 0));
  146|       |      // this is the version "nearly pruned"
  147|   953k|      __m256i pruned = _mm256_shuffle_epi8(*this, shufmask);
  148|       |      // we still need to put the  pieces back together.
  149|       |      // we compute the popcount of the first words:
  150|   953k|      int pop1 = BitsSetTable256mul2[mask1];
  151|   953k|      int pop3 = BitsSetTable256mul2[mask3];
  152|       |
  153|       |      // then load the corresponding mask
  154|       |      // could be done with _mm256_loadu2_m128i but many standard libraries omit this intrinsic.
  155|   953k|      __m256i v256 = _mm256_castsi128_si256(
  156|   953k|        _mm_loadu_si128(reinterpret_cast<const __m128i *>(pshufb_combine_table + pop1 * 8)));
  157|   953k|      __m256i compactmask = _mm256_insertf128_si256(v256,
  158|   953k|         _mm_loadu_si128(reinterpret_cast<const __m128i *>(pshufb_combine_table + pop3 * 8)), 1);
  159|   953k|      __m256i almostthere =  _mm256_shuffle_epi8(pruned, compactmask);
  160|       |      // We just need to write out the result.
  161|       |      // This is the tricky bit that is hard to do
  162|       |      // if we want to return a SIMD register, since there
  163|       |      // is no single-instruction approach to recombine
  164|       |      // the two 128-bit lanes with an offset.
  165|   953k|      __m128i v128;
  166|   953k|      v128 = _mm256_castsi256_si128(almostthere);
  167|   953k|      _mm_storeu_si128( reinterpret_cast<__m128i *>(output), v128);
  168|   953k|      v128 = _mm256_extractf128_si256(almostthere, 1);
  169|   953k|      _mm_storeu_si128( reinterpret_cast<__m128i *>(output + 16 - count_ones(mask & 0xFFFF)), v128);
  170|   953k|    }

_ZN8simdjson7icelake14implementationC2Ev:
   19|      1|  simdjson_inline implementation() : simdjson::implementation(
   20|      1|      "icelake",
   21|      1|      "Intel/AMD AVX512",
   22|      1|      internal::instruction_set::AVX2 | internal::instruction_set::PCLMULQDQ | internal::instruction_set::BMI1 | internal::instruction_set::BMI2 | internal::instruction_set::AVX512F | internal::instruction_set::AVX512DQ | internal::instruction_set::AVX512CD | internal::instruction_set::AVX512BW | internal::instruction_set::AVX512VL | internal::instruction_set::AVX512VBMI2
   23|      1|  ) {}

_ZNK8simdjson14implementation25required_instruction_setsEv:
   84|      4|  virtual uint32_t required_instruction_sets() const { return _required_instruction_sets; }
_ZN8simdjson14implementationC2ENSt3__117basic_string_viewIcNS1_11char_traitsIcEEEES5_j:
  137|      4|    _name(name),
  138|      4|    _description(description),
  139|      4|    _required_instruction_sets(required_instruction_sets)
  140|      4|  {
  141|      4|  }
_ZN8simdjson8internal29available_implementation_listC2Ev:
  171|      1|  simdjson_inline available_implementation_list() {}

simdjson.cpp:_ZN8simdjson8westmere12_GLOBAL__N_110count_onesEm:
   59|  1.90M|simdjson_inline long long int count_ones(uint64_t input_num) {
   60|  1.90M|  return _popcnt64(input_num);
   61|  1.90M|}

simdjson.cpp:_ZN8simdjson8westmere12_GLOBAL__N_110prefix_xorEm:
   18|   476k|simdjson_inline uint64_t prefix_xor(const uint64_t bitmask) {
   19|       |  // There should be no such thing with a processing supporting avx2
   20|       |  // but not clmul.
   21|   476k|  __m128i all_ones = _mm_set1_epi8('\xFF');
   22|   476k|  __m128i result = _mm_clmulepi64_si128(_mm_set_epi64x(0ULL, bitmask), all_ones, 0);
   23|   476k|  return _mm_cvtsi128_si64(result);
   24|   476k|}

_ZN8simdjson8westmere14implementationC2Ev:
   19|      1|  simdjson_inline implementation() : simdjson::implementation("westmere", "Intel/AMD SSE4.2", internal::instruction_set::SSE42 | internal::instruction_set::PCLMULQDQ) {}

simdjson.cpp:_ZN8simdjson8westmere12_GLOBAL__N_14simd8simd8x64IhEC2EPKh:
  274|   952k|    simdjson_inline simd8x64(const T ptr[64]) : chunks{simd8<T>::load(ptr), simd8<T>::load(ptr+16), simd8<T>::load(ptr+32), simd8<T>::load(ptr+48)} {}
simdjson.cpp:_ZN8simdjson8westmere12_GLOBAL__N_14simd13base8_numericIhE4loadEPKh:
   76|  3.80M|    static simdjson_inline simd8<T> load(const T values[16]) {
   77|  3.80M|      return _mm_loadu_si128(reinterpret_cast<const __m128i *>(values));
   78|  3.80M|    }
simdjson.cpp:_ZN8simdjson8westmere12_GLOBAL__N_14simd5simd8IhEC2EDv2_x:
  203|  13.3M|    simdjson_inline simd8(const __m128i _value) : base8_numeric<uint8_t>(_value) {}
simdjson.cpp:_ZN8simdjson8westmere12_GLOBAL__N_14simd13base8_numericIhEC2EDv2_x:
   91|  13.3M|    simdjson_inline base8_numeric(const __m128i _value) : base8<T>(_value) {}
simdjson.cpp:_ZN8simdjson8westmere12_GLOBAL__N_14simd5base8IhNS2_5simd8IbEEEC2EDv2_x:
   45|  13.3M|    simdjson_inline base8(const __m128i _value) : base<simd8<T>>(_value) {}
simdjson.cpp:_ZN8simdjson8westmere12_GLOBAL__N_14simd4baseINS2_5simd8IhEEEC2EDv2_x:
   23|  13.3M|    simdjson_inline base(const __m128i _value) : value(_value) {}
simdjson.cpp:_ZNK8simdjson8westmere12_GLOBAL__N_14simd4baseINS2_5simd8IhEEEorES5_:
   30|  1.90M|    simdjson_inline Child operator|(const Child other) const { return _mm_or_si128(*this, other); }
simdjson.cpp:_ZNK8simdjson8westmere12_GLOBAL__N_14simd4baseINS2_5simd8IhEEEcvRKDv2_xEv:
   26|  26.6M|    simdjson_inline operator const __m128i&() const { return this->value; }
simdjson.cpp:_ZN8simdjson8westmere12_GLOBAL__N_14simd4baseINS2_5simd8IhEEEcvRDv2_xEv:
   27|  1.90M|    simdjson_inline operator __m128i&() { return this->value; }
simdjson.cpp:_ZN8simdjson8westmere12_GLOBAL__N_14simd5simd8IhE9repeat_16Ehhhhhhhhhhhhhhhh:
  220|   952k|    ) {
  221|   952k|      return simd8<uint8_t>(
  222|   952k|        v0, v1, v2, v3, v4, v5, v6, v7,
  223|   952k|        v8, v9, v10,v11,v12,v13,v14,v15
  224|   952k|      );
  225|   952k|    }
simdjson.cpp:_ZN8simdjson8westmere12_GLOBAL__N_14simd5simd8IhEC2Ehhhhhhhhhhhhhhhh:
  212|   952k|    ) : simd8(_mm_setr_epi8(
  213|   952k|      v0, v1, v2, v3, v4, v5, v6, v7,
  214|   952k|      v8, v9, v10,v11,v12,v13,v14,v15
  215|   952k|    )) {}
simdjson.cpp:_ZN8simdjson8westmere12_GLOBAL__N_14simd5simd8IhEC2Eh:
  205|  1.90M|    simdjson_inline simd8(uint8_t _value) : simd8(splat(_value)) {}
simdjson.cpp:_ZN8simdjson8westmere12_GLOBAL__N_14simd13base8_numericIhE5splatEh:
   74|  2.85M|    static simdjson_inline simd8<T> splat(T _value) { return _mm_set1_epi8(_value); }
simdjson.cpp:_ZN8simdjson8westmere12_GLOBAL__N_14simdeqENS2_5simd8IhEES4_:
   47|  7.61M|    friend simdjson_inline Mask operator==(const simd8<T> lhs, const simd8<T> rhs) { return _mm_cmpeq_epi8(lhs, rhs); }
simdjson.cpp:_ZN8simdjson8westmere12_GLOBAL__N_14simd5simd8IbEC2EDv2_x:
   63|  7.61M|    simdjson_inline simd8(const __m128i _value) : base8<bool>(_value) {}
simdjson.cpp:_ZN8simdjson8westmere12_GLOBAL__N_14simd5base8IbNS2_5simd8IbEEEC2EDv2_x:
   45|  7.61M|    simdjson_inline base8(const __m128i _value) : base<simd8<T>>(_value) {}
simdjson.cpp:_ZN8simdjson8westmere12_GLOBAL__N_14simd4baseINS2_5simd8IbEEEC2EDv2_x:
   23|  7.61M|    simdjson_inline base(const __m128i _value) : value(_value) {}
simdjson.cpp:_ZN8simdjson8westmere12_GLOBAL__N_14simd8simd8x64IbEC2ENS2_5simd8IbEES6_S6_S6_:
  273|  1.90M|    simdjson_inline simd8x64(const simd8<T> chunk0, const simd8<T> chunk1, const simd8<T> chunk2, const simd8<T> chunk3) : chunks{chunk0, chunk1, chunk2, chunk3} {}
simdjson.cpp:_ZNK8simdjson8westmere12_GLOBAL__N_14simd8simd8x64IbE10to_bitmaskEv:
  295|  1.90M|    simdjson_inline uint64_t to_bitmask() const {
  296|  1.90M|      uint64_t r0 = uint32_t(this->chunks[0].to_bitmask() );
  297|  1.90M|      uint64_t r1 =          this->chunks[1].to_bitmask() ;
  298|  1.90M|      uint64_t r2 =          this->chunks[2].to_bitmask() ;
  299|  1.90M|      uint64_t r3 =          this->chunks[3].to_bitmask() ;
  300|  1.90M|      return r0 | (r1 << 16) | (r2 << 32) | (r3 << 48);
  301|  1.90M|    }
simdjson.cpp:_ZNK8simdjson8westmere12_GLOBAL__N_14simd5simd8IbE10to_bitmaskEv:
   67|  7.61M|    simdjson_inline int to_bitmask() const { return _mm_movemask_epi8(*this); }
simdjson.cpp:_ZNK8simdjson8westmere12_GLOBAL__N_14simd4baseINS2_5simd8IbEEEcvRKDv2_xEv:
   26|  7.61M|    simdjson_inline operator const __m128i&() const { return this->value; }
simdjson.cpp:_ZNK8simdjson8westmere12_GLOBAL__N_14simd8simd8x64IhE2eqEh:
  303|   952k|    simdjson_inline uint64_t eq(const T m) const {
  304|   952k|      const simd8<T> mask = simd8<T>::splat(m);
  305|   952k|      return  simd8x64<bool>(
  306|   952k|        this->chunks[0] == mask,
  307|   952k|        this->chunks[1] == mask,
  308|   952k|        this->chunks[2] == mask,
  309|   952k|        this->chunks[3] == mask
  310|   952k|      ).to_bitmask();
  311|   952k|    }
simdjson.cpp:_ZNK8simdjson8westmere12_GLOBAL__N_14simd8simd8x64IhE2eqERKS4_:
  313|   952k|    simdjson_inline uint64_t eq(const simd8x64<uint8_t> &other) const {
  314|   952k|      return  simd8x64<bool>(
  315|   952k|        this->chunks[0] == other.chunks[0],
  316|   952k|        this->chunks[1] == other.chunks[1],
  317|   952k|        this->chunks[2] == other.chunks[2],
  318|   952k|        this->chunks[3] == other.chunks[3]
  319|   952k|      ).to_bitmask();
  320|   952k|    }
simdjson.cpp:_ZN8simdjson8westmere12_GLOBAL__N_14simd8simd8x64IhEC2ENS2_5simd8IhEES6_S6_S6_:
  273|  1.42M|    simdjson_inline simd8x64(const simd8<T> chunk0, const simd8<T> chunk1, const simd8<T> chunk2, const simd8<T> chunk3) : chunks{chunk0, chunk1, chunk2, chunk3} {}
simdjson.cpp:_ZNK8simdjson8westmere12_GLOBAL__N_14simd8simd8x64IhE8compressEmPh:
  287|   476k|    simdjson_inline uint64_t compress(uint64_t mask, T * output) const {
  288|   476k|      this->chunks[0].compress(uint16_t(mask), output);
  289|   476k|      this->chunks[1].compress(uint16_t(mask >> 16), output + 16 - count_ones(mask & 0xFFFF));
  290|   476k|      this->chunks[2].compress(uint16_t(mask >> 32), output + 32 - count_ones(mask & 0xFFFFFFFF));
  291|   476k|      this->chunks[3].compress(uint16_t(mask >> 48), output + 48 - count_ones(mask & 0xFFFFFFFFFFFF));
  292|   476k|      return 64 - count_ones(mask);
  293|   476k|    }
simdjson.cpp:_ZNK8simdjson8westmere12_GLOBAL__N_14simd13base8_numericIhE8compressIhEEvtPT_:
  119|  1.90M|    simdjson_inline void compress(uint16_t mask, L * output) const {
  120|  1.90M|      using internal::thintable_epi8;
  121|  1.90M|      using internal::BitsSetTable256mul2;
  122|  1.90M|      using internal::pshufb_combine_table;
  123|       |      // this particular implementation was inspired by work done by @animetosho
  124|       |      // we do it in two steps, first 8 bytes and then second 8 bytes
  125|  1.90M|      uint8_t mask1 = uint8_t(mask); // least significant 8 bits
  126|  1.90M|      uint8_t mask2 = uint8_t(mask >> 8); // most significant 8 bits
  127|       |      // next line just loads the 64-bit values thintable_epi8[mask1] and
  128|       |      // thintable_epi8[mask2] into a 128-bit register, using only
  129|       |      // two instructions on most compilers.
  130|  1.90M|      __m128i shufmask =  _mm_set_epi64x(thintable_epi8[mask2], thintable_epi8[mask1]);
  131|       |      // we increment by 0x08 the second half of the mask
  132|  1.90M|      shufmask =
  133|  1.90M|      _mm_add_epi8(shufmask, _mm_set_epi32(0x08080808, 0x08080808, 0, 0));
  134|       |      // this is the version "nearly pruned"
  135|  1.90M|      __m128i pruned = _mm_shuffle_epi8(*this, shufmask);
  136|       |      // we still need to put the two halves together.
  137|       |      // we compute the popcount of the first half:
  138|  1.90M|      int pop1 = BitsSetTable256mul2[mask1];
  139|       |      // then load the corresponding mask, what it does is to write
  140|       |      // only the first pop1 bytes from the first 8 bytes, and then
  141|       |      // it fills in with the bytes from the second 8 bytes + some filling
  142|       |      // at the end.
  143|  1.90M|      __m128i compactmask =
  144|  1.90M|      _mm_loadu_si128(reinterpret_cast<const __m128i *>(pshufb_combine_table + pop1 * 8));
  145|  1.90M|      __m128i answer = _mm_shuffle_epi8(pruned, compactmask);
  146|  1.90M|      _mm_storeu_si128(reinterpret_cast<__m128i *>(output), answer);
  147|  1.90M|    }

_ZNK8simdjson8fallback14implementation6minifyEPKhmPhRm:
  289|    689|simdjson_warn_unused error_code implementation::minify(const uint8_t *buf, size_t len, uint8_t *dst, size_t &dst_len) const noexcept {
  290|    689|  size_t i = 0, pos = 0;
  291|    689|  uint8_t quote = 0;
  292|    689|  uint8_t nonescape = 1;
  293|       |
  294|  30.4M|  while (i < len) {
  ------------------
  |  Branch (294:10): [True: 30.4M, False: 689]
  ------------------
  295|  30.4M|    unsigned char c = buf[i];
  296|  30.4M|    uint8_t *meta = jump_table + 3 * c;
  297|       |
  298|  30.4M|    quote = quote ^ (meta[0] & nonescape);
  299|  30.4M|    dst[pos] = c;
  300|  30.4M|    pos += meta[2] | quote;
  301|       |
  302|  30.4M|    i += 1;
  303|  30.4M|    nonescape = uint8_t(~nonescape) | (meta[1]);
  304|  30.4M|  }
  305|    689|  dst_len = pos; // we intentionally do not work with a reference
  306|       |  // for fear of aliasing
  307|    689|  return quote ? UNCLOSED_STRING : SUCCESS;
  ------------------
  |  Branch (307:10): [True: 131, False: 558]
  ------------------
  308|    689|}

simdjson.cpp:_ZNK8simdjson7haswell12_GLOBAL__N_120json_character_block6scalarEv:
   17|   476k|  simdjson_inline uint64_t scalar() const noexcept { return ~(op() | whitespace()); }
simdjson.cpp:_ZNK8simdjson7haswell12_GLOBAL__N_120json_character_block2opEv:
   16|   476k|  simdjson_inline uint64_t op() const noexcept { return _op; }
simdjson.cpp:_ZNK8simdjson7haswell12_GLOBAL__N_120json_character_block10whitespaceEv:
   15|   953k|  simdjson_inline uint64_t whitespace() const noexcept { return _whitespace; }
simdjson.cpp:_ZNK8simdjson8westmere12_GLOBAL__N_120json_character_block6scalarEv:
   17|   476k|  simdjson_inline uint64_t scalar() const noexcept { return ~(op() | whitespace()); }
simdjson.cpp:_ZNK8simdjson8westmere12_GLOBAL__N_120json_character_block2opEv:
   16|   476k|  simdjson_inline uint64_t op() const noexcept { return _op; }
simdjson.cpp:_ZNK8simdjson8westmere12_GLOBAL__N_120json_character_block10whitespaceEv:
   15|   952k|  simdjson_inline uint64_t whitespace() const noexcept { return _whitespace; }

simdjson.cpp:_ZN8simdjson8westmere12_GLOBAL__N_16stage116buf_block_readerILm64EEC2EPKhm:
   83|    689|simdjson_inline buf_block_reader<STEP_SIZE>::buf_block_reader(const uint8_t *_buf, size_t _len) : buf{_buf}, len{_len}, lenminusstep{len < STEP_SIZE ? 0 : len - STEP_SIZE}, idx{0} {}
  ------------------
  |  Branch (83:134): [True: 104, False: 585]
  ------------------
simdjson.cpp:_ZNK8simdjson8westmere12_GLOBAL__N_16stage116buf_block_readerILm64EE14has_full_blockEv:
   89|   476k|simdjson_inline bool buf_block_reader<STEP_SIZE>::has_full_block() const {
   90|   476k|  return idx < lenminusstep;
   91|   476k|}
simdjson.cpp:_ZNK8simdjson8westmere12_GLOBAL__N_16stage116buf_block_readerILm64EE10full_blockEv:
   94|   475k|simdjson_inline const uint8_t *buf_block_reader<STEP_SIZE>::full_block() const {
   95|   475k|  return &buf[idx];
   96|   475k|}
simdjson.cpp:_ZN8simdjson8westmere12_GLOBAL__N_16stage116buf_block_readerILm64EE7advanceEv:
  107|   476k|simdjson_inline void buf_block_reader<STEP_SIZE>::advance() {
  108|   476k|  idx += STEP_SIZE;
  109|   476k|}
simdjson.cpp:_ZNK8simdjson8westmere12_GLOBAL__N_16stage116buf_block_readerILm64EE13get_remainderEPh:
   99|    689|simdjson_inline size_t buf_block_reader<STEP_SIZE>::get_remainder(uint8_t *dst) const {
  100|    689|  if(len == idx) { return 0; } // memcpy(dst, null, 0) will trigger an error with some sanitizers
  ------------------
  |  Branch (100:6): [True: 0, False: 689]
  ------------------
  101|    689|  std::memset(dst, 0x20, STEP_SIZE); // std::memset STEP_SIZE because it's more efficient to write out 8 or 16 bytes at once.
  102|    689|  std::memcpy(dst, buf + idx, len - idx);
  103|    689|  return len - idx;
  104|    689|}
simdjson.cpp:_ZN8simdjson7haswell12_GLOBAL__N_16stage116buf_block_readerILm128EEC2EPKhm:
   83|    689|simdjson_inline buf_block_reader<STEP_SIZE>::buf_block_reader(const uint8_t *_buf, size_t _len) : buf{_buf}, len{_len}, lenminusstep{len < STEP_SIZE ? 0 : len - STEP_SIZE}, idx{0} {}
  ------------------
  |  Branch (83:134): [True: 334, False: 355]
  ------------------
simdjson.cpp:_ZNK8simdjson7haswell12_GLOBAL__N_16stage116buf_block_readerILm128EE14has_full_blockEv:
   89|   238k|simdjson_inline bool buf_block_reader<STEP_SIZE>::has_full_block() const {
   90|   238k|  return idx < lenminusstep;
   91|   238k|}
simdjson.cpp:_ZN8simdjson7haswell12_GLOBAL__N_16stage116buf_block_readerILm128EE7advanceEv:
  107|   238k|simdjson_inline void buf_block_reader<STEP_SIZE>::advance() {
  108|   238k|  idx += STEP_SIZE;
  109|   238k|}
simdjson.cpp:_ZNK8simdjson7haswell12_GLOBAL__N_16stage116buf_block_readerILm128EE10full_blockEv:
   94|   237k|simdjson_inline const uint8_t *buf_block_reader<STEP_SIZE>::full_block() const {
   95|   237k|  return &buf[idx];
   96|   237k|}
simdjson.cpp:_ZNK8simdjson7haswell12_GLOBAL__N_16stage116buf_block_readerILm128EE13get_remainderEPh:
   99|    689|simdjson_inline size_t buf_block_reader<STEP_SIZE>::get_remainder(uint8_t *dst) const {
  100|    689|  if(len == idx) { return 0; } // memcpy(dst, null, 0) will trigger an error with some sanitizers
  ------------------
  |  Branch (100:6): [True: 0, False: 689]
  ------------------
  101|    689|  std::memset(dst, 0x20, STEP_SIZE); // std::memset STEP_SIZE because it's more efficient to write out 8 or 16 bytes at once.
  102|    689|  std::memcpy(dst, buf + idx, len - idx);
  103|    689|  return len - idx;
  104|    689|}

simdjson.cpp:_ZN8simdjson7haswell12_GLOBAL__N_16stage119json_escape_scanner4nextEm:
   50|   476k|  simdjson_really_inline escaped_and_escape next(uint64_t backslash) noexcept {
   51|       |
   52|   476k|#if !SIMDJSON_SKIP_BACKSLASH_SHORT_CIRCUIT
   53|   476k|    if (!backslash) { return {next_escaped_without_backslashes(), 0}; }
  ------------------
  |  Branch (53:9): [True: 448k, False: 28.1k]
  ------------------
   54|  28.1k|#endif
   55|       |
   56|       |    // |                                | Mask (shows characters instead of 1's) | Depth | Instructions        |
   57|       |    // |--------------------------------|----------------------------------------|-------|---------------------|
   58|       |    // | string                         | `\\n_\\\n___\\\n___\\\\___\\\\__\\\`   |       |                     |
   59|       |    // |                                | `    even   odd    even   odd   odd`   |       |                     |
   60|       |    // | potential_escape               | ` \  \\\    \\\    \\\\   \\\\  \\\`   | 1     | 1 (backslash & ~first_is_escaped)
   61|       |    // | escape_and_terminal_code       | ` \n \ \n   \ \n   \ \    \ \   \ \`   | 5     | 5 (next_escape_and_terminal_code())
   62|       |    // | escaped                        | `\    \ n    \ n    \ \    \ \   \ ` X | 6     | 7 (escape_and_terminal_code ^ (potential_escape | first_is_escaped))
   63|       |    // | escape                         | `    \ \    \ \    \ \    \ \   \ \`   | 6     | 8 (escape_and_terminal_code & backslash)
   64|       |    // | first_is_escaped               | `\                                 `   | 7 (*) | 9 (escape >> 63) ()
   65|       |    //                                                                               (*) this is not needed until the next iteration
   66|  28.1k|    uint64_t escape_and_terminal_code = next_escape_and_terminal_code(backslash & ~this->next_is_escaped);
   67|  28.1k|    uint64_t escaped = escape_and_terminal_code ^ (backslash | this->next_is_escaped);
   68|  28.1k|    uint64_t escape = escape_and_terminal_code & backslash;
   69|  28.1k|    this->next_is_escaped = escape >> 63;
   70|  28.1k|    return {escaped, escape};
   71|   476k|  }
simdjson.cpp:_ZN8simdjson7haswell12_GLOBAL__N_16stage119json_escape_scanner32next_escaped_without_backslashesEv:
   76|   448k|  simdjson_really_inline uint64_t next_escaped_without_backslashes() noexcept {
   77|   448k|    uint64_t escaped = this->next_is_escaped;
   78|   448k|    this->next_is_escaped = 0;
   79|   448k|    return escaped;
   80|   448k|  }
simdjson.cpp:_ZN8simdjson7haswell12_GLOBAL__N_16stage119json_escape_scanner29next_escape_and_terminal_codeEm:
   96|  28.1k|  static simdjson_really_inline uint64_t next_escape_and_terminal_code(uint64_t potential_escape) noexcept {
   97|       |    // If we were to just shift and mask out any odd bits, we'd actually get a *half* right answer:
   98|       |    // any even-aligned backslash runs would be correct! Odd-aligned backslash runs would be
   99|       |    // inverted (\\\ would be 010 instead of 101).
  100|       |    //
  101|       |    // ```
  102|       |    // string:              | ____\\\\_\\\\_____ |
  103|       |    // maybe_escaped | ODD  |     \ \   \ \      |
  104|       |    //               even-aligned ^^^  ^^^^ odd-aligned
  105|       |    // ```
  106|       |    //
  107|       |    // Taking that into account, our basic strategy is:
  108|       |    //
  109|       |    // 1. Use subtraction to produce a mask with 1's for even-aligned runs and 0's for
  110|       |    //    odd-aligned runs.
  111|       |    // 2. XOR all odd bits, which masks out the odd bits in even-aligned runs, and brings IN the
  112|       |    //    odd bits in odd-aligned runs.
  113|       |    // 3. & with backslash to clean up any stray bits.
  114|       |    // runs are set to 0, and then XORing with "odd":
  115|       |    //
  116|       |    // |                                | Mask (shows characters instead of 1's) | Instructions        |
  117|       |    // |--------------------------------|----------------------------------------|---------------------|
  118|       |    // | string                         | `\\n_\\\n___\\\n___\\\\___\\\\__\\\`   |
  119|       |    // |                                | `    even   odd    even   odd   odd`   |
  120|       |    // | maybe_escaped                  | `  n  \\n    \\n    \\\_   \\\_  \\` X | 1 (potential_escape << 1)
  121|       |    // | maybe_escaped_and_odd          | ` \n_ \\n _ \\\n_ _ \\\__ _\\\_ \\\`   | 1 (maybe_escaped | odd)
  122|       |    // | even_series_codes_and_odd      | `  n_\\\  _    n_ _\\\\ _     _    `   | 1 (maybe_escaped_and_odd - potential_escape)
  123|       |    // | escape_and_terminal_code       | ` \n \ \n   \ \n   \ \    \ \   \ \`   | 1 (^ odd)
  124|       |    //
  125|       |
  126|       |    // Escaped characters are characters following an escape.
  127|  28.1k|    uint64_t maybe_escaped = potential_escape << 1;
  128|       |
  129|       |    // To distinguish odd from even escape sequences, therefore, we turn on any *starting*
  130|       |    // escapes that are on an odd byte. (We actually bring in all odd bits, for speed.)
  131|       |    // - Odd runs of backslashes are 0000, and the code at the end ("n" in \n or \\n) is 1.
  132|       |    // - Odd runs of backslashes are 1111, and the code at the end ("n" in \n or \\n) is 0.
  133|       |    // - All other odd bytes are 1, and even bytes are 0.
  134|  28.1k|    uint64_t maybe_escaped_and_odd_bits     = maybe_escaped | ODD_BITS;
  135|  28.1k|    uint64_t even_series_codes_and_odd_bits = maybe_escaped_and_odd_bits - potential_escape;
  136|       |
  137|       |    // Now we flip all odd bytes back with xor. This:
  138|       |    // - Makes odd runs of backslashes go from 0000 to 1010
  139|       |    // - Makes even runs of backslashes go from 1111 to 1010
  140|       |    // - Sets actually-escaped codes to 1 (the n in \n and \\n: \n = 11, \\n = 100)
  141|       |    // - Resets all other bytes to 0
  142|  28.1k|    return even_series_codes_and_odd_bits ^ ODD_BITS;
  143|  28.1k|  }
simdjson.cpp:_ZN8simdjson8westmere12_GLOBAL__N_16stage119json_escape_scanner4nextEm:
   50|   476k|  simdjson_really_inline escaped_and_escape next(uint64_t backslash) noexcept {
   51|       |
   52|   476k|#if !SIMDJSON_SKIP_BACKSLASH_SHORT_CIRCUIT
   53|   476k|    if (!backslash) { return {next_escaped_without_backslashes(), 0}; }
  ------------------
  |  Branch (53:9): [True: 448k, False: 28.1k]
  ------------------
   54|  28.1k|#endif
   55|       |
   56|       |    // |                                | Mask (shows characters instead of 1's) | Depth | Instructions        |
   57|       |    // |--------------------------------|----------------------------------------|-------|---------------------|
   58|       |    // | string                         | `\\n_\\\n___\\\n___\\\\___\\\\__\\\`   |       |                     |
   59|       |    // |                                | `    even   odd    even   odd   odd`   |       |                     |
   60|       |    // | potential_escape               | ` \  \\\    \\\    \\\\   \\\\  \\\`   | 1     | 1 (backslash & ~first_is_escaped)
   61|       |    // | escape_and_terminal_code       | ` \n \ \n   \ \n   \ \    \ \   \ \`   | 5     | 5 (next_escape_and_terminal_code())
   62|       |    // | escaped                        | `\    \ n    \ n    \ \    \ \   \ ` X | 6     | 7 (escape_and_terminal_code ^ (potential_escape | first_is_escaped))
   63|       |    // | escape                         | `    \ \    \ \    \ \    \ \   \ \`   | 6     | 8 (escape_and_terminal_code & backslash)
   64|       |    // | first_is_escaped               | `\                                 `   | 7 (*) | 9 (escape >> 63) ()
   65|       |    //                                                                               (*) this is not needed until the next iteration
   66|  28.1k|    uint64_t escape_and_terminal_code = next_escape_and_terminal_code(backslash & ~this->next_is_escaped);
   67|  28.1k|    uint64_t escaped = escape_and_terminal_code ^ (backslash | this->next_is_escaped);
   68|  28.1k|    uint64_t escape = escape_and_terminal_code & backslash;
   69|  28.1k|    this->next_is_escaped = escape >> 63;
   70|  28.1k|    return {escaped, escape};
   71|   476k|  }
simdjson.cpp:_ZN8simdjson8westmere12_GLOBAL__N_16stage119json_escape_scanner32next_escaped_without_backslashesEv:
   76|   448k|  simdjson_really_inline uint64_t next_escaped_without_backslashes() noexcept {
   77|   448k|    uint64_t escaped = this->next_is_escaped;
   78|   448k|    this->next_is_escaped = 0;
   79|   448k|    return escaped;
   80|   448k|  }
simdjson.cpp:_ZN8simdjson8westmere12_GLOBAL__N_16stage119json_escape_scanner29next_escape_and_terminal_codeEm:
   96|  28.1k|  static simdjson_really_inline uint64_t next_escape_and_terminal_code(uint64_t potential_escape) noexcept {
   97|       |    // If we were to just shift and mask out any odd bits, we'd actually get a *half* right answer:
   98|       |    // any even-aligned backslash runs would be correct! Odd-aligned backslash runs would be
   99|       |    // inverted (\\\ would be 010 instead of 101).
  100|       |    //
  101|       |    // ```
  102|       |    // string:              | ____\\\\_\\\\_____ |
  103|       |    // maybe_escaped | ODD  |     \ \   \ \      |
  104|       |    //               even-aligned ^^^  ^^^^ odd-aligned
  105|       |    // ```
  106|       |    //
  107|       |    // Taking that into account, our basic strategy is:
  108|       |    //
  109|       |    // 1. Use subtraction to produce a mask with 1's for even-aligned runs and 0's for
  110|       |    //    odd-aligned runs.
  111|       |    // 2. XOR all odd bits, which masks out the odd bits in even-aligned runs, and brings IN the
  112|       |    //    odd bits in odd-aligned runs.
  113|       |    // 3. & with backslash to clean up any stray bits.
  114|       |    // runs are set to 0, and then XORing with "odd":
  115|       |    //
  116|       |    // |                                | Mask (shows characters instead of 1's) | Instructions        |
  117|       |    // |--------------------------------|----------------------------------------|---------------------|
  118|       |    // | string                         | `\\n_\\\n___\\\n___\\\\___\\\\__\\\`   |
  119|       |    // |                                | `    even   odd    even   odd   odd`   |
  120|       |    // | maybe_escaped                  | `  n  \\n    \\n    \\\_   \\\_  \\` X | 1 (potential_escape << 1)
  121|       |    // | maybe_escaped_and_odd          | ` \n_ \\n _ \\\n_ _ \\\__ _\\\_ \\\`   | 1 (maybe_escaped | odd)
  122|       |    // | even_series_codes_and_odd      | `  n_\\\  _    n_ _\\\\ _     _    `   | 1 (maybe_escaped_and_odd - potential_escape)
  123|       |    // | escape_and_terminal_code       | ` \n \ \n   \ \n   \ \    \ \   \ \`   | 1 (^ odd)
  124|       |    //
  125|       |
  126|       |    // Escaped characters are characters following an escape.
  127|  28.1k|    uint64_t maybe_escaped = potential_escape << 1;
  128|       |
  129|       |    // To distinguish odd from even escape sequences, therefore, we turn on any *starting*
  130|       |    // escapes that are on an odd byte. (We actually bring in all odd bits, for speed.)
  131|       |    // - Odd runs of backslashes are 0000, and the code at the end ("n" in \n or \\n) is 1.
  132|       |    // - Odd runs of backslashes are 1111, and the code at the end ("n" in \n or \\n) is 0.
  133|       |    // - All other odd bytes are 1, and even bytes are 0.
  134|  28.1k|    uint64_t maybe_escaped_and_odd_bits     = maybe_escaped | ODD_BITS;
  135|  28.1k|    uint64_t even_series_codes_and_odd_bits = maybe_escaped_and_odd_bits - potential_escape;
  136|       |
  137|       |    // Now we flip all odd bytes back with xor. This:
  138|       |    // - Makes odd runs of backslashes go from 0000 to 1010
  139|       |    // - Makes even runs of backslashes go from 1111 to 1010
  140|       |    // - Sets actually-escaped codes to 1 (the n in \n and \\n: \n = 11, \\n = 100)
  141|       |    // - Resets all other bytes to 0
  142|  28.1k|    return even_series_codes_and_odd_bits ^ ODD_BITS;
  143|  28.1k|  }

simdjson.cpp:_ZN8simdjson7haswell12_GLOBAL__N_16stage113json_minifier6minifyILm128EEENS_10error_codeEPKhmPhRm:
   69|    689|error_code json_minifier::minify(const uint8_t *buf, size_t len, uint8_t *dst, size_t &dst_len) noexcept {
   70|    689|  buf_block_reader<STEP_SIZE> reader(buf, len);
   71|    689|  json_minifier minifier(dst);
   72|       |
   73|       |  // Index the first n-1 blocks
   74|   238k|  while (reader.has_full_block()) {
  ------------------
  |  Branch (74:10): [True: 237k, False: 689]
  ------------------
   75|   237k|    minifier.step<STEP_SIZE>(reader.full_block(), reader);
   76|   237k|  }
   77|       |
   78|       |  // Index the last (remainder) block, padded with spaces
   79|    689|  uint8_t block[STEP_SIZE];
   80|    689|  size_t remaining_bytes = reader.get_remainder(block);
   81|    689|  if (remaining_bytes > 0) {
  ------------------
  |  Branch (81:7): [True: 689, False: 0]
  ------------------
   82|       |    // We do not want to write directly to the output stream. Rather, we write
   83|       |    // to a local buffer (for safety).
   84|    689|    uint8_t out_block[STEP_SIZE];
   85|    689|    uint8_t * const guarded_dst{minifier.dst};
   86|    689|    minifier.dst = out_block;
   87|    689|    minifier.step<STEP_SIZE>(block, reader);
   88|    689|    size_t to_write = minifier.dst - out_block;
   89|       |    // In some cases, we could be enticed to consider the padded spaces
   90|       |    // as part of the string. This is fine as long as we do not write more
   91|       |    // than we consumed.
   92|    689|    if(to_write > remaining_bytes) { to_write = remaining_bytes; }
  ------------------
  |  Branch (92:8): [True: 120, False: 569]
  ------------------
   93|    689|    memcpy(guarded_dst, out_block, to_write);
   94|    689|    minifier.dst = guarded_dst + to_write;
   95|    689|  }
   96|    689|  return minifier.finish(dst, dst_len);
   97|    689|}
simdjson.cpp:_ZN8simdjson7haswell12_GLOBAL__N_16stage113json_minifierC2EPh:
   27|    689|  : dst{_dst}
   28|    689|  {}
simdjson.cpp:_ZN8simdjson7haswell12_GLOBAL__N_16stage113json_minifier4stepILm128EEEvPKhRNS2_16buf_block_readerIXT_EEE:
   50|   238k|simdjson_inline void json_minifier::step<128>(const uint8_t *block_buf, buf_block_reader<128> &reader) noexcept {
   51|   238k|  simd::simd8x64<uint8_t> in_1(block_buf);
   52|   238k|  simd::simd8x64<uint8_t> in_2(block_buf+64);
   53|   238k|  json_block block_1 = scanner.next(in_1);
   54|   238k|  json_block block_2 = scanner.next(in_2);
   55|   238k|  this->next(in_1, block_1);
   56|   238k|  this->next(in_2, block_2);
   57|   238k|  reader.advance();
   58|   238k|}
simdjson.cpp:_ZN8simdjson7haswell12_GLOBAL__N_16stage113json_minifier4nextERKNS1_4simd8simd8x64IhEERKNS2_10json_blockE:
   37|   476k|simdjson_inline void json_minifier::next(const simd::simd8x64<uint8_t>& in, const json_block& block) {
   38|   476k|  uint64_t mask = block.whitespace();
   39|   476k|  dst += in.compress(mask, dst);
   40|   476k|}
simdjson.cpp:_ZN8simdjson7haswell12_GLOBAL__N_16stage113json_minifier6finishEPhRm:
   42|    689|simdjson_inline error_code json_minifier::finish(uint8_t *dst_start, size_t &dst_len) {
   43|    689|  error_code error = scanner.finish();
   44|    689|  if (error) { dst_len = 0; return error; }
  ------------------
  |  Branch (44:7): [True: 131, False: 558]
  ------------------
   45|    558|  dst_len = dst - dst_start;
   46|    558|  return SUCCESS;
   47|    689|}
simdjson.cpp:_ZN8simdjson8westmere12_GLOBAL__N_16stage113json_minifier6minifyILm64EEENS_10error_codeEPKhmPhRm:
   69|    689|error_code json_minifier::minify(const uint8_t *buf, size_t len, uint8_t *dst, size_t &dst_len) noexcept {
   70|    689|  buf_block_reader<STEP_SIZE> reader(buf, len);
   71|    689|  json_minifier minifier(dst);
   72|       |
   73|       |  // Index the first n-1 blocks
   74|   476k|  while (reader.has_full_block()) {
  ------------------
  |  Branch (74:10): [True: 475k, False: 689]
  ------------------
   75|   475k|    minifier.step<STEP_SIZE>(reader.full_block(), reader);
   76|   475k|  }
   77|       |
   78|       |  // Index the last (remainder) block, padded with spaces
   79|    689|  uint8_t block[STEP_SIZE];
   80|    689|  size_t remaining_bytes = reader.get_remainder(block);
   81|    689|  if (remaining_bytes > 0) {
  ------------------
  |  Branch (81:7): [True: 689, False: 0]
  ------------------
   82|       |    // We do not want to write directly to the output stream. Rather, we write
   83|       |    // to a local buffer (for safety).
   84|    689|    uint8_t out_block[STEP_SIZE];
   85|    689|    uint8_t * const guarded_dst{minifier.dst};
   86|    689|    minifier.dst = out_block;
   87|    689|    minifier.step<STEP_SIZE>(block, reader);
   88|    689|    size_t to_write = minifier.dst - out_block;
   89|       |    // In some cases, we could be enticed to consider the padded spaces
   90|       |    // as part of the string. This is fine as long as we do not write more
   91|       |    // than we consumed.
   92|    689|    if(to_write > remaining_bytes) { to_write = remaining_bytes; }
  ------------------
  |  Branch (92:8): [True: 106, False: 583]
  ------------------
   93|    689|    memcpy(guarded_dst, out_block, to_write);
   94|    689|    minifier.dst = guarded_dst + to_write;
   95|    689|  }
   96|    689|  return minifier.finish(dst, dst_len);
   97|    689|}
simdjson.cpp:_ZN8simdjson8westmere12_GLOBAL__N_16stage113json_minifierC2EPh:
   27|    689|  : dst{_dst}
   28|    689|  {}
simdjson.cpp:_ZN8simdjson8westmere12_GLOBAL__N_16stage113json_minifier4stepILm64EEEvPKhRNS2_16buf_block_readerIXT_EEE:
   61|   476k|simdjson_inline void json_minifier::step<64>(const uint8_t *block_buf, buf_block_reader<64> &reader) noexcept {
   62|   476k|  simd::simd8x64<uint8_t> in_1(block_buf);
   63|   476k|  json_block block_1 = scanner.next(in_1);
   64|   476k|  this->next(block_buf, block_1);
   65|   476k|  reader.advance();
   66|   476k|}
simdjson.cpp:_ZN8simdjson8westmere12_GLOBAL__N_16stage113json_minifier4nextERKNS1_4simd8simd8x64IhEERKNS2_10json_blockE:
   37|   476k|simdjson_inline void json_minifier::next(const simd::simd8x64<uint8_t>& in, const json_block& block) {
   38|   476k|  uint64_t mask = block.whitespace();
   39|   476k|  dst += in.compress(mask, dst);
   40|   476k|}
simdjson.cpp:_ZN8simdjson8westmere12_GLOBAL__N_16stage113json_minifier6finishEPhRm:
   42|    689|simdjson_inline error_code json_minifier::finish(uint8_t *dst_start, size_t &dst_len) {
   43|    689|  error_code error = scanner.finish();
   44|    689|  if (error) { dst_len = 0; return error; }
  ------------------
  |  Branch (44:7): [True: 131, False: 558]
  ------------------
   45|    558|  dst_len = dst - dst_start;
   46|    558|  return SUCCESS;
   47|    689|}

simdjson.cpp:_ZN8simdjson7haswell12_GLOBAL__N_16stage112json_scannerC2Ev:
  108|    689|  json_scanner() = default;
simdjson.cpp:_ZN8simdjson7haswell12_GLOBAL__N_16stage112json_scanner4nextERKNS1_4simd8simd8x64IhEE:
  134|   476k|simdjson_inline json_block json_scanner::next(const simd::simd8x64<uint8_t>& in) {
  135|   476k|  json_string_block strings = string_scanner.next(in);
  136|       |  // identifies the white-space and the structural characters
  137|   476k|  json_character_block characters = json_character_block::classify(in);
  138|       |  // The term "scalar" refers to anything except structural characters and white space
  139|       |  // (so letters, numbers, quotes).
  140|       |  // We want follows_scalar to mark anything that follows a non-quote scalar (so letters and numbers).
  141|       |  //
  142|       |  // A terminal quote should either be followed by a structural character (comma, brace, bracket, colon)
  143|       |  // or nothing. However, we still want ' "a string"true ' to mark the 't' of 'true' as a potential
  144|       |  // pseudo-structural character just like we would if we had  ' "a string" true '; otherwise we
  145|       |  // may need to add an extra check when parsing strings.
  146|       |  //
  147|       |  // Performance: there are many ways to skin this cat.
  148|   476k|  const uint64_t nonquote_scalar = characters.scalar() & ~strings.quote();
  149|   476k|  uint64_t follows_nonquote_scalar = follows(nonquote_scalar, prev_scalar);
  150|       |  // We are returning a function-local object so either we get a move constructor
  151|       |  // or we get copy elision.
  152|   476k|  return json_block(
  153|   476k|    strings,// strings is a function-local object so either it moves or the copy is elided.
  154|   476k|    characters,
  155|   476k|    follows_nonquote_scalar
  156|   476k|  );
  157|   476k|}
simdjson.cpp:_ZN8simdjson7haswell12_GLOBAL__N_16stage17followsEmRm:
  128|   476k|simdjson_inline uint64_t follows(const uint64_t match, uint64_t &overflow) {
  129|   476k|  const uint64_t result = match << 1 | overflow;
  130|   476k|  overflow = match >> 63;
  131|   476k|  return result;
  132|   476k|}
simdjson.cpp:_ZN8simdjson7haswell12_GLOBAL__N_16stage110json_blockC2ENS2_17json_string_blockENS1_20json_character_blockEm:
   38|   476k|  _string(string), _characters(characters), _follows_potential_nonquote_scalar(follows_potential_nonquote_scalar) {}
simdjson.cpp:_ZNK8simdjson7haswell12_GLOBAL__N_16stage110json_block10whitespaceEv:
   46|   476k|  simdjson_inline uint64_t whitespace() const noexcept { return non_quote_outside_string(_characters.whitespace()); }
simdjson.cpp:_ZNK8simdjson7haswell12_GLOBAL__N_16stage110json_block24non_quote_outside_stringEm:
   53|   476k|  simdjson_inline uint64_t non_quote_outside_string(uint64_t mask) const noexcept { return _string.non_quote_outside_string(mask); }
simdjson.cpp:_ZN8simdjson7haswell12_GLOBAL__N_16stage112json_scanner6finishEv:
  159|    689|simdjson_inline error_code json_scanner::finish() {
  160|    689|  return string_scanner.finish();
  161|    689|}
simdjson.cpp:_ZN8simdjson8westmere12_GLOBAL__N_16stage112json_scannerC2Ev:
  108|    689|  json_scanner() = default;
simdjson.cpp:_ZN8simdjson8westmere12_GLOBAL__N_16stage112json_scanner4nextERKNS1_4simd8simd8x64IhEE:
  134|   476k|simdjson_inline json_block json_scanner::next(const simd::simd8x64<uint8_t>& in) {
  135|   476k|  json_string_block strings = string_scanner.next(in);
  136|       |  // identifies the white-space and the structural characters
  137|   476k|  json_character_block characters = json_character_block::classify(in);
  138|       |  // The term "scalar" refers to anything except structural characters and white space
  139|       |  // (so letters, numbers, quotes).
  140|       |  // We want follows_scalar to mark anything that follows a non-quote scalar (so letters and numbers).
  141|       |  //
  142|       |  // A terminal quote should either be followed by a structural character (comma, brace, bracket, colon)
  143|       |  // or nothing. However, we still want ' "a string"true ' to mark the 't' of 'true' as a potential
  144|       |  // pseudo-structural character just like we would if we had  ' "a string" true '; otherwise we
  145|       |  // may need to add an extra check when parsing strings.
  146|       |  //
  147|       |  // Performance: there are many ways to skin this cat.
  148|   476k|  const uint64_t nonquote_scalar = characters.scalar() & ~strings.quote();
  149|   476k|  uint64_t follows_nonquote_scalar = follows(nonquote_scalar, prev_scalar);
  150|       |  // We are returning a function-local object so either we get a move constructor
  151|       |  // or we get copy elision.
  152|   476k|  return json_block(
  153|   476k|    strings,// strings is a function-local object so either it moves or the copy is elided.
  154|   476k|    characters,
  155|   476k|    follows_nonquote_scalar
  156|   476k|  );
  157|   476k|}
simdjson.cpp:_ZN8simdjson8westmere12_GLOBAL__N_16stage17followsEmRm:
  128|   476k|simdjson_inline uint64_t follows(const uint64_t match, uint64_t &overflow) {
  129|   476k|  const uint64_t result = match << 1 | overflow;
  130|   476k|  overflow = match >> 63;
  131|   476k|  return result;
  132|   476k|}
simdjson.cpp:_ZN8simdjson8westmere12_GLOBAL__N_16stage110json_blockC2ENS2_17json_string_blockENS1_20json_character_blockEm:
   38|   476k|  _string(string), _characters(characters), _follows_potential_nonquote_scalar(follows_potential_nonquote_scalar) {}
simdjson.cpp:_ZNK8simdjson8westmere12_GLOBAL__N_16stage110json_block10whitespaceEv:
   46|   476k|  simdjson_inline uint64_t whitespace() const noexcept { return non_quote_outside_string(_characters.whitespace()); }
simdjson.cpp:_ZNK8simdjson8westmere12_GLOBAL__N_16stage110json_block24non_quote_outside_stringEm:
   53|   476k|  simdjson_inline uint64_t non_quote_outside_string(uint64_t mask) const noexcept { return _string.non_quote_outside_string(mask); }
simdjson.cpp:_ZN8simdjson8westmere12_GLOBAL__N_16stage112json_scanner6finishEv:
  159|    689|simdjson_inline error_code json_scanner::finish() {
  160|    689|  return string_scanner.finish();
  161|    689|}

simdjson.cpp:_ZN8simdjson7haswell12_GLOBAL__N_16stage119json_string_scanner4nextERKNS1_4simd8simd8x64IhEE:
   62|   476k|simdjson_really_inline json_string_block json_string_scanner::next(const simd::simd8x64<uint8_t>& in) {
   63|   476k|  const uint64_t backslash = in.eq('\\');
   64|   476k|  const uint64_t escaped = escape_scanner.next(backslash).escaped;
   65|   476k|  const uint64_t quote = in.eq('"') & ~escaped;
   66|       |
   67|       |  //
   68|       |  // prefix_xor flips on bits inside the string (and flips off the end quote).
   69|       |  //
   70|       |  // Then we xor with prev_in_string: if we were in a string already, its effect is flipped
   71|       |  // (characters inside strings are outside, and characters outside strings are inside).
   72|       |  //
   73|   476k|  const uint64_t in_string = prefix_xor(quote) ^ prev_in_string;
   74|       |
   75|       |  //
   76|       |  // Check if we're still in a string at the end of the box so the next block will know
   77|       |  //
   78|   476k|  prev_in_string = uint64_t(static_cast<int64_t>(in_string) >> 63);
   79|       |
   80|       |  // Use ^ to turn the beginning quote off, and the end quote on.
   81|       |
   82|       |  // We are returning a function-local object so either we get a move constructor
   83|       |  // or we get copy elision.
   84|   476k|  return json_string_block(escaped, quote, in_string);
   85|   476k|}
simdjson.cpp:_ZN8simdjson7haswell12_GLOBAL__N_16stage117json_string_blockC2Emmm:
   17|   476k|  _escaped(escaped), _quote(quote), _in_string(in_string) {}
simdjson.cpp:_ZNK8simdjson7haswell12_GLOBAL__N_16stage117json_string_block5quoteEv:
   22|   476k|  simdjson_really_inline uint64_t quote() const { return _quote; }
simdjson.cpp:_ZNK8simdjson7haswell12_GLOBAL__N_16stage117json_string_block24non_quote_outside_stringEm:
   28|   476k|  simdjson_really_inline uint64_t non_quote_outside_string(uint64_t mask) const { return mask & ~_in_string; }
simdjson.cpp:_ZN8simdjson7haswell12_GLOBAL__N_16stage119json_string_scanner6finishEv:
   87|    689|simdjson_really_inline error_code json_string_scanner::finish() {
   88|    689|  if (prev_in_string) {
  ------------------
  |  Branch (88:7): [True: 131, False: 558]
  ------------------
   89|    131|    return UNCLOSED_STRING;
   90|    131|  }
   91|    558|  return SUCCESS;
   92|    689|}
simdjson.cpp:_ZN8simdjson8westmere12_GLOBAL__N_16stage119json_string_scanner4nextERKNS1_4simd8simd8x64IhEE:
   62|   476k|simdjson_really_inline json_string_block json_string_scanner::next(const simd::simd8x64<uint8_t>& in) {
   63|   476k|  const uint64_t backslash = in.eq('\\');
   64|   476k|  const uint64_t escaped = escape_scanner.next(backslash).escaped;
   65|   476k|  const uint64_t quote = in.eq('"') & ~escaped;
   66|       |
   67|       |  //
   68|       |  // prefix_xor flips on bits inside the string (and flips off the end quote).
   69|       |  //
   70|       |  // Then we xor with prev_in_string: if we were in a string already, its effect is flipped
   71|       |  // (characters inside strings are outside, and characters outside strings are inside).
   72|       |  //
   73|   476k|  const uint64_t in_string = prefix_xor(quote) ^ prev_in_string;
   74|       |
   75|       |  //
   76|       |  // Check if we're still in a string at the end of the box so the next block will know
   77|       |  //
   78|   476k|  prev_in_string = uint64_t(static_cast<int64_t>(in_string) >> 63);
   79|       |
   80|       |  // Use ^ to turn the beginning quote off, and the end quote on.
   81|       |
   82|       |  // We are returning a function-local object so either we get a move constructor
   83|       |  // or we get copy elision.
   84|   476k|  return json_string_block(escaped, quote, in_string);
   85|   476k|}
simdjson.cpp:_ZN8simdjson8westmere12_GLOBAL__N_16stage117json_string_blockC2Emmm:
   17|   476k|  _escaped(escaped), _quote(quote), _in_string(in_string) {}
simdjson.cpp:_ZNK8simdjson8westmere12_GLOBAL__N_16stage117json_string_block5quoteEv:
   22|   476k|  simdjson_really_inline uint64_t quote() const { return _quote; }
simdjson.cpp:_ZNK8simdjson8westmere12_GLOBAL__N_16stage117json_string_block24non_quote_outside_stringEm:
   28|   476k|  simdjson_really_inline uint64_t non_quote_outside_string(uint64_t mask) const { return mask & ~_in_string; }
simdjson.cpp:_ZN8simdjson8westmere12_GLOBAL__N_16stage119json_string_scanner6finishEv:
   87|    689|simdjson_really_inline error_code json_string_scanner::finish() {
   88|    689|  if (prev_in_string) {
  ------------------
  |  Branch (88:7): [True: 131, False: 558]
  ------------------
   89|    131|    return UNCLOSED_STRING;
   90|    131|  }
   91|    558|  return SUCCESS;
   92|    689|}

_ZNK8simdjson7haswell14implementation6minifyEPKhmPhRm:
  128|    689|simdjson_warn_unused error_code implementation::minify(const uint8_t *buf, size_t len, uint8_t *dst, size_t &dst_len) const noexcept {
  129|    689|  return haswell::stage1::json_minifier::minify<128>(buf, len, dst, dst_len);
  130|    689|}
simdjson.cpp:_ZN8simdjson7haswell12_GLOBAL__N_120json_character_block8classifyERKNS1_4simd8simd8x64IhEE:
   43|   476k|simdjson_inline json_character_block json_character_block::classify(const simd::simd8x64<uint8_t>& in) {
   44|       |  // These lookups rely on the fact that anything < 127 will match the lower 4 bits, which is why
   45|       |  // we can't use the generic lookup_16.
   46|   476k|  const auto whitespace_table = simd8<uint8_t>::repeat_16(' ', 100, 100, 100, 17, 100, 113, 2, 100, '\t', '\n', 112, 100, '\r', 100, 100);
   47|       |
   48|       |  // The 6 operators (:,[]{}) have these values:
   49|       |  //
   50|       |  // , 2C
   51|       |  // : 3A
   52|       |  // [ 5B
   53|       |  // { 7B
   54|       |  // ] 5D
   55|       |  // } 7D
   56|       |  //
   57|       |  // If you use | 0x20 to turn [ and ] into { and }, the lower 4 bits of each character is unique.
   58|       |  // We exploit this, using a simd 4-bit lookup to tell us which character match against, and then
   59|       |  // match it (against | 0x20).
   60|       |  //
   61|       |  // To prevent recognizing other characters, everything else gets compared with 0, which cannot
   62|       |  // match due to the | 0x20.
   63|       |  //
   64|       |  // NOTE: Due to the | 0x20, this ALSO treats <FF> and <SUB> (control characters 0C and 1A) like ,
   65|       |  // and :. This gets caught in stage 2, which checks the actual character to ensure the right
   66|       |  // operators are in the right places.
   67|   476k|  const auto op_table = simd8<uint8_t>::repeat_16(
   68|   476k|    0, 0, 0, 0,
   69|   476k|    0, 0, 0, 0,
   70|   476k|    0, 0, ':', '{', // : = 3A, [ = 5B, { = 7B
   71|   476k|    ',', '}', 0, 0  // , = 2C, ] = 5D, } = 7D
   72|   476k|  );
   73|       |
   74|       |  // We compute whitespace and op separately. If later code only uses one or the
   75|       |  // other, given the fact that all functions are aggressively inlined, we can
   76|       |  // hope that useless computations will be omitted. This is namely case when
   77|       |  // minifying (we only need whitespace).
   78|       |
   79|   476k|  const uint64_t whitespace = in.eq({
   80|   476k|    _mm256_shuffle_epi8(whitespace_table, in.chunks[0]),
   81|   476k|    _mm256_shuffle_epi8(whitespace_table, in.chunks[1])
   82|   476k|  });
   83|       |  // Turn [ and ] into { and }
   84|   476k|  const simd8x64<uint8_t> curlified{
   85|   476k|    in.chunks[0] | 0x20,
   86|   476k|    in.chunks[1] | 0x20
   87|   476k|  };
   88|   476k|  const uint64_t op = curlified.eq({
   89|   476k|    _mm256_shuffle_epi8(op_table, in.chunks[0]),
   90|   476k|    _mm256_shuffle_epi8(op_table, in.chunks[1])
   91|   476k|  });
   92|       |
   93|   476k|  return { whitespace, op };
   94|   476k|}

_ZNK8simdjson14implementation27supported_by_runtime_systemEv:
   14|      4|bool implementation::supported_by_runtime_system() const {
   15|      4|  uint32_t required_instruction_sets = this->required_instruction_sets();
   16|      4|  uint32_t supported_instruction_sets = internal::detect_supported_architectures();
   17|      4|  return ((supported_instruction_sets & required_instruction_sets) == required_instruction_sets);
   18|      4|}
_ZNK8simdjson8internal29available_implementation_list5beginEv:
  262|      1|const implementation * const *available_implementation_list::begin() const noexcept {
  263|      1|  return internal::get_available_implementation_pointers().begin();
  264|      1|}
_ZNK8simdjson8internal29available_implementation_list3endEv:
  265|      1|const implementation * const *available_implementation_list::end() const noexcept {
  266|      1|  return internal::get_available_implementation_pointers().end();
  267|      1|}
_ZN8simdjson29get_available_implementationsEv:
  298|      1|SIMDJSON_DLLIMPORTEXPORT const internal::available_implementation_list& get_available_implementations() {
  299|      1|  static const internal::available_implementation_list available_implementations{};
  300|      1|  return available_implementations;
  301|      1|}
simdjson.cpp:_ZN8simdjson8internalL37get_available_implementation_pointersEv:
  196|      2|static const std::initializer_list<const implementation *>& get_available_implementation_pointers() {
  197|      2|  static const std::initializer_list<const implementation *> available_implementation_pointers {
  198|      2|#if SIMDJSON_IMPLEMENTATION_ICELAKE
  199|      2|    get_icelake_singleton(),
  200|      2|#endif
  201|      2|#if SIMDJSON_IMPLEMENTATION_HASWELL
  202|      2|    get_haswell_singleton(),
  203|      2|#endif
  204|      2|#if SIMDJSON_IMPLEMENTATION_WESTMERE
  205|      2|    get_westmere_singleton(),
  206|      2|#endif
  207|       |#if SIMDJSON_IMPLEMENTATION_ARM64
  208|       |    get_arm64_singleton(),
  209|       |#endif
  210|       |#if SIMDJSON_IMPLEMENTATION_PPC64
  211|       |    get_ppc64_singleton(),
  212|       |#endif
  213|       |#if SIMDJSON_IMPLEMENTATION_LSX
  214|       |    get_lsx_singleton(),
  215|       |#endif
  216|       |#if SIMDJSON_IMPLEMENTATION_LASX
  217|       |    get_lasx_singleton(),
  218|       |#endif
  219|      2|#if SIMDJSON_IMPLEMENTATION_FALLBACK
  220|      2|    get_fallback_singleton(),
  221|      2|#endif
  222|      2|  }; // available_implementation_pointers
  223|      2|  return available_implementation_pointers;
  224|      2|}
simdjson.cpp:_ZN8simdjson8internalL21get_icelake_singletonEv:
   65|      1|static const icelake::implementation* get_icelake_singleton() {
   66|      1|  static const icelake::implementation icelake_singleton{};
   67|      1|  return &icelake_singleton;
   68|      1|}
simdjson.cpp:_ZN8simdjson8internalL21get_haswell_singletonEv:
   53|      1|static const haswell::implementation* get_haswell_singleton() {
   54|      1|  static const haswell::implementation haswell_singleton{};
   55|      1|  return &haswell_singleton;
   56|      1|}
simdjson.cpp:_ZN8simdjson8internalL22get_westmere_singletonEv:
   89|      1|static const simdjson::westmere::implementation* get_westmere_singleton() {
   90|      1|  static const simdjson::westmere::implementation westmere_singleton{};
   91|      1|  return &westmere_singleton;
   92|      1|}
simdjson.cpp:_ZN8simdjson8internalL22get_fallback_singletonEv:
   40|      1|static const fallback::implementation* get_fallback_singleton() {
   41|      1|  static const fallback::implementation fallback_singleton{};
   42|      1|  return &fallback_singleton;
   43|      1|}

simdjson.cpp:_ZN8simdjson8internalL30detect_supported_architecturesEv:
  133|      4|static inline uint32_t detect_supported_architectures() {
  134|      4|  uint32_t eax, ebx, ecx, edx;
  135|      4|  uint32_t host_isa = 0x0;
  136|       |
  137|       |  // EBX for EAX=0x1
  138|      4|  eax = 0x1;
  139|      4|  ecx = 0x0;
  140|      4|  cpuid(&eax, &ebx, &ecx, &edx);
  141|       |
  142|      4|  if (ecx & cpuid_sse42_bit) {
  ------------------
  |  Branch (142:7): [True: 4, False: 0]
  ------------------
  143|      4|    host_isa |= instruction_set::SSE42;
  144|      4|  } else {
  145|      0|    return host_isa; // everything after is redundant
  146|      0|  }
  147|       |
  148|      4|  if (ecx & cpuid_pclmulqdq_bit) {
  ------------------
  |  Branch (148:7): [True: 4, False: 0]
  ------------------
  149|      4|    host_isa |= instruction_set::PCLMULQDQ;
  150|      4|  }
  151|       |
  152|       |
  153|      4|  if ((ecx & cpuid_osxsave) != cpuid_osxsave) {
  ------------------
  |  Branch (153:7): [True: 0, False: 4]
  ------------------
  154|      0|    return host_isa;
  155|      0|  }
  156|       |
  157|       |  // xgetbv for checking if the OS saves registers
  158|      4|  uint64_t xcr0 = xgetbv();
  159|       |
  160|      4|  if ((xcr0 & cpuid_avx256_saved) == 0) {
  ------------------
  |  Branch (160:7): [True: 0, False: 4]
  ------------------
  161|      0|    return host_isa;
  162|      0|  }
  163|       |
  164|       |  // ECX for EAX=0x7
  165|      4|  eax = 0x7;
  166|      4|  ecx = 0x0;
  167|      4|  cpuid(&eax, &ebx, &ecx, &edx);
  168|      4|  if (ebx & cpuid_avx2_bit) {
  ------------------
  |  Branch (168:7): [True: 4, False: 0]
  ------------------
  169|      4|    host_isa |= instruction_set::AVX2;
  170|      4|  }
  171|      4|  if (ebx & cpuid_bmi1_bit) {
  ------------------
  |  Branch (171:7): [True: 4, False: 0]
  ------------------
  172|      4|    host_isa |= instruction_set::BMI1;
  173|      4|  }
  174|       |
  175|      4|  if (ebx & cpuid_bmi2_bit) {
  ------------------
  |  Branch (175:7): [True: 4, False: 0]
  ------------------
  176|      4|    host_isa |= instruction_set::BMI2;
  177|      4|  }
  178|       |
  179|      4|  if (!((xcr0 & cpuid_avx512_saved) == cpuid_avx512_saved)) {
  ------------------
  |  Branch (179:7): [True: 4, False: 0]
  ------------------
  180|      4|     return host_isa;
  181|      4|  }
  182|       |
  183|      0|  if (ebx & cpuid_avx512f_bit) {
  ------------------
  |  Branch (183:7): [True: 0, False: 0]
  ------------------
  184|      0|    host_isa |= instruction_set::AVX512F;
  185|      0|  }
  186|       |
  187|      0|  if (ebx & cpuid_avx512dq_bit) {
  ------------------
  |  Branch (187:7): [True: 0, False: 0]
  ------------------
  188|      0|    host_isa |= instruction_set::AVX512DQ;
  189|      0|  }
  190|       |
  191|      0|  if (ebx & cpuid_avx512ifma_bit) {
  ------------------
  |  Branch (191:7): [True: 0, False: 0]
  ------------------
  192|      0|    host_isa |= instruction_set::AVX512IFMA;
  193|      0|  }
  194|       |
  195|      0|  if (ebx & cpuid_avx512pf_bit) {
  ------------------
  |  Branch (195:7): [True: 0, False: 0]
  ------------------
  196|      0|    host_isa |= instruction_set::AVX512PF;
  197|      0|  }
  198|       |
  199|      0|  if (ebx & cpuid_avx512er_bit) {
  ------------------
  |  Branch (199:7): [True: 0, False: 0]
  ------------------
  200|      0|    host_isa |= instruction_set::AVX512ER;
  201|      0|  }
  202|       |
  203|      0|  if (ebx & cpuid_avx512cd_bit) {
  ------------------
  |  Branch (203:7): [True: 0, False: 0]
  ------------------
  204|      0|    host_isa |= instruction_set::AVX512CD;
  205|      0|  }
  206|       |
  207|      0|  if (ebx & cpuid_avx512bw_bit) {
  ------------------
  |  Branch (207:7): [True: 0, False: 0]
  ------------------
  208|      0|    host_isa |= instruction_set::AVX512BW;
  209|      0|  }
  210|       |
  211|      0|  if (ebx & cpuid_avx512vl_bit) {
  ------------------
  |  Branch (211:7): [True: 0, False: 0]
  ------------------
  212|      0|    host_isa |= instruction_set::AVX512VL;
  213|      0|  }
  214|       |
  215|      0|  if (ecx & cpuid_avx512vbmi2_bit) {
  ------------------
  |  Branch (215:7): [True: 0, False: 0]
  ------------------
  216|      0|    host_isa |= instruction_set::AVX512VBMI2;
  217|      0|  }
  218|       |
  219|      0|  return host_isa;
  220|      4|}
simdjson.cpp:_ZN8simdjson8internalL5cpuidEPjS1_S1_S1_:
  101|      8|                         uint32_t *edx) {
  102|       |#if defined(_MSC_VER)
  103|       |  int cpu_info[4];
  104|       |  __cpuidex(cpu_info, *eax, *ecx);
  105|       |  *eax = cpu_info[0];
  106|       |  *ebx = cpu_info[1];
  107|       |  *ecx = cpu_info[2];
  108|       |  *edx = cpu_info[3];
  109|       |#elif defined(HAVE_GCC_GET_CPUID) && defined(USE_GCC_GET_CPUID)
  110|       |  uint32_t level = *eax;
  111|       |  __get_cpuid(level, eax, ebx, ecx, edx);
  112|       |#else
  113|      8|  uint32_t a = *eax, b, c = *ecx, d;
  114|      8|  asm volatile("cpuid\n\t" : "+a"(a), "=b"(b), "+c"(c), "=d"(d));
  115|      8|  *eax = a;
  116|      8|  *ebx = b;
  117|      8|  *ecx = c;
  118|      8|  *edx = d;
  119|      8|#endif
  120|      8|}
simdjson.cpp:_ZN8simdjson8internalL6xgetbvEv:
  123|      4|static inline uint64_t xgetbv() {
  124|       |#if defined(_MSC_VER)
  125|       |  return _xgetbv(0);
  126|       |#else
  127|      4|  uint32_t xcr0_lo, xcr0_hi;
  128|      4|  asm volatile("xgetbv\n\t" : "=a" (xcr0_lo), "=d" (xcr0_hi) : "c" (0));
  129|      4|  return xcr0_lo | (uint64_t(xcr0_hi) << 32);
  130|      4|#endif
  131|      4|}

_ZNK8simdjson8westmere14implementation6minifyEPKhmPhRm:
  133|    689|simdjson_warn_unused error_code implementation::minify(const uint8_t *buf, size_t len, uint8_t *dst, size_t &dst_len) const noexcept {
  134|    689|  return westmere::stage1::json_minifier::minify<64>(buf, len, dst, dst_len);
  135|    689|}
simdjson.cpp:_ZN8simdjson8westmere12_GLOBAL__N_120json_character_block8classifyERKNS1_4simd8simd8x64IhEE:
   41|   476k|simdjson_inline json_character_block json_character_block::classify(const simd::simd8x64<uint8_t>& in) {
   42|       |  // These lookups rely on the fact that anything < 127 will match the lower 4 bits, which is why
   43|       |  // we can't use the generic lookup_16.
   44|   476k|  auto whitespace_table = simd8<uint8_t>::repeat_16(' ', 100, 100, 100, 17, 100, 113, 2, 100, '\t', '\n', 112, 100, '\r', 100, 100);
   45|       |
   46|       |  // The 6 operators (:,[]{}) have these values:
   47|       |  //
   48|       |  // , 2C
   49|       |  // : 3A
   50|       |  // [ 5B
   51|       |  // { 7B
   52|       |  // ] 5D
   53|       |  // } 7D
   54|       |  //
   55|       |  // If you use | 0x20 to turn [ and ] into { and }, the lower 4 bits of each character is unique.
   56|       |  // We exploit this, using a simd 4-bit lookup to tell us which character match against, and then
   57|       |  // match it (against | 0x20).
   58|       |  //
   59|       |  // To prevent recognizing other characters, everything else gets compared with 0, which cannot
   60|       |  // match due to the | 0x20.
   61|       |  //
   62|       |  // NOTE: Due to the | 0x20, this ALSO treats <FF> and <SUB> (control characters 0C and 1A) like ,
   63|       |  // and :. This gets caught in stage 2, which checks the actual character to ensure the right
   64|       |  // operators are in the right places.
   65|   476k|  const auto op_table = simd8<uint8_t>::repeat_16(
   66|   476k|    0, 0, 0, 0,
   67|   476k|    0, 0, 0, 0,
   68|   476k|    0, 0, ':', '{', // : = 3A, [ = 5B, { = 7B
   69|   476k|    ',', '}', 0, 0  // , = 2C, ] = 5D, } = 7D
   70|   476k|  );
   71|       |
   72|       |  // We compute whitespace and op separately. If the code later only use one or the
   73|       |  // other, given the fact that all functions are aggressively inlined, we can
   74|       |  // hope that useless computations will be omitted. This is namely case when
   75|       |  // minifying (we only need whitespace).
   76|       |
   77|       |
   78|   476k|  const uint64_t whitespace = in.eq({
   79|   476k|    _mm_shuffle_epi8(whitespace_table, in.chunks[0]),
   80|   476k|    _mm_shuffle_epi8(whitespace_table, in.chunks[1]),
   81|   476k|    _mm_shuffle_epi8(whitespace_table, in.chunks[2]),
   82|   476k|    _mm_shuffle_epi8(whitespace_table, in.chunks[3])
   83|   476k|  });
   84|       |  // Turn [ and ] into { and }
   85|   476k|  const simd8x64<uint8_t> curlified{
   86|   476k|    in.chunks[0] | 0x20,
   87|   476k|    in.chunks[1] | 0x20,
   88|   476k|    in.chunks[2] | 0x20,
   89|   476k|    in.chunks[3] | 0x20
   90|   476k|  };
   91|   476k|  const uint64_t op = curlified.eq({
   92|   476k|    _mm_shuffle_epi8(op_table, in.chunks[0]),
   93|   476k|    _mm_shuffle_epi8(op_table, in.chunks[1]),
   94|   476k|    _mm_shuffle_epi8(op_table, in.chunks[2]),
   95|   476k|    _mm_shuffle_epi8(op_table, in.chunks[3])
   96|   476k|  });
   97|   476k|    return { whitespace, op };
   98|   476k|}

