LLVMFuzzerTestOneInput:
  182|  1.11k|extern "C" int LLVMFuzzerTestOneInput(const uint8_t* Data, size_t Size) {
  183|  1.11k|  assert(Data);
  ------------------
  |  Branch (183:3): [True: 1.11k, False: 0]
  ------------------
  184|       |
  185|  1.11k|  try {
  186|  1.11k|    const Buffer b(Data, implicit_cast<Buffer::size_type>(Size));
  187|  1.11k|    const DataBuffer db(b, Endianness::little);
  188|  1.11k|    ByteStream bs(db);
  189|       |
  190|  1.11k|    const auto flavor = bs.getByte();
  191|       |
  192|  1.11k|    const auto numValues = bs.getU32();
  193|  1.11k|    const auto bitLengths = bs.getStream(numValues, sizeof(uint8_t));
  194|  1.11k|    const auto bitVals = bs.getStream(numValues, sizeof(uint32_t));
  195|  1.11k|    const InputWrapper w(bitLengths, bitVals);
  196|       |
  197|       |    // Which flavor?
  198|  1.11k|    switch (flavor) {
  199|    155|    case 0:
  ------------------
  |  Branch (199:5): [True: 155, False: 957]
  ------------------
  200|    155|      checkFlavour<BitstreamFlavorLSB>(w);
  201|    155|      return 0;
  202|    157|    case 1:
  ------------------
  |  Branch (202:5): [True: 157, False: 955]
  ------------------
  203|    157|      checkFlavour<BitstreamFlavorMSB>(w);
  204|    157|      return 0;
  205|    154|    case 2:
  ------------------
  |  Branch (205:5): [True: 154, False: 958]
  ------------------
  206|    154|      checkFlavour<BitstreamFlavorMSB16>(w);
  207|    154|      return 0;
  208|    149|    case 3:
  ------------------
  |  Branch (208:5): [True: 149, False: 963]
  ------------------
  209|    149|      checkFlavour<BitstreamFlavorMSB32>(w);
  210|    149|      return 0;
  211|    371|    case 4:
  ------------------
  |  Branch (211:5): [True: 371, False: 741]
  ------------------
  212|    371|      checkFlavour<BitstreamFlavorJPEG>(w);
  213|    371|      return 0;
  214|      3|    default:
  ------------------
  |  Branch (214:5): [True: 3, False: 1.10k]
  ------------------
  215|      3|      ThrowRSE("Unknown flavor");
  ------------------
  |  |   95|      3|  ThrowExceptionHelper(rawspeed::RawspeedException, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   84|      3|  rawspeed::ThrowException<CLASS>("%s, line " STR(__LINE__) ": " fmt,          \
  |  |  |  |   85|      3|                                  __PRETTY_FUNCTION__ __VA_OPT__(, )           \
  |  |  |  |   86|      3|                                      __VA_ARGS__)
  |  |  ------------------
  ------------------
  216|  1.11k|    }
  217|  1.11k|  } catch (const RawspeedException&) {
  218|    126|    return 0;
  219|    126|  }
  220|       |
  221|      0|  __builtin_unreachable();
  222|  1.11k|}
BitVacuumerRoundtrip.cpp:_ZN8rawspeed12_GLOBAL__N_112InputWrapperC2ENS_10ByteStreamES2_:
  110|    989|      : bitLengths(bitLengths_), bitVals(bitVals_) {
  111|       |    invariant(size() >= 0);
  ------------------
  |  |   27|    989|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (111:5): [True: 989, False: 0]
  ------------------
  112|    989|  }
BitVacuumerRoundtrip.cpp:_ZNK8rawspeed12_GLOBAL__N_112InputWrapper4sizeEv:
  114|  31.0M|  [[nodiscard]] int size() const RAWSPEED_READNONE {
  115|  31.0M|    invariant(bitVals.getSize() == 4 * bitLengths.getSize());
  ------------------
  |  |   27|  31.0M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (115:5): [True: 31.0M, False: 0]
  ------------------
  116|  31.0M|    return bitLengths.getSize();
  117|  31.0M|  }
BitVacuumerRoundtrip.cpp:_ZN8rawspeed12_GLOBAL__N_112checkFlavourINS0_18BitstreamFlavorLSBEEEvRKNS0_12InputWrapperE:
  174|    155|template <typename flavor> void checkFlavour(const InputWrapper& w) {
  175|    155|  try {
  176|    155|    checkFlavourImpl<flavor>(w);
  177|    155|  } catch (const RawspeedException&) {
  178|       |    assert(false && "Unexpected exception in `checkFlavourImpl()`.");
  ------------------
  |  Branch (178:5): [Folded, False: 0]
  |  Branch (178:5): [True: 0, Folded]
  |  Branch (178:5): [Folded, False: 0]
  ------------------
  179|      0|  }
  180|    155|}
BitVacuumerRoundtrip.cpp:_ZN8rawspeed12_GLOBAL__N_116checkFlavourImplINS0_18BitstreamFlavorLSBEEEvRKNS0_12InputWrapperE:
  167|    155|template <typename flavor> void checkFlavourImpl(const InputWrapper& w) {
  168|    155|  const std::vector<uint8_t> bitstream = produceBitstream<flavor>(w);
  169|    155|  const auto input =
  170|    155|      Array1DRef(bitstream.data(), implicit_cast<int>(bitstream.size()));
  171|    155|  reparseBitstream<flavor>(input, w);
  172|    155|}
BitVacuumerRoundtrip.cpp:_ZN8rawspeed12_GLOBAL__N_116produceBitstreamINS0_18BitstreamFlavorLSBEEENSt3__16vectorIhNS3_9allocatorIhEEEERKNS0_12InputWrapperE:
  132|    155|std::vector<uint8_t> produceBitstream(const InputWrapper& w) {
  133|    155|  std::vector<uint8_t> bitstream;
  134|       |
  135|    155|  {
  136|    155|    auto bsInserter = PartitioningOutputIterator(std::back_inserter(bitstream));
  137|    155|    using BitVacuumer = typename BitStreamRoundtripTypes<
  138|    155|        flavor>::template vacuumer<decltype(bsInserter)>;
  139|    155|    auto bv = BitVacuumer(bsInserter);
  140|       |
  141|  1.06M|    for (int i = 0; i != w.size(); ++i) {
  ------------------
  |  Branch (141:21): [True: 1.06M, False: 155]
  ------------------
  142|  1.06M|      const auto [val, len] = w[i];
  143|  1.06M|      bv.put(val, len);
  144|  1.06M|    }
  145|    155|  }
  146|       |
  147|    155|  using BitStreamer = typename BitStreamRoundtripTypes<flavor>::streamer;
  148|    155|  if (constexpr int MinSize = BitStreamerTraits<BitStreamer>::MaxProcessBytes;
  149|    155|      bitstream.size() < MinSize)
  ------------------
  |  Branch (149:7): [True: 14, False: 141]
  ------------------
  150|     14|    bitstream.resize(MinSize, uint8_t(0));
  151|       |
  152|    155|  return bitstream;
  153|    155|}
BitVacuumerRoundtrip.cpp:_ZNK8rawspeed12_GLOBAL__N_112InputWrapperixEi:
  120|  15.5M|  operator[](int i) const RAWSPEED_READNONE {
  121|  15.5M|    invariant(i >= 0);
  ------------------
  |  |   27|  15.5M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (121:5): [True: 15.5M, False: 0]
  ------------------
  122|  15.5M|    invariant(i < size());
  ------------------
  |  |   27|  15.5M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (122:5): [True: 15.5M, False: 0]
  ------------------
  123|       |
  124|  15.5M|    auto len = implicit_cast<int>(bitLengths.peekByte(i) % 33); // 0-32 bits
  125|  15.5M|    uint32_t val = extractLowBitsSafe(bitVals.peekU32(i), len);
  126|       |
  127|  15.5M|    return {val, len};
  128|  15.5M|  }
BitVacuumerRoundtrip.cpp:_ZN8rawspeed12_GLOBAL__N_116reparseBitstreamINS0_18BitstreamFlavorLSBEEEvNS_10Array1DRefIKhEERKNS0_12InputWrapperE:
  156|    155|void reparseBitstream(Array1DRef<const uint8_t> input, const InputWrapper& w) {
  157|    155|  using BitStreamer = typename BitStreamRoundtripTypes<flavor>::streamer;
  158|    155|  auto bs = BitStreamer(input);
  159|  1.06M|  for (int i = 0; i != w.size(); ++i) {
  ------------------
  |  Branch (159:19): [True: 1.06M, False: 155]
  ------------------
  160|  1.06M|    const auto [expectedVal, len] = w[i];
  161|  1.06M|    bs.fill(32);
  162|  1.06M|    const auto actualVal = len != 0 ? bs.getBitsNoFill(len) : 0;
  ------------------
  |  Branch (162:28): [True: 947k, False: 113k]
  ------------------
  163|       |    invariant(actualVal == expectedVal);
  ------------------
  |  |   27|  1.06M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (163:5): [True: 1.06M, False: 0]
  ------------------
  164|  1.06M|  }
  165|    155|}
BitVacuumerRoundtrip.cpp:_ZN8rawspeed12_GLOBAL__N_112checkFlavourINS0_18BitstreamFlavorMSBEEEvRKNS0_12InputWrapperE:
  174|    157|template <typename flavor> void checkFlavour(const InputWrapper& w) {
  175|    157|  try {
  176|    157|    checkFlavourImpl<flavor>(w);
  177|    157|  } catch (const RawspeedException&) {
  178|       |    assert(false && "Unexpected exception in `checkFlavourImpl()`.");
  ------------------
  |  Branch (178:5): [Folded, False: 0]
  |  Branch (178:5): [True: 0, Folded]
  |  Branch (178:5): [Folded, False: 0]
  ------------------
  179|      0|  }
  180|    157|}
BitVacuumerRoundtrip.cpp:_ZN8rawspeed12_GLOBAL__N_116checkFlavourImplINS0_18BitstreamFlavorMSBEEEvRKNS0_12InputWrapperE:
  167|    157|template <typename flavor> void checkFlavourImpl(const InputWrapper& w) {
  168|    157|  const std::vector<uint8_t> bitstream = produceBitstream<flavor>(w);
  169|    157|  const auto input =
  170|    157|      Array1DRef(bitstream.data(), implicit_cast<int>(bitstream.size()));
  171|    157|  reparseBitstream<flavor>(input, w);
  172|    157|}
BitVacuumerRoundtrip.cpp:_ZN8rawspeed12_GLOBAL__N_116produceBitstreamINS0_18BitstreamFlavorMSBEEENSt3__16vectorIhNS3_9allocatorIhEEEERKNS0_12InputWrapperE:
  132|    157|std::vector<uint8_t> produceBitstream(const InputWrapper& w) {
  133|    157|  std::vector<uint8_t> bitstream;
  134|       |
  135|    157|  {
  136|    157|    auto bsInserter = PartitioningOutputIterator(std::back_inserter(bitstream));
  137|    157|    using BitVacuumer = typename BitStreamRoundtripTypes<
  138|    157|        flavor>::template vacuumer<decltype(bsInserter)>;
  139|    157|    auto bv = BitVacuumer(bsInserter);
  140|       |
  141|  1.16M|    for (int i = 0; i != w.size(); ++i) {
  ------------------
  |  Branch (141:21): [True: 1.16M, False: 157]
  ------------------
  142|  1.16M|      const auto [val, len] = w[i];
  143|  1.16M|      bv.put(val, len);
  144|  1.16M|    }
  145|    157|  }
  146|       |
  147|    157|  using BitStreamer = typename BitStreamRoundtripTypes<flavor>::streamer;
  148|    157|  if (constexpr int MinSize = BitStreamerTraits<BitStreamer>::MaxProcessBytes;
  149|    157|      bitstream.size() < MinSize)
  ------------------
  |  Branch (149:7): [True: 13, False: 144]
  ------------------
  150|     13|    bitstream.resize(MinSize, uint8_t(0));
  151|       |
  152|    157|  return bitstream;
  153|    157|}
BitVacuumerRoundtrip.cpp:_ZN8rawspeed12_GLOBAL__N_116reparseBitstreamINS0_18BitstreamFlavorMSBEEEvNS_10Array1DRefIKhEERKNS0_12InputWrapperE:
  156|    157|void reparseBitstream(Array1DRef<const uint8_t> input, const InputWrapper& w) {
  157|    157|  using BitStreamer = typename BitStreamRoundtripTypes<flavor>::streamer;
  158|    157|  auto bs = BitStreamer(input);
  159|  1.16M|  for (int i = 0; i != w.size(); ++i) {
  ------------------
  |  Branch (159:19): [True: 1.16M, False: 157]
  ------------------
  160|  1.16M|    const auto [expectedVal, len] = w[i];
  161|  1.16M|    bs.fill(32);
  162|  1.16M|    const auto actualVal = len != 0 ? bs.getBitsNoFill(len) : 0;
  ------------------
  |  Branch (162:28): [True: 993k, False: 175k]
  ------------------
  163|       |    invariant(actualVal == expectedVal);
  ------------------
  |  |   27|  1.16M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (163:5): [True: 1.16M, False: 0]
  ------------------
  164|  1.16M|  }
  165|    157|}
BitVacuumerRoundtrip.cpp:_ZN8rawspeed12_GLOBAL__N_112checkFlavourINS0_20BitstreamFlavorMSB16EEEvRKNS0_12InputWrapperE:
  174|    154|template <typename flavor> void checkFlavour(const InputWrapper& w) {
  175|    154|  try {
  176|    154|    checkFlavourImpl<flavor>(w);
  177|    154|  } catch (const RawspeedException&) {
  178|       |    assert(false && "Unexpected exception in `checkFlavourImpl()`.");
  ------------------
  |  Branch (178:5): [Folded, False: 0]
  |  Branch (178:5): [True: 0, Folded]
  |  Branch (178:5): [Folded, False: 0]
  ------------------
  179|      0|  }
  180|    154|}
BitVacuumerRoundtrip.cpp:_ZN8rawspeed12_GLOBAL__N_116checkFlavourImplINS0_20BitstreamFlavorMSB16EEEvRKNS0_12InputWrapperE:
  167|    154|template <typename flavor> void checkFlavourImpl(const InputWrapper& w) {
  168|    154|  const std::vector<uint8_t> bitstream = produceBitstream<flavor>(w);
  169|    154|  const auto input =
  170|    154|      Array1DRef(bitstream.data(), implicit_cast<int>(bitstream.size()));
  171|    154|  reparseBitstream<flavor>(input, w);
  172|    154|}
BitVacuumerRoundtrip.cpp:_ZN8rawspeed12_GLOBAL__N_116produceBitstreamINS0_20BitstreamFlavorMSB16EEENSt3__16vectorIhNS3_9allocatorIhEEEERKNS0_12InputWrapperE:
  132|    154|std::vector<uint8_t> produceBitstream(const InputWrapper& w) {
  133|    154|  std::vector<uint8_t> bitstream;
  134|       |
  135|    154|  {
  136|    154|    auto bsInserter = PartitioningOutputIterator(std::back_inserter(bitstream));
  137|    154|    using BitVacuumer = typename BitStreamRoundtripTypes<
  138|    154|        flavor>::template vacuumer<decltype(bsInserter)>;
  139|    154|    auto bv = BitVacuumer(bsInserter);
  140|       |
  141|  1.18M|    for (int i = 0; i != w.size(); ++i) {
  ------------------
  |  Branch (141:21): [True: 1.18M, False: 154]
  ------------------
  142|  1.18M|      const auto [val, len] = w[i];
  143|  1.18M|      bv.put(val, len);
  144|  1.18M|    }
  145|    154|  }
  146|       |
  147|    154|  using BitStreamer = typename BitStreamRoundtripTypes<flavor>::streamer;
  148|    154|  if (constexpr int MinSize = BitStreamerTraits<BitStreamer>::MaxProcessBytes;
  149|    154|      bitstream.size() < MinSize)
  ------------------
  |  Branch (149:7): [True: 13, False: 141]
  ------------------
  150|     13|    bitstream.resize(MinSize, uint8_t(0));
  151|       |
  152|    154|  return bitstream;
  153|    154|}
BitVacuumerRoundtrip.cpp:_ZN8rawspeed12_GLOBAL__N_116reparseBitstreamINS0_20BitstreamFlavorMSB16EEEvNS_10Array1DRefIKhEERKNS0_12InputWrapperE:
  156|    154|void reparseBitstream(Array1DRef<const uint8_t> input, const InputWrapper& w) {
  157|    154|  using BitStreamer = typename BitStreamRoundtripTypes<flavor>::streamer;
  158|    154|  auto bs = BitStreamer(input);
  159|  1.18M|  for (int i = 0; i != w.size(); ++i) {
  ------------------
  |  Branch (159:19): [True: 1.18M, False: 154]
  ------------------
  160|  1.18M|    const auto [expectedVal, len] = w[i];
  161|  1.18M|    bs.fill(32);
  162|  1.18M|    const auto actualVal = len != 0 ? bs.getBitsNoFill(len) : 0;
  ------------------
  |  Branch (162:28): [True: 978k, False: 207k]
  ------------------
  163|       |    invariant(actualVal == expectedVal);
  ------------------
  |  |   27|  1.18M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (163:5): [True: 1.18M, False: 0]
  ------------------
  164|  1.18M|  }
  165|    154|}
BitVacuumerRoundtrip.cpp:_ZN8rawspeed12_GLOBAL__N_112checkFlavourINS0_20BitstreamFlavorMSB32EEEvRKNS0_12InputWrapperE:
  174|    149|template <typename flavor> void checkFlavour(const InputWrapper& w) {
  175|    149|  try {
  176|    149|    checkFlavourImpl<flavor>(w);
  177|    149|  } catch (const RawspeedException&) {
  178|       |    assert(false && "Unexpected exception in `checkFlavourImpl()`.");
  ------------------
  |  Branch (178:5): [Folded, False: 0]
  |  Branch (178:5): [True: 0, Folded]
  |  Branch (178:5): [Folded, False: 0]
  ------------------
  179|      0|  }
  180|    149|}
BitVacuumerRoundtrip.cpp:_ZN8rawspeed12_GLOBAL__N_116checkFlavourImplINS0_20BitstreamFlavorMSB32EEEvRKNS0_12InputWrapperE:
  167|    149|template <typename flavor> void checkFlavourImpl(const InputWrapper& w) {
  168|    149|  const std::vector<uint8_t> bitstream = produceBitstream<flavor>(w);
  169|    149|  const auto input =
  170|    149|      Array1DRef(bitstream.data(), implicit_cast<int>(bitstream.size()));
  171|    149|  reparseBitstream<flavor>(input, w);
  172|    149|}
BitVacuumerRoundtrip.cpp:_ZN8rawspeed12_GLOBAL__N_116produceBitstreamINS0_20BitstreamFlavorMSB32EEENSt3__16vectorIhNS3_9allocatorIhEEEERKNS0_12InputWrapperE:
  132|    149|std::vector<uint8_t> produceBitstream(const InputWrapper& w) {
  133|    149|  std::vector<uint8_t> bitstream;
  134|       |
  135|    149|  {
  136|    149|    auto bsInserter = PartitioningOutputIterator(std::back_inserter(bitstream));
  137|    149|    using BitVacuumer = typename BitStreamRoundtripTypes<
  138|    149|        flavor>::template vacuumer<decltype(bsInserter)>;
  139|    149|    auto bv = BitVacuumer(bsInserter);
  140|       |
  141|  1.28M|    for (int i = 0; i != w.size(); ++i) {
  ------------------
  |  Branch (141:21): [True: 1.28M, False: 149]
  ------------------
  142|  1.28M|      const auto [val, len] = w[i];
  143|  1.28M|      bv.put(val, len);
  144|  1.28M|    }
  145|    149|  }
  146|       |
  147|    149|  using BitStreamer = typename BitStreamRoundtripTypes<flavor>::streamer;
  148|    149|  if (constexpr int MinSize = BitStreamerTraits<BitStreamer>::MaxProcessBytes;
  149|    149|      bitstream.size() < MinSize)
  ------------------
  |  Branch (149:7): [True: 12, False: 137]
  ------------------
  150|     12|    bitstream.resize(MinSize, uint8_t(0));
  151|       |
  152|    149|  return bitstream;
  153|    149|}
BitVacuumerRoundtrip.cpp:_ZN8rawspeed12_GLOBAL__N_116reparseBitstreamINS0_20BitstreamFlavorMSB32EEEvNS_10Array1DRefIKhEERKNS0_12InputWrapperE:
  156|    149|void reparseBitstream(Array1DRef<const uint8_t> input, const InputWrapper& w) {
  157|    149|  using BitStreamer = typename BitStreamRoundtripTypes<flavor>::streamer;
  158|    149|  auto bs = BitStreamer(input);
  159|  1.28M|  for (int i = 0; i != w.size(); ++i) {
  ------------------
  |  Branch (159:19): [True: 1.28M, False: 149]
  ------------------
  160|  1.28M|    const auto [expectedVal, len] = w[i];
  161|  1.28M|    bs.fill(32);
  162|  1.28M|    const auto actualVal = len != 0 ? bs.getBitsNoFill(len) : 0;
  ------------------
  |  Branch (162:28): [True: 1.16M, False: 122k]
  ------------------
  163|       |    invariant(actualVal == expectedVal);
  ------------------
  |  |   27|  1.28M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (163:5): [True: 1.28M, False: 0]
  ------------------
  164|  1.28M|  }
  165|    149|}
BitVacuumerRoundtrip.cpp:_ZN8rawspeed12_GLOBAL__N_112checkFlavourINS0_19BitstreamFlavorJPEGEEEvRKNS0_12InputWrapperE:
  174|    371|template <typename flavor> void checkFlavour(const InputWrapper& w) {
  175|    371|  try {
  176|    371|    checkFlavourImpl<flavor>(w);
  177|    371|  } catch (const RawspeedException&) {
  178|       |    assert(false && "Unexpected exception in `checkFlavourImpl()`.");
  ------------------
  |  Branch (178:5): [Folded, False: 0]
  |  Branch (178:5): [True: 0, Folded]
  |  Branch (178:5): [Folded, False: 0]
  ------------------
  179|      0|  }
  180|    371|}
BitVacuumerRoundtrip.cpp:_ZN8rawspeed12_GLOBAL__N_116checkFlavourImplINS0_19BitstreamFlavorJPEGEEEvRKNS0_12InputWrapperE:
  167|    371|template <typename flavor> void checkFlavourImpl(const InputWrapper& w) {
  168|    371|  const std::vector<uint8_t> bitstream = produceBitstream<flavor>(w);
  169|    371|  const auto input =
  170|    371|      Array1DRef(bitstream.data(), implicit_cast<int>(bitstream.size()));
  171|    371|  reparseBitstream<flavor>(input, w);
  172|    371|}
BitVacuumerRoundtrip.cpp:_ZN8rawspeed12_GLOBAL__N_116produceBitstreamINS0_19BitstreamFlavorJPEGEEENSt3__16vectorIhNS3_9allocatorIhEEEERKNS0_12InputWrapperE:
  132|    371|std::vector<uint8_t> produceBitstream(const InputWrapper& w) {
  133|    371|  std::vector<uint8_t> bitstream;
  134|       |
  135|    371|  {
  136|    371|    auto bsInserter = PartitioningOutputIterator(std::back_inserter(bitstream));
  137|    371|    using BitVacuumer = typename BitStreamRoundtripTypes<
  138|    371|        flavor>::template vacuumer<decltype(bsInserter)>;
  139|    371|    auto bv = BitVacuumer(bsInserter);
  140|       |
  141|  3.05M|    for (int i = 0; i != w.size(); ++i) {
  ------------------
  |  Branch (141:21): [True: 3.05M, False: 371]
  ------------------
  142|  3.05M|      const auto [val, len] = w[i];
  143|  3.05M|      bv.put(val, len);
  144|  3.05M|    }
  145|    371|  }
  146|       |
  147|    371|  using BitStreamer = typename BitStreamRoundtripTypes<flavor>::streamer;
  148|    371|  if (constexpr int MinSize = BitStreamerTraits<BitStreamer>::MaxProcessBytes;
  149|    371|      bitstream.size() < MinSize)
  ------------------
  |  Branch (149:7): [True: 83, False: 288]
  ------------------
  150|     83|    bitstream.resize(MinSize, uint8_t(0));
  151|       |
  152|    371|  return bitstream;
  153|    371|}
BitVacuumerRoundtrip.cpp:_ZN8rawspeed12_GLOBAL__N_116reparseBitstreamINS0_19BitstreamFlavorJPEGEEEvNS_10Array1DRefIKhEERKNS0_12InputWrapperE:
  156|    371|void reparseBitstream(Array1DRef<const uint8_t> input, const InputWrapper& w) {
  157|    371|  using BitStreamer = typename BitStreamRoundtripTypes<flavor>::streamer;
  158|    371|  auto bs = BitStreamer(input);
  159|  3.05M|  for (int i = 0; i != w.size(); ++i) {
  ------------------
  |  Branch (159:19): [True: 3.05M, False: 371]
  ------------------
  160|  3.05M|    const auto [expectedVal, len] = w[i];
  161|  3.05M|    bs.fill(32);
  162|  3.05M|    const auto actualVal = len != 0 ? bs.getBitsNoFill(len) : 0;
  ------------------
  |  Branch (162:28): [True: 2.55M, False: 496k]
  ------------------
  163|       |    invariant(actualVal == expectedVal);
  ------------------
  |  |   27|  3.05M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (163:5): [True: 3.05M, False: 0]
  ------------------
  164|  3.05M|  }
  165|    371|}

_ZN8rawspeed10Array1DRefIKhEC2EPS1_i:
  104|  93.0M|    : data(data_), numElts(numElts_) {
  105|  93.0M|  establishClassInvariants();
  106|  93.0M|}
_ZNK8rawspeed10Array1DRefIKhE24establishClassInvariantsEv:
   97|   806M|Array1DRef<T>::establishClassInvariants() const noexcept {
   98|   806M|  invariant(data);
  ------------------
  |  |   27|   806M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (98:3): [True: 806M, False: 0]
  ------------------
   99|   806M|  invariant(numElts >= 0);
  ------------------
  |  |   27|   806M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (99:3): [True: 806M, False: 0]
  ------------------
  100|   806M|}
_ZNK8rawspeed10Array1DRefIKhE5beginEv:
  159|  62.0M|template <class T> inline T* Array1DRef<T>::begin() const {
  160|  62.0M|  establishClassInvariants();
  161|  62.0M|  return addressOf(/*eltIdx=*/0);
  162|  62.0M|}
_ZNK8rawspeed10Array1DRefIKhE9addressOfEi:
  133|  93.0M|Array1DRef<T>::addressOf(const int eltIdx) const {
  134|  93.0M|  establishClassInvariants();
  135|  93.0M|  invariant(eltIdx >= 0);
  ------------------
  |  |   27|  93.0M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (135:3): [True: 93.0M, False: 0]
  ------------------
  136|  93.0M|  invariant(eltIdx <= numElts);
  ------------------
  |  |   27|  93.0M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (136:3): [True: 93.0M, False: 0]
  ------------------
  137|  93.0M|#pragma GCC diagnostic push
  138|  93.0M|#pragma GCC diagnostic ignored "-Wpragmas"
  139|  93.0M|#pragma GCC diagnostic ignored "-Wunknown-warning-option"
  140|  93.0M|#pragma GCC diagnostic ignored "-Wunsafe-buffer-usage"
  141|  93.0M|  return data + eltIdx;
  142|  93.0M|#pragma GCC diagnostic pop
  143|  93.0M|}
_ZNK8rawspeed10Array1DRefIKhE4sizeEv:
  154|   403M|template <class T> inline int Array1DRef<T>::size() const {
  155|   403M|  establishClassInvariants();
  156|   403M|  return numElts;
  157|   403M|}
_ZNK8rawspeed10Array1DRefIKhE7getCropEii:
  110|  31.0M|Array1DRef<T>::getCrop(int offset, int size) const {
  111|  31.0M|  establishClassInvariants();
  112|  31.0M|  invariant(offset >= 0);
  ------------------
  |  |   27|  31.0M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (112:3): [True: 31.0M, False: 0]
  ------------------
  113|  31.0M|  invariant(size >= 0);
  ------------------
  |  |   27|  31.0M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (113:3): [True: 31.0M, False: 0]
  ------------------
  114|  31.0M|  invariant(offset <= numElts);
  ------------------
  |  |   27|  31.0M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (114:3): [True: 31.0M, False: 0]
  ------------------
  115|  31.0M|  invariant(size <= numElts);
  ------------------
  |  |   27|  31.0M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (115:3): [True: 31.0M, False: 0]
  ------------------
  116|  31.0M|  invariant(offset + size <= numElts);
  ------------------
  |  |   27|  31.0M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (116:3): [True: 31.0M, False: 0]
  ------------------
  117|  31.0M|  return {*this, offset, size};
  118|  31.0M|}
_ZN8rawspeed10Array1DRefIKSt4byteEC2IKhQaaaantaasr3stdE10is_const_vITL0__Entsr3stdE10is_const_vIT_Entsr3stdE9is_same_vIu14__remove_constIS7_Eu14__remove_constIS6_EEsr3stdE9is_same_vIS8_S1_EEENS0_IS7_EE:
   78|    986|      : Array1DRef(reinterpret_cast<T*>(RHS.data), sizeof(T2) * RHS.numElts) {}
_ZN8rawspeed10Array1DRefIKSt4byteEC2EPS2_i:
  104|  8.44M|    : data(data_), numElts(numElts_) {
  105|  8.44M|  establishClassInvariants();
  106|  8.44M|}
_ZNK8rawspeed10Array1DRefIKSt4byteE24establishClassInvariantsEv:
   97|   272M|Array1DRef<T>::establishClassInvariants() const noexcept {
   98|   272M|  invariant(data);
  ------------------
  |  |   27|   272M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (98:3): [True: 272M, False: 0]
  ------------------
   99|   272M|  invariant(numElts >= 0);
  ------------------
  |  |   27|   272M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (99:3): [True: 272M, False: 0]
  ------------------
  100|   272M|}
_ZNK8rawspeed10Array1DRefIKSt4byteE4sizeEv:
  154|   143M|template <class T> inline int Array1DRef<T>::size() const {
  155|   143M|  establishClassInvariants();
  156|   143M|  return numElts;
  157|   143M|}
_ZN8rawspeed10Array1DRefISt4byteEC2EPS1_i:
  104|  12.1M|    : data(data_), numElts(numElts_) {
  105|  12.1M|  establishClassInvariants();
  106|  12.1M|}
_ZNK8rawspeed10Array1DRefISt4byteE24establishClassInvariantsEv:
   97|   135M|Array1DRef<T>::establishClassInvariants() const noexcept {
   98|   135M|  invariant(data);
  ------------------
  |  |   27|   135M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (98:3): [True: 135M, False: 0]
  ------------------
   99|   135M|  invariant(numElts >= 0);
  ------------------
  |  |   27|   135M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (99:3): [True: 135M, False: 0]
  ------------------
  100|   135M|}
_ZNK8rawspeed10Array1DRefIKSt4byteE7getCropEii:
  110|  6.09M|Array1DRef<T>::getCrop(int offset, int size) const {
  111|  6.09M|  establishClassInvariants();
  112|  6.09M|  invariant(offset >= 0);
  ------------------
  |  |   27|  6.09M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (112:3): [True: 6.09M, False: 0]
  ------------------
  113|  6.09M|  invariant(size >= 0);
  ------------------
  |  |   27|  6.09M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (113:3): [True: 6.09M, False: 0]
  ------------------
  114|  6.09M|  invariant(offset <= numElts);
  ------------------
  |  |   27|  6.09M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (114:3): [True: 6.09M, False: 0]
  ------------------
  115|  6.09M|  invariant(size <= numElts);
  ------------------
  |  |   27|  6.09M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (115:3): [True: 6.09M, False: 0]
  ------------------
  116|  6.09M|  invariant(offset + size <= numElts);
  ------------------
  |  |   27|  6.09M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (116:3): [True: 6.09M, False: 0]
  ------------------
  117|  6.09M|  return {*this, offset, size};
  118|  6.09M|}
_ZNK8rawspeed10Array1DRefIKSt4byteE9addressOfEi:
  133|  18.8M|Array1DRef<T>::addressOf(const int eltIdx) const {
  134|  18.8M|  establishClassInvariants();
  135|  18.8M|  invariant(eltIdx >= 0);
  ------------------
  |  |   27|  18.8M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (135:3): [True: 18.8M, False: 0]
  ------------------
  136|  18.8M|  invariant(eltIdx <= numElts);
  ------------------
  |  |   27|  18.8M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (136:3): [True: 18.8M, False: 0]
  ------------------
  137|  18.8M|#pragma GCC diagnostic push
  138|  18.8M|#pragma GCC diagnostic ignored "-Wpragmas"
  139|  18.8M|#pragma GCC diagnostic ignored "-Wunknown-warning-option"
  140|  18.8M|#pragma GCC diagnostic ignored "-Wunsafe-buffer-usage"
  141|  18.8M|  return data + eltIdx;
  142|  18.8M|#pragma GCC diagnostic pop
  143|  18.8M|}
_ZNK8rawspeed10Array1DRefISt4byteE4sizeEv:
  154|  54.0M|template <class T> inline int Array1DRef<T>::size() const {
  155|  54.0M|  establishClassInvariants();
  156|  54.0M|  return numElts;
  157|  54.0M|}
_ZNK8rawspeed10Array1DRefISt4byteE5beginEv:
  159|  8.44M|template <class T> inline T* Array1DRef<T>::begin() const {
  160|  8.44M|  establishClassInvariants();
  161|  8.44M|  return addressOf(/*eltIdx=*/0);
  162|  8.44M|}
_ZNK8rawspeed10Array1DRefISt4byteE9addressOfEi:
  133|  25.5M|Array1DRef<T>::addressOf(const int eltIdx) const {
  134|  25.5M|  establishClassInvariants();
  135|  25.5M|  invariant(eltIdx >= 0);
  ------------------
  |  |   27|  25.5M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (135:3): [True: 25.5M, False: 0]
  ------------------
  136|  25.5M|  invariant(eltIdx <= numElts);
  ------------------
  |  |   27|  25.5M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (136:3): [True: 25.5M, False: 0]
  ------------------
  137|  25.5M|#pragma GCC diagnostic push
  138|  25.5M|#pragma GCC diagnostic ignored "-Wpragmas"
  139|  25.5M|#pragma GCC diagnostic ignored "-Wunknown-warning-option"
  140|  25.5M|#pragma GCC diagnostic ignored "-Wunsafe-buffer-usage"
  141|  25.5M|  return data + eltIdx;
  142|  25.5M|#pragma GCC diagnostic pop
  143|  25.5M|}
_ZNK8rawspeed10Array1DRefIKSt4byteE5beginEv:
  159|  9.41M|template <class T> inline T* Array1DRef<T>::begin() const {
  160|  9.41M|  establishClassInvariants();
  161|  9.41M|  return addressOf(/*eltIdx=*/0);
  162|  9.41M|}
_ZNK8rawspeed10Array1DRefISt4byteE3endEv:
  163|    507|template <class T> inline T* Array1DRef<T>::end() const {
  164|    507|  establishClassInvariants();
  165|    507|  return addressOf(/*eltIdx=*/numElts);
  166|    507|}
_ZNK8rawspeed10Array1DRefISt4byteE7getCropEii:
  110|  4.65M|Array1DRef<T>::getCrop(int offset, int size) const {
  111|  4.65M|  establishClassInvariants();
  112|  4.65M|  invariant(offset >= 0);
  ------------------
  |  |   27|  4.65M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (112:3): [True: 4.65M, False: 0]
  ------------------
  113|  4.65M|  invariant(size >= 0);
  ------------------
  |  |   27|  4.65M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (113:3): [True: 4.65M, False: 0]
  ------------------
  114|  4.65M|  invariant(offset <= numElts);
  ------------------
  |  |   27|  4.65M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (114:3): [True: 4.65M, False: 0]
  ------------------
  115|  4.65M|  invariant(size <= numElts);
  ------------------
  |  |   27|  4.65M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (115:3): [True: 4.65M, False: 0]
  ------------------
  116|  4.65M|  invariant(offset + size <= numElts);
  ------------------
  |  |   27|  4.65M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (116:3): [True: 4.65M, False: 0]
  ------------------
  117|  4.65M|  return {*this, offset, size};
  118|  4.65M|}
_ZNK8rawspeed10Array1DRefISt4byteE8getBlockEii:
  122|  4.65M|Array1DRef<T>::getBlock(int size, int index) const {
  123|  4.65M|  establishClassInvariants();
  124|  4.65M|  invariant(index >= 0);
  ------------------
  |  |   27|  4.65M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (124:3): [True: 4.65M, False: 0]
  ------------------
  125|  4.65M|  invariant(size >= 0);
  ------------------
  |  |   27|  4.65M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (125:3): [True: 4.65M, False: 0]
  ------------------
  126|  4.65M|  invariant(index <= numElts);
  ------------------
  |  |   27|  4.65M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (126:3): [True: 4.65M, False: 0]
  ------------------
  127|  4.65M|  invariant(size <= numElts);
  ------------------
  |  |   27|  4.65M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (127:3): [True: 4.65M, False: 0]
  ------------------
  128|  4.65M|  return getCrop(size * index, size);
  129|  4.65M|}
_ZN8rawspeed10Array1DRefIjEC2EPji:
  104|  2.34M|    : data(data_), numElts(numElts_) {
  105|  2.34M|  establishClassInvariants();
  106|  2.34M|}
_ZNK8rawspeed10Array1DRefIjE24establishClassInvariantsEv:
   97|  2.34M|Array1DRef<T>::establishClassInvariants() const noexcept {
   98|  2.34M|  invariant(data);
  ------------------
  |  |   27|  2.34M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (98:3): [True: 2.34M, False: 0]
  ------------------
   99|  2.34M|  invariant(numElts >= 0);
  ------------------
  |  |   27|  2.34M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (99:3): [True: 2.34M, False: 0]
  ------------------
  100|  2.34M|}
_ZN8rawspeed10Array1DRefIKSt4byteEC2IjQaaaantaasr3stdE10is_const_vITL0__Entsr3stdE10is_const_vIT_Entsr3stdE9is_same_vIu14__remove_constIS6_Eu14__remove_constIS5_EEsr3stdE9is_same_vIS7_S1_EEENS0_IS6_EE:
   78|  2.34M|      : Array1DRef(reinterpret_cast<T*>(RHS.data), sizeof(T2) * RHS.numElts) {}
_ZNK8rawspeed10Array1DRefIKSt4byteE3endEv:
  163|  3.32M|template <class T> inline T* Array1DRef<T>::end() const {
  164|  3.32M|  establishClassInvariants();
  165|  3.32M|  return addressOf(/*eltIdx=*/numElts);
  166|  3.32M|}
_ZNK8rawspeed10Array1DRefISt4byteEclEi:
  147|  12.4M|Array1DRef<T>::operator()(const int eltIdx) const {
  148|  12.4M|  establishClassInvariants();
  149|  12.4M|  invariant(eltIdx >= 0);
  ------------------
  |  |   27|  12.4M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (149:3): [True: 12.4M, False: 0]
  ------------------
  150|  12.4M|  invariant(eltIdx < numElts);
  ------------------
  |  |   27|  12.4M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (150:3): [True: 12.4M, False: 0]
  ------------------
  151|  12.4M|  return *addressOf(eltIdx);
  152|  12.4M|}

_ZN8rawspeed18extractLowBitsSafeIjQsr3stdE17unsigned_integralIT_EEES1_S1_j:
  110|  15.5M|constexpr RAWSPEED_READNONE T extractLowBitsSafe(T value, unsigned nBits) {
  111|       |  // invariant(nBits >= 0);
  112|  15.5M|  invariant(nBits <= bitwidth<T>());
  ------------------
  |  |   27|  15.5M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (112:3): [True: 15.5M, False: 0]
  ------------------
  113|  15.5M|  if (nBits == 0)
  ------------------
  |  Branch (113:7): [True: 2.23M, False: 13.2M]
  ------------------
  114|  2.23M|    return 0;
  115|  13.2M|  return extractLowBits(value, nBits);
  116|  15.5M|}
_ZN8rawspeed8bitwidthIjEEjT_:
   43|  30.6M|constexpr unsigned RAWSPEED_READNONE bitwidth([[maybe_unused]] T unused = {}) {
   44|       |  return CHAR_BIT * sizeof(T);
   45|  30.6M|}
_ZN8rawspeed14extractLowBitsIjQsr3stdE17unsigned_integralIT_EEES1_S1_j:
   96|  15.1M|constexpr RAWSPEED_READNONE T extractLowBits(T value, unsigned nBits) {
   97|       |  // invariant(nBits >= 0);
   98|  15.1M|  invariant(nBits != 0);             // Would result in out-of-bound shift.
  ------------------
  |  |   27|  15.1M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (98:3): [True: 15.1M, False: 0]
  ------------------
   99|  15.1M|  invariant(nBits <= bitwidth<T>()); // No-op is fine.
  ------------------
  |  |   27|  15.1M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (99:3): [True: 15.1M, False: 0]
  ------------------
  100|  15.1M|  unsigned numHighPaddingBits = bitwidth<T>() - nBits;
  101|       |  // invariant(numHighPaddingBits >= 0);
  102|  15.1M|  invariant(numHighPaddingBits < bitwidth<T>()); // Shift is in-bounds.
  ------------------
  |  |   27|  15.1M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (102:3): [True: 15.1M, False: 0]
  ------------------
  103|  15.1M|  value <<= numHighPaddingBits;
  104|  15.1M|  value >>= numHighPaddingBits;
  105|  15.1M|  return value;
  106|  15.1M|}
_ZN8rawspeed8bitwidthIhEEjT_:
   43|  20.4M|constexpr unsigned RAWSPEED_READNONE bitwidth([[maybe_unused]] T unused = {}) {
   44|       |  return CHAR_BIT * sizeof(T);
   45|  20.4M|}
_ZN8rawspeed15extractHighBitsImQsr3stdE13is_unsigned_vIT_EEES1_S1_jj:
  121|  11.8M|    T value, unsigned nBits, unsigned effectiveBitwidth = bitwidth<T>()) {
  122|  11.8M|  invariant(effectiveBitwidth <= bitwidth<T>());
  ------------------
  |  |   27|  11.8M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (122:3): [True: 11.8M, False: 0]
  ------------------
  123|  11.8M|  invariant(nBits <= effectiveBitwidth);
  ------------------
  |  |   27|  11.8M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (123:3): [True: 11.8M, False: 0]
  ------------------
  124|  11.8M|  auto numLowBitsToSkip = effectiveBitwidth - nBits;
  125|  11.8M|  invariant(numLowBitsToSkip < bitwidth<T>());
  ------------------
  |  |   27|  11.8M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (125:3): [True: 11.8M, False: 0]
  ------------------
  126|  11.8M|  return value >> numLowBitsToSkip;
  127|  11.8M|}
_ZN8rawspeed8bitwidthImEEjT_:
   43|  11.8M|constexpr unsigned RAWSPEED_READNONE bitwidth([[maybe_unused]] T unused = {}) {
   44|       |  return CHAR_BIT * sizeof(T);
   45|  11.8M|}

_ZN8rawspeed13implicit_castIjmQaaaaoosr3stdE13is_integral_vIT0_Esr3stdE19is_floating_point_vIS1_Eoosr3stdE13is_integral_vIT_Esr3stdE19is_floating_point_vIS2_Entsr3stdE9is_same_vIS1_S2_EEES2_S1_:
   32|  11.8M|constexpr RAWSPEED_READNONE Ttgt implicit_cast(Tsrc value) {
   33|  11.8M|#pragma GCC diagnostic push
   34|  11.8M|#pragma GCC diagnostic ignored "-Wconversion"
   35|  11.8M|#pragma GCC diagnostic ignored "-Wdouble-promotion"
   36|  11.8M|  return value;
   37|  11.8M|#pragma GCC diagnostic pop
   38|  11.8M|}
_ZN8rawspeed13implicit_castIijQaaaaoosr3stdE13is_integral_vIT0_Esr3stdE19is_floating_point_vIS1_Eoosr3stdE13is_integral_vIT_Esr3stdE19is_floating_point_vIS2_Entsr3stdE9is_same_vIS1_S2_EEES2_S1_:
   32|  62.0M|constexpr RAWSPEED_READNONE Ttgt implicit_cast(Tsrc value) {
   33|  62.0M|#pragma GCC diagnostic push
   34|  62.0M|#pragma GCC diagnostic ignored "-Wconversion"
   35|  62.0M|#pragma GCC diagnostic ignored "-Wdouble-promotion"
   36|  62.0M|  return value;
   37|  62.0M|#pragma GCC diagnostic pop
   38|  62.0M|}
_ZN8rawspeed13implicit_castIiiQaaaaoosr3stdE13is_integral_vIT0_Esr3stdE19is_floating_point_vIS1_Eoosr3stdE13is_integral_vIT_Esr3stdE19is_floating_point_vIS2_Esr3stdE9is_same_vIS1_S2_EEES2_S1_:
   46|  15.5M|constexpr RAWSPEED_READNONE Ttgt implicit_cast(Tsrc value) {
   47|  15.5M|  return value;
   48|  15.5M|}
_ZN8rawspeed13implicit_castIjjQaaaaoosr3stdE13is_integral_vIT0_Esr3stdE19is_floating_point_vIS1_Eoosr3stdE13is_integral_vIT_Esr3stdE19is_floating_point_vIS2_Esr3stdE9is_same_vIS1_S2_EEES2_S1_:
   46|  5.20M|constexpr RAWSPEED_READNONE Ttgt implicit_cast(Tsrc value) {
   47|  5.20M|  return value;
   48|  5.20M|}
_ZN8rawspeed13implicit_castIimQaaaaoosr3stdE13is_integral_vIT0_Esr3stdE19is_floating_point_vIS1_Eoosr3stdE13is_integral_vIT_Esr3stdE19is_floating_point_vIS2_Entsr3stdE9is_same_vIS1_S2_EEES2_S1_:
   32|  12.1M|constexpr RAWSPEED_READNONE Ttgt implicit_cast(Tsrc value) {
   33|  12.1M|#pragma GCC diagnostic push
   34|  12.1M|#pragma GCC diagnostic ignored "-Wconversion"
   35|  12.1M|#pragma GCC diagnostic ignored "-Wdouble-promotion"
   36|  12.1M|  return value;
   37|  12.1M|#pragma GCC diagnostic pop
   38|  12.1M|}
_ZN8rawspeed13implicit_castItjQaaaaoosr3stdE13is_integral_vIT0_Esr3stdE19is_floating_point_vIS1_Eoosr3stdE13is_integral_vIT_Esr3stdE19is_floating_point_vIS2_Entsr3stdE9is_same_vIS1_S2_EEES2_S1_:
   32|  1.79M|constexpr RAWSPEED_READNONE Ttgt implicit_cast(Tsrc value) {
   33|  1.79M|#pragma GCC diagnostic push
   34|  1.79M|#pragma GCC diagnostic ignored "-Wconversion"
   35|  1.79M|#pragma GCC diagnostic ignored "-Wdouble-promotion"
   36|  1.79M|  return value;
   37|  1.79M|#pragma GCC diagnostic pop
   38|  1.79M|}

_ZN8rawspeed17CroppedArray1DRefIKhEC2ENS_10Array1DRefIS1_EEii:
  107|  31.0M|    : base(base_), offset(offset_), numElts(numElts_) {
  108|  31.0M|  establishClassInvariants();
  109|  31.0M|}
_ZNK8rawspeed17CroppedArray1DRefIKhE24establishClassInvariantsEv:
   94|   124M|CroppedArray1DRef<T>::establishClassInvariants() const noexcept {
   95|   124M|  base.establishClassInvariants();
   96|   124M|  invariant(offset >= 0);
  ------------------
  |  |   27|   124M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (96:3): [True: 124M, False: 0]
  ------------------
   97|   124M|  invariant(numElts >= 0);
  ------------------
  |  |   27|   124M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (97:3): [True: 124M, False: 0]
  ------------------
   98|   124M|  invariant(offset <= base.size());
  ------------------
  |  |   27|   124M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (98:3): [True: 124M, False: 0]
  ------------------
   99|   124M|  invariant(numElts <= base.size());
  ------------------
  |  |   27|   124M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (99:3): [True: 124M, False: 0]
  ------------------
  100|   124M|  invariant(offset + numElts <= base.size());
  ------------------
  |  |   27|   124M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (100:3): [True: 124M, False: 0]
  ------------------
  101|   124M|}
_ZNK8rawspeed17CroppedArray1DRefIKhE15getAsArray1DRefEv:
   71|  31.0M|  [[nodiscard]] Array1DRef<T> getAsArray1DRef() const {
   72|  31.0M|    return {begin(), size()};
   73|  31.0M|  }
_ZNK8rawspeed17CroppedArray1DRefIKhE5beginEv:
  137|  31.0M|template <class T> inline T* CroppedArray1DRef<T>::begin() const {
  138|  31.0M|  establishClassInvariants();
  139|  31.0M|  return addressOf(/*eltIdx=*/0);
  140|  31.0M|}
_ZNK8rawspeed17CroppedArray1DRefIKhE9addressOfEi:
  152|  31.0M|inline T* CroppedArray1DRef<T>::addressOf(const int eltIdx) const {
  153|  31.0M|  establishClassInvariants();
  154|  31.0M|  invariant(eltIdx >= 0);
  ------------------
  |  |   27|  31.0M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (154:3): [True: 31.0M, False: 0]
  ------------------
  155|  31.0M|  invariant(eltIdx <= numElts);
  ------------------
  |  |   27|  31.0M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (155:3): [True: 31.0M, False: 0]
  ------------------
  156|  31.0M|  return base.addressOf(offset + eltIdx);
  157|  31.0M|}
_ZNK8rawspeed17CroppedArray1DRefIKhE4sizeEv:
  146|  31.0M|template <class T> inline int CroppedArray1DRef<T>::size() const {
  147|  31.0M|  establishClassInvariants();
  148|  31.0M|  return numElts;
  149|  31.0M|}
_ZN8rawspeed17CroppedArray1DRefIKSt4byteEC2ENS_10Array1DRefIS2_EEii:
  107|  6.09M|    : base(base_), offset(offset_), numElts(numElts_) {
  108|  6.09M|  establishClassInvariants();
  109|  6.09M|}
_ZNK8rawspeed17CroppedArray1DRefIKSt4byteE24establishClassInvariantsEv:
   94|  24.3M|CroppedArray1DRef<T>::establishClassInvariants() const noexcept {
   95|  24.3M|  base.establishClassInvariants();
   96|  24.3M|  invariant(offset >= 0);
  ------------------
  |  |   27|  24.3M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (96:3): [True: 24.3M, False: 0]
  ------------------
   97|  24.3M|  invariant(numElts >= 0);
  ------------------
  |  |   27|  24.3M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (97:3): [True: 24.3M, False: 0]
  ------------------
   98|  24.3M|  invariant(offset <= base.size());
  ------------------
  |  |   27|  24.3M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (98:3): [True: 24.3M, False: 0]
  ------------------
   99|  24.3M|  invariant(numElts <= base.size());
  ------------------
  |  |   27|  24.3M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (99:3): [True: 24.3M, False: 0]
  ------------------
  100|  24.3M|  invariant(offset + numElts <= base.size());
  ------------------
  |  |   27|  24.3M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (100:3): [True: 24.3M, False: 0]
  ------------------
  101|  24.3M|}
_ZNK8rawspeed17CroppedArray1DRefIKSt4byteE15getAsArray1DRefEv:
   71|  6.09M|  [[nodiscard]] Array1DRef<T> getAsArray1DRef() const {
   72|  6.09M|    return {begin(), size()};
   73|  6.09M|  }
_ZNK8rawspeed17CroppedArray1DRefIKSt4byteE5beginEv:
  137|  6.09M|template <class T> inline T* CroppedArray1DRef<T>::begin() const {
  138|  6.09M|  establishClassInvariants();
  139|  6.09M|  return addressOf(/*eltIdx=*/0);
  140|  6.09M|}
_ZNK8rawspeed17CroppedArray1DRefIKSt4byteE9addressOfEi:
  152|  6.09M|inline T* CroppedArray1DRef<T>::addressOf(const int eltIdx) const {
  153|  6.09M|  establishClassInvariants();
  154|  6.09M|  invariant(eltIdx >= 0);
  ------------------
  |  |   27|  6.09M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (154:3): [True: 6.09M, False: 0]
  ------------------
  155|  6.09M|  invariant(eltIdx <= numElts);
  ------------------
  |  |   27|  6.09M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (155:3): [True: 6.09M, False: 0]
  ------------------
  156|  6.09M|  return base.addressOf(offset + eltIdx);
  157|  6.09M|}
_ZNK8rawspeed17CroppedArray1DRefIKSt4byteE4sizeEv:
  146|  6.09M|template <class T> inline int CroppedArray1DRef<T>::size() const {
  147|  6.09M|  establishClassInvariants();
  148|  6.09M|  return numElts;
  149|  6.09M|}
_ZN8rawspeed17CroppedArray1DRefISt4byteEC2ENS_10Array1DRefIS1_EEii:
  107|  4.65M|    : base(base_), offset(offset_), numElts(numElts_) {
  108|  4.65M|  establishClassInvariants();
  109|  4.65M|}
_ZNK8rawspeed17CroppedArray1DRefISt4byteE24establishClassInvariantsEv:
   94|  13.9M|CroppedArray1DRef<T>::establishClassInvariants() const noexcept {
   95|  13.9M|  base.establishClassInvariants();
   96|  13.9M|  invariant(offset >= 0);
  ------------------
  |  |   27|  13.9M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (96:3): [True: 13.9M, False: 0]
  ------------------
   97|  13.9M|  invariant(numElts >= 0);
  ------------------
  |  |   27|  13.9M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (97:3): [True: 13.9M, False: 0]
  ------------------
   98|  13.9M|  invariant(offset <= base.size());
  ------------------
  |  |   27|  13.9M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (98:3): [True: 13.9M, False: 0]
  ------------------
   99|  13.9M|  invariant(numElts <= base.size());
  ------------------
  |  |   27|  13.9M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (99:3): [True: 13.9M, False: 0]
  ------------------
  100|  13.9M|  invariant(offset + numElts <= base.size());
  ------------------
  |  |   27|  13.9M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (100:3): [True: 13.9M, False: 0]
  ------------------
  101|  13.9M|}
_ZNK8rawspeed17CroppedArray1DRefISt4byteE15getAsArray1DRefEv:
   71|    507|  [[nodiscard]] Array1DRef<T> getAsArray1DRef() const {
   72|    507|    return {begin(), size()};
   73|    507|  }
_ZNK8rawspeed17CroppedArray1DRefISt4byteE5beginEv:
  137|  4.65M|template <class T> inline T* CroppedArray1DRef<T>::begin() const {
  138|  4.65M|  establishClassInvariants();
  139|  4.65M|  return addressOf(/*eltIdx=*/0);
  140|  4.65M|}
_ZNK8rawspeed17CroppedArray1DRefISt4byteE9addressOfEi:
  152|  4.65M|inline T* CroppedArray1DRef<T>::addressOf(const int eltIdx) const {
  153|  4.65M|  establishClassInvariants();
  154|  4.65M|  invariant(eltIdx >= 0);
  ------------------
  |  |   27|  4.65M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (154:3): [True: 4.65M, False: 0]
  ------------------
  155|  4.65M|  invariant(eltIdx <= numElts);
  ------------------
  |  |   27|  4.65M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (155:3): [True: 4.65M, False: 0]
  ------------------
  156|  4.65M|  return base.addressOf(offset + eltIdx);
  157|  4.65M|}
_ZNK8rawspeed17CroppedArray1DRefISt4byteE4sizeEv:
  146|    507|template <class T> inline int CroppedArray1DRef<T>::size() const {
  147|    507|  establishClassInvariants();
  148|    507|  return numElts;
  149|    507|}

_ZN8rawspeed26PartitioningOutputIteratorINSt3__120back_insert_iteratorINS1_6vectorIhNS1_9allocatorIhEEEEEEhEC2IS7_Qsr3stdE7same_asIT_u20__remove_reference_tITL0__EEEEOSA_:
   51|    986|  explicit PartitioningOutputIterator(U&& it_) : it(std::forward<U>(it_)) {}
_ZN8rawspeed26PartitioningOutputIteratorINSt3__120back_insert_iteratorINS1_6vectorIhNS1_9allocatorIhEEEEEEhEdeEv:
   53|  13.7M|  [[nodiscard]] PartitioningOutputIterator& operator*() { return *this; }
_ZN8rawspeed26PartitioningOutputIteratorINSt3__120back_insert_iteratorINS1_6vectorIhNS1_9allocatorIhEEEEEEhEaSIjQaaaasr3stdE17unsigned_integralITL0__EgestSA_stT0_eqrmstSA_stSB_Li0EEERS8_T_:
   63|  4.22M|  PartitioningOutputIterator& operator=(U coalesced) {
   64|       |    // NOLINTNEXTLINE(bugprone-sizeof-expression)
   65|  4.22M|    constexpr int NumParts = sizeof(U) / sizeof(PartType);
   66|  21.1M|    for (int i = 0; i != NumParts; ++i) {
  ------------------
  |  Branch (66:21): [True: 16.9M, False: 4.22M]
  ------------------
   67|  16.9M|      const auto part = static_cast<PartType>(coalesced);
   68|       |      if constexpr (NumParts != 1)
   69|  16.9M|        coalesced >>= bitwidth<PartType>();
   70|  16.9M|      *it = part;
   71|  16.9M|      ++it;
   72|  16.9M|    }
   73|  4.22M|    return *this;
   74|  4.22M|  }
_ZN8rawspeed26PartitioningOutputIteratorINSt3__120back_insert_iteratorINS1_6vectorIhNS1_9allocatorIhEEEEEEhEppEv:
   55|  13.7M|  PartitioningOutputIterator& operator++() { return *this; }
_ZN8rawspeed26PartitioningOutputIteratorINSt3__120back_insert_iteratorINS1_6vectorIhNS1_9allocatorIhEEEEEEhEaSItQaaaasr3stdE17unsigned_integralITL0__EgestSA_stT0_eqrmstSA_stSB_Li0EEERS8_T_:
   63|  1.79M|  PartitioningOutputIterator& operator=(U coalesced) {
   64|       |    // NOLINTNEXTLINE(bugprone-sizeof-expression)
   65|  1.79M|    constexpr int NumParts = sizeof(U) / sizeof(PartType);
   66|  5.37M|    for (int i = 0; i != NumParts; ++i) {
  ------------------
  |  Branch (66:21): [True: 3.58M, False: 1.79M]
  ------------------
   67|  3.58M|      const auto part = static_cast<PartType>(coalesced);
   68|       |      if constexpr (NumParts != 1)
   69|  3.58M|        coalesced >>= bitwidth<PartType>();
   70|  3.58M|      *it = part;
   71|  3.58M|      ++it;
   72|  3.58M|    }
   73|  1.79M|    return *this;
   74|  1.79M|  }
_ZN8rawspeed26PartitioningOutputIteratorINSt3__120back_insert_iteratorINS1_6vectorIhNS1_9allocatorIhEEEEEEhEaSIhQaaaasr3stdE17unsigned_integralITL0__EgestSA_stT0_eqrmstSA_stSB_Li0EEERS8_T_:
   63|  7.73M|  PartitioningOutputIterator& operator=(U coalesced) {
   64|       |    // NOLINTNEXTLINE(bugprone-sizeof-expression)
   65|  7.73M|    constexpr int NumParts = sizeof(U) / sizeof(PartType);
   66|  15.4M|    for (int i = 0; i != NumParts; ++i) {
  ------------------
  |  Branch (66:21): [True: 7.73M, False: 7.73M]
  ------------------
   67|  7.73M|      const auto part = static_cast<PartType>(coalesced);
   68|       |      if constexpr (NumParts != 1)
   69|       |        coalesced >>= bitwidth<PartType>();
   70|  7.73M|      *it = part;
   71|  7.73M|      ++it;
   72|  7.73M|    }
   73|  7.73M|    return *this;
   74|  7.73M|  }

_ZN8rawspeed32variableLengthLoadNaiveViaMemcpyENS_10Array1DRefISt4byteEENS0_IKS1_EEi:
  150|    507|                                             int inPos) {
  151|    507|  invariant(out.size() != 0);
  ------------------
  |  |   27|    507|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (151:3): [True: 507, False: 0]
  ------------------
  152|    507|  invariant(in.size() != 0);
  ------------------
  |  |   27|    507|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (152:3): [True: 507, False: 0]
  ------------------
  153|    507|  invariant(out.size() <= in.size());
  ------------------
  |  |   27|    507|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (153:3): [True: 507, False: 0]
  ------------------
  154|    507|  invariant(inPos >= 0);
  ------------------
  |  |   27|    507|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (154:3): [True: 507, False: 0]
  ------------------
  155|       |
  156|    507|  std::fill(out.begin(), out.end(), std::byte{0x00});
  157|       |
  158|    507|  inPos = std::min(inPos, in.size());
  159|       |
  160|    507|  int inPosEnd = inPos + out.size();
  161|    507|  inPosEnd = std::min(inPosEnd, in.size());
  162|    507|  invariant(inPos <= inPosEnd);
  ------------------
  |  |   27|    507|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (162:3): [True: 507, False: 0]
  ------------------
  163|       |
  164|    507|  const int copySize = inPosEnd - inPos;
  165|    507|  invariant(copySize >= 0);
  ------------------
  |  |   27|    507|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (165:3): [True: 507, False: 0]
  ------------------
  166|    507|  invariant(copySize <= out.size());
  ------------------
  |  |   27|    507|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (166:3): [True: 507, False: 0]
  ------------------
  167|       |
  168|    507|  out = out.getCrop(/*offset=*/0, copySize).getAsArray1DRef();
  169|    507|  in = in.getCrop(/*offset=*/inPos, copySize).getAsArray1DRef();
  170|    507|  invariant(in.size() == out.size());
  ------------------
  |  |   27|    507|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (170:3): [True: 507, False: 0]
  ------------------
  171|       |
  172|    507|  memcpy(out.begin(), in.begin(), copySize);
  173|    507|}

_ZNK8rawspeed28BitStreamCacheLeftInRightOut4peekEi:
   70|  1.82M|  [[nodiscard]] uint32_t peek(int count) const noexcept {
   71|  1.82M|    establishClassInvariants();
   72|  1.82M|    invariant(count >= 0);
  ------------------
  |  |   27|  1.82M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (72:5): [True: 1.82M, False: 0]
  ------------------
   73|  1.82M|    invariant(count <= MaxGetBits);
  ------------------
  |  |   27|  1.82M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (73:5): [True: 1.82M, False: 0]
  ------------------
   74|  1.82M|    invariant(count != 0);
  ------------------
  |  |   27|  1.82M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (74:5): [True: 1.82M, False: 0]
  ------------------
   75|  1.82M|    invariant(count <= Size);
  ------------------
  |  |   27|  1.82M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (75:5): [True: 1.82M, False: 0]
  ------------------
   76|  1.82M|    invariant(count <= fillLevel);
  ------------------
  |  |   27|  1.82M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (76:5): [True: 1.82M, False: 0]
  ------------------
   77|  1.82M|    return extractLowBits(static_cast<uint32_t>(cache), count);
   78|  1.82M|  }
_ZNK8rawspeed18BitStreamCacheBase24establishClassInvariantsEv:
   54|  79.7M|BitStreamCacheBase::establishClassInvariants() const noexcept {
   55|  79.7M|  invariant(fillLevel >= 0);
  ------------------
  |  |   27|  79.7M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (55:3): [True: 79.7M, False: 0]
  ------------------
   56|  79.7M|  invariant(fillLevel <= Size);
  ------------------
  |  |   27|  79.7M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (56:3): [True: 79.7M, False: 0]
  ------------------
   57|  79.7M|}
_ZN8rawspeed28BitStreamCacheLeftInRightOut4skipEi:
   80|  1.82M|  void skip(int count) noexcept {
   81|  1.82M|    establishClassInvariants();
   82|  1.82M|    invariant(count >= 0);
  ------------------
  |  |   27|  1.82M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (82:5): [True: 1.82M, False: 0]
  ------------------
   83|       |    // `count` *could* be larger than `MaxGetBits`.
   84|       |    // `count` could be zero.
   85|  1.82M|    invariant(count <= Size);
  ------------------
  |  |   27|  1.82M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (85:5): [True: 1.82M, False: 0]
  ------------------
   86|  1.82M|    invariant(count <= fillLevel);
  ------------------
  |  |   27|  1.82M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (86:5): [True: 1.82M, False: 0]
  ------------------
   87|  1.82M|    cache >>= count;
   88|  1.82M|    fillLevel -= count;
   89|  1.82M|  }
_ZN8rawspeed28BitStreamCacheLeftInRightOut4pushEmi:
   60|  1.93M|  void push(uint64_t bits, int count) noexcept {
   61|  1.93M|    establishClassInvariants();
   62|  1.93M|    invariant(count >= 0);
  ------------------
  |  |   27|  1.93M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (62:5): [True: 1.93M, False: 0]
  ------------------
   63|       |    // NOTE: count may be zero!
   64|  1.93M|    invariant(count <= Size);
  ------------------
  |  |   27|  1.93M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (64:5): [True: 1.93M, False: 0]
  ------------------
   65|  1.93M|    invariant(count + fillLevel <= Size);
  ------------------
  |  |   27|  1.93M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (65:5): [True: 1.93M, False: 0]
  ------------------
   66|  1.93M|    cache |= bits << fillLevel;
   67|  1.93M|    fillLevel += count;
   68|  1.93M|  }
_ZNK8rawspeed28BitStreamCacheRightInLeftOut4peekEi:
  119|  11.8M|  [[nodiscard]] auto peek(int count) const noexcept {
  120|  11.8M|    establishClassInvariants();
  121|  11.8M|    invariant(count >= 0);
  ------------------
  |  |   27|  11.8M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (121:5): [True: 11.8M, False: 0]
  ------------------
  122|  11.8M|    invariant(count <= Size);
  ------------------
  |  |   27|  11.8M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (122:5): [True: 11.8M, False: 0]
  ------------------
  123|  11.8M|    invariant(count <= MaxGetBits);
  ------------------
  |  |   27|  11.8M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (123:5): [True: 11.8M, False: 0]
  ------------------
  124|  11.8M|    invariant(count != 0);
  ------------------
  |  |   27|  11.8M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (124:5): [True: 11.8M, False: 0]
  ------------------
  125|  11.8M|    invariant(count <= fillLevel);
  ------------------
  |  |   27|  11.8M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (125:5): [True: 11.8M, False: 0]
  ------------------
  126|  11.8M|    return implicit_cast<uint32_t>(
  127|  11.8M|        extractHighBits(cache, count,
  128|  11.8M|                        /*effectiveBitwidth=*/BitStreamCacheBase::Size));
  129|  11.8M|  }
_ZN8rawspeed28BitStreamCacheRightInLeftOut4skipEi:
  131|  11.8M|  void skip(int count) noexcept {
  132|  11.8M|    establishClassInvariants();
  133|  11.8M|    invariant(count >= 0);
  ------------------
  |  |   27|  11.8M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (133:5): [True: 11.8M, False: 0]
  ------------------
  134|       |    // `count` *could* be larger than `MaxGetBits`.
  135|       |    // `count` could be zero.
  136|  11.8M|    invariant(count <= Size);
  ------------------
  |  |   27|  11.8M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (136:5): [True: 11.8M, False: 0]
  ------------------
  137|  11.8M|    invariant(count <= fillLevel);
  ------------------
  |  |   27|  11.8M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (137:5): [True: 11.8M, False: 0]
  ------------------
  138|  11.8M|    fillLevel -= count;
  139|  11.8M|    cache <<= count;
  140|  11.8M|  }
_ZN8rawspeed28BitStreamCacheRightInLeftOut4pushEmi:
   93|  16.7M|  void push(uint64_t bits, int count) noexcept {
   94|  16.7M|    establishClassInvariants();
   95|  16.7M|    invariant(count >= 0);
  ------------------
  |  |   27|  16.7M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (95:5): [True: 16.7M, False: 0]
  ------------------
   96|       |    // NOTE: count may be zero!
   97|  16.7M|    invariant(count <= Size);
  ------------------
  |  |   27|  16.7M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (97:5): [True: 16.7M, False: 0]
  ------------------
   98|  16.7M|    invariant(count + fillLevel <= Size);
  ------------------
  |  |   27|  16.7M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (98:5): [True: 16.7M, False: 0]
  ------------------
   99|       |    // If the maximal size of the cache is BitStreamCacheBase::Size, and we
  100|       |    // have fillLevel [high] bits set, how many empty [low] bits do we have?
  101|  16.7M|    const int vacantBits = BitStreamCacheBase::Size - fillLevel;
  102|  16.7M|    invariant(vacantBits >= 0);
  ------------------
  |  |   27|  16.7M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (102:5): [True: 16.7M, False: 0]
  ------------------
  103|  16.7M|    invariant(vacantBits <= Size);
  ------------------
  |  |   27|  16.7M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (103:5): [True: 16.7M, False: 0]
  ------------------
  104|  16.7M|    invariant(vacantBits != 0);
  ------------------
  |  |   27|  16.7M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (104:5): [True: 16.7M, False: 0]
  ------------------
  105|  16.7M|    invariant(vacantBits >= count);
  ------------------
  |  |   27|  16.7M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (105:5): [True: 16.7M, False: 0]
  ------------------
  106|       |    // If we just directly 'or' these low bits into the cache right now,
  107|       |    // how many unfilled bits of a gap will there be in the middle of a cache?
  108|  16.7M|    const int emptyBitsGap = vacantBits - count;
  109|  16.7M|    invariant(emptyBitsGap >= 0);
  ------------------
  |  |   27|  16.7M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (109:5): [True: 16.7M, False: 0]
  ------------------
  110|  16.7M|    invariant(emptyBitsGap <= Size);
  ------------------
  |  |   27|  16.7M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (110:5): [True: 16.7M, False: 0]
  ------------------
  111|  16.7M|    if (count != 0) {
  ------------------
  |  Branch (111:9): [True: 15.7M, False: 1.00M]
  ------------------
  112|  15.7M|      invariant(emptyBitsGap < Size);
  ------------------
  |  |   27|  15.7M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (112:7): [True: 15.7M, False: 0]
  ------------------
  113|       |      // So just shift the new bits so that there is no gap in the middle.
  114|  15.7M|      cache |= bits << emptyBitsGap;
  115|  15.7M|    }
  116|  16.7M|    fillLevel += count;
  117|  16.7M|  }

_ZN8rawspeed11BitStreamerINS_14BitStreamerLSBENS_39BitStreamerForwardSequentialReplenisherIS1_EEEC2ENS_10Array1DRefIKSt4byteEE:
  192|    155|  explicit BitStreamer(Array1DRef<const std::byte> input) : replenisher(input) {
  193|    155|    establishClassInvariants();
  194|    155|  }
_ZN8rawspeed26BitStreamerReplenisherBaseINS_14BitStreamerLSBEEC2ENS_10Array1DRefIKSt4byteEE:
   57|    155|      : input(input_) {
   58|    155|    if (input.size() < BitStreamerTraits<Tag>::MaxProcessBytes)
  ------------------
  |  Branch (58:9): [True: 0, False: 155]
  ------------------
   59|    155|      ThrowIOE("Bit stream size is smaller than MaxProcessBytes");
  ------------------
  |  |   37|      0|#define ThrowIOE(...) ThrowExceptionHelper(rawspeed::IOException, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   84|      0|  rawspeed::ThrowException<CLASS>("%s, line " STR(__LINE__) ": " fmt,          \
  |  |  |  |   85|      0|                                  __PRETTY_FUNCTION__ __VA_OPT__(, )           \
  |  |  |  |   86|      0|                                      __VA_ARGS__)
  |  |  ------------------
  ------------------
   60|    155|  }
_ZNK8rawspeed11BitStreamerINS_14BitStreamerLSBENS_39BitStreamerForwardSequentialReplenisherIS1_EEE24establishClassInvariantsEv:
  185|  4.78M|  void establishClassInvariants() const noexcept {
  186|  4.78M|    cache.establishClassInvariants();
  187|  4.78M|    replenisher.establishClassInvariants();
  188|  4.78M|  }
_ZNK8rawspeed26BitStreamerReplenisherBaseINS_14BitStreamerLSBEE24establishClassInvariantsEv:
   65|  8.29M|BitStreamerReplenisherBase<Tag>::establishClassInvariants() const noexcept {
   66|  8.29M|  input.establishClassInvariants();
   67|  8.29M|  invariant(input.size() >= BitStreamerTraits<Tag>::MaxProcessBytes);
  ------------------
  |  |   27|  8.29M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (67:3): [True: 8.29M, False: 0]
  ------------------
   68|  8.29M|  invariant(pos >= 0);
  ------------------
  |  |   27|  8.29M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (68:3): [True: 8.29M, False: 0]
  ------------------
   69|  8.29M|  invariant(pos % StreamTraits::MinLoadStepByteMultiple == 0);
  ------------------
  |  |   27|  8.29M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (69:3): [True: 8.29M, False: 0]
  ------------------
   70|       |  // `pos` *could* be out-of-bounds of `input`.
   71|  8.29M|}
_ZN8rawspeed11BitStreamerINS_14BitStreamerLSBENS_39BitStreamerForwardSequentialReplenisherIS1_EEE4fillEi:
  216|  1.06M|  void fill(int nbits = Cache::MaxGetBits) {
  217|  1.06M|    establishClassInvariants();
  218|  1.06M|    invariant(nbits >= 0);
  ------------------
  |  |   27|  1.06M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (218:5): [True: 1.06M, False: 0]
  ------------------
  219|  1.06M|    invariant(nbits != 0);
  ------------------
  |  |   27|  1.06M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (219:5): [True: 1.06M, False: 0]
  ------------------
  220|  1.06M|    invariant(nbits <= Cache::MaxGetBits);
  ------------------
  |  |   27|  1.06M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (220:5): [True: 1.06M, False: 0]
  ------------------
  221|       |
  222|  1.06M|    if (cache.fillLevel >= nbits)
  ------------------
  |  Branch (222:9): [True: 181k, False: 878k]
  ------------------
  223|   181k|      return;
  224|       |
  225|   878k|    const auto input = replenisher.getInput();
  226|   878k|    const auto numBytes = static_cast<Derived*>(this)->fillCache(input);
  227|   878k|    replenisher.markNumBytesAsConsumed(numBytes);
  228|       |    invariant(cache.fillLevel >= nbits);
  ------------------
  |  |   27|   878k|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (228:5): [True: 878k, False: 0]
  ------------------
  229|   878k|  }
_ZN8rawspeed39BitStreamerForwardSequentialReplenisherINS_14BitStreamerLSBEE8getInputEv:
  100|   878k|  std::array<std::byte, BitStreamerTraits<Tag>::MaxProcessBytes> getInput() {
  101|   878k|    Base::establishClassInvariants();
  102|       |
  103|   878k|    std::array<std::byte, BitStreamerTraits<Tag>::MaxProcessBytes> tmpStorage;
  104|   878k|    auto tmp = Array1DRef<std::byte>(tmpStorage.data(),
  105|   878k|                                     implicit_cast<int>(tmpStorage.size()));
  106|       |
  107|       |    // Do we have BitStreamerTraits<Tag>::MaxProcessBytes or more bytes left in
  108|       |    // the input buffer? If so, then we can just read from said buffer.
  109|   878k|    if (getPos() + BitStreamerTraits<Tag>::MaxProcessBytes <=
  ------------------
  |  Branch (109:9): [True: 878k, False: 35]
  ------------------
  110|   878k|        Base::input.size()) [[likely]] {
  111|   878k|      auto currInput =
  112|   878k|          Base::input.getCrop(getPos(), BitStreamerTraits<Tag>::MaxProcessBytes)
  113|   878k|              .getAsArray1DRef();
  114|   878k|      invariant(currInput.size() == tmp.size());
  ------------------
  |  |   27|   878k|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (114:7): [True: 878k, False: 0]
  ------------------
  115|   878k|      memcpy(tmp.begin(), currInput.begin(),
  116|   878k|             BitStreamerTraits<Tag>::MaxProcessBytes);
  117|   878k|      return tmpStorage;
  118|   878k|    }
  119|       |
  120|       |    // We have to use intermediate buffer, either because the input is running
  121|       |    // out of bytes, or because we want to enforce bounds checking.
  122|       |
  123|       |    // Note that in order to keep all fill-level invariants we must allow to
  124|       |    // over-read past-the-end a bit.
  125|     35|    if (getPos() > Base::input.size() +
  ------------------
  |  Branch (125:9): [True: 0, False: 35]
  ------------------
  126|     35|                       2 * BitStreamerTraits<Tag>::MaxProcessBytes) [[unlikely]]
  127|      0|      ThrowIOE("Buffer overflow read in BitStreamer");
  ------------------
  |  |   37|      0|#define ThrowIOE(...) ThrowExceptionHelper(rawspeed::IOException, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   84|      0|  rawspeed::ThrowException<CLASS>("%s, line " STR(__LINE__) ": " fmt,          \
  |  |  |  |   85|      0|                                  __PRETTY_FUNCTION__ __VA_OPT__(, )           \
  |  |  |  |   86|      0|                                      __VA_ARGS__)
  |  |  ------------------
  ------------------
  128|       |
  129|     35|    variableLengthLoadNaiveViaMemcpy(tmp, Base::input, getPos());
  130|       |
  131|     35|    return tmpStorage;
  132|     35|  }
_ZNK8rawspeed39BitStreamerForwardSequentialReplenisherINS_14BitStreamerLSBEE6getPosEv:
   84|  1.75M|  [[nodiscard]] typename Base::size_type getPos() const {
   85|  1.75M|    Base::establishClassInvariants();
   86|  1.75M|    return Base::pos;
   87|  1.75M|  }
_ZN8rawspeed11BitStreamerINS_14BitStreamerLSBENS_39BitStreamerForwardSequentialReplenisherIS1_EEE9fillCacheENSt3__15arrayISt4byteLm4EEE:
  157|   878k|                inputStorage) {
  158|   878k|    static_assert(BitStreamCacheBase::MaxGetBits >= 32, "check implementation");
  159|   878k|    establishClassInvariants();
  160|   878k|    auto input = Array1DRef<std::byte>(inputStorage.data(),
  161|   878k|                                       implicit_cast<int>(inputStorage.size()));
  162|   878k|    invariant(input.size() == Traits::MaxProcessBytes);
  ------------------
  |  |   27|   878k|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (162:5): [True: 878k, False: 0]
  ------------------
  163|       |
  164|   878k|    constexpr int StreamChunkBitwidth =
  165|   878k|        bitwidth<typename StreamTraits::ChunkType>();
  166|   878k|    static_assert(CHAR_BIT * Traits::MaxProcessBytes >= StreamChunkBitwidth);
  167|   878k|    static_assert(CHAR_BIT * Traits::MaxProcessBytes % StreamChunkBitwidth ==
  168|   878k|                  0);
  169|   878k|    constexpr int NumChunksNeeded =
  170|   878k|        (CHAR_BIT * Traits::MaxProcessBytes) / StreamChunkBitwidth;
  171|   878k|    static_assert(NumChunksNeeded >= 1);
  172|       |
  173|  1.75M|    for (int i = 0; i != NumChunksNeeded; ++i) {
  ------------------
  |  Branch (173:21): [True: 878k, False: 878k]
  ------------------
  174|   878k|      auto chunkInput =
  175|   878k|          input.getBlock(sizeof(typename StreamTraits::ChunkType), i);
  176|   878k|      auto chunk = getByteSwapped<typename StreamTraits::ChunkType>(
  177|   878k|          chunkInput.begin(),
  178|   878k|          StreamTraits::ChunkEndianness != getHostEndianness());
  179|   878k|      cache.push(chunk, StreamChunkBitwidth);
  180|   878k|    }
  181|   878k|    return Traits::MaxProcessBytes;
  182|   878k|  }
_ZN8rawspeed39BitStreamerForwardSequentialReplenisherINS_14BitStreamerLSBEE22markNumBytesAsConsumedEi:
   92|   878k|  void markNumBytesAsConsumed(typename Base::size_type numBytes) {
   93|   878k|    Base::establishClassInvariants();
   94|   878k|    invariant(numBytes >= 0);
  ------------------
  |  |   27|   878k|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (94:5): [True: 878k, False: 0]
  ------------------
   95|   878k|    invariant(numBytes != 0);
  ------------------
  |  |   27|   878k|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (95:5): [True: 878k, False: 0]
  ------------------
   96|   878k|    invariant(numBytes % StreamTraits::MinLoadStepByteMultiple == 0);
  ------------------
  |  |   27|   878k|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (96:5): [True: 878k, False: 0]
  ------------------
   97|   878k|    Base::pos += numBytes;
   98|   878k|  }
_ZN8rawspeed11BitStreamerINS_14BitStreamerLSBENS_39BitStreamerForwardSequentialReplenisherIS1_EEE13getBitsNoFillEi:
  269|   947k|  uint32_t getBitsNoFill(int nbits) {
  270|   947k|    establishClassInvariants();
  271|   947k|    invariant(nbits >= 0);
  ------------------
  |  |   27|   947k|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (271:5): [True: 947k, False: 0]
  ------------------
  272|   947k|    invariant(nbits != 0);
  ------------------
  |  |   27|   947k|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (272:5): [True: 947k, False: 0]
  ------------------
  273|   947k|    invariant(nbits <= Cache::MaxGetBits);
  ------------------
  |  |   27|   947k|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (273:5): [True: 947k, False: 0]
  ------------------
  274|   947k|    uint32_t ret = peekBitsNoFill(nbits);
  275|   947k|    skipBitsNoFill(nbits);
  276|   947k|    return ret;
  277|   947k|  }
_ZN8rawspeed11BitStreamerINS_14BitStreamerLSBENS_39BitStreamerForwardSequentialReplenisherIS1_EEE14peekBitsNoFillEi:
  253|   947k|  uint32_t RAWSPEED_READONLY peekBitsNoFill(int nbits) {
  254|   947k|    establishClassInvariants();
  255|   947k|    invariant(nbits >= 0);
  ------------------
  |  |   27|   947k|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (255:5): [True: 947k, False: 0]
  ------------------
  256|   947k|    invariant(nbits != 0);
  ------------------
  |  |   27|   947k|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (256:5): [True: 947k, False: 0]
  ------------------
  257|   947k|    invariant(nbits <= Cache::MaxGetBits);
  ------------------
  |  |   27|   947k|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (257:5): [True: 947k, False: 0]
  ------------------
  258|   947k|    return cache.peek(nbits);
  259|   947k|  }
_ZN8rawspeed11BitStreamerINS_14BitStreamerLSBENS_39BitStreamerForwardSequentialReplenisherIS1_EEE14skipBitsNoFillEi:
  261|   947k|  void skipBitsNoFill(int nbits) {
  262|   947k|    establishClassInvariants();
  263|   947k|    invariant(nbits >= 0);
  ------------------
  |  |   27|   947k|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (263:5): [True: 947k, False: 0]
  ------------------
  264|       |    // `nbits` could be zero.
  265|   947k|    invariant(nbits <= Cache::MaxGetBits);
  ------------------
  |  |   27|   947k|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (265:5): [True: 947k, False: 0]
  ------------------
  266|   947k|    cache.skip(nbits);
  267|   947k|  }
_ZN8rawspeed11BitStreamerINS_14BitStreamerMSBENS_39BitStreamerForwardSequentialReplenisherIS1_EEEC2ENS_10Array1DRefIKSt4byteEE:
  192|    157|  explicit BitStreamer(Array1DRef<const std::byte> input) : replenisher(input) {
  193|    157|    establishClassInvariants();
  194|    157|  }
_ZN8rawspeed26BitStreamerReplenisherBaseINS_14BitStreamerMSBEEC2ENS_10Array1DRefIKSt4byteEE:
   57|    157|      : input(input_) {
   58|    157|    if (input.size() < BitStreamerTraits<Tag>::MaxProcessBytes)
  ------------------
  |  Branch (58:9): [True: 0, False: 157]
  ------------------
   59|    157|      ThrowIOE("Bit stream size is smaller than MaxProcessBytes");
  ------------------
  |  |   37|      0|#define ThrowIOE(...) ThrowExceptionHelper(rawspeed::IOException, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   84|      0|  rawspeed::ThrowException<CLASS>("%s, line " STR(__LINE__) ": " fmt,          \
  |  |  |  |   85|      0|                                  __PRETTY_FUNCTION__ __VA_OPT__(, )           \
  |  |  |  |   86|      0|                                      __VA_ARGS__)
  |  |  ------------------
  ------------------
   60|    157|  }
_ZNK8rawspeed11BitStreamerINS_14BitStreamerMSBENS_39BitStreamerForwardSequentialReplenisherIS1_EEE24establishClassInvariantsEv:
  185|  5.05M|  void establishClassInvariants() const noexcept {
  186|  5.05M|    cache.establishClassInvariants();
  187|  5.05M|    replenisher.establishClassInvariants();
  188|  5.05M|  }
_ZNK8rawspeed26BitStreamerReplenisherBaseINS_14BitStreamerMSBEE24establishClassInvariantsEv:
   65|  8.70M|BitStreamerReplenisherBase<Tag>::establishClassInvariants() const noexcept {
   66|  8.70M|  input.establishClassInvariants();
   67|  8.70M|  invariant(input.size() >= BitStreamerTraits<Tag>::MaxProcessBytes);
  ------------------
  |  |   27|  8.70M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (67:3): [True: 8.70M, False: 0]
  ------------------
   68|  8.70M|  invariant(pos >= 0);
  ------------------
  |  |   27|  8.70M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (68:3): [True: 8.70M, False: 0]
  ------------------
   69|  8.70M|  invariant(pos % StreamTraits::MinLoadStepByteMultiple == 0);
  ------------------
  |  |   27|  8.70M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (69:3): [True: 8.70M, False: 0]
  ------------------
   70|       |  // `pos` *could* be out-of-bounds of `input`.
   71|  8.70M|}
_ZN8rawspeed11BitStreamerINS_14BitStreamerMSBENS_39BitStreamerForwardSequentialReplenisherIS1_EEE4fillEi:
  216|  1.16M|  void fill(int nbits = Cache::MaxGetBits) {
  217|  1.16M|    establishClassInvariants();
  218|  1.16M|    invariant(nbits >= 0);
  ------------------
  |  |   27|  1.16M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (218:5): [True: 1.16M, False: 0]
  ------------------
  219|  1.16M|    invariant(nbits != 0);
  ------------------
  |  |   27|  1.16M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (219:5): [True: 1.16M, False: 0]
  ------------------
  220|  1.16M|    invariant(nbits <= Cache::MaxGetBits);
  ------------------
  |  |   27|  1.16M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (220:5): [True: 1.16M, False: 0]
  ------------------
  221|       |
  222|  1.16M|    if (cache.fillLevel >= nbits)
  ------------------
  |  Branch (222:9): [True: 257k, False: 910k]
  ------------------
  223|   257k|      return;
  224|       |
  225|   910k|    const auto input = replenisher.getInput();
  226|   910k|    const auto numBytes = static_cast<Derived*>(this)->fillCache(input);
  227|   910k|    replenisher.markNumBytesAsConsumed(numBytes);
  228|       |    invariant(cache.fillLevel >= nbits);
  ------------------
  |  |   27|   910k|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (228:5): [True: 910k, False: 0]
  ------------------
  229|   910k|  }
_ZN8rawspeed39BitStreamerForwardSequentialReplenisherINS_14BitStreamerMSBEE8getInputEv:
  100|   910k|  std::array<std::byte, BitStreamerTraits<Tag>::MaxProcessBytes> getInput() {
  101|   910k|    Base::establishClassInvariants();
  102|       |
  103|   910k|    std::array<std::byte, BitStreamerTraits<Tag>::MaxProcessBytes> tmpStorage;
  104|   910k|    auto tmp = Array1DRef<std::byte>(tmpStorage.data(),
  105|   910k|                                     implicit_cast<int>(tmpStorage.size()));
  106|       |
  107|       |    // Do we have BitStreamerTraits<Tag>::MaxProcessBytes or more bytes left in
  108|       |    // the input buffer? If so, then we can just read from said buffer.
  109|   910k|    if (getPos() + BitStreamerTraits<Tag>::MaxProcessBytes <=
  ------------------
  |  Branch (109:9): [True: 910k, False: 47]
  ------------------
  110|   910k|        Base::input.size()) [[likely]] {
  111|   910k|      auto currInput =
  112|   910k|          Base::input.getCrop(getPos(), BitStreamerTraits<Tag>::MaxProcessBytes)
  113|   910k|              .getAsArray1DRef();
  114|   910k|      invariant(currInput.size() == tmp.size());
  ------------------
  |  |   27|   910k|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (114:7): [True: 910k, False: 0]
  ------------------
  115|   910k|      memcpy(tmp.begin(), currInput.begin(),
  116|   910k|             BitStreamerTraits<Tag>::MaxProcessBytes);
  117|   910k|      return tmpStorage;
  118|   910k|    }
  119|       |
  120|       |    // We have to use intermediate buffer, either because the input is running
  121|       |    // out of bytes, or because we want to enforce bounds checking.
  122|       |
  123|       |    // Note that in order to keep all fill-level invariants we must allow to
  124|       |    // over-read past-the-end a bit.
  125|     47|    if (getPos() > Base::input.size() +
  ------------------
  |  Branch (125:9): [True: 0, False: 47]
  ------------------
  126|     47|                       2 * BitStreamerTraits<Tag>::MaxProcessBytes) [[unlikely]]
  127|      0|      ThrowIOE("Buffer overflow read in BitStreamer");
  ------------------
  |  |   37|      0|#define ThrowIOE(...) ThrowExceptionHelper(rawspeed::IOException, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   84|      0|  rawspeed::ThrowException<CLASS>("%s, line " STR(__LINE__) ": " fmt,          \
  |  |  |  |   85|      0|                                  __PRETTY_FUNCTION__ __VA_OPT__(, )           \
  |  |  |  |   86|      0|                                      __VA_ARGS__)
  |  |  ------------------
  ------------------
  128|       |
  129|     47|    variableLengthLoadNaiveViaMemcpy(tmp, Base::input, getPos());
  130|       |
  131|     47|    return tmpStorage;
  132|     47|  }
_ZNK8rawspeed39BitStreamerForwardSequentialReplenisherINS_14BitStreamerMSBEE6getPosEv:
   84|  1.82M|  [[nodiscard]] typename Base::size_type getPos() const {
   85|  1.82M|    Base::establishClassInvariants();
   86|  1.82M|    return Base::pos;
   87|  1.82M|  }
_ZN8rawspeed11BitStreamerINS_14BitStreamerMSBENS_39BitStreamerForwardSequentialReplenisherIS1_EEE9fillCacheENSt3__15arrayISt4byteLm4EEE:
  157|   910k|                inputStorage) {
  158|   910k|    static_assert(BitStreamCacheBase::MaxGetBits >= 32, "check implementation");
  159|   910k|    establishClassInvariants();
  160|   910k|    auto input = Array1DRef<std::byte>(inputStorage.data(),
  161|   910k|                                       implicit_cast<int>(inputStorage.size()));
  162|   910k|    invariant(input.size() == Traits::MaxProcessBytes);
  ------------------
  |  |   27|   910k|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (162:5): [True: 910k, False: 0]
  ------------------
  163|       |
  164|   910k|    constexpr int StreamChunkBitwidth =
  165|   910k|        bitwidth<typename StreamTraits::ChunkType>();
  166|   910k|    static_assert(CHAR_BIT * Traits::MaxProcessBytes >= StreamChunkBitwidth);
  167|   910k|    static_assert(CHAR_BIT * Traits::MaxProcessBytes % StreamChunkBitwidth ==
  168|   910k|                  0);
  169|   910k|    constexpr int NumChunksNeeded =
  170|   910k|        (CHAR_BIT * Traits::MaxProcessBytes) / StreamChunkBitwidth;
  171|   910k|    static_assert(NumChunksNeeded >= 1);
  172|       |
  173|  1.82M|    for (int i = 0; i != NumChunksNeeded; ++i) {
  ------------------
  |  Branch (173:21): [True: 910k, False: 910k]
  ------------------
  174|   910k|      auto chunkInput =
  175|   910k|          input.getBlock(sizeof(typename StreamTraits::ChunkType), i);
  176|   910k|      auto chunk = getByteSwapped<typename StreamTraits::ChunkType>(
  177|   910k|          chunkInput.begin(),
  178|   910k|          StreamTraits::ChunkEndianness != getHostEndianness());
  179|   910k|      cache.push(chunk, StreamChunkBitwidth);
  180|   910k|    }
  181|   910k|    return Traits::MaxProcessBytes;
  182|   910k|  }
_ZN8rawspeed39BitStreamerForwardSequentialReplenisherINS_14BitStreamerMSBEE22markNumBytesAsConsumedEi:
   92|   910k|  void markNumBytesAsConsumed(typename Base::size_type numBytes) {
   93|   910k|    Base::establishClassInvariants();
   94|   910k|    invariant(numBytes >= 0);
  ------------------
  |  |   27|   910k|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (94:5): [True: 910k, False: 0]
  ------------------
   95|   910k|    invariant(numBytes != 0);
  ------------------
  |  |   27|   910k|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (95:5): [True: 910k, False: 0]
  ------------------
   96|   910k|    invariant(numBytes % StreamTraits::MinLoadStepByteMultiple == 0);
  ------------------
  |  |   27|   910k|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (96:5): [True: 910k, False: 0]
  ------------------
   97|   910k|    Base::pos += numBytes;
   98|   910k|  }
_ZN8rawspeed11BitStreamerINS_14BitStreamerMSBENS_39BitStreamerForwardSequentialReplenisherIS1_EEE13getBitsNoFillEi:
  269|   993k|  uint32_t getBitsNoFill(int nbits) {
  270|   993k|    establishClassInvariants();
  271|   993k|    invariant(nbits >= 0);
  ------------------
  |  |   27|   993k|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (271:5): [True: 993k, False: 0]
  ------------------
  272|   993k|    invariant(nbits != 0);
  ------------------
  |  |   27|   993k|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (272:5): [True: 993k, False: 0]
  ------------------
  273|   993k|    invariant(nbits <= Cache::MaxGetBits);
  ------------------
  |  |   27|   993k|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (273:5): [True: 993k, False: 0]
  ------------------
  274|   993k|    uint32_t ret = peekBitsNoFill(nbits);
  275|   993k|    skipBitsNoFill(nbits);
  276|   993k|    return ret;
  277|   993k|  }
_ZN8rawspeed11BitStreamerINS_14BitStreamerMSBENS_39BitStreamerForwardSequentialReplenisherIS1_EEE14peekBitsNoFillEi:
  253|   993k|  uint32_t RAWSPEED_READONLY peekBitsNoFill(int nbits) {
  254|   993k|    establishClassInvariants();
  255|   993k|    invariant(nbits >= 0);
  ------------------
  |  |   27|   993k|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (255:5): [True: 993k, False: 0]
  ------------------
  256|   993k|    invariant(nbits != 0);
  ------------------
  |  |   27|   993k|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (256:5): [True: 993k, False: 0]
  ------------------
  257|   993k|    invariant(nbits <= Cache::MaxGetBits);
  ------------------
  |  |   27|   993k|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (257:5): [True: 993k, False: 0]
  ------------------
  258|   993k|    return cache.peek(nbits);
  259|   993k|  }
_ZN8rawspeed11BitStreamerINS_14BitStreamerMSBENS_39BitStreamerForwardSequentialReplenisherIS1_EEE14skipBitsNoFillEi:
  261|   993k|  void skipBitsNoFill(int nbits) {
  262|   993k|    establishClassInvariants();
  263|   993k|    invariant(nbits >= 0);
  ------------------
  |  |   27|   993k|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (263:5): [True: 993k, False: 0]
  ------------------
  264|       |    // `nbits` could be zero.
  265|   993k|    invariant(nbits <= Cache::MaxGetBits);
  ------------------
  |  |   27|   993k|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (265:5): [True: 993k, False: 0]
  ------------------
  266|   993k|    cache.skip(nbits);
  267|   993k|  }
_ZN8rawspeed11BitStreamerINS_16BitStreamerMSB16ENS_39BitStreamerForwardSequentialReplenisherIS1_EEEC2ENS_10Array1DRefIKSt4byteEE:
  192|    154|  explicit BitStreamer(Array1DRef<const std::byte> input) : replenisher(input) {
  193|    154|    establishClassInvariants();
  194|    154|  }
_ZN8rawspeed26BitStreamerReplenisherBaseINS_16BitStreamerMSB16EEC2ENS_10Array1DRefIKSt4byteEE:
   57|    154|      : input(input_) {
   58|    154|    if (input.size() < BitStreamerTraits<Tag>::MaxProcessBytes)
  ------------------
  |  Branch (58:9): [True: 0, False: 154]
  ------------------
   59|    154|      ThrowIOE("Bit stream size is smaller than MaxProcessBytes");
  ------------------
  |  |   37|      0|#define ThrowIOE(...) ThrowExceptionHelper(rawspeed::IOException, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   84|      0|  rawspeed::ThrowException<CLASS>("%s, line " STR(__LINE__) ": " fmt,          \
  |  |  |  |   85|      0|                                  __PRETTY_FUNCTION__ __VA_OPT__(, )           \
  |  |  |  |   86|      0|                                      __VA_ARGS__)
  |  |  ------------------
  ------------------
   60|    154|  }
_ZNK8rawspeed11BitStreamerINS_16BitStreamerMSB16ENS_39BitStreamerForwardSequentialReplenisherIS1_EEE24establishClassInvariantsEv:
  185|  5.01M|  void establishClassInvariants() const noexcept {
  186|  5.01M|    cache.establishClassInvariants();
  187|  5.01M|    replenisher.establishClassInvariants();
  188|  5.01M|  }
_ZNK8rawspeed26BitStreamerReplenisherBaseINS_16BitStreamerMSB16EE24establishClassInvariantsEv:
   65|  8.59M|BitStreamerReplenisherBase<Tag>::establishClassInvariants() const noexcept {
   66|  8.59M|  input.establishClassInvariants();
   67|  8.59M|  invariant(input.size() >= BitStreamerTraits<Tag>::MaxProcessBytes);
  ------------------
  |  |   27|  8.59M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (67:3): [True: 8.59M, False: 0]
  ------------------
   68|  8.59M|  invariant(pos >= 0);
  ------------------
  |  |   27|  8.59M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (68:3): [True: 8.59M, False: 0]
  ------------------
   69|  8.59M|  invariant(pos % StreamTraits::MinLoadStepByteMultiple == 0);
  ------------------
  |  |   27|  8.59M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (69:3): [True: 8.59M, False: 0]
  ------------------
   70|       |  // `pos` *could* be out-of-bounds of `input`.
   71|  8.59M|}
_ZN8rawspeed11BitStreamerINS_16BitStreamerMSB16ENS_39BitStreamerForwardSequentialReplenisherIS1_EEE4fillEi:
  216|  1.18M|  void fill(int nbits = Cache::MaxGetBits) {
  217|  1.18M|    establishClassInvariants();
  218|  1.18M|    invariant(nbits >= 0);
  ------------------
  |  |   27|  1.18M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (218:5): [True: 1.18M, False: 0]
  ------------------
  219|  1.18M|    invariant(nbits != 0);
  ------------------
  |  |   27|  1.18M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (219:5): [True: 1.18M, False: 0]
  ------------------
  220|  1.18M|    invariant(nbits <= Cache::MaxGetBits);
  ------------------
  |  |   27|  1.18M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (220:5): [True: 1.18M, False: 0]
  ------------------
  221|       |
  222|  1.18M|    if (cache.fillLevel >= nbits)
  ------------------
  |  Branch (222:9): [True: 290k, False: 895k]
  ------------------
  223|   290k|      return;
  224|       |
  225|   895k|    const auto input = replenisher.getInput();
  226|   895k|    const auto numBytes = static_cast<Derived*>(this)->fillCache(input);
  227|   895k|    replenisher.markNumBytesAsConsumed(numBytes);
  228|       |    invariant(cache.fillLevel >= nbits);
  ------------------
  |  |   27|   895k|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (228:5): [True: 895k, False: 0]
  ------------------
  229|   895k|  }
_ZN8rawspeed39BitStreamerForwardSequentialReplenisherINS_16BitStreamerMSB16EE8getInputEv:
  100|   895k|  std::array<std::byte, BitStreamerTraits<Tag>::MaxProcessBytes> getInput() {
  101|   895k|    Base::establishClassInvariants();
  102|       |
  103|   895k|    std::array<std::byte, BitStreamerTraits<Tag>::MaxProcessBytes> tmpStorage;
  104|   895k|    auto tmp = Array1DRef<std::byte>(tmpStorage.data(),
  105|   895k|                                     implicit_cast<int>(tmpStorage.size()));
  106|       |
  107|       |    // Do we have BitStreamerTraits<Tag>::MaxProcessBytes or more bytes left in
  108|       |    // the input buffer? If so, then we can just read from said buffer.
  109|   895k|    if (getPos() + BitStreamerTraits<Tag>::MaxProcessBytes <=
  ------------------
  |  Branch (109:9): [True: 895k, False: 42]
  ------------------
  110|   895k|        Base::input.size()) [[likely]] {
  111|   895k|      auto currInput =
  112|   895k|          Base::input.getCrop(getPos(), BitStreamerTraits<Tag>::MaxProcessBytes)
  113|   895k|              .getAsArray1DRef();
  114|   895k|      invariant(currInput.size() == tmp.size());
  ------------------
  |  |   27|   895k|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (114:7): [True: 895k, False: 0]
  ------------------
  115|   895k|      memcpy(tmp.begin(), currInput.begin(),
  116|   895k|             BitStreamerTraits<Tag>::MaxProcessBytes);
  117|   895k|      return tmpStorage;
  118|   895k|    }
  119|       |
  120|       |    // We have to use intermediate buffer, either because the input is running
  121|       |    // out of bytes, or because we want to enforce bounds checking.
  122|       |
  123|       |    // Note that in order to keep all fill-level invariants we must allow to
  124|       |    // over-read past-the-end a bit.
  125|     42|    if (getPos() > Base::input.size() +
  ------------------
  |  Branch (125:9): [True: 0, False: 42]
  ------------------
  126|     42|                       2 * BitStreamerTraits<Tag>::MaxProcessBytes) [[unlikely]]
  127|      0|      ThrowIOE("Buffer overflow read in BitStreamer");
  ------------------
  |  |   37|      0|#define ThrowIOE(...) ThrowExceptionHelper(rawspeed::IOException, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   84|      0|  rawspeed::ThrowException<CLASS>("%s, line " STR(__LINE__) ": " fmt,          \
  |  |  |  |   85|      0|                                  __PRETTY_FUNCTION__ __VA_OPT__(, )           \
  |  |  |  |   86|      0|                                      __VA_ARGS__)
  |  |  ------------------
  ------------------
  128|       |
  129|     42|    variableLengthLoadNaiveViaMemcpy(tmp, Base::input, getPos());
  130|       |
  131|     42|    return tmpStorage;
  132|     42|  }
_ZNK8rawspeed39BitStreamerForwardSequentialReplenisherINS_16BitStreamerMSB16EE6getPosEv:
   84|  1.79M|  [[nodiscard]] typename Base::size_type getPos() const {
   85|  1.79M|    Base::establishClassInvariants();
   86|  1.79M|    return Base::pos;
   87|  1.79M|  }
_ZN8rawspeed11BitStreamerINS_16BitStreamerMSB16ENS_39BitStreamerForwardSequentialReplenisherIS1_EEE9fillCacheENSt3__15arrayISt4byteLm4EEE:
  157|   895k|                inputStorage) {
  158|   895k|    static_assert(BitStreamCacheBase::MaxGetBits >= 32, "check implementation");
  159|   895k|    establishClassInvariants();
  160|   895k|    auto input = Array1DRef<std::byte>(inputStorage.data(),
  161|   895k|                                       implicit_cast<int>(inputStorage.size()));
  162|   895k|    invariant(input.size() == Traits::MaxProcessBytes);
  ------------------
  |  |   27|   895k|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (162:5): [True: 895k, False: 0]
  ------------------
  163|       |
  164|   895k|    constexpr int StreamChunkBitwidth =
  165|   895k|        bitwidth<typename StreamTraits::ChunkType>();
  166|   895k|    static_assert(CHAR_BIT * Traits::MaxProcessBytes >= StreamChunkBitwidth);
  167|   895k|    static_assert(CHAR_BIT * Traits::MaxProcessBytes % StreamChunkBitwidth ==
  168|   895k|                  0);
  169|   895k|    constexpr int NumChunksNeeded =
  170|   895k|        (CHAR_BIT * Traits::MaxProcessBytes) / StreamChunkBitwidth;
  171|   895k|    static_assert(NumChunksNeeded >= 1);
  172|       |
  173|  2.68M|    for (int i = 0; i != NumChunksNeeded; ++i) {
  ------------------
  |  Branch (173:21): [True: 1.79M, False: 895k]
  ------------------
  174|  1.79M|      auto chunkInput =
  175|  1.79M|          input.getBlock(sizeof(typename StreamTraits::ChunkType), i);
  176|  1.79M|      auto chunk = getByteSwapped<typename StreamTraits::ChunkType>(
  177|  1.79M|          chunkInput.begin(),
  178|  1.79M|          StreamTraits::ChunkEndianness != getHostEndianness());
  179|  1.79M|      cache.push(chunk, StreamChunkBitwidth);
  180|  1.79M|    }
  181|   895k|    return Traits::MaxProcessBytes;
  182|   895k|  }
_ZN8rawspeed39BitStreamerForwardSequentialReplenisherINS_16BitStreamerMSB16EE22markNumBytesAsConsumedEi:
   92|   895k|  void markNumBytesAsConsumed(typename Base::size_type numBytes) {
   93|   895k|    Base::establishClassInvariants();
   94|   895k|    invariant(numBytes >= 0);
  ------------------
  |  |   27|   895k|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (94:5): [True: 895k, False: 0]
  ------------------
   95|   895k|    invariant(numBytes != 0);
  ------------------
  |  |   27|   895k|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (95:5): [True: 895k, False: 0]
  ------------------
   96|   895k|    invariant(numBytes % StreamTraits::MinLoadStepByteMultiple == 0);
  ------------------
  |  |   27|   895k|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (96:5): [True: 895k, False: 0]
  ------------------
   97|   895k|    Base::pos += numBytes;
   98|   895k|  }
_ZN8rawspeed11BitStreamerINS_16BitStreamerMSB16ENS_39BitStreamerForwardSequentialReplenisherIS1_EEE13getBitsNoFillEi:
  269|   978k|  uint32_t getBitsNoFill(int nbits) {
  270|   978k|    establishClassInvariants();
  271|   978k|    invariant(nbits >= 0);
  ------------------
  |  |   27|   978k|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (271:5): [True: 978k, False: 0]
  ------------------
  272|   978k|    invariant(nbits != 0);
  ------------------
  |  |   27|   978k|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (272:5): [True: 978k, False: 0]
  ------------------
  273|   978k|    invariant(nbits <= Cache::MaxGetBits);
  ------------------
  |  |   27|   978k|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (273:5): [True: 978k, False: 0]
  ------------------
  274|   978k|    uint32_t ret = peekBitsNoFill(nbits);
  275|   978k|    skipBitsNoFill(nbits);
  276|   978k|    return ret;
  277|   978k|  }
_ZN8rawspeed11BitStreamerINS_16BitStreamerMSB16ENS_39BitStreamerForwardSequentialReplenisherIS1_EEE14peekBitsNoFillEi:
  253|   978k|  uint32_t RAWSPEED_READONLY peekBitsNoFill(int nbits) {
  254|   978k|    establishClassInvariants();
  255|   978k|    invariant(nbits >= 0);
  ------------------
  |  |   27|   978k|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (255:5): [True: 978k, False: 0]
  ------------------
  256|   978k|    invariant(nbits != 0);
  ------------------
  |  |   27|   978k|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (256:5): [True: 978k, False: 0]
  ------------------
  257|   978k|    invariant(nbits <= Cache::MaxGetBits);
  ------------------
  |  |   27|   978k|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (257:5): [True: 978k, False: 0]
  ------------------
  258|   978k|    return cache.peek(nbits);
  259|   978k|  }
_ZN8rawspeed11BitStreamerINS_16BitStreamerMSB16ENS_39BitStreamerForwardSequentialReplenisherIS1_EEE14skipBitsNoFillEi:
  261|   978k|  void skipBitsNoFill(int nbits) {
  262|   978k|    establishClassInvariants();
  263|   978k|    invariant(nbits >= 0);
  ------------------
  |  |   27|   978k|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (263:5): [True: 978k, False: 0]
  ------------------
  264|       |    // `nbits` could be zero.
  265|   978k|    invariant(nbits <= Cache::MaxGetBits);
  ------------------
  |  |   27|   978k|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (265:5): [True: 978k, False: 0]
  ------------------
  266|   978k|    cache.skip(nbits);
  267|   978k|  }
_ZN8rawspeed11BitStreamerINS_16BitStreamerMSB32ENS_39BitStreamerForwardSequentialReplenisherIS1_EEEC2ENS_10Array1DRefIKSt4byteEE:
  192|    149|  explicit BitStreamer(Array1DRef<const std::byte> input) : replenisher(input) {
  193|    149|    establishClassInvariants();
  194|    149|  }
_ZN8rawspeed26BitStreamerReplenisherBaseINS_16BitStreamerMSB32EEC2ENS_10Array1DRefIKSt4byteEE:
   57|    149|      : input(input_) {
   58|    149|    if (input.size() < BitStreamerTraits<Tag>::MaxProcessBytes)
  ------------------
  |  Branch (58:9): [True: 0, False: 149]
  ------------------
   59|    149|      ThrowIOE("Bit stream size is smaller than MaxProcessBytes");
  ------------------
  |  |   37|      0|#define ThrowIOE(...) ThrowExceptionHelper(rawspeed::IOException, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   84|      0|  rawspeed::ThrowException<CLASS>("%s, line " STR(__LINE__) ": " fmt,          \
  |  |  |  |   85|      0|                                  __PRETTY_FUNCTION__ __VA_OPT__(, )           \
  |  |  |  |   86|      0|                                      __VA_ARGS__)
  |  |  ------------------
  ------------------
   60|    149|  }
_ZNK8rawspeed11BitStreamerINS_16BitStreamerMSB32ENS_39BitStreamerForwardSequentialReplenisherIS1_EEE24establishClassInvariantsEv:
  185|  5.85M|  void establishClassInvariants() const noexcept {
  186|  5.85M|    cache.establishClassInvariants();
  187|  5.85M|    replenisher.establishClassInvariants();
  188|  5.85M|  }
_ZNK8rawspeed26BitStreamerReplenisherBaseINS_16BitStreamerMSB32EE24establishClassInvariantsEv:
   65|  10.1M|BitStreamerReplenisherBase<Tag>::establishClassInvariants() const noexcept {
   66|  10.1M|  input.establishClassInvariants();
   67|  10.1M|  invariant(input.size() >= BitStreamerTraits<Tag>::MaxProcessBytes);
  ------------------
  |  |   27|  10.1M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (67:3): [True: 10.1M, False: 0]
  ------------------
   68|  10.1M|  invariant(pos >= 0);
  ------------------
  |  |   27|  10.1M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (68:3): [True: 10.1M, False: 0]
  ------------------
   69|  10.1M|  invariant(pos % StreamTraits::MinLoadStepByteMultiple == 0);
  ------------------
  |  |   27|  10.1M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (69:3): [True: 10.1M, False: 0]
  ------------------
   70|       |  // `pos` *could* be out-of-bounds of `input`.
   71|  10.1M|}
_ZN8rawspeed11BitStreamerINS_16BitStreamerMSB32ENS_39BitStreamerForwardSequentialReplenisherIS1_EEE4fillEi:
  216|  1.28M|  void fill(int nbits = Cache::MaxGetBits) {
  217|  1.28M|    establishClassInvariants();
  218|  1.28M|    invariant(nbits >= 0);
  ------------------
  |  |   27|  1.28M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (218:5): [True: 1.28M, False: 0]
  ------------------
  219|  1.28M|    invariant(nbits != 0);
  ------------------
  |  |   27|  1.28M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (219:5): [True: 1.28M, False: 0]
  ------------------
  220|  1.28M|    invariant(nbits <= Cache::MaxGetBits);
  ------------------
  |  |   27|  1.28M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (220:5): [True: 1.28M, False: 0]
  ------------------
  221|       |
  222|  1.28M|    if (cache.fillLevel >= nbits)
  ------------------
  |  Branch (222:9): [True: 217k, False: 1.06M]
  ------------------
  223|   217k|      return;
  224|       |
  225|  1.06M|    const auto input = replenisher.getInput();
  226|  1.06M|    const auto numBytes = static_cast<Derived*>(this)->fillCache(input);
  227|  1.06M|    replenisher.markNumBytesAsConsumed(numBytes);
  228|       |    invariant(cache.fillLevel >= nbits);
  ------------------
  |  |   27|  1.06M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (228:5): [True: 1.06M, False: 0]
  ------------------
  229|  1.06M|  }
_ZN8rawspeed39BitStreamerForwardSequentialReplenisherINS_16BitStreamerMSB32EE8getInputEv:
  100|  1.06M|  std::array<std::byte, BitStreamerTraits<Tag>::MaxProcessBytes> getInput() {
  101|  1.06M|    Base::establishClassInvariants();
  102|       |
  103|  1.06M|    std::array<std::byte, BitStreamerTraits<Tag>::MaxProcessBytes> tmpStorage;
  104|  1.06M|    auto tmp = Array1DRef<std::byte>(tmpStorage.data(),
  105|  1.06M|                                     implicit_cast<int>(tmpStorage.size()));
  106|       |
  107|       |    // Do we have BitStreamerTraits<Tag>::MaxProcessBytes or more bytes left in
  108|       |    // the input buffer? If so, then we can just read from said buffer.
  109|  1.06M|    if (getPos() + BitStreamerTraits<Tag>::MaxProcessBytes <=
  ------------------
  |  Branch (109:9): [True: 1.06M, False: 41]
  ------------------
  110|  1.06M|        Base::input.size()) [[likely]] {
  111|  1.06M|      auto currInput =
  112|  1.06M|          Base::input.getCrop(getPos(), BitStreamerTraits<Tag>::MaxProcessBytes)
  113|  1.06M|              .getAsArray1DRef();
  114|  1.06M|      invariant(currInput.size() == tmp.size());
  ------------------
  |  |   27|  1.06M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (114:7): [True: 1.06M, False: 0]
  ------------------
  115|  1.06M|      memcpy(tmp.begin(), currInput.begin(),
  116|  1.06M|             BitStreamerTraits<Tag>::MaxProcessBytes);
  117|  1.06M|      return tmpStorage;
  118|  1.06M|    }
  119|       |
  120|       |    // We have to use intermediate buffer, either because the input is running
  121|       |    // out of bytes, or because we want to enforce bounds checking.
  122|       |
  123|       |    // Note that in order to keep all fill-level invariants we must allow to
  124|       |    // over-read past-the-end a bit.
  125|     41|    if (getPos() > Base::input.size() +
  ------------------
  |  Branch (125:9): [True: 0, False: 41]
  ------------------
  126|     41|                       2 * BitStreamerTraits<Tag>::MaxProcessBytes) [[unlikely]]
  127|      0|      ThrowIOE("Buffer overflow read in BitStreamer");
  ------------------
  |  |   37|      0|#define ThrowIOE(...) ThrowExceptionHelper(rawspeed::IOException, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   84|      0|  rawspeed::ThrowException<CLASS>("%s, line " STR(__LINE__) ": " fmt,          \
  |  |  |  |   85|      0|                                  __PRETTY_FUNCTION__ __VA_OPT__(, )           \
  |  |  |  |   86|      0|                                      __VA_ARGS__)
  |  |  ------------------
  ------------------
  128|       |
  129|     41|    variableLengthLoadNaiveViaMemcpy(tmp, Base::input, getPos());
  130|       |
  131|     41|    return tmpStorage;
  132|     41|  }
_ZNK8rawspeed39BitStreamerForwardSequentialReplenisherINS_16BitStreamerMSB32EE6getPosEv:
   84|  2.13M|  [[nodiscard]] typename Base::size_type getPos() const {
   85|  2.13M|    Base::establishClassInvariants();
   86|  2.13M|    return Base::pos;
   87|  2.13M|  }
_ZN8rawspeed11BitStreamerINS_16BitStreamerMSB32ENS_39BitStreamerForwardSequentialReplenisherIS1_EEE9fillCacheENSt3__15arrayISt4byteLm4EEE:
  157|  1.06M|                inputStorage) {
  158|  1.06M|    static_assert(BitStreamCacheBase::MaxGetBits >= 32, "check implementation");
  159|  1.06M|    establishClassInvariants();
  160|  1.06M|    auto input = Array1DRef<std::byte>(inputStorage.data(),
  161|  1.06M|                                       implicit_cast<int>(inputStorage.size()));
  162|  1.06M|    invariant(input.size() == Traits::MaxProcessBytes);
  ------------------
  |  |   27|  1.06M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (162:5): [True: 1.06M, False: 0]
  ------------------
  163|       |
  164|  1.06M|    constexpr int StreamChunkBitwidth =
  165|  1.06M|        bitwidth<typename StreamTraits::ChunkType>();
  166|  1.06M|    static_assert(CHAR_BIT * Traits::MaxProcessBytes >= StreamChunkBitwidth);
  167|  1.06M|    static_assert(CHAR_BIT * Traits::MaxProcessBytes % StreamChunkBitwidth ==
  168|  1.06M|                  0);
  169|  1.06M|    constexpr int NumChunksNeeded =
  170|  1.06M|        (CHAR_BIT * Traits::MaxProcessBytes) / StreamChunkBitwidth;
  171|  1.06M|    static_assert(NumChunksNeeded >= 1);
  172|       |
  173|  2.13M|    for (int i = 0; i != NumChunksNeeded; ++i) {
  ------------------
  |  Branch (173:21): [True: 1.06M, False: 1.06M]
  ------------------
  174|  1.06M|      auto chunkInput =
  175|  1.06M|          input.getBlock(sizeof(typename StreamTraits::ChunkType), i);
  176|  1.06M|      auto chunk = getByteSwapped<typename StreamTraits::ChunkType>(
  177|  1.06M|          chunkInput.begin(),
  178|  1.06M|          StreamTraits::ChunkEndianness != getHostEndianness());
  179|  1.06M|      cache.push(chunk, StreamChunkBitwidth);
  180|  1.06M|    }
  181|  1.06M|    return Traits::MaxProcessBytes;
  182|  1.06M|  }
_ZN8rawspeed39BitStreamerForwardSequentialReplenisherINS_16BitStreamerMSB32EE22markNumBytesAsConsumedEi:
   92|  1.06M|  void markNumBytesAsConsumed(typename Base::size_type numBytes) {
   93|  1.06M|    Base::establishClassInvariants();
   94|  1.06M|    invariant(numBytes >= 0);
  ------------------
  |  |   27|  1.06M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (94:5): [True: 1.06M, False: 0]
  ------------------
   95|  1.06M|    invariant(numBytes != 0);
  ------------------
  |  |   27|  1.06M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (95:5): [True: 1.06M, False: 0]
  ------------------
   96|  1.06M|    invariant(numBytes % StreamTraits::MinLoadStepByteMultiple == 0);
  ------------------
  |  |   27|  1.06M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (96:5): [True: 1.06M, False: 0]
  ------------------
   97|  1.06M|    Base::pos += numBytes;
   98|  1.06M|  }
_ZN8rawspeed11BitStreamerINS_16BitStreamerMSB32ENS_39BitStreamerForwardSequentialReplenisherIS1_EEE13getBitsNoFillEi:
  269|  1.16M|  uint32_t getBitsNoFill(int nbits) {
  270|  1.16M|    establishClassInvariants();
  271|  1.16M|    invariant(nbits >= 0);
  ------------------
  |  |   27|  1.16M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (271:5): [True: 1.16M, False: 0]
  ------------------
  272|  1.16M|    invariant(nbits != 0);
  ------------------
  |  |   27|  1.16M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (272:5): [True: 1.16M, False: 0]
  ------------------
  273|  1.16M|    invariant(nbits <= Cache::MaxGetBits);
  ------------------
  |  |   27|  1.16M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (273:5): [True: 1.16M, False: 0]
  ------------------
  274|  1.16M|    uint32_t ret = peekBitsNoFill(nbits);
  275|  1.16M|    skipBitsNoFill(nbits);
  276|  1.16M|    return ret;
  277|  1.16M|  }
_ZN8rawspeed11BitStreamerINS_16BitStreamerMSB32ENS_39BitStreamerForwardSequentialReplenisherIS1_EEE14peekBitsNoFillEi:
  253|  1.16M|  uint32_t RAWSPEED_READONLY peekBitsNoFill(int nbits) {
  254|  1.16M|    establishClassInvariants();
  255|  1.16M|    invariant(nbits >= 0);
  ------------------
  |  |   27|  1.16M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (255:5): [True: 1.16M, False: 0]
  ------------------
  256|  1.16M|    invariant(nbits != 0);
  ------------------
  |  |   27|  1.16M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (256:5): [True: 1.16M, False: 0]
  ------------------
  257|  1.16M|    invariant(nbits <= Cache::MaxGetBits);
  ------------------
  |  |   27|  1.16M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (257:5): [True: 1.16M, False: 0]
  ------------------
  258|  1.16M|    return cache.peek(nbits);
  259|  1.16M|  }
_ZN8rawspeed11BitStreamerINS_16BitStreamerMSB32ENS_39BitStreamerForwardSequentialReplenisherIS1_EEE14skipBitsNoFillEi:
  261|  1.16M|  void skipBitsNoFill(int nbits) {
  262|  1.16M|    establishClassInvariants();
  263|  1.16M|    invariant(nbits >= 0);
  ------------------
  |  |   27|  1.16M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (263:5): [True: 1.16M, False: 0]
  ------------------
  264|       |    // `nbits` could be zero.
  265|  1.16M|    invariant(nbits <= Cache::MaxGetBits);
  ------------------
  |  |   27|  1.16M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (265:5): [True: 1.16M, False: 0]
  ------------------
  266|  1.16M|    cache.skip(nbits);
  267|  1.16M|  }
_ZN8rawspeed11BitStreamerINS_15BitStreamerJPEGENS_39BitStreamerForwardSequentialReplenisherIS1_EEEC2ENS_10Array1DRefIKSt4byteEE:
  192|    371|  explicit BitStreamer(Array1DRef<const std::byte> input) : replenisher(input) {
  193|    371|    establishClassInvariants();
  194|    371|  }
_ZN8rawspeed26BitStreamerReplenisherBaseINS_15BitStreamerJPEGEEC2ENS_10Array1DRefIKSt4byteEE:
   57|    371|      : input(input_) {
   58|    371|    if (input.size() < BitStreamerTraits<Tag>::MaxProcessBytes)
  ------------------
  |  Branch (58:9): [True: 0, False: 371]
  ------------------
   59|    371|      ThrowIOE("Bit stream size is smaller than MaxProcessBytes");
  ------------------
  |  |   37|      0|#define ThrowIOE(...) ThrowExceptionHelper(rawspeed::IOException, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   84|      0|  rawspeed::ThrowException<CLASS>("%s, line " STR(__LINE__) ": " fmt,          \
  |  |  |  |   85|      0|                                  __PRETTY_FUNCTION__ __VA_OPT__(, )           \
  |  |  |  |   86|      0|                                      __VA_ARGS__)
  |  |  ------------------
  ------------------
   60|    371|  }
_ZNK8rawspeed11BitStreamerINS_15BitStreamerJPEGENS_39BitStreamerForwardSequentialReplenisherIS1_EEE24establishClassInvariantsEv:
  185|  13.0M|  void establishClassInvariants() const noexcept {
  186|  13.0M|    cache.establishClassInvariants();
  187|  13.0M|    replenisher.establishClassInvariants();
  188|  13.0M|  }
_ZNK8rawspeed26BitStreamerReplenisherBaseINS_15BitStreamerJPEGEE24establishClassInvariantsEv:
   65|  22.4M|BitStreamerReplenisherBase<Tag>::establishClassInvariants() const noexcept {
   66|  22.4M|  input.establishClassInvariants();
   67|  22.4M|  invariant(input.size() >= BitStreamerTraits<Tag>::MaxProcessBytes);
  ------------------
  |  |   27|  22.4M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (67:3): [True: 22.4M, False: 0]
  ------------------
   68|  22.4M|  invariant(pos >= 0);
  ------------------
  |  |   27|  22.4M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (68:3): [True: 22.4M, False: 0]
  ------------------
   69|  22.4M|  invariant(pos % StreamTraits::MinLoadStepByteMultiple == 0);
  ------------------
  |  |   27|  22.4M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (69:3): [True: 22.4M, False: 0]
  ------------------
   70|       |  // `pos` *could* be out-of-bounds of `input`.
   71|  22.4M|}
_ZN8rawspeed11BitStreamerINS_15BitStreamerJPEGENS_39BitStreamerForwardSequentialReplenisherIS1_EEE4fillEi:
  216|  3.05M|  void fill(int nbits = Cache::MaxGetBits) {
  217|  3.05M|    establishClassInvariants();
  218|  3.05M|    invariant(nbits >= 0);
  ------------------
  |  |   27|  3.05M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (218:5): [True: 3.05M, False: 0]
  ------------------
  219|  3.05M|    invariant(nbits != 0);
  ------------------
  |  |   27|  3.05M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (219:5): [True: 3.05M, False: 0]
  ------------------
  220|  3.05M|    invariant(nbits <= Cache::MaxGetBits);
  ------------------
  |  |   27|  3.05M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (220:5): [True: 3.05M, False: 0]
  ------------------
  221|       |
  222|  3.05M|    if (cache.fillLevel >= nbits)
  ------------------
  |  Branch (222:9): [True: 709k, False: 2.34M]
  ------------------
  223|   709k|      return;
  224|       |
  225|  2.34M|    const auto input = replenisher.getInput();
  226|  2.34M|    const auto numBytes = static_cast<Derived*>(this)->fillCache(input);
  227|  2.34M|    replenisher.markNumBytesAsConsumed(numBytes);
  228|       |    invariant(cache.fillLevel >= nbits);
  ------------------
  |  |   27|  2.34M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (228:5): [True: 2.34M, False: 0]
  ------------------
  229|  2.34M|  }
_ZN8rawspeed39BitStreamerForwardSequentialReplenisherINS_15BitStreamerJPEGEE8getInputEv:
  100|  2.34M|  std::array<std::byte, BitStreamerTraits<Tag>::MaxProcessBytes> getInput() {
  101|  2.34M|    Base::establishClassInvariants();
  102|       |
  103|  2.34M|    std::array<std::byte, BitStreamerTraits<Tag>::MaxProcessBytes> tmpStorage;
  104|  2.34M|    auto tmp = Array1DRef<std::byte>(tmpStorage.data(),
  105|  2.34M|                                     implicit_cast<int>(tmpStorage.size()));
  106|       |
  107|       |    // Do we have BitStreamerTraits<Tag>::MaxProcessBytes or more bytes left in
  108|       |    // the input buffer? If so, then we can just read from said buffer.
  109|  2.34M|    if (getPos() + BitStreamerTraits<Tag>::MaxProcessBytes <=
  ------------------
  |  Branch (109:9): [True: 2.34M, False: 342]
  ------------------
  110|  2.34M|        Base::input.size()) [[likely]] {
  111|  2.34M|      auto currInput =
  112|  2.34M|          Base::input.getCrop(getPos(), BitStreamerTraits<Tag>::MaxProcessBytes)
  113|  2.34M|              .getAsArray1DRef();
  114|  2.34M|      invariant(currInput.size() == tmp.size());
  ------------------
  |  |   27|  2.34M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (114:7): [True: 2.34M, False: 0]
  ------------------
  115|  2.34M|      memcpy(tmp.begin(), currInput.begin(),
  116|  2.34M|             BitStreamerTraits<Tag>::MaxProcessBytes);
  117|  2.34M|      return tmpStorage;
  118|  2.34M|    }
  119|       |
  120|       |    // We have to use intermediate buffer, either because the input is running
  121|       |    // out of bytes, or because we want to enforce bounds checking.
  122|       |
  123|       |    // Note that in order to keep all fill-level invariants we must allow to
  124|       |    // over-read past-the-end a bit.
  125|    342|    if (getPos() > Base::input.size() +
  ------------------
  |  Branch (125:9): [True: 0, False: 342]
  ------------------
  126|    342|                       2 * BitStreamerTraits<Tag>::MaxProcessBytes) [[unlikely]]
  127|      0|      ThrowIOE("Buffer overflow read in BitStreamer");
  ------------------
  |  |   37|      0|#define ThrowIOE(...) ThrowExceptionHelper(rawspeed::IOException, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   84|      0|  rawspeed::ThrowException<CLASS>("%s, line " STR(__LINE__) ": " fmt,          \
  |  |  |  |   85|      0|                                  __PRETTY_FUNCTION__ __VA_OPT__(, )           \
  |  |  |  |   86|      0|                                      __VA_ARGS__)
  |  |  ------------------
  ------------------
  128|       |
  129|    342|    variableLengthLoadNaiveViaMemcpy(tmp, Base::input, getPos());
  130|       |
  131|    342|    return tmpStorage;
  132|    342|  }
_ZNK8rawspeed39BitStreamerForwardSequentialReplenisherINS_15BitStreamerJPEGEE6getPosEv:
   84|  4.68M|  [[nodiscard]] typename Base::size_type getPos() const {
   85|  4.68M|    Base::establishClassInvariants();
   86|  4.68M|    return Base::pos;
   87|  4.68M|  }
_ZN8rawspeed39BitStreamerForwardSequentialReplenisherINS_15BitStreamerJPEGEE22markNumBytesAsConsumedEi:
   92|  2.34M|  void markNumBytesAsConsumed(typename Base::size_type numBytes) {
   93|  2.34M|    Base::establishClassInvariants();
   94|  2.34M|    invariant(numBytes >= 0);
  ------------------
  |  |   27|  2.34M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (94:5): [True: 2.34M, False: 0]
  ------------------
   95|  2.34M|    invariant(numBytes != 0);
  ------------------
  |  |   27|  2.34M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (95:5): [True: 2.34M, False: 0]
  ------------------
   96|  2.34M|    invariant(numBytes % StreamTraits::MinLoadStepByteMultiple == 0);
  ------------------
  |  |   27|  2.34M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (96:5): [True: 2.34M, False: 0]
  ------------------
   97|  2.34M|    Base::pos += numBytes;
   98|  2.34M|  }
_ZN8rawspeed11BitStreamerINS_15BitStreamerJPEGENS_39BitStreamerForwardSequentialReplenisherIS1_EEE13getBitsNoFillEi:
  269|  2.55M|  uint32_t getBitsNoFill(int nbits) {
  270|  2.55M|    establishClassInvariants();
  271|  2.55M|    invariant(nbits >= 0);
  ------------------
  |  |   27|  2.55M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (271:5): [True: 2.55M, False: 0]
  ------------------
  272|  2.55M|    invariant(nbits != 0);
  ------------------
  |  |   27|  2.55M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (272:5): [True: 2.55M, False: 0]
  ------------------
  273|  2.55M|    invariant(nbits <= Cache::MaxGetBits);
  ------------------
  |  |   27|  2.55M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (273:5): [True: 2.55M, False: 0]
  ------------------
  274|  2.55M|    uint32_t ret = peekBitsNoFill(nbits);
  275|  2.55M|    skipBitsNoFill(nbits);
  276|  2.55M|    return ret;
  277|  2.55M|  }
_ZN8rawspeed11BitStreamerINS_15BitStreamerJPEGENS_39BitStreamerForwardSequentialReplenisherIS1_EEE14peekBitsNoFillEi:
  253|  2.55M|  uint32_t RAWSPEED_READONLY peekBitsNoFill(int nbits) {
  254|  2.55M|    establishClassInvariants();
  255|  2.55M|    invariant(nbits >= 0);
  ------------------
  |  |   27|  2.55M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (255:5): [True: 2.55M, False: 0]
  ------------------
  256|  2.55M|    invariant(nbits != 0);
  ------------------
  |  |   27|  2.55M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (256:5): [True: 2.55M, False: 0]
  ------------------
  257|  2.55M|    invariant(nbits <= Cache::MaxGetBits);
  ------------------
  |  |   27|  2.55M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (257:5): [True: 2.55M, False: 0]
  ------------------
  258|  2.55M|    return cache.peek(nbits);
  259|  2.55M|  }
_ZN8rawspeed11BitStreamerINS_15BitStreamerJPEGENS_39BitStreamerForwardSequentialReplenisherIS1_EEE14skipBitsNoFillEi:
  261|  2.55M|  void skipBitsNoFill(int nbits) {
  262|  2.55M|    establishClassInvariants();
  263|  2.55M|    invariant(nbits >= 0);
  ------------------
  |  |   27|  2.55M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (263:5): [True: 2.55M, False: 0]
  ------------------
  264|       |    // `nbits` could be zero.
  265|  2.55M|    invariant(nbits <= Cache::MaxGetBits);
  ------------------
  |  |   27|  2.55M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (265:5): [True: 2.55M, False: 0]
  ------------------
  266|  2.55M|    cache.skip(nbits);
  267|  2.55M|  }

_ZN8rawspeed12PosOrUnknownIiEC2Ev:
   46|    371|  PosOrUnknown() = default;
_ZN8rawspeed15BitStreamerJPEG9fillCacheENSt3__15arrayISt4byteLm8EEE:
  108|  2.34M|        inputStorage) {
  109|  2.34M|  static_assert(BitStreamCacheBase::MaxGetBits >= 32, "check implementation");
  110|  2.34M|  establishClassInvariants();
  111|  2.34M|  auto input = Array1DRef<std::byte>(inputStorage.data(),
  112|  2.34M|                                     implicit_cast<int>(inputStorage.size()));
  113|  2.34M|  invariant(input.size() == Traits::MaxProcessBytes);
  ------------------
  |  |   27|  2.34M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (113:3): [True: 2.34M, False: 0]
  ------------------
  114|       |
  115|  2.34M|  constexpr int StreamChunkBitwidth =
  116|  2.34M|      bitwidth<typename StreamTraits::ChunkType>();
  117|       |
  118|  2.34M|  auto speculativeOptimisticCache = cache;
  119|  2.34M|  auto speculativeOptimisticChunk =
  120|  2.34M|      getByteSwapped<typename StreamTraits::ChunkType>(
  121|  2.34M|          input.begin(), StreamTraits::ChunkEndianness != getHostEndianness());
  122|  2.34M|  speculativeOptimisticCache.push(speculativeOptimisticChunk,
  123|  2.34M|                                  StreamChunkBitwidth);
  124|       |
  125|       |  // short-cut path for the most common case (no FF marker in the next 4 bytes)
  126|       |  // this is slightly faster than the else-case alone.
  127|  2.34M|  if (std::accumulate(&input(0), &input(4), true, [](bool b, std::byte byte) {
  ------------------
  |  Branch (127:7): [True: 1.36M, False: 976k]
  ------------------
  128|  2.34M|        return b && (byte != std::byte{0xFF});
  129|  2.34M|      })) {
  130|  1.36M|    cache = speculativeOptimisticCache;
  131|  1.36M|    return 4;
  132|  1.36M|  }
  133|       |
  134|   976k|  size_type p = 0;
  135|  4.88M|  for (size_type i = 0; i < 4; ++i) {
  ------------------
  |  Branch (135:25): [True: 3.90M, False: 976k]
  ------------------
  136|  3.90M|    const int numBytesNeeded = 4 - i;
  137|       |
  138|       |    // Pre-execute most common case, where next byte is 'normal'/non-FF
  139|  3.90M|    const std::byte c0 = input(p + 0);
  140|  3.90M|    cache.push(std::to_integer<uint8_t>(c0), 8);
  141|  3.90M|    if (c0 != std::byte{0xFF}) {
  ------------------
  |  Branch (141:9): [True: 79.5k, False: 3.82M]
  ------------------
  142|  79.5k|      p += 1;
  143|  79.5k|      continue; // Got normal byte.
  144|  79.5k|    }
  145|       |
  146|       |    // Found FF -> pre-execute case of FF/00, which represents an FF data byte
  147|  3.82M|    const std::byte c1 = input(p + 1);
  148|  3.82M|    if (c1 == std::byte{0x00}) {
  ------------------
  |  Branch (148:9): [True: 3.82M, False: 0]
  ------------------
  149|       |      // Got FF/00, where 0x00 is a stuffing byte (that should be ignored),
  150|       |      // so 0xFF is a normal byte. All good.
  151|  3.82M|      p += 2;
  152|  3.82M|      continue;
  153|  3.82M|    }
  154|       |
  155|       |    // Found FF/xx with xx != 00. This is the end of stream marker.
  156|      0|    endOfStreamPos = getInputPosition() + p;
  157|       |
  158|       |    // That means we shouldn't have pushed last 8 bits (0xFF, from c0).
  159|       |    // We need to "unpush" them, and fill the vacant cache bits with zeros.
  160|       |
  161|       |    // First, recover the cache fill level.
  162|      0|    cache.fillLevel -= 8;
  163|       |    // Now, this code is incredibly underencapsulated, and the
  164|       |    // implementation details are leaking into here. Thus, we know that
  165|       |    // all the fillLevel bits in cache are all high bits. So to "unpush"
  166|       |    // the last 8 bits, and fill the vacant cache bits with zeros, we only
  167|       |    // need to keep the high fillLevel bits. So just create a mask with only
  168|       |    // high fillLevel bits set, and 'and' the cache with it.
  169|       |    // Caution, we know fillLevel won't be 64, but it may be 0,
  170|       |    // so pick the mask-creation idiom accordingly.
  171|      0|    cache.cache &= ~((~0ULL) >> cache.fillLevel);
  172|      0|    cache.fillLevel = 64;
  173|       |
  174|       |    // No further reading from this buffer shall happen. Do signal that by
  175|       |    // claiming that we have consumed all the remaining bytes of the buffer.
  176|       |
  177|      0|    p = getRemainingSize() + numBytesNeeded;
  178|      0|    invariant(p >= 6);
  ------------------
  |  |   27|      0|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (178:5): [True: 0, False: 0]
  ------------------
  179|      0|    break;
  180|      0|  }
  181|   976k|  invariant(p >= 5);
  ------------------
  |  |   27|   976k|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (181:3): [True: 976k, False: 0]
  ------------------
  182|   976k|  return p;
  183|   976k|}
_ZZN8rawspeed15BitStreamerJPEG9fillCacheENSt3__15arrayISt4byteLm8EEEENKUlbS3_E_clEbS3_:
  127|  9.37M|  if (std::accumulate(&input(0), &input(4), true, [](bool b, std::byte byte) {
  128|  9.37M|        return b && (byte != std::byte{0xFF});
  ------------------
  |  Branch (128:16): [True: 6.48M, False: 2.89M]
  |  Branch (128:21): [True: 5.50M, False: 976k]
  ------------------
  129|  9.37M|      })) {

_ZN8rawspeed11BitVacuumerINS_14BitVacuumerLSBINS_26PartitioningOutputIteratorINSt3__120back_insert_iteratorINS3_6vectorIhNS3_9allocatorIhEEEEEEhEEEESA_EC2IRSA_Qsr3stdE7same_asIT0_u20__remove_reference_tITL0__EEEEOT_:
  117|    155|  explicit BitVacuumer(U&& output_) : output(std::forward<U>(output_)) {}
_ZN8rawspeed11BitVacuumerINS_14BitVacuumerLSBINS_26PartitioningOutputIteratorINSt3__120back_insert_iteratorINS3_6vectorIhNS3_9allocatorIhEEEEEEhEEEESA_E3putEji:
  121|  1.06M|  void put(uint32_t bits, int count) {
  122|  1.06M|    invariant(count >= 0);
  ------------------
  |  |   27|  1.06M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (122:5): [True: 1.06M, False: 0]
  ------------------
  123|       |    // NOTE: count may be zero!
  124|  1.06M|    drain();
  125|  1.06M|    cache.push(bits, count);
  126|  1.06M|  }
_ZN8rawspeed11BitVacuumerINS_14BitVacuumerLSBINS_26PartitioningOutputIteratorINSt3__120back_insert_iteratorINS3_6vectorIhNS3_9allocatorIhEEEEEEhEEEESA_E5drainEv:
   80|  1.06M|  void drain() {
   81|  1.06M|    invariant(!flushed);
  ------------------
  |  |   27|  1.06M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (81:5): [True: 1.06M, False: 0]
  ------------------
   82|       |
   83|  1.06M|    if (cache.fillLevel < chunk_bitwidth)
  ------------------
  |  Branch (83:9): [True: 182k, False: 878k]
  ------------------
   84|   182k|      return; // NOTE: does not mean the cache is empty!
   85|       |
   86|   878k|    static_cast<Derived*>(this)->drainImpl();
   87|       |    invariant(cache.fillLevel < chunk_bitwidth);
  ------------------
  |  |   27|   878k|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (87:5): [True: 878k, False: 0]
  ------------------
   88|   878k|  }
_ZN8rawspeed11BitVacuumerINS_14BitVacuumerLSBINS_26PartitioningOutputIteratorINSt3__120back_insert_iteratorINS3_6vectorIhNS3_9allocatorIhEEEEEEhEEEESA_E9drainImplEv:
   57|   878k|  void drainImpl() {
   58|   878k|    invariant(cache.fillLevel >= chunk_bitwidth);
  ------------------
  |  |   27|   878k|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (58:5): [True: 878k, False: 0]
  ------------------
   59|   878k|    static_assert(chunk_bitwidth == 32);
   60|       |
   61|   878k|    constexpr int StreamChunkBitwidth =
   62|   878k|        bitwidth<typename StreamTraits::ChunkType>();
   63|   878k|    static_assert(chunk_bitwidth >= StreamChunkBitwidth);
   64|   878k|    static_assert(chunk_bitwidth % StreamChunkBitwidth == 0);
   65|   878k|    constexpr int NumChunksNeeded = chunk_bitwidth / StreamChunkBitwidth;
   66|   878k|    static_assert(NumChunksNeeded >= 1);
   67|       |
   68|  1.75M|    for (int i = 0; i != NumChunksNeeded; ++i) {
  ------------------
  |  Branch (68:21): [True: 878k, False: 878k]
  ------------------
   69|   878k|      auto chunk = implicit_cast<typename StreamTraits::ChunkType>(
   70|   878k|          cache.peek(StreamChunkBitwidth));
   71|   878k|      chunk = getByteSwapped<typename StreamTraits::ChunkType>(
   72|   878k|          &chunk, StreamTraits::ChunkEndianness != Endianness::little);
   73|   878k|      cache.skip(StreamChunkBitwidth);
   74|       |
   75|   878k|      *output = chunk;
   76|   878k|      ++output;
   77|   878k|    }
   78|   878k|  }
_ZN8rawspeed11BitVacuumerINS_14BitVacuumerLSBINS_26PartitioningOutputIteratorINSt3__120back_insert_iteratorINS3_6vectorIhNS3_9allocatorIhEEEEEEhEEEESA_ED2Ev:
  119|    155|  ~BitVacuumer() { flush(); }
_ZN8rawspeed11BitVacuumerINS_14BitVacuumerLSBINS_26PartitioningOutputIteratorINSt3__120back_insert_iteratorINS3_6vectorIhNS3_9allocatorIhEEEEEEhEEEESA_E5flushEv:
   90|    155|  void flush() {
   91|    155|    drain();
   92|       |
   93|    155|    if (cache.fillLevel == 0) {
  ------------------
  |  Branch (93:9): [True: 40, False: 115]
  ------------------
   94|     40|      flushed = true;
   95|     40|      return;
   96|     40|    }
   97|       |
   98|       |    // Pad with zero bits, so we can drain the partial chunk.
   99|    115|    put(/*bits=*/0, chunk_bitwidth - cache.fillLevel);
  100|    115|    invariant(cache.fillLevel == chunk_bitwidth);
  ------------------
  |  |   27|    115|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (100:5): [True: 115, False: 0]
  ------------------
  101|       |
  102|    115|    drain();
  103|       |
  104|    115|    invariant(cache.fillLevel == 0);
  ------------------
  |  |   27|    115|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (104:5): [True: 115, False: 0]
  ------------------
  105|    115|    flushed = true;
  106|    115|  }
_ZN8rawspeed11BitVacuumerINS_14BitVacuumerMSBINS_26PartitioningOutputIteratorINSt3__120back_insert_iteratorINS3_6vectorIhNS3_9allocatorIhEEEEEEhEEEESA_EC2IRSA_Qsr3stdE7same_asIT0_u20__remove_reference_tITL0__EEEEOT_:
  117|    157|  explicit BitVacuumer(U&& output_) : output(std::forward<U>(output_)) {}
_ZN8rawspeed11BitVacuumerINS_14BitVacuumerMSBINS_26PartitioningOutputIteratorINSt3__120back_insert_iteratorINS3_6vectorIhNS3_9allocatorIhEEEEEEhEEEESA_E3putEji:
  121|  1.16M|  void put(uint32_t bits, int count) {
  122|  1.16M|    invariant(count >= 0);
  ------------------
  |  |   27|  1.16M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (122:5): [True: 1.16M, False: 0]
  ------------------
  123|       |    // NOTE: count may be zero!
  124|  1.16M|    drain();
  125|  1.16M|    cache.push(bits, count);
  126|  1.16M|  }
_ZN8rawspeed11BitVacuumerINS_14BitVacuumerMSBINS_26PartitioningOutputIteratorINSt3__120back_insert_iteratorINS3_6vectorIhNS3_9allocatorIhEEEEEEhEEEESA_E5drainEv:
   80|  1.16M|  void drain() {
   81|  1.16M|    invariant(!flushed);
  ------------------
  |  |   27|  1.16M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (81:5): [True: 1.16M, False: 0]
  ------------------
   82|       |
   83|  1.16M|    if (cache.fillLevel < chunk_bitwidth)
  ------------------
  |  Branch (83:9): [True: 258k, False: 910k]
  ------------------
   84|   258k|      return; // NOTE: does not mean the cache is empty!
   85|       |
   86|   910k|    static_cast<Derived*>(this)->drainImpl();
   87|       |    invariant(cache.fillLevel < chunk_bitwidth);
  ------------------
  |  |   27|   910k|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (87:5): [True: 910k, False: 0]
  ------------------
   88|   910k|  }
_ZN8rawspeed11BitVacuumerINS_14BitVacuumerMSBINS_26PartitioningOutputIteratorINSt3__120back_insert_iteratorINS3_6vectorIhNS3_9allocatorIhEEEEEEhEEEESA_E9drainImplEv:
   57|   910k|  void drainImpl() {
   58|   910k|    invariant(cache.fillLevel >= chunk_bitwidth);
  ------------------
  |  |   27|   910k|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (58:5): [True: 910k, False: 0]
  ------------------
   59|   910k|    static_assert(chunk_bitwidth == 32);
   60|       |
   61|   910k|    constexpr int StreamChunkBitwidth =
   62|   910k|        bitwidth<typename StreamTraits::ChunkType>();
   63|   910k|    static_assert(chunk_bitwidth >= StreamChunkBitwidth);
   64|   910k|    static_assert(chunk_bitwidth % StreamChunkBitwidth == 0);
   65|   910k|    constexpr int NumChunksNeeded = chunk_bitwidth / StreamChunkBitwidth;
   66|   910k|    static_assert(NumChunksNeeded >= 1);
   67|       |
   68|  1.82M|    for (int i = 0; i != NumChunksNeeded; ++i) {
  ------------------
  |  Branch (68:21): [True: 910k, False: 910k]
  ------------------
   69|   910k|      auto chunk = implicit_cast<typename StreamTraits::ChunkType>(
   70|   910k|          cache.peek(StreamChunkBitwidth));
   71|   910k|      chunk = getByteSwapped<typename StreamTraits::ChunkType>(
   72|   910k|          &chunk, StreamTraits::ChunkEndianness != Endianness::little);
   73|   910k|      cache.skip(StreamChunkBitwidth);
   74|       |
   75|   910k|      *output = chunk;
   76|   910k|      ++output;
   77|   910k|    }
   78|   910k|  }
_ZN8rawspeed11BitVacuumerINS_14BitVacuumerMSBINS_26PartitioningOutputIteratorINSt3__120back_insert_iteratorINS3_6vectorIhNS3_9allocatorIhEEEEEEhEEEESA_ED2Ev:
  119|    157|  ~BitVacuumer() { flush(); }
_ZN8rawspeed11BitVacuumerINS_14BitVacuumerMSBINS_26PartitioningOutputIteratorINSt3__120back_insert_iteratorINS3_6vectorIhNS3_9allocatorIhEEEEEEhEEEESA_E5flushEv:
   90|    157|  void flush() {
   91|    157|    drain();
   92|       |
   93|    157|    if (cache.fillLevel == 0) {
  ------------------
  |  Branch (93:9): [True: 32, False: 125]
  ------------------
   94|     32|      flushed = true;
   95|     32|      return;
   96|     32|    }
   97|       |
   98|       |    // Pad with zero bits, so we can drain the partial chunk.
   99|    125|    put(/*bits=*/0, chunk_bitwidth - cache.fillLevel);
  100|    125|    invariant(cache.fillLevel == chunk_bitwidth);
  ------------------
  |  |   27|    125|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (100:5): [True: 125, False: 0]
  ------------------
  101|       |
  102|    125|    drain();
  103|       |
  104|    125|    invariant(cache.fillLevel == 0);
  ------------------
  |  |   27|    125|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (104:5): [True: 125, False: 0]
  ------------------
  105|    125|    flushed = true;
  106|    125|  }
_ZN8rawspeed11BitVacuumerINS_16BitVacuumerMSB16INS_26PartitioningOutputIteratorINSt3__120back_insert_iteratorINS3_6vectorIhNS3_9allocatorIhEEEEEEhEEEESA_EC2IRSA_Qsr3stdE7same_asIT0_u20__remove_reference_tITL0__EEEEOT_:
  117|    154|  explicit BitVacuumer(U&& output_) : output(std::forward<U>(output_)) {}
_ZN8rawspeed11BitVacuumerINS_16BitVacuumerMSB16INS_26PartitioningOutputIteratorINSt3__120back_insert_iteratorINS3_6vectorIhNS3_9allocatorIhEEEEEEhEEEESA_E3putEji:
  121|  1.18M|  void put(uint32_t bits, int count) {
  122|  1.18M|    invariant(count >= 0);
  ------------------
  |  |   27|  1.18M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (122:5): [True: 1.18M, False: 0]
  ------------------
  123|       |    // NOTE: count may be zero!
  124|  1.18M|    drain();
  125|  1.18M|    cache.push(bits, count);
  126|  1.18M|  }
_ZN8rawspeed11BitVacuumerINS_16BitVacuumerMSB16INS_26PartitioningOutputIteratorINSt3__120back_insert_iteratorINS3_6vectorIhNS3_9allocatorIhEEEEEEhEEEESA_E5drainEv:
   80|  1.18M|  void drain() {
   81|  1.18M|    invariant(!flushed);
  ------------------
  |  |   27|  1.18M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (81:5): [True: 1.18M, False: 0]
  ------------------
   82|       |
   83|  1.18M|    if (cache.fillLevel < chunk_bitwidth)
  ------------------
  |  Branch (83:9): [True: 291k, False: 895k]
  ------------------
   84|   291k|      return; // NOTE: does not mean the cache is empty!
   85|       |
   86|   895k|    static_cast<Derived*>(this)->drainImpl();
   87|       |    invariant(cache.fillLevel < chunk_bitwidth);
  ------------------
  |  |   27|   895k|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (87:5): [True: 895k, False: 0]
  ------------------
   88|   895k|  }
_ZN8rawspeed11BitVacuumerINS_16BitVacuumerMSB16INS_26PartitioningOutputIteratorINSt3__120back_insert_iteratorINS3_6vectorIhNS3_9allocatorIhEEEEEEhEEEESA_E9drainImplEv:
   57|   895k|  void drainImpl() {
   58|   895k|    invariant(cache.fillLevel >= chunk_bitwidth);
  ------------------
  |  |   27|   895k|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (58:5): [True: 895k, False: 0]
  ------------------
   59|   895k|    static_assert(chunk_bitwidth == 32);
   60|       |
   61|   895k|    constexpr int StreamChunkBitwidth =
   62|   895k|        bitwidth<typename StreamTraits::ChunkType>();
   63|   895k|    static_assert(chunk_bitwidth >= StreamChunkBitwidth);
   64|   895k|    static_assert(chunk_bitwidth % StreamChunkBitwidth == 0);
   65|   895k|    constexpr int NumChunksNeeded = chunk_bitwidth / StreamChunkBitwidth;
   66|   895k|    static_assert(NumChunksNeeded >= 1);
   67|       |
   68|  2.68M|    for (int i = 0; i != NumChunksNeeded; ++i) {
  ------------------
  |  Branch (68:21): [True: 1.79M, False: 895k]
  ------------------
   69|  1.79M|      auto chunk = implicit_cast<typename StreamTraits::ChunkType>(
   70|  1.79M|          cache.peek(StreamChunkBitwidth));
   71|  1.79M|      chunk = getByteSwapped<typename StreamTraits::ChunkType>(
   72|  1.79M|          &chunk, StreamTraits::ChunkEndianness != Endianness::little);
   73|  1.79M|      cache.skip(StreamChunkBitwidth);
   74|       |
   75|  1.79M|      *output = chunk;
   76|  1.79M|      ++output;
   77|  1.79M|    }
   78|   895k|  }
_ZN8rawspeed11BitVacuumerINS_16BitVacuumerMSB16INS_26PartitioningOutputIteratorINSt3__120back_insert_iteratorINS3_6vectorIhNS3_9allocatorIhEEEEEEhEEEESA_ED2Ev:
  119|    154|  ~BitVacuumer() { flush(); }
_ZN8rawspeed11BitVacuumerINS_16BitVacuumerMSB16INS_26PartitioningOutputIteratorINSt3__120back_insert_iteratorINS3_6vectorIhNS3_9allocatorIhEEEEEEhEEEESA_E5flushEv:
   90|    154|  void flush() {
   91|    154|    drain();
   92|       |
   93|    154|    if (cache.fillLevel == 0) {
  ------------------
  |  Branch (93:9): [True: 37, False: 117]
  ------------------
   94|     37|      flushed = true;
   95|     37|      return;
   96|     37|    }
   97|       |
   98|       |    // Pad with zero bits, so we can drain the partial chunk.
   99|    117|    put(/*bits=*/0, chunk_bitwidth - cache.fillLevel);
  100|    117|    invariant(cache.fillLevel == chunk_bitwidth);
  ------------------
  |  |   27|    117|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (100:5): [True: 117, False: 0]
  ------------------
  101|       |
  102|    117|    drain();
  103|       |
  104|    117|    invariant(cache.fillLevel == 0);
  ------------------
  |  |   27|    117|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (104:5): [True: 117, False: 0]
  ------------------
  105|    117|    flushed = true;
  106|    117|  }
_ZN8rawspeed11BitVacuumerINS_16BitVacuumerMSB32INS_26PartitioningOutputIteratorINSt3__120back_insert_iteratorINS3_6vectorIhNS3_9allocatorIhEEEEEEhEEEESA_EC2IRSA_Qsr3stdE7same_asIT0_u20__remove_reference_tITL0__EEEEOT_:
  117|    149|  explicit BitVacuumer(U&& output_) : output(std::forward<U>(output_)) {}
_ZN8rawspeed11BitVacuumerINS_16BitVacuumerMSB32INS_26PartitioningOutputIteratorINSt3__120back_insert_iteratorINS3_6vectorIhNS3_9allocatorIhEEEEEEhEEEESA_E3putEji:
  121|  1.28M|  void put(uint32_t bits, int count) {
  122|  1.28M|    invariant(count >= 0);
  ------------------
  |  |   27|  1.28M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (122:5): [True: 1.28M, False: 0]
  ------------------
  123|       |    // NOTE: count may be zero!
  124|  1.28M|    drain();
  125|  1.28M|    cache.push(bits, count);
  126|  1.28M|  }
_ZN8rawspeed11BitVacuumerINS_16BitVacuumerMSB32INS_26PartitioningOutputIteratorINSt3__120back_insert_iteratorINS3_6vectorIhNS3_9allocatorIhEEEEEEhEEEESA_E5drainEv:
   80|  1.28M|  void drain() {
   81|  1.28M|    invariant(!flushed);
  ------------------
  |  |   27|  1.28M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (81:5): [True: 1.28M, False: 0]
  ------------------
   82|       |
   83|  1.28M|    if (cache.fillLevel < chunk_bitwidth)
  ------------------
  |  Branch (83:9): [True: 217k, False: 1.06M]
  ------------------
   84|   217k|      return; // NOTE: does not mean the cache is empty!
   85|       |
   86|  1.06M|    static_cast<Derived*>(this)->drainImpl();
   87|       |    invariant(cache.fillLevel < chunk_bitwidth);
  ------------------
  |  |   27|  1.06M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (87:5): [True: 1.06M, False: 0]
  ------------------
   88|  1.06M|  }
_ZN8rawspeed11BitVacuumerINS_16BitVacuumerMSB32INS_26PartitioningOutputIteratorINSt3__120back_insert_iteratorINS3_6vectorIhNS3_9allocatorIhEEEEEEhEEEESA_E9drainImplEv:
   57|  1.06M|  void drainImpl() {
   58|  1.06M|    invariant(cache.fillLevel >= chunk_bitwidth);
  ------------------
  |  |   27|  1.06M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (58:5): [True: 1.06M, False: 0]
  ------------------
   59|  1.06M|    static_assert(chunk_bitwidth == 32);
   60|       |
   61|  1.06M|    constexpr int StreamChunkBitwidth =
   62|  1.06M|        bitwidth<typename StreamTraits::ChunkType>();
   63|  1.06M|    static_assert(chunk_bitwidth >= StreamChunkBitwidth);
   64|  1.06M|    static_assert(chunk_bitwidth % StreamChunkBitwidth == 0);
   65|  1.06M|    constexpr int NumChunksNeeded = chunk_bitwidth / StreamChunkBitwidth;
   66|  1.06M|    static_assert(NumChunksNeeded >= 1);
   67|       |
   68|  2.13M|    for (int i = 0; i != NumChunksNeeded; ++i) {
  ------------------
  |  Branch (68:21): [True: 1.06M, False: 1.06M]
  ------------------
   69|  1.06M|      auto chunk = implicit_cast<typename StreamTraits::ChunkType>(
   70|  1.06M|          cache.peek(StreamChunkBitwidth));
   71|  1.06M|      chunk = getByteSwapped<typename StreamTraits::ChunkType>(
   72|  1.06M|          &chunk, StreamTraits::ChunkEndianness != Endianness::little);
   73|  1.06M|      cache.skip(StreamChunkBitwidth);
   74|       |
   75|  1.06M|      *output = chunk;
   76|  1.06M|      ++output;
   77|  1.06M|    }
   78|  1.06M|  }
_ZN8rawspeed11BitVacuumerINS_16BitVacuumerMSB32INS_26PartitioningOutputIteratorINSt3__120back_insert_iteratorINS3_6vectorIhNS3_9allocatorIhEEEEEEhEEEESA_ED2Ev:
  119|    149|  ~BitVacuumer() { flush(); }
_ZN8rawspeed11BitVacuumerINS_16BitVacuumerMSB32INS_26PartitioningOutputIteratorINSt3__120back_insert_iteratorINS3_6vectorIhNS3_9allocatorIhEEEEEEhEEEESA_E5flushEv:
   90|    149|  void flush() {
   91|    149|    drain();
   92|       |
   93|    149|    if (cache.fillLevel == 0) {
  ------------------
  |  Branch (93:9): [True: 31, False: 118]
  ------------------
   94|     31|      flushed = true;
   95|     31|      return;
   96|     31|    }
   97|       |
   98|       |    // Pad with zero bits, so we can drain the partial chunk.
   99|    118|    put(/*bits=*/0, chunk_bitwidth - cache.fillLevel);
  100|    118|    invariant(cache.fillLevel == chunk_bitwidth);
  ------------------
  |  |   27|    118|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (100:5): [True: 118, False: 0]
  ------------------
  101|       |
  102|    118|    drain();
  103|       |
  104|    118|    invariant(cache.fillLevel == 0);
  ------------------
  |  |   27|    118|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (104:5): [True: 118, False: 0]
  ------------------
  105|    118|    flushed = true;
  106|    118|  }
_ZN8rawspeed11BitVacuumerINS_15BitVacuumerJPEGINS_26PartitioningOutputIteratorINSt3__120back_insert_iteratorINS3_6vectorIhNS3_9allocatorIhEEEEEEhEEEESA_EC2IRSA_Qsr3stdE7same_asIT0_u20__remove_reference_tITL0__EEEEOT_:
  117|    371|  explicit BitVacuumer(U&& output_) : output(std::forward<U>(output_)) {}
_ZN8rawspeed11BitVacuumerINS_15BitVacuumerJPEGINS_26PartitioningOutputIteratorINSt3__120back_insert_iteratorINS3_6vectorIhNS3_9allocatorIhEEEEEEhEEEESA_E3putEji:
  121|  3.05M|  void put(uint32_t bits, int count) {
  122|  3.05M|    invariant(count >= 0);
  ------------------
  |  |   27|  3.05M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (122:5): [True: 3.05M, False: 0]
  ------------------
  123|       |    // NOTE: count may be zero!
  124|  3.05M|    drain();
  125|  3.05M|    cache.push(bits, count);
  126|  3.05M|  }
_ZN8rawspeed11BitVacuumerINS_15BitVacuumerJPEGINS_26PartitioningOutputIteratorINSt3__120back_insert_iteratorINS3_6vectorIhNS3_9allocatorIhEEEEEEhEEEESA_E5drainEv:
   80|  3.05M|  void drain() {
   81|  3.05M|    invariant(!flushed);
  ------------------
  |  |   27|  3.05M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (81:5): [True: 3.05M, False: 0]
  ------------------
   82|       |
   83|  3.05M|    if (cache.fillLevel < chunk_bitwidth)
  ------------------
  |  Branch (83:9): [True: 710k, False: 2.34M]
  ------------------
   84|   710k|      return; // NOTE: does not mean the cache is empty!
   85|       |
   86|  2.34M|    static_cast<Derived*>(this)->drainImpl();
   87|       |    invariant(cache.fillLevel < chunk_bitwidth);
  ------------------
  |  |   27|  2.34M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (87:5): [True: 2.34M, False: 0]
  ------------------
   88|  2.34M|  }
_ZN8rawspeed11BitVacuumerINS_15BitVacuumerJPEGINS_26PartitioningOutputIteratorINSt3__120back_insert_iteratorINS3_6vectorIhNS3_9allocatorIhEEEEEEhEEEESA_ED2Ev:
  119|    371|  ~BitVacuumer() { flush(); }
_ZN8rawspeed11BitVacuumerINS_15BitVacuumerJPEGINS_26PartitioningOutputIteratorINSt3__120back_insert_iteratorINS3_6vectorIhNS3_9allocatorIhEEEEEEhEEEESA_E5flushEv:
   90|    371|  void flush() {
   91|    371|    drain();
   92|       |
   93|    371|    if (cache.fillLevel == 0) {
  ------------------
  |  Branch (93:9): [True: 83, False: 288]
  ------------------
   94|     83|      flushed = true;
   95|     83|      return;
   96|     83|    }
   97|       |
   98|       |    // Pad with zero bits, so we can drain the partial chunk.
   99|    288|    put(/*bits=*/0, chunk_bitwidth - cache.fillLevel);
  100|    288|    invariant(cache.fillLevel == chunk_bitwidth);
  ------------------
  |  |   27|    288|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (100:5): [True: 288, False: 0]
  ------------------
  101|       |
  102|    288|    drain();
  103|       |
  104|    288|    invariant(cache.fillLevel == 0);
  ------------------
  |  |   27|    288|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (104:5): [True: 288, False: 0]
  ------------------
  105|    288|    flushed = true;
  106|    288|  }

_ZN8rawspeed15BitVacuumerJPEGINS_26PartitioningOutputIteratorINSt3__120back_insert_iteratorINS2_6vectorIhNS2_9allocatorIhEEEEEEhEEE9drainImplEv:
   51|  2.34M|  void drainImpl() {
   52|  2.34M|    invariant(Base::cache.fillLevel >= Base::chunk_bitwidth);
  ------------------
  |  |   27|  2.34M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (52:5): [True: 2.34M, False: 0]
  ------------------
   53|  2.34M|    invariant(Base::chunk_bitwidth == 32);
  ------------------
  |  |   27|  2.34M|#define invariant(expr) assert(expr)
  ------------------
  |  Branch (53:5): [True: 2.34M, Folded]
  ------------------
   54|       |
   55|  2.34M|    constexpr int StreamChunkBitwidth =
   56|  2.34M|        bitwidth<typename StreamTraits::ChunkType>();
   57|  2.34M|    static_assert(Base::chunk_bitwidth >= StreamChunkBitwidth);
   58|  2.34M|    static_assert(Base::chunk_bitwidth % StreamChunkBitwidth == 0);
   59|  2.34M|    constexpr int NumChunksNeeded = Base::chunk_bitwidth / StreamChunkBitwidth;
   60|  2.34M|    static_assert(NumChunksNeeded == 1);
   61|       |
   62|  2.34M|    auto chunk = implicit_cast<typename StreamTraits::ChunkType>(
   63|  2.34M|        Base::cache.peek(StreamChunkBitwidth));
   64|  2.34M|    Base::cache.skip(StreamChunkBitwidth);
   65|       |
   66|  2.34M|    const auto bytes = Array1DRef<const std::byte>(Array1DRef(&chunk, 1));
   67|       |
   68|       |    // short-cut path for the most common case (no FF marker in the next 4
   69|       |    // bytes) this is slightly faster than the else-case alone.
   70|  2.34M|    if (std::accumulate(bytes.begin(), bytes.end(), true,
  ------------------
  |  Branch (70:9): [True: 1.36M, False: 976k]
  ------------------
   71|  2.34M|                        [](bool b, std::byte byte) {
   72|  2.34M|                          return b && (byte != std::byte{0xFF});
   73|  2.34M|                        })) {
   74|  1.36M|      chunk = getByteSwapped<typename StreamTraits::ChunkType>(
   75|  1.36M|          &chunk, StreamTraits::ChunkEndianness != Endianness::little);
   76|  1.36M|      *Base::output = chunk;
   77|  1.36M|      ++Base::output;
   78|  1.36M|      return;
   79|  1.36M|    }
   80|       |
   81|   976k|    chunk = getByteSwapped<typename StreamTraits::ChunkType>(
   82|   976k|        &chunk, StreamTraits::ChunkEndianness != getHostEndianness());
   83|       |
   84|  3.90M|    for (const auto byte : bytes) {
  ------------------
  |  Branch (84:26): [True: 3.90M, False: 976k]
  ------------------
   85|  3.90M|      *Base::output = static_cast<uint8_t>(byte);
   86|  3.90M|      ++Base::output;
   87|  3.90M|      if (static_cast<uint8_t>(byte) == 0xFF) {
  ------------------
  |  Branch (87:11): [True: 3.82M, False: 79.5k]
  ------------------
   88|  3.82M|        *Base::output = uint8_t(0x00); // Stuffing byte
   89|  3.82M|        ++Base::output;
   90|  3.82M|      }
   91|  3.90M|    }
   92|   976k|  }
_ZZN8rawspeed15BitVacuumerJPEGINS_26PartitioningOutputIteratorINSt3__120back_insert_iteratorINS2_6vectorIhNS2_9allocatorIhEEEEEEhEEE9drainImplEvENKUlbSt4byteE_clEbSB_:
   71|  9.37M|                        [](bool b, std::byte byte) {
   72|  9.37M|                          return b && (byte != std::byte{0xFF});
  ------------------
  |  Branch (72:34): [True: 6.48M, False: 2.89M]
  |  Branch (72:39): [True: 5.50M, False: 976k]
  ------------------
   73|  9.37M|                        })) {

_ZN8rawspeed8writeLogENS_10DEBUG_PRIOEPKcz:
   31|    252|void writeLog(DEBUG_PRIO priority, const char* format, ...) {
   32|       |  // When fuzzing, any output is really undesirable.
   33|    252|}

_ZN8rawspeed14ThrowExceptionINS_11IOExceptionEEEvPKcz:
   36|    123|    ThrowException(const char* fmt, ...) {
   37|    123|  static constexpr size_t bufSize = 8192;
   38|    123|#if defined(HAVE_CXX_THREAD_LOCAL)
   39|    123|  static thread_local std::array<char, bufSize> buf;
   40|       |#elif defined(HAVE_GCC_THREAD_LOCAL)
   41|       |  static __thread char buf[bufSize];
   42|       |#else
   43|       |#pragma message                                                                \
   44|       |    "Don't have thread-local-storage! Exception text may be garbled if used multithreaded"
   45|       |  static char buf[bufSize];
   46|       |#endif
   47|       |
   48|    123|  va_list val;
   49|    123|  va_start(val, fmt);
   50|    123|  vsnprintf(buf.data(), sizeof(buf), fmt, val);
   51|       |  va_end(val);
   52|    123|  writeLog(DEBUG_PRIO::EXTRA, "EXCEPTION: %s", buf.data());
   53|    123|  throw T(buf.data());
   54|    123|}
_ZN8rawspeed17RawspeedExceptionC2EPKc:
   67|    126|      : std::runtime_error(msg) {
   68|    126|    log(msg);
   69|    126|  }
_ZN8rawspeed17RawspeedException3logEPKc:
   58|    126|  log(const char* msg) {
   59|    126|    writeLog(DEBUG_PRIO::EXTRA, "EXCEPTION: %s", msg);
   60|    126|  }
_ZN8rawspeed14ThrowExceptionINS_17RawspeedExceptionEEEvPKcz:
   36|      3|    ThrowException(const char* fmt, ...) {
   37|      3|  static constexpr size_t bufSize = 8192;
   38|      3|#if defined(HAVE_CXX_THREAD_LOCAL)
   39|      3|  static thread_local std::array<char, bufSize> buf;
   40|       |#elif defined(HAVE_GCC_THREAD_LOCAL)
   41|       |  static __thread char buf[bufSize];
   42|       |#else
   43|       |#pragma message                                                                \
   44|       |    "Don't have thread-local-storage! Exception text may be garbled if used multithreaded"
   45|       |  static char buf[bufSize];
   46|       |#endif
   47|       |
   48|      3|  va_list val;
   49|      3|  va_start(val, fmt);
   50|      3|  vsnprintf(buf.data(), sizeof(buf), fmt, val);
   51|       |  va_end(val);
   52|      3|  writeLog(DEBUG_PRIO::EXTRA, "EXCEPTION: %s", buf.data());
   53|      3|  throw T(buf.data());
   54|      3|}

_ZN8rawspeed6BufferC2EPKhj:
   68|  1.11k|      : Buffer(Array1DRef(data_, implicit_cast<int>(size_))) {}
_ZN8rawspeed6BufferC2ENS_10Array1DRefIKhEE:
   62|  31.0M|      : data(data_.begin()), size(data_.size()) {
   63|  31.0M|    assert(data);
  ------------------
  |  Branch (63:5): [True: 31.0M, False: 0]
  ------------------
   64|  31.0M|    assert(!ASan::RegionIsPoisoned(data, size));
  ------------------
  |  Branch (64:5): [True: 31.0M, False: 0]
  ------------------
   65|  31.0M|  }
_ZN8rawspeed10DataBufferC2ENS_6BufferENS_10EndiannessE:
  142|  3.15k|      : Buffer(data_), endianness(endianness_) {}
_ZNK8rawspeed10DataBuffer3getIhEET_jj:
  147|  15.5M|  [[nodiscard]] T get(size_type offset, size_type index = 0) const {
  148|  15.5M|    assert(Endianness::unknown != endianness);
  ------------------
  |  Branch (148:5): [True: 15.5M, False: 0]
  ------------------
  149|  15.5M|    assert(Endianness::little == endianness || Endianness::big == endianness);
  ------------------
  |  Branch (149:5): [True: 15.5M, False: 0]
  |  Branch (149:5): [True: 0, False: 0]
  |  Branch (149:5): [True: 15.5M, False: 0]
  ------------------
  150|       |
  151|  15.5M|    return Buffer::get<T>(getHostEndianness() == endianness, offset, index);
  152|  15.5M|  }
_ZNK8rawspeed6Buffer3getIhEET_bjj:
  108|  15.5M|                      size_type index = 0) const {
  109|  15.5M|    const Buffer buf =
  110|  15.5M|        getSubView(offset + (index * static_cast<size_type>(sizeof(T))),
  111|  15.5M|                   static_cast<size_type>(sizeof(T)));
  112|  15.5M|    return getByteSwapped<T>(buf.begin(), !inNativeByteOrder);
  113|  15.5M|  }
_ZNK8rawspeed6Buffer10getSubViewEjj:
   78|  31.0M|  [[nodiscard]] Buffer getSubView(size_type offset, size_type size_) const {
   79|  31.0M|    if (!isValid(offset, size_))
  ------------------
  |  Branch (79:9): [True: 123, False: 31.0M]
  ------------------
   80|  31.0M|      ThrowIOE("Buffer overflow: image file may be truncated");
  ------------------
  |  |   37|    123|#define ThrowIOE(...) ThrowExceptionHelper(rawspeed::IOException, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   84|    123|  rawspeed::ThrowException<CLASS>("%s, line " STR(__LINE__) ": " fmt,          \
  |  |  |  |   85|    123|                                  __PRETTY_FUNCTION__ __VA_OPT__(, )           \
  |  |  |  |   86|    123|                                      __VA_ARGS__)
  |  |  ------------------
  ------------------
   81|       |
   82|  31.0M|    return getAsArray1DRef().getCrop(offset, size_).getAsArray1DRef();
   83|  31.0M|  }
_ZNK8rawspeed6Buffer7isValidEjj:
  117|  31.0M|  [[nodiscard]] bool isValid(size_type offset, size_type count = 1) const {
  118|  31.0M|    return static_cast<uint64_t>(offset) + count <=
  119|  31.0M|           static_cast<uint64_t>(getSize());
  120|  31.0M|  }
_ZNK8rawspeed6Buffer7getSizeEv:
  115|   124M|  [[nodiscard]] size_type RAWSPEED_READONLY getSize() const { return size; }
_ZNK8rawspeed6Buffer15getAsArray1DRefEv:
   70|  62.0M|  [[nodiscard]] Array1DRef<const uint8_t> getAsArray1DRef() const {
   71|  62.0M|    return {data, implicit_cast<int>(size)};
   72|  62.0M|  }
_ZNK8rawspeed6Buffer5beginEv:
   99|  31.0M|  [[nodiscard]] const uint8_t* begin() const {
  100|  31.0M|    return getAsArray1DRef().begin();
  101|  31.0M|  }
_ZNK8rawspeed10DataBuffer3getIjEET_jj:
  147|  15.5M|  [[nodiscard]] T get(size_type offset, size_type index = 0) const {
  148|  15.5M|    assert(Endianness::unknown != endianness);
  ------------------
  |  Branch (148:5): [True: 15.5M, False: 0]
  ------------------
  149|  15.5M|    assert(Endianness::little == endianness || Endianness::big == endianness);
  ------------------
  |  Branch (149:5): [True: 15.5M, False: 0]
  |  Branch (149:5): [True: 0, False: 0]
  |  Branch (149:5): [True: 15.5M, False: 0]
  ------------------
  150|       |
  151|  15.5M|    return Buffer::get<T>(getHostEndianness() == endianness, offset, index);
  152|  15.5M|  }
_ZNK8rawspeed6Buffer3getIjEET_bjj:
  108|  15.5M|                      size_type index = 0) const {
  109|  15.5M|    const Buffer buf =
  110|  15.5M|        getSubView(offset + (index * static_cast<size_type>(sizeof(T))),
  111|  15.5M|                   static_cast<size_type>(sizeof(T)));
  112|  15.5M|    return getByteSwapped<T>(buf.begin(), !inNativeByteOrder);
  113|  15.5M|  }
_ZNK8rawspeed10DataBuffer12getByteOrderEv:
  154|  2.04k|  [[nodiscard]] Endianness getByteOrder() const { return endianness; }

_ZN8rawspeed10ByteStreamC2ENS_10DataBufferE:
   50|  3.15k|  explicit ByteStream(DataBuffer buffer) : DataBuffer(buffer) {}
_ZN8rawspeed10ByteStream7getByteEv:
  186|  1.11k|  uint8_t getByte() { return get<uint8_t>(); }
_ZN8rawspeed10ByteStream3getIhEET_v:
  159|  1.11k|  template <typename T> T get() {
  160|  1.11k|    auto ret = peek<T>();
  161|  1.11k|    pos += sizeof(T);
  162|  1.11k|    return ret;
  163|  1.11k|  }
_ZNK8rawspeed10ByteStream4peekIhEET_j:
  156|  15.5M|  template <typename T> [[nodiscard]] T peek(size_type i = 0) const {
  157|  15.5M|    return DataBuffer::get<T>(pos, i);
  158|  15.5M|  }
_ZN8rawspeed10ByteStream6getU32Ev:
  196|  1.11k|  uint32_t getU32() { return get<uint32_t>(); }
_ZN8rawspeed10ByteStream3getIjEET_v:
  159|  1.11k|  template <typename T> T get() {
  160|  1.11k|    auto ret = peek<T>();
  161|  1.11k|    pos += sizeof(T);
  162|  1.11k|    return ret;
  163|  1.11k|  }
_ZNK8rawspeed10ByteStream4peekIjEET_j:
  156|  15.5M|  template <typename T> [[nodiscard]] T peek(size_type i = 0) const {
  157|  15.5M|    return DataBuffer::get<T>(pos, i);
  158|  15.5M|  }
_ZN8rawspeed10ByteStream9getStreamEjj:
  124|  2.15k|  ByteStream getStream(size_type nmemb, size_type size_) {
  125|  2.15k|    if (size_ && nmemb > std::numeric_limits<size_type>::max() / size_)
  ------------------
  |  Branch (125:9): [True: 2.15k, False: 0]
  |  Branch (125:18): [True: 0, False: 2.15k]
  ------------------
  126|  2.15k|      ThrowIOE("Integer overflow when calculating stream length");
  ------------------
  |  |   37|      0|#define ThrowIOE(...) ThrowExceptionHelper(rawspeed::IOException, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   84|      0|  rawspeed::ThrowException<CLASS>("%s, line " STR(__LINE__) ": " fmt,          \
  |  |  |  |   85|      0|                                  __PRETTY_FUNCTION__ __VA_OPT__(, )           \
  |  |  |  |   86|      0|                                      __VA_ARGS__)
  |  |  ------------------
  ------------------
  127|  2.15k|    return getStream(nmemb * size_);
  128|  2.15k|  }
_ZN8rawspeed10ByteStream9getStreamEj:
  119|  2.15k|  ByteStream getStream(size_type size_) {
  120|  2.15k|    ByteStream ret = peekStream(size_);
  121|  2.15k|    pos += size_;
  122|  2.15k|    return ret;
  123|  2.15k|  }
_ZNK8rawspeed10ByteStream10peekStreamEj:
  111|  2.15k|  [[nodiscard]] ByteStream peekStream(size_type size_) const {
  112|  2.15k|    return getSubStream(pos, size_);
  113|  2.15k|  }
_ZNK8rawspeed10ByteStream12getSubStreamEjj:
   55|  2.15k|                                        size_type size_) const {
   56|  2.15k|    return ByteStream(DataBuffer(getSubView(offset, size_), getByteOrder()));
   57|  2.15k|  }
_ZNK8rawspeed10ByteStream8peekByteEj:
  183|  15.5M|  [[nodiscard]] uint8_t peekByte(size_type i = 0) const {
  184|  15.5M|    return peek<uint8_t>(i);
  185|  15.5M|  }
_ZNK8rawspeed10ByteStream7peekU32Ej:
  190|  15.5M|  [[nodiscard]] uint32_t peekU32(size_type i = 0) const {
  191|  15.5M|    return peek<uint32_t>(i);
  192|  15.5M|  }

_ZN8rawspeed14getByteSwappedIhEET_PKvb:
  100|  15.5M|template <typename T> inline T getByteSwapped(const void* data, bool bswap) {
  101|  15.5M|  T ret;
  102|       |  // all interesting compilers optimize this memcpy into a single move
  103|       |  // this is the most effective way to load some bytes without running into
  104|       |  // alignment or aliasing issues
  105|  15.5M|  memcpy(&ret, data, sizeof(T));
  106|  15.5M|  return bswap ? getByteSwapped(ret) : ret;
  ------------------
  |  Branch (106:10): [True: 0, False: 15.5M]
  ------------------
  107|  15.5M|}
_ZN8rawspeed17getHostEndiannessEv:
   63|  38.9M|inline Endianness getHostEndianness() {
   64|  38.9M|#if defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
   65|  38.9M|  return Endianness::little;
   66|       |#elif defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
   67|       |  return Endianness::big;
   68|       |#elif defined(__BYTE_ORDER__)
   69|       |#error "uhm, __BYTE_ORDER__ has some strange value"
   70|       |#else
   71|       |  return getHostEndiannessRuntime();
   72|       |#endif
   73|  38.9M|}
_ZN8rawspeed14getByteSwappedIjEET_PKvb:
  100|  25.9M|template <typename T> inline T getByteSwapped(const void* data, bool bswap) {
  101|  25.9M|  T ret;
  102|       |  // all interesting compilers optimize this memcpy into a single move
  103|       |  // this is the most effective way to load some bytes without running into
  104|       |  // alignment or aliasing issues
  105|  25.9M|  memcpy(&ret, data, sizeof(T));
  106|  25.9M|  return bswap ? getByteSwapped(ret) : ret;
  ------------------
  |  Branch (106:10): [True: 6.51M, False: 19.4M]
  ------------------
  107|  25.9M|}
_ZN8rawspeed14getByteSwappedEj:
   84|  6.51M|inline uint32_t getByteSwapped(uint32_t v) { return BSWAP32(v); }
  ------------------
  |  |   37|  6.51M|#define BSWAP32(A) __builtin_bswap32(A)
  ------------------
_ZN8rawspeed14getByteSwappedItEET_PKvb:
  100|  3.58M|template <typename T> inline T getByteSwapped(const void* data, bool bswap) {
  101|  3.58M|  T ret;
  102|       |  // all interesting compilers optimize this memcpy into a single move
  103|       |  // this is the most effective way to load some bytes without running into
  104|       |  // alignment or aliasing issues
  105|  3.58M|  memcpy(&ret, data, sizeof(T));
  106|  3.58M|  return bswap ? getByteSwapped(ret) : ret;
  ------------------
  |  Branch (106:10): [True: 0, False: 3.58M]
  ------------------
  107|  3.58M|}

_ZNSt9exceptionC2B8ne180100Ev:
   74|    126|  _LIBCPP_HIDE_FROM_ABI exception() _NOEXCEPT {}

_ZNSt3__122__libcpp_aligned_allocB8ne180100Emm:
   30|    126|inline _LIBCPP_HIDE_FROM_ABI void* __libcpp_aligned_alloc(std::size_t __alignment, std::size_t __size) {
   31|       |#  if defined(_LIBCPP_MSVCRT_LIKE)
   32|       |  return ::_aligned_malloc(__size, __alignment);
   33|       |#  elif _LIBCPP_STD_VER >= 17 && !defined(_LIBCPP_HAS_NO_C11_ALIGNED_ALLOC)
   34|       |  // aligned_alloc() requires that __size is a multiple of __alignment,
   35|       |  // but for C++ [new.delete.general], only states "if the value of an
   36|       |  // alignment argument passed to any of these functions is not a valid
   37|       |  // alignment value, the behavior is undefined".
   38|       |  // To handle calls such as ::operator new(1, std::align_val_t(128)), we
   39|       |  // round __size up to the next multiple of __alignment.
   40|    126|  size_t __rounded_size = (__size + __alignment - 1) & ~(__alignment - 1);
   41|       |  // Rounding up could have wrapped around to zero, so we have to add another
   42|       |  // max() ternary to the actual call site to avoid succeeded in that case.
   43|    126|  return ::aligned_alloc(__alignment, __size > __rounded_size ? __size : __rounded_size);
  ------------------
  |  Branch (43:39): [True: 0, False: 126]
  ------------------
   44|       |#  else
   45|       |  void* __result = nullptr;
   46|       |  (void)::posix_memalign(&__result, __alignment, __size);
   47|       |  // If posix_memalign fails, __result is unmodified so we still return `nullptr`.
   48|       |  return __result;
   49|       |#  endif
   50|    126|}
_ZNSt3__121__libcpp_aligned_freeB8ne180100EPv:
   52|    126|inline _LIBCPP_HIDE_FROM_ABI void __libcpp_aligned_free(void* __ptr) {
   53|       |#  if defined(_LIBCPP_MSVCRT_LIKE)
   54|       |  ::_aligned_free(__ptr);
   55|       |#  else
   56|    126|  ::free(__ptr);
   57|    126|#  endif
   58|    126|}

_ZNSt3__116__libcpp_tls_setB8ne180100EjPv:
  352|      1|int __libcpp_tls_set(__libcpp_tls_key __key, void* __p) { return pthread_setspecific(__key, __p); }
_ZNSt3__121__libcpp_execute_onceB8ne180100EPiPFvvE:
  302|    378|int __libcpp_execute_once(__libcpp_exec_once_flag* __flag, void (*__init_routine)()) {
  303|    378|  return pthread_once(__flag, __init_routine);
  304|    378|}
_ZNSt3__119__libcpp_tls_createB8ne180100EPjPFvPvE:
  346|      1|int __libcpp_tls_create(__libcpp_tls_key* __key, void (*__at_exit)(void*)) {
  347|      1|  return pthread_key_create(__key, __at_exit);
  348|      1|}
_ZNSt3__116__libcpp_tls_getB8ne180100Ej:
  350|    378|void* __libcpp_tls_get(__libcpp_tls_key __key) { return pthread_getspecific(__key); }

_ZNSt27__type_info_implementations13__unique_impl4__eqB8ne180100EPKcS2_:
  203|    741|    _LIBCPP_HIDE_FROM_ABI _LIBCPP_ALWAYS_INLINE static bool __eq(__type_name_t __lhs, __type_name_t __rhs) _NOEXCEPT {
  204|    741|      return __lhs == __rhs;
  205|    741|    }
_ZNKSt9type_infoeqB8ne180100ERKS_:
  302|    741|  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool operator==(const type_info& __arg) const _NOEXCEPT {
  303|       |    // When evaluated in a constant expression, both type infos simply can't come
  304|       |    // from different translation units, so it is sufficient to compare their addresses.
  305|    741|    if (__libcpp_is_constant_evaluated()) {
  ------------------
  |  Branch (305:9): [Folded, False: 741]
  ------------------
  306|      0|      return this == &__arg;
  307|      0|    }
  308|    741|    return __impl::__eq(__type_name, __arg.__type_name);
  309|    741|  }

cxa_handlers.cpp:_ZNSt3__112_GLOBAL__N_120__libcpp_atomic_loadB8ne180100IPFvvEEET_PKS4_i:
   58|    252|inline _LIBCPP_HIDE_FROM_ABI _ValueType __libcpp_atomic_load(_ValueType const* __val, int __order = _AO_Seq) {
   59|    252|  return __atomic_load_n(__val, __order);
   60|    252|}
cxa_exception.cpp:_ZNSt3__112_GLOBAL__N_119__libcpp_atomic_addB8ne180100ImmEET_PS2_T0_i:
   63|    126|inline _LIBCPP_HIDE_FROM_ABI _ValueType __libcpp_atomic_add(_ValueType* __val, _AddType __a, int __order = _AO_Seq) {
   64|    126|  return __atomic_add_fetch(__val, __a, __order);
   65|    126|}
stdlib_stdexcept.cpp:_ZNSt3__112_GLOBAL__N_119__libcpp_atomic_addB8ne180100IiiEET_PS2_T0_i:
   63|    126|inline _LIBCPP_HIDE_FROM_ABI _ValueType __libcpp_atomic_add(_ValueType* __val, _AddType __a, int __order = _AO_Seq) {
   64|    126|  return __atomic_add_fetch(__val, __a, __order);
   65|    126|}

_ZNSt3__118__libcpp_refstringD2Ev:
  108|    126|inline __libcpp_refstring::~__libcpp_refstring() {
  109|    126|  if (__uses_refcount()) {
  ------------------
  |  Branch (109:7): [True: 126, False: 0]
  ------------------
  110|    126|    _Rep_base* rep = rep_from_data(__imp_);
  111|    126|    if (__libcpp_atomic_add(&rep->count, count_t(-1)) < 0) {
  ------------------
  |  Branch (111:9): [True: 126, False: 0]
  ------------------
  112|    126|      ::operator delete(rep);
  113|    126|    }
  114|    126|  }
  115|    126|}
_ZNKSt3__118__libcpp_refstring15__uses_refcountEv:
  117|    126|inline bool __libcpp_refstring::__uses_refcount() const {
  118|       |#if defined(_LIBCPP_CHECK_FOR_GCC_EMPTY_STRING_STORAGE)
  119|       |  return __imp_ != get_gcc_empty_string_storage();
  120|       |#else
  121|    126|  return true;
  122|    126|#endif
  123|    126|}
stdlib_stdexcept.cpp:_ZNSt3__115__refstring_imp12_GLOBAL__N_113rep_from_dataEPKc:
   46|    126|inline _Rep_base* rep_from_data(const char* data_) noexcept {
   47|    126|  char* data = const_cast<char*>(data_);
   48|    126|  return reinterpret_cast<_Rep_base*>(data - sizeof(_Rep_base));
   49|    126|}
_ZNSt3__118__libcpp_refstringC2EPKc:
   78|    126|inline __libcpp_refstring::__libcpp_refstring(const char* msg) {
   79|    126|  std::size_t len = strlen(msg);
   80|    126|  _Rep_base* rep  = static_cast<_Rep_base*>(::operator new(sizeof(*rep) + len + 1));
   81|    126|  rep->len        = len;
   82|    126|  rep->cap        = len;
   83|    126|  rep->count      = 0;
   84|    126|  char* data      = data_from_rep(rep);
   85|    126|  std::memcpy(data, msg, len + 1);
   86|    126|  __imp_ = data;
   87|    126|}
stdexcept.cpp:_ZNSt3__115__refstring_imp12_GLOBAL__N_113data_from_repEPNS1_9_Rep_baseE:
   51|    126|inline char* data_from_rep(_Rep_base* rep) noexcept {
   52|    126|  char* data = reinterpret_cast<char*>(rep);
   53|    126|  return data + sizeof(*rep);
   54|    126|}

_ZNSt13runtime_errorC2EPKc:
   34|    126|runtime_error::runtime_error(const char* msg) : __imp_(msg) {}

_ZN10__cxxabiv119__setExceptionClassEP17_Unwind_Exceptionm:
   81|    126|void __setExceptionClass(_Unwind_Exception* unwind_exception, uint64_t newValue) {
   82|    126|    ::memcpy(&unwind_exception->exception_class, &newValue, sizeof(newValue));
   83|    126|}
_ZN10__cxxabiv119__getExceptionClassEPK17_Unwind_Exception:
   95|    504|uint64_t __getExceptionClass(const _Unwind_Exception* unwind_exception) {
   96|       |    // On x86 and some ARM unwinders, unwind_exception->exception_class is
   97|       |    // a uint64_t. On other ARM unwinders, it is a char[8].
   98|       |    // See: http://infocenter.arm.com/help/topic/com.arm.doc.ihi0038b/IHI0038B_ehabi.pdf
   99|       |    // So we just copy it into a uint64_t to be sure.
  100|    504|    uint64_t exClass;
  101|    504|    ::memcpy(&exClass, &unwind_exception->exception_class, sizeof(exClass));
  102|    504|    return exClass;
  103|    504|}
_ZN10__cxxabiv121__isOurExceptionClassEPK17_Unwind_Exception:
  105|    252|bool __isOurExceptionClass(const _Unwind_Exception* unwind_exception) {
  106|    252|    return (__getExceptionClass(unwind_exception) & get_vendor_and_language) ==
  107|    252|           (kOurExceptionClass                    & get_vendor_and_language);
  108|    252|}
__cxa_allocate_exception:
  183|    126|void *__cxa_allocate_exception(size_t thrown_size) throw() {
  184|    126|    size_t actual_size = cxa_exception_size_from_exception_thrown_size(thrown_size);
  185|       |
  186|       |    // Allocate extra space before the __cxa_exception header to ensure the
  187|       |    // start of the thrown object is sufficiently aligned.
  188|    126|    size_t header_offset = get_cxa_exception_offset();
  189|    126|    char *raw_buffer =
  190|    126|        (char *)__aligned_malloc_with_fallback(header_offset + actual_size);
  191|    126|    if (NULL == raw_buffer)
  ------------------
  |  Branch (191:9): [True: 0, False: 126]
  ------------------
  192|      0|        std::terminate();
  193|    126|    __cxa_exception *exception_header =
  194|    126|        static_cast<__cxa_exception *>((void *)(raw_buffer + header_offset));
  195|    126|    ::memset(exception_header, 0, actual_size);
  196|    126|    return thrown_object_from_cxa_exception(exception_header);
  197|    126|}
__cxa_free_exception:
  201|    126|void __cxa_free_exception(void *thrown_object) throw() {
  202|       |    // Compute the size of the padding before the header.
  203|    126|    size_t header_offset = get_cxa_exception_offset();
  204|    126|    char *raw_buffer =
  205|    126|        ((char *)cxa_exception_from_thrown_object(thrown_object)) - header_offset;
  206|    126|    __aligned_free_with_fallback((void *)raw_buffer);
  207|    126|}
__cxa_init_primary_exception:
  210|    126|                                              void(_LIBCXXABI_DTOR_FUNC* dest)(void*)) throw() {
  211|    126|  __cxa_exception* exception_header = cxa_exception_from_thrown_object(object);
  212|    126|  exception_header->referenceCount = 0;
  213|    126|  exception_header->unexpectedHandler = std::get_unexpected();
  214|    126|  exception_header->terminateHandler = std::get_terminate();
  215|    126|  exception_header->exceptionType = tinfo;
  216|    126|  exception_header->exceptionDestructor = dest;
  217|    126|  setOurExceptionClass(&exception_header->unwindHeader);
  218|    126|  exception_header->unwindHeader.exception_cleanup = exception_cleanup_func;
  219|       |
  220|    126|  return exception_header;
  221|    126|}
__cxa_throw:
  274|    126|__cxa_throw(void *thrown_object, std::type_info *tinfo, void (_LIBCXXABI_DTOR_FUNC *dest)(void *)) {
  275|    126|#endif
  276|    126|  __cxa_eh_globals* globals = __cxa_get_globals();
  277|    126|  globals->uncaughtExceptions += 1; // Not atomically, since globals are thread-local
  278|       |
  279|    126|  __cxa_exception* exception_header = __cxa_init_primary_exception(thrown_object, tinfo, dest);
  280|    126|  exception_header->referenceCount = 1; // This is a newly allocated exception, no need for thread safety.
  281|       |
  282|       |#if __has_feature(address_sanitizer)
  283|       |  // Inform the ASan runtime that now might be a good time to clean stuff up.
  284|       |  __asan_handle_no_return();
  285|       |#endif
  286|       |
  287|       |#ifdef __USING_SJLJ_EXCEPTIONS__
  288|       |    _Unwind_SjLj_RaiseException(&exception_header->unwindHeader);
  289|       |#else
  290|    126|    _Unwind_RaiseException(&exception_header->unwindHeader);
  291|    126|#endif
  292|       |    //  This only happens when there is no handler, or some unexpected unwinding
  293|       |    //     error happens.
  294|    126|    failed_throw(exception_header);
  295|    126|}
__cxa_begin_catch:
  446|    126|{
  447|    126|    _Unwind_Exception* unwind_exception = static_cast<_Unwind_Exception*>(unwind_arg);
  448|    126|    bool native_exception = __isOurExceptionClass(unwind_exception);
  449|    126|    __cxa_eh_globals* globals = __cxa_get_globals();
  450|       |    // exception_header is a hackish offset from a foreign exception, but it
  451|       |    //   works as long as we're careful not to try to access any __cxa_exception
  452|       |    //   parts.
  453|    126|    __cxa_exception* exception_header =
  454|    126|            cxa_exception_from_exception_unwind_exception
  455|    126|            (
  456|    126|                static_cast<_Unwind_Exception*>(unwind_exception)
  457|    126|            );
  458|       |
  459|       |#if defined(__MVS__)
  460|       |    // Remove the exception object from the linked list of exceptions that the z/OS unwinder
  461|       |    // maintains before adding it to the libc++abi list of caught exceptions.
  462|       |    // The libc++abi will manage the lifetime of the exception from this point forward.
  463|       |    _UnwindZOS_PopException();
  464|       |#endif
  465|       |
  466|    126|    if (native_exception)
  ------------------
  |  Branch (466:9): [True: 126, False: 0]
  ------------------
  467|    126|    {
  468|       |        // Increment the handler count, removing the flag about being rethrown
  469|    126|        exception_header->handlerCount = exception_header->handlerCount < 0 ?
  ------------------
  |  Branch (469:42): [True: 0, False: 126]
  ------------------
  470|    126|            -exception_header->handlerCount + 1 : exception_header->handlerCount + 1;
  471|       |        //  place the exception on the top of the stack if it's not already
  472|       |        //    there by a previous rethrow
  473|    126|        if (exception_header != globals->caughtExceptions)
  ------------------
  |  Branch (473:13): [True: 126, False: 0]
  ------------------
  474|    126|        {
  475|    126|            exception_header->nextException = globals->caughtExceptions;
  476|    126|            globals->caughtExceptions = exception_header;
  477|    126|        }
  478|    126|        globals->uncaughtExceptions -= 1;   // Not atomically, since globals are thread-local
  479|       |#if defined(_LIBCXXABI_ARM_EHABI)
  480|       |        return reinterpret_cast<void*>(exception_header->unwindHeader.barrier_cache.bitpattern[0]);
  481|       |#else
  482|    126|        return exception_header->adjustedPtr;
  483|    126|#endif
  484|    126|    }
  485|       |    // Else this is a foreign exception
  486|       |    // If the caughtExceptions stack is not empty, terminate
  487|      0|    if (globals->caughtExceptions != 0)
  ------------------
  |  Branch (487:9): [True: 0, False: 0]
  ------------------
  488|      0|        std::terminate();
  489|       |    // Push the foreign exception on to the stack
  490|      0|    globals->caughtExceptions = exception_header;
  491|      0|    return unwind_exception + 1;
  492|    126|}
__cxa_end_catch:
  513|    126|void __cxa_end_catch() {
  514|    126|  static_assert(sizeof(__cxa_exception) == sizeof(__cxa_dependent_exception),
  515|    126|                "sizeof(__cxa_exception) must be equal to "
  516|    126|                "sizeof(__cxa_dependent_exception)");
  517|    126|  static_assert(__builtin_offsetof(__cxa_exception, referenceCount) ==
  518|    126|                    __builtin_offsetof(__cxa_dependent_exception,
  519|    126|                                       primaryException),
  520|    126|                "the layout of __cxa_exception must match the layout of "
  521|    126|                "__cxa_dependent_exception");
  522|    126|  static_assert(__builtin_offsetof(__cxa_exception, handlerCount) ==
  523|    126|                    __builtin_offsetof(__cxa_dependent_exception, handlerCount),
  524|    126|                "the layout of __cxa_exception must match the layout of "
  525|    126|                "__cxa_dependent_exception");
  526|    126|    __cxa_eh_globals* globals = __cxa_get_globals_fast(); // __cxa_get_globals called in __cxa_begin_catch
  527|    126|    __cxa_exception* exception_header = globals->caughtExceptions;
  528|       |    // If we've rethrown a foreign exception, then globals->caughtExceptions
  529|       |    //    will have been made an empty stack by __cxa_rethrow() and there is
  530|       |    //    nothing more to be done.  Do nothing!
  531|    126|    if (NULL != exception_header)
  ------------------
  |  Branch (531:9): [True: 126, False: 0]
  ------------------
  532|    126|    {
  533|    126|        bool native_exception = __isOurExceptionClass(&exception_header->unwindHeader);
  534|    126|        if (native_exception)
  ------------------
  |  Branch (534:13): [True: 126, False: 0]
  ------------------
  535|    126|        {
  536|       |            // This is a native exception
  537|    126|            if (exception_header->handlerCount < 0)
  ------------------
  |  Branch (537:17): [True: 0, False: 126]
  ------------------
  538|      0|            {
  539|       |                //  The exception has been rethrown by __cxa_rethrow, so don't delete it
  540|      0|                if (0 == incrementHandlerCount(exception_header))
  ------------------
  |  Branch (540:21): [True: 0, False: 0]
  ------------------
  541|      0|                {
  542|       |                    //  Remove from the chain of uncaught exceptions
  543|      0|                    globals->caughtExceptions = exception_header->nextException;
  544|       |                    // but don't destroy
  545|      0|                }
  546|       |                // Keep handlerCount negative in case there are nested catch's
  547|       |                //   that need to be told that this exception is rethrown.  Don't
  548|       |                //   erase this rethrow flag until the exception is recaught.
  549|      0|            }
  550|    126|            else
  551|    126|            {
  552|       |                // The native exception has not been rethrown
  553|    126|                if (0 == decrementHandlerCount(exception_header))
  ------------------
  |  Branch (553:21): [True: 126, False: 0]
  ------------------
  554|    126|                {
  555|       |                    //  Remove from the chain of uncaught exceptions
  556|    126|                    globals->caughtExceptions = exception_header->nextException;
  557|       |                    // Destroy this exception, being careful to distinguish
  558|       |                    //    between dependent and primary exceptions
  559|    126|                    if (isDependentException(&exception_header->unwindHeader))
  ------------------
  |  Branch (559:25): [True: 0, False: 126]
  ------------------
  560|      0|                    {
  561|       |                        // Reset exception_header to primaryException and deallocate the dependent exception
  562|      0|                        __cxa_dependent_exception* dep_exception_header =
  563|      0|                            reinterpret_cast<__cxa_dependent_exception*>(exception_header);
  564|      0|                        exception_header =
  565|      0|                            cxa_exception_from_thrown_object(dep_exception_header->primaryException);
  566|      0|                        __cxa_free_dependent_exception(dep_exception_header);
  567|      0|                    }
  568|       |                    // Destroy the primary exception only if its referenceCount goes to 0
  569|       |                    //    (this decrement must be atomic)
  570|    126|                    __cxa_decrement_exception_refcount(thrown_object_from_cxa_exception(exception_header));
  571|    126|                }
  572|    126|            }
  573|    126|        }
  574|      0|        else
  575|      0|        {
  576|       |            // The foreign exception has not been rethrown.  Pop the stack
  577|       |            //    and delete it.  If there are nested catch's and they try
  578|       |            //    to touch a foreign exception in any way, that is undefined
  579|       |            //     behavior.  They likely can't since the only way to catch
  580|       |            //     a foreign exception is with catch (...)!
  581|      0|            _Unwind_DeleteException(&globals->caughtExceptions->unwindHeader);
  582|      0|            globals->caughtExceptions = 0;
  583|      0|        }
  584|    126|    }
  585|    126|}
__cxa_decrement_exception_refcount:
  678|    126|void __cxa_decrement_exception_refcount(void *thrown_object) throw() {
  679|    126|    if (thrown_object != NULL )
  ------------------
  |  Branch (679:9): [True: 126, False: 0]
  ------------------
  680|    126|    {
  681|    126|        __cxa_exception* exception_header = cxa_exception_from_thrown_object(thrown_object);
  682|    126|        if (std::__libcpp_atomic_add(&exception_header->referenceCount, size_t(-1)) == 0)
  ------------------
  |  Branch (682:13): [True: 126, False: 0]
  ------------------
  683|    126|        {
  684|    126|            if (NULL != exception_header->exceptionDestructor)
  ------------------
  |  Branch (684:17): [True: 126, False: 0]
  ------------------
  685|    126|                exception_header->exceptionDestructor(thrown_object);
  686|    126|            __cxa_free_exception(thrown_object);
  687|    126|        }
  688|    126|    }
  689|    126|}
cxa_exception.cpp:_ZN10__cxxabiv1L45cxa_exception_size_from_exception_thrown_sizeEm:
   76|    126|size_t cxa_exception_size_from_exception_thrown_size(size_t size) {
   77|    126|    return aligned_allocation_size(size + sizeof (__cxa_exception),
   78|    126|                                   alignof(__cxa_exception));
   79|    126|}
cxa_exception.cpp:_ZN10__cxxabiv1L23aligned_allocation_sizeEmm:
   71|    126|size_t aligned_allocation_size(size_t s, size_t a) {
   72|    126|    return (s + a - 1) & ~(a - 1);
   73|    126|}
cxa_exception.cpp:_ZN10__cxxabiv1L24get_cxa_exception_offsetEv:
  161|    252|static size_t get_cxa_exception_offset() {
  162|    252|  struct S {
  163|    252|  } __attribute__((aligned));
  164|       |
  165|       |  // Compute the maximum alignment for the target machine.
  166|    252|  constexpr size_t alignment = alignof(S);
  167|    252|  constexpr size_t excp_size = sizeof(__cxa_exception);
  168|    252|  constexpr size_t aligned_size =
  169|    252|      (excp_size + alignment - 1) / alignment * alignment;
  170|    252|  constexpr size_t offset = aligned_size - excp_size;
  171|    252|  static_assert((offset == 0 || alignof(_Unwind_Exception) < alignment),
  172|    252|                "offset is non-zero only if _Unwind_Exception isn't aligned");
  173|    252|  return offset;
  174|    252|}
cxa_exception.cpp:_ZN10__cxxabiv1L32thrown_object_from_cxa_exceptionEPNS_15__cxa_exceptionE:
   54|    252|{
   55|    252|    return static_cast<void*>(exception_header + 1);
   56|    252|}
cxa_exception.cpp:_ZN10__cxxabiv1L32cxa_exception_from_thrown_objectEPv:
   44|    504|{
   45|    504|    return static_cast<__cxa_exception*>(thrown_object) - 1;
   46|    504|}
cxa_exception.cpp:_ZN10__cxxabiv1L20setOurExceptionClassEP17_Unwind_Exception:
   86|    126|static void setOurExceptionClass(_Unwind_Exception* unwind_exception) {
   87|    126|    __setExceptionClass(unwind_exception, kOurExceptionClass);
   88|    126|}
cxa_exception.cpp:_ZN10__cxxabiv1L45cxa_exception_from_exception_unwind_exceptionEP17_Unwind_Exception:
   65|    126|{
   66|    126|    return cxa_exception_from_thrown_object(unwind_exception + 1 );
   67|    126|}
cxa_exception.cpp:_ZN10__cxxabiv1L21decrementHandlerCountEPNS_15__cxa_exceptionE:
  120|    126|static inline  int decrementHandlerCount(__cxa_exception *exception) {
  121|    126|    return --exception->handlerCount;
  122|    126|}
cxa_exception.cpp:_ZN10__cxxabiv1L20isDependentExceptionEP17_Unwind_Exception:
  110|    126|static bool isDependentException(_Unwind_Exception* unwind_exception) {
  111|    126|    return (__getExceptionClass(unwind_exception) & 0xFF) == 0x01;
  112|    126|}

__cxa_get_globals:
   74|    252|    __cxa_eh_globals *__cxa_get_globals() {
   75|       |        // Try to get the globals for this thread
   76|    252|        __cxa_eh_globals *retVal = __cxa_get_globals_fast();
   77|       |
   78|       |        // If this is the first time we've been asked for these globals, create them
   79|    252|        if (NULL == retVal) {
  ------------------
  |  Branch (79:13): [True: 1, False: 251]
  ------------------
   80|      1|            retVal = static_cast<__cxa_eh_globals*>(
   81|      1|                __calloc_with_fallback(1, sizeof(__cxa_eh_globals)));
   82|      1|            if (NULL == retVal)
  ------------------
  |  Branch (82:17): [True: 0, False: 1]
  ------------------
   83|      0|                abort_message("cannot allocate __cxa_eh_globals");
   84|      1|            if (0 != std::__libcpp_tls_set(key_, retVal))
  ------------------
  |  Branch (84:17): [True: 0, False: 1]
  ------------------
   85|      0|               abort_message("std::__libcpp_tls_set failure in __cxa_get_globals()");
   86|      1|        }
   87|    252|        return retVal;
   88|    252|    }
__cxa_get_globals_fast:
   94|    378|    __cxa_eh_globals *__cxa_get_globals_fast() {
   95|       |        // First time through, create the key.
   96|    378|        if (0 != std::__libcpp_execute_once(&flag_, construct_))
  ------------------
  |  Branch (96:13): [True: 0, False: 378]
  ------------------
   97|      0|            abort_message("execute once failure in __cxa_get_globals_fast()");
   98|    378|        return static_cast<__cxa_eh_globals*>(std::__libcpp_tls_get(key_));
   99|    378|    }
cxa_exception_storage.cpp:_ZN10__cxxabiv112_GLOBAL__N_110construct_Ev:
   67|      1|    void construct_() {
   68|      1|        if (0 != std::__libcpp_tls_create(&key_, destruct_))
  ------------------
  |  Branch (68:13): [True: 0, False: 1]
  ------------------
   69|      0|            abort_message("cannot create thread specific key for __cxa_get_globals()");
   70|      1|    }

_ZSt14get_unexpectedv:
   27|    126|{
   28|    126|    return __libcpp_atomic_load(&__cxa_unexpected_handler, _AO_Acquire);
   29|    126|}
_ZSt13get_terminatev:
   48|    126|{
   49|    126|    return __libcpp_atomic_load(&__cxa_terminate_handler, _AO_Acquire);
   50|    126|}

__gxx_personality_v0:
  924|    504|{
  925|    504|    if (version != 1 || unwind_exception == 0 || context == 0)
  ------------------
  |  Branch (925:9): [True: 0, False: 504]
  |  Branch (925:25): [True: 0, False: 504]
  |  Branch (925:50): [True: 0, False: 504]
  ------------------
  926|      0|        return _URC_FATAL_PHASE1_ERROR;
  927|       |
  928|    504|    bool native_exception = (exceptionClass     & get_vendor_and_language) ==
  929|    504|                            (kOurExceptionClass & get_vendor_and_language);
  930|    504|    scan_results results;
  931|       |    // Process a catch handler for a native exception first.
  932|    504|    if (actions == (_UA_CLEANUP_PHASE | _UA_HANDLER_FRAME) &&
  ------------------
  |  Branch (932:9): [True: 126, False: 378]
  ------------------
  933|    126|        native_exception) {
  ------------------
  |  Branch (933:9): [True: 126, False: 0]
  ------------------
  934|       |        // Reload the results from the phase 1 cache.
  935|    126|        __cxa_exception* exception_header =
  936|    126|            (__cxa_exception*)(unwind_exception + 1) - 1;
  937|    126|        results.ttypeIndex = exception_header->handlerSwitchValue;
  938|    126|        results.actionRecord = exception_header->actionRecord;
  939|    126|        results.languageSpecificData = exception_header->languageSpecificData;
  940|    126|        results.landingPad =
  941|    126|            reinterpret_cast<uintptr_t>(exception_header->catchTemp);
  942|    126|        results.adjustedPtr = exception_header->adjustedPtr;
  943|       |
  944|       |        // Jump to the handler.
  945|    126|        set_registers(unwind_exception, context, results);
  946|       |        // Cache base for calculating the address of ttype in
  947|       |        // __cxa_call_unexpected.
  948|    126|        if (results.ttypeIndex < 0) {
  ------------------
  |  Branch (948:13): [True: 0, False: 126]
  ------------------
  949|       |#if defined(_AIX)
  950|       |          exception_header->catchTemp = (void *)_Unwind_GetDataRelBase(context);
  951|       |#else
  952|      0|          exception_header->catchTemp = 0;
  953|      0|#endif
  954|      0|        }
  955|    126|        return _URC_INSTALL_CONTEXT;
  956|    126|    }
  957|       |
  958|       |    // In other cases we need to scan LSDA.
  959|    378|    scan_eh_tab(results, actions, native_exception, unwind_exception, context);
  960|    378|    if (results.reason == _URC_CONTINUE_UNWIND ||
  ------------------
  |  Branch (960:9): [True: 252, False: 126]
  ------------------
  961|    126|        results.reason == _URC_FATAL_PHASE1_ERROR)
  ------------------
  |  Branch (961:9): [True: 0, False: 126]
  ------------------
  962|    252|        return results.reason;
  963|       |
  964|    126|    if (actions & _UA_SEARCH_PHASE)
  ------------------
  |  Branch (964:9): [True: 126, False: 0]
  ------------------
  965|    126|    {
  966|       |        // Phase 1 search:  All we're looking for in phase 1 is a handler that
  967|       |        //   halts unwinding
  968|    126|        assert(results.reason == _URC_HANDLER_FOUND);
  ------------------
  |  Branch (968:9): [True: 126, False: 0]
  ------------------
  969|    126|        if (native_exception) {
  ------------------
  |  Branch (969:13): [True: 126, False: 0]
  ------------------
  970|       |            // For a native exception, cache the LSDA result.
  971|    126|            __cxa_exception* exc = (__cxa_exception*)(unwind_exception + 1) - 1;
  972|    126|            exc->handlerSwitchValue = static_cast<int>(results.ttypeIndex);
  973|    126|            exc->actionRecord = results.actionRecord;
  974|    126|            exc->languageSpecificData = results.languageSpecificData;
  975|    126|            exc->catchTemp = reinterpret_cast<void*>(results.landingPad);
  976|    126|            exc->adjustedPtr = results.adjustedPtr;
  977|       |#ifdef __USING_WASM_EXCEPTIONS__
  978|       |            // Wasm only uses a single phase (_UA_SEARCH_PHASE), so save the
  979|       |            // results here.
  980|       |            set_registers(unwind_exception, context, results);
  981|       |#endif
  982|    126|        }
  983|    126|        return _URC_HANDLER_FOUND;
  984|    126|    }
  985|       |
  986|    126|    assert(actions & _UA_CLEANUP_PHASE);
  ------------------
  |  Branch (986:5): [True: 0, False: 0]
  ------------------
  987|      0|    assert(results.reason == _URC_HANDLER_FOUND);
  ------------------
  |  Branch (987:5): [True: 0, False: 0]
  ------------------
  988|      0|    set_registers(unwind_exception, context, results);
  989|       |    // Cache base for calculating the address of ttype in __cxa_call_unexpected.
  990|      0|    if (results.ttypeIndex < 0) {
  ------------------
  |  Branch (990:9): [True: 0, False: 0]
  ------------------
  991|      0|      __cxa_exception* exception_header =
  992|      0|            (__cxa_exception*)(unwind_exception + 1) - 1;
  993|       |#if defined(_AIX)
  994|       |      exception_header->catchTemp = (void *)_Unwind_GetDataRelBase(context);
  995|       |#else
  996|      0|      exception_header->catchTemp = 0;
  997|      0|#endif
  998|      0|    }
  999|      0|    return _URC_INSTALL_CONTEXT;
 1000|      0|}
cxa_personality.cpp:_ZN10__cxxabiv1L13set_registersEP17_Unwind_ExceptionP15_Unwind_ContextRKNS_12_GLOBAL__N_112scan_resultsE:
  549|    126|{
  550|       |#if defined(__USING_SJLJ_EXCEPTIONS__) || defined(__USING_WASM_EXCEPTIONS__)
  551|       |#define __builtin_eh_return_data_regno(regno) regno
  552|       |#elif defined(__ibmxl__)
  553|       |// IBM xlclang++ compiler does not support __builtin_eh_return_data_regno.
  554|       |#define __builtin_eh_return_data_regno(regno) regno + 3
  555|       |#endif
  556|    126|  _Unwind_SetGR(context, __builtin_eh_return_data_regno(0),
  557|    126|                reinterpret_cast<uintptr_t>(unwind_exception));
  558|    126|  _Unwind_SetGR(context, __builtin_eh_return_data_regno(1),
  559|    126|                static_cast<uintptr_t>(results.ttypeIndex));
  560|    126|  _Unwind_SetIP(context, results.landingPad);
  561|    126|}
cxa_personality.cpp:_ZN10__cxxabiv1L11scan_eh_tabERNS_12_GLOBAL__N_112scan_resultsE14_Unwind_ActionbP17_Unwind_ExceptionP15_Unwind_Context:
  587|    378|                        _Unwind_Context *context) {
  588|       |    // Initialize results to found nothing but an error
  589|    378|    results.ttypeIndex = 0;
  590|    378|    results.actionRecord = 0;
  591|    378|    results.languageSpecificData = 0;
  592|    378|    results.landingPad = 0;
  593|    378|    results.adjustedPtr = 0;
  594|    378|    results.reason = _URC_FATAL_PHASE1_ERROR;
  595|       |    // Check for consistent actions
  596|    378|    if (actions & _UA_SEARCH_PHASE)
  ------------------
  |  Branch (596:9): [True: 252, False: 126]
  ------------------
  597|    252|    {
  598|       |        // Do Phase 1
  599|    252|        if (actions & (_UA_CLEANUP_PHASE | _UA_HANDLER_FRAME | _UA_FORCE_UNWIND))
  ------------------
  |  Branch (599:13): [True: 0, False: 252]
  ------------------
  600|      0|        {
  601|       |            // None of these flags should be set during Phase 1
  602|       |            //   Client error
  603|      0|            results.reason = _URC_FATAL_PHASE1_ERROR;
  604|      0|            return;
  605|      0|        }
  606|    252|    }
  607|    126|    else if (actions & _UA_CLEANUP_PHASE)
  ------------------
  |  Branch (607:14): [True: 126, False: 0]
  ------------------
  608|    126|    {
  609|    126|        if ((actions & _UA_HANDLER_FRAME) && (actions & _UA_FORCE_UNWIND))
  ------------------
  |  Branch (609:13): [True: 0, False: 126]
  |  Branch (609:46): [True: 0, False: 0]
  ------------------
  610|      0|        {
  611|       |            // _UA_HANDLER_FRAME should only be set if phase 1 found a handler.
  612|       |            // If _UA_FORCE_UNWIND is set, phase 1 shouldn't have happened.
  613|       |            //    Client error
  614|      0|            results.reason = _URC_FATAL_PHASE2_ERROR;
  615|      0|            return;
  616|      0|        }
  617|    126|    }
  618|      0|    else // Neither _UA_SEARCH_PHASE nor _UA_CLEANUP_PHASE is set
  619|      0|    {
  620|       |        // One of these should be set.
  621|       |        //   Client error
  622|      0|        results.reason = _URC_FATAL_PHASE1_ERROR;
  623|      0|        return;
  624|      0|    }
  625|       |    // Start scan by getting exception table address.
  626|    378|    const uint8_t *lsda = (const uint8_t *)_Unwind_GetLanguageSpecificData(context);
  627|    378|    if (lsda == 0)
  ------------------
  |  Branch (627:9): [True: 0, False: 378]
  ------------------
  628|      0|    {
  629|       |        // There is no exception table
  630|      0|        results.reason = _URC_CONTINUE_UNWIND;
  631|      0|        return;
  632|      0|    }
  633|    378|    results.languageSpecificData = lsda;
  634|       |#if defined(_AIX)
  635|       |    uintptr_t base = _Unwind_GetDataRelBase(context);
  636|       |#else
  637|    378|    uintptr_t base = 0;
  638|    378|#endif
  639|       |    // Get the current instruction pointer and offset it before next
  640|       |    // instruction in the current frame which threw the exception.
  641|    378|    uintptr_t ip = _Unwind_GetIP(context) - 1;
  642|       |    // Get beginning current frame's code (as defined by the
  643|       |    // emitted dwarf code)
  644|    378|    uintptr_t funcStart = _Unwind_GetRegionStart(context);
  645|       |#if defined(__USING_SJLJ_EXCEPTIONS__) || defined(__USING_WASM_EXCEPTIONS__)
  646|       |    if (ip == uintptr_t(-1))
  647|       |    {
  648|       |        // no action
  649|       |        results.reason = _URC_CONTINUE_UNWIND;
  650|       |        return;
  651|       |    }
  652|       |    else if (ip == 0)
  653|       |        call_terminate(native_exception, unwind_exception);
  654|       |    // ip is 1-based index into call site table
  655|       |#else  // !__USING_SJLJ_EXCEPTIONS__ && !__USING_WASM_EXCEPTIONS__
  656|    378|    uintptr_t ipOffset = ip - funcStart;
  657|    378|#endif // !__USING_SJLJ_EXCEPTIONS__ && !__USING_WASM_EXCEPTIONS__
  658|    378|    const uint8_t* classInfo = NULL;
  659|       |    // Note: See JITDwarfEmitter::EmitExceptionTable(...) for corresponding
  660|       |    //       dwarf emission
  661|       |    // Parse LSDA header.
  662|    378|    uint8_t lpStartEncoding = *lsda++;
  663|    378|    const uint8_t* lpStart = lpStartEncoding == DW_EH_PE_omit
  ------------------
  |  Branch (663:30): [True: 378, False: 0]
  ------------------
  664|    378|                                 ? (const uint8_t*)funcStart
  665|    378|                                 : (const uint8_t*)readEncodedPointer(&lsda, lpStartEncoding, base);
  666|    378|    uint8_t ttypeEncoding = *lsda++;
  667|    378|    if (ttypeEncoding != DW_EH_PE_omit)
  ------------------
  |  Branch (667:9): [True: 126, False: 252]
  ------------------
  668|    126|    {
  669|       |        // Calculate type info locations in emitted dwarf code which
  670|       |        // were flagged by type info arguments to llvm.eh.selector
  671|       |        // intrinsic
  672|    126|        uintptr_t classInfoOffset = readULEB128(&lsda);
  673|    126|        classInfo = lsda + classInfoOffset;
  674|    126|    }
  675|       |    // Walk call-site table looking for range that
  676|       |    // includes current PC.
  677|    378|    uint8_t callSiteEncoding = *lsda++;
  678|       |#if defined(__USING_SJLJ_EXCEPTIONS__) || defined(__USING_WASM_EXCEPTIONS__)
  679|       |    (void)callSiteEncoding;  // When using SjLj/Wasm exceptions, callSiteEncoding is never used
  680|       |#endif
  681|    378|    uint32_t callSiteTableLength = static_cast<uint32_t>(readULEB128(&lsda));
  682|    378|    const uint8_t* callSiteTableStart = lsda;
  683|    378|    const uint8_t* callSiteTableEnd = callSiteTableStart + callSiteTableLength;
  684|    378|    const uint8_t* actionTableStart = callSiteTableEnd;
  685|    378|    const uint8_t* callSitePtr = callSiteTableStart;
  686|  1.42k|    while (callSitePtr < callSiteTableEnd)
  ------------------
  |  Branch (686:12): [True: 1.42k, False: 0]
  ------------------
  687|  1.42k|    {
  688|       |        // There is one entry per call site.
  689|  1.42k|#if !defined(__USING_SJLJ_EXCEPTIONS__) && !defined(__USING_WASM_EXCEPTIONS__)
  690|       |        // The call sites are non-overlapping in [start, start+length)
  691|       |        // The call sites are ordered in increasing value of start
  692|  1.42k|        uintptr_t start = readEncodedPointer(&callSitePtr, callSiteEncoding);
  693|  1.42k|        uintptr_t length = readEncodedPointer(&callSitePtr, callSiteEncoding);
  694|  1.42k|        uintptr_t landingPad = readEncodedPointer(&callSitePtr, callSiteEncoding);
  695|  1.42k|        uintptr_t actionEntry = readULEB128(&callSitePtr);
  696|  1.42k|        if ((start <= ipOffset) && (ipOffset < (start + length)))
  ------------------
  |  Branch (696:13): [True: 1.42k, False: 0]
  |  Branch (696:36): [True: 378, False: 1.05k]
  ------------------
  697|       |#else  // __USING_SJLJ_EXCEPTIONS__ || __USING_WASM_EXCEPTIONS__
  698|       |        // ip is 1-based index into this table
  699|       |        uintptr_t landingPad = readULEB128(&callSitePtr);
  700|       |        uintptr_t actionEntry = readULEB128(&callSitePtr);
  701|       |        if (--ip == 0)
  702|       |#endif // __USING_SJLJ_EXCEPTIONS__ || __USING_WASM_EXCEPTIONS__
  703|    378|        {
  704|       |            // Found the call site containing ip.
  705|    378|#if !defined(__USING_SJLJ_EXCEPTIONS__) && !defined(__USING_WASM_EXCEPTIONS__)
  706|    378|            if (landingPad == 0)
  ------------------
  |  Branch (706:17): [True: 252, False: 126]
  ------------------
  707|    252|            {
  708|       |                // No handler here
  709|    252|                results.reason = _URC_CONTINUE_UNWIND;
  710|    252|                return;
  711|    252|            }
  712|    126|            landingPad = (uintptr_t)lpStart + landingPad;
  713|       |#else  // __USING_SJLJ_EXCEPTIONS__ || __USING_WASM_EXCEPTIONS__
  714|       |            ++landingPad;
  715|       |#endif // __USING_SJLJ_EXCEPTIONS__ || __USING_WASM_EXCEPTIONS__
  716|    126|            results.landingPad = landingPad;
  717|    126|            if (actionEntry == 0)
  ------------------
  |  Branch (717:17): [True: 0, False: 126]
  ------------------
  718|      0|            {
  719|       |                // Found a cleanup
  720|      0|                results.reason = actions & _UA_SEARCH_PHASE
  ------------------
  |  Branch (720:34): [True: 0, False: 0]
  ------------------
  721|      0|                                     ? _URC_CONTINUE_UNWIND
  722|      0|                                     : _URC_HANDLER_FOUND;
  723|      0|                return;
  724|      0|            }
  725|       |            // Convert 1-based byte offset into
  726|    126|            const uint8_t* action = actionTableStart + (actionEntry - 1);
  727|    126|            bool hasCleanup = false;
  728|       |            // Scan action entries until you find a matching handler, cleanup, or the end of action list
  729|    126|            while (true)
  ------------------
  |  Branch (729:20): [True: 126, Folded]
  ------------------
  730|    126|            {
  731|    126|                const uint8_t* actionRecord = action;
  732|    126|                int64_t ttypeIndex = readSLEB128(&action);
  733|    126|                if (ttypeIndex > 0)
  ------------------
  |  Branch (733:21): [True: 126, False: 0]
  ------------------
  734|    126|                {
  735|       |                    // Found a catch, does it actually catch?
  736|       |                    // First check for catch (...)
  737|    126|                    const __shim_type_info* catchType =
  738|    126|                        get_shim_type_info(static_cast<uint64_t>(ttypeIndex),
  739|    126|                                           classInfo, ttypeEncoding,
  740|    126|                                           native_exception, unwind_exception,
  741|    126|                                           base);
  742|    126|                    if (catchType == 0)
  ------------------
  |  Branch (742:25): [True: 0, False: 126]
  ------------------
  743|      0|                    {
  744|       |                        // Found catch (...) catches everything, including
  745|       |                        // foreign exceptions. This is search phase, cleanup
  746|       |                        // phase with foreign exception, or forced unwinding.
  747|      0|                        assert(actions & (_UA_SEARCH_PHASE | _UA_HANDLER_FRAME |
  ------------------
  |  Branch (747:25): [True: 0, False: 0]
  ------------------
  748|      0|                                          _UA_FORCE_UNWIND));
  749|      0|                        results.ttypeIndex = ttypeIndex;
  750|      0|                        results.actionRecord = actionRecord;
  751|      0|                        results.adjustedPtr =
  752|      0|                            get_thrown_object_ptr(unwind_exception);
  753|      0|                        results.reason = _URC_HANDLER_FOUND;
  754|      0|                        return;
  755|      0|                    }
  756|       |                    // Else this is a catch (T) clause and will never
  757|       |                    //    catch a foreign exception
  758|    126|                    else if (native_exception)
  ------------------
  |  Branch (758:30): [True: 126, False: 0]
  ------------------
  759|    126|                    {
  760|    126|                        __cxa_exception* exception_header = (__cxa_exception*)(unwind_exception+1) - 1;
  761|    126|                        void* adjustedPtr = get_thrown_object_ptr(unwind_exception);
  762|    126|                        const __shim_type_info* excpType =
  763|    126|                            static_cast<const __shim_type_info*>(exception_header->exceptionType);
  764|    126|                        if (adjustedPtr == 0 || excpType == 0)
  ------------------
  |  Branch (764:29): [True: 0, False: 126]
  |  Branch (764:49): [True: 0, False: 126]
  ------------------
  765|      0|                        {
  766|       |                            // Something very bad happened
  767|      0|                            call_terminate(native_exception, unwind_exception);
  768|      0|                        }
  769|    126|                        if (catchType->can_catch(excpType, adjustedPtr))
  ------------------
  |  Branch (769:29): [True: 126, False: 0]
  ------------------
  770|    126|                        {
  771|       |                            // Found a matching handler. This is either search
  772|       |                            // phase or forced unwinding.
  773|    126|                            assert(actions &
  ------------------
  |  Branch (773:29): [True: 126, False: 0]
  ------------------
  774|    126|                                   (_UA_SEARCH_PHASE | _UA_FORCE_UNWIND));
  775|    126|                            results.ttypeIndex = ttypeIndex;
  776|    126|                            results.actionRecord = actionRecord;
  777|    126|                            results.adjustedPtr = adjustedPtr;
  778|    126|                            results.reason = _URC_HANDLER_FOUND;
  779|    126|                            return;
  780|    126|                        }
  781|    126|                    }
  782|       |                    // Scan next action ...
  783|    126|                }
  784|      0|                else if (ttypeIndex < 0)
  ------------------
  |  Branch (784:26): [True: 0, False: 0]
  ------------------
  785|      0|                {
  786|       |                    // Found an exception specification.
  787|      0|                    if (actions & _UA_FORCE_UNWIND) {
  ------------------
  |  Branch (787:25): [True: 0, False: 0]
  ------------------
  788|       |                        // Skip if forced unwinding.
  789|      0|                    } else if (native_exception) {
  ------------------
  |  Branch (789:32): [True: 0, False: 0]
  ------------------
  790|       |                        // Does the exception spec catch this native exception?
  791|      0|                        __cxa_exception* exception_header = (__cxa_exception*)(unwind_exception+1) - 1;
  792|      0|                        void* adjustedPtr = get_thrown_object_ptr(unwind_exception);
  793|      0|                        const __shim_type_info* excpType =
  794|      0|                            static_cast<const __shim_type_info*>(exception_header->exceptionType);
  795|      0|                        if (adjustedPtr == 0 || excpType == 0)
  ------------------
  |  Branch (795:29): [True: 0, False: 0]
  |  Branch (795:49): [True: 0, False: 0]
  ------------------
  796|      0|                        {
  797|       |                            // Something very bad happened
  798|      0|                            call_terminate(native_exception, unwind_exception);
  799|      0|                        }
  800|      0|                        if (exception_spec_can_catch(ttypeIndex, classInfo,
  ------------------
  |  Branch (800:29): [True: 0, False: 0]
  ------------------
  801|      0|                                                     ttypeEncoding, excpType,
  802|      0|                                                     adjustedPtr,
  803|      0|                                                     unwind_exception, base))
  804|      0|                        {
  805|       |                            // Native exception caught by exception
  806|       |                            // specification.
  807|      0|                            assert(actions & _UA_SEARCH_PHASE);
  ------------------
  |  Branch (807:29): [True: 0, False: 0]
  ------------------
  808|      0|                            results.ttypeIndex = ttypeIndex;
  809|      0|                            results.actionRecord = actionRecord;
  810|      0|                            results.adjustedPtr = adjustedPtr;
  811|      0|                            results.reason = _URC_HANDLER_FOUND;
  812|      0|                            return;
  813|      0|                        }
  814|      0|                    } else {
  815|       |                        // foreign exception caught by exception spec
  816|      0|                        results.ttypeIndex = ttypeIndex;
  817|      0|                        results.actionRecord = actionRecord;
  818|      0|                        results.adjustedPtr =
  819|      0|                            get_thrown_object_ptr(unwind_exception);
  820|      0|                        results.reason = _URC_HANDLER_FOUND;
  821|      0|                        return;
  822|      0|                    }
  823|       |                    // Scan next action ...
  824|      0|                } else {
  825|      0|                    hasCleanup = true;
  826|      0|                }
  827|      0|                const uint8_t* temp = action;
  828|      0|                int64_t actionOffset = readSLEB128(&temp);
  829|      0|                if (actionOffset == 0)
  ------------------
  |  Branch (829:21): [True: 0, False: 0]
  ------------------
  830|      0|                {
  831|       |                    // End of action list. If this is phase 2 and we have found
  832|       |                    // a cleanup (ttypeIndex=0), return _URC_HANDLER_FOUND;
  833|       |                    // otherwise return _URC_CONTINUE_UNWIND.
  834|      0|                    results.reason = hasCleanup && actions & _UA_CLEANUP_PHASE
  ------------------
  |  Branch (834:38): [True: 0, False: 0]
  |  Branch (834:52): [True: 0, False: 0]
  ------------------
  835|      0|                                         ? _URC_HANDLER_FOUND
  836|      0|                                         : _URC_CONTINUE_UNWIND;
  837|      0|                    return;
  838|      0|                }
  839|       |                // Go to next action
  840|      0|                action += actionOffset;
  841|      0|            }  // there is no break out of this loop, only return
  842|    126|        }
  843|  1.05k|#if !defined(__USING_SJLJ_EXCEPTIONS__) && !defined(__USING_WASM_EXCEPTIONS__)
  844|  1.05k|        else if (ipOffset < start)
  ------------------
  |  Branch (844:18): [True: 0, False: 1.05k]
  ------------------
  845|      0|        {
  846|       |            // There is no call site for this ip
  847|       |            // Something bad has happened.  We should never get here.
  848|       |            // Possible stack corruption.
  849|      0|            call_terminate(native_exception, unwind_exception);
  850|      0|        }
  851|  1.42k|#endif // !__USING_SJLJ_EXCEPTIONS__ && !__USING_WASM_EXCEPTIONS__
  852|  1.42k|    }  // there might be some tricky cases which break out of this loop
  853|       |
  854|       |    // It is possible that no eh table entry specify how to handle
  855|       |    // this exception. By spec, terminate it immediately.
  856|      0|    call_terminate(native_exception, unwind_exception);
  857|      0|}
cxa_personality.cpp:_ZN10__cxxabiv1L11readSLEB128EPPKh:
  231|    126|{
  232|    126|    uintptr_t result = 0;
  233|    126|    uintptr_t shift = 0;
  234|    126|    unsigned char byte;
  235|    126|    const uint8_t *p = *data;
  236|    126|    do
  237|    126|    {
  238|    126|        byte = *p++;
  239|    126|        result |= static_cast<uintptr_t>(byte & 0x7F) << shift;
  240|    126|        shift += 7;
  241|    126|    } while (byte & 0x80);
  ------------------
  |  Branch (241:14): [True: 0, False: 126]
  ------------------
  242|    126|    *data = p;
  243|    126|    if ((byte & 0x40) && (shift < (sizeof(result) << 3)))
  ------------------
  |  Branch (243:9): [True: 0, False: 126]
  |  Branch (243:26): [True: 0, False: 0]
  ------------------
  244|      0|        result |= static_cast<uintptr_t>(~0) << shift;
  245|    126|    return static_cast<intptr_t>(result);
  246|    126|}
cxa_personality.cpp:_ZN10__cxxabiv1L18get_shim_type_infoEmPKhhbP17_Unwind_Exceptionm:
  389|    126|{
  390|    126|    if (classInfo == 0)
  ------------------
  |  Branch (390:9): [True: 0, False: 126]
  ------------------
  391|      0|    {
  392|       |        // this should not happen.  Indicates corrupted eh_table.
  393|      0|        call_terminate(native_exception, unwind_exception);
  394|      0|    }
  395|    126|    switch (ttypeEncoding & 0x0F)
  396|    126|    {
  397|      0|    case DW_EH_PE_absptr:
  ------------------
  |  Branch (397:5): [True: 0, False: 126]
  ------------------
  398|      0|        ttypeIndex *= sizeof(void*);
  399|      0|        break;
  400|      0|    case DW_EH_PE_udata2:
  ------------------
  |  Branch (400:5): [True: 0, False: 126]
  ------------------
  401|      0|    case DW_EH_PE_sdata2:
  ------------------
  |  Branch (401:5): [True: 0, False: 126]
  ------------------
  402|      0|        ttypeIndex *= 2;
  403|      0|        break;
  404|      0|    case DW_EH_PE_udata4:
  ------------------
  |  Branch (404:5): [True: 0, False: 126]
  ------------------
  405|    126|    case DW_EH_PE_sdata4:
  ------------------
  |  Branch (405:5): [True: 126, False: 0]
  ------------------
  406|    126|        ttypeIndex *= 4;
  407|    126|        break;
  408|      0|    case DW_EH_PE_udata8:
  ------------------
  |  Branch (408:5): [True: 0, False: 126]
  ------------------
  409|      0|    case DW_EH_PE_sdata8:
  ------------------
  |  Branch (409:5): [True: 0, False: 126]
  ------------------
  410|      0|        ttypeIndex *= 8;
  411|      0|        break;
  412|      0|    default:
  ------------------
  |  Branch (412:5): [True: 0, False: 126]
  ------------------
  413|       |        // this should not happen.   Indicates corrupted eh_table.
  414|      0|        call_terminate(native_exception, unwind_exception);
  415|    126|    }
  416|    126|    classInfo -= ttypeIndex;
  417|    126|    return (const __shim_type_info*)readEncodedPointer(&classInfo,
  418|    126|                                                       ttypeEncoding, base);
  419|    126|}
cxa_personality.cpp:_ZN10__cxxabiv1L21get_thrown_object_ptrEP17_Unwind_Exception:
  518|    126|{
  519|       |    // Even for foreign exceptions, the exception object is *probably* at unwind_exception + 1
  520|       |    //    Regardless, this library is prohibited from touching a foreign exception
  521|    126|    void* adjustedPtr = unwind_exception + 1;
  522|    126|    if (__getExceptionClass(unwind_exception) == kOurDependentExceptionClass)
  ------------------
  |  Branch (522:9): [True: 0, False: 126]
  ------------------
  523|      0|        adjustedPtr = ((__cxa_dependent_exception*)adjustedPtr - 1)->primaryException;
  524|    126|    return adjustedPtr;
  525|    126|}
cxa_personality.cpp:_ZN10__cxxabiv1L18readEncodedPointerEPPKhhm:
  258|  4.41k|{
  259|  4.41k|    uintptr_t result = 0;
  260|  4.41k|    if (encoding == DW_EH_PE_omit)
  ------------------
  |  Branch (260:9): [True: 0, False: 4.41k]
  ------------------
  261|      0|        return result;
  262|  4.41k|    const uint8_t* p = *data;
  263|       |    // first get value
  264|  4.41k|    switch (encoding & 0x0F)
  265|  4.41k|    {
  266|      0|    case DW_EH_PE_absptr:
  ------------------
  |  Branch (266:5): [True: 0, False: 4.41k]
  ------------------
  267|      0|        result = readPointerHelper<uintptr_t>(p);
  268|      0|        break;
  269|  4.28k|    case DW_EH_PE_uleb128:
  ------------------
  |  Branch (269:5): [True: 4.28k, False: 126]
  ------------------
  270|  4.28k|        result = readULEB128(&p);
  271|  4.28k|        break;
  272|      0|    case DW_EH_PE_sleb128:
  ------------------
  |  Branch (272:5): [True: 0, False: 4.41k]
  ------------------
  273|      0|        result = static_cast<uintptr_t>(readSLEB128(&p));
  274|      0|        break;
  275|      0|    case DW_EH_PE_udata2:
  ------------------
  |  Branch (275:5): [True: 0, False: 4.41k]
  ------------------
  276|      0|        result = readPointerHelper<uint16_t>(p);
  277|      0|        break;
  278|      0|    case DW_EH_PE_udata4:
  ------------------
  |  Branch (278:5): [True: 0, False: 4.41k]
  ------------------
  279|      0|        result = readPointerHelper<uint32_t>(p);
  280|      0|        break;
  281|      0|    case DW_EH_PE_udata8:
  ------------------
  |  Branch (281:5): [True: 0, False: 4.41k]
  ------------------
  282|      0|        result = readPointerHelper<uint64_t>(p);
  283|      0|        break;
  284|      0|    case DW_EH_PE_sdata2:
  ------------------
  |  Branch (284:5): [True: 0, False: 4.41k]
  ------------------
  285|      0|        result = readPointerHelper<int16_t>(p);
  286|      0|        break;
  287|    126|    case DW_EH_PE_sdata4:
  ------------------
  |  Branch (287:5): [True: 126, False: 4.28k]
  ------------------
  288|    126|        result = readPointerHelper<int32_t>(p);
  289|    126|        break;
  290|      0|    case DW_EH_PE_sdata8:
  ------------------
  |  Branch (290:5): [True: 0, False: 4.41k]
  ------------------
  291|      0|        result = readPointerHelper<int64_t>(p);
  292|      0|        break;
  293|      0|    default:
  ------------------
  |  Branch (293:5): [True: 0, False: 4.41k]
  ------------------
  294|       |        // not supported
  295|      0|        abort();
  296|      0|        break;
  297|  4.41k|    }
  298|       |    // then add relative offset
  299|  4.41k|    switch (encoding & 0x70)
  300|  4.41k|    {
  301|  4.28k|    case DW_EH_PE_absptr:
  ------------------
  |  Branch (301:5): [True: 4.28k, False: 126]
  ------------------
  302|       |        // do nothing
  303|  4.28k|        break;
  304|    126|    case DW_EH_PE_pcrel:
  ------------------
  |  Branch (304:5): [True: 126, False: 4.28k]
  ------------------
  305|    126|        if (result)
  ------------------
  |  Branch (305:13): [True: 126, False: 0]
  ------------------
  306|    126|            result += (uintptr_t)(*data);
  307|    126|        break;
  308|      0|    case DW_EH_PE_datarel:
  ------------------
  |  Branch (308:5): [True: 0, False: 4.41k]
  ------------------
  309|      0|        assert((base != 0) && "DW_EH_PE_datarel is invalid with a base of 0");
  ------------------
  |  Branch (309:9): [True: 0, False: 0]
  |  Branch (309:9): [True: 0, Folded]
  |  Branch (309:9): [True: 0, False: 0]
  ------------------
  310|      0|        if (result)
  ------------------
  |  Branch (310:13): [True: 0, False: 0]
  ------------------
  311|      0|            result += base;
  312|      0|        break;
  313|      0|    case DW_EH_PE_textrel:
  ------------------
  |  Branch (313:5): [True: 0, False: 4.41k]
  ------------------
  314|      0|    case DW_EH_PE_funcrel:
  ------------------
  |  Branch (314:5): [True: 0, False: 4.41k]
  ------------------
  315|      0|    case DW_EH_PE_aligned:
  ------------------
  |  Branch (315:5): [True: 0, False: 4.41k]
  ------------------
  316|      0|    default:
  ------------------
  |  Branch (316:5): [True: 0, False: 4.41k]
  ------------------
  317|       |        // not supported
  318|      0|        abort();
  319|      0|        break;
  320|  4.41k|    }
  321|       |    // then apply indirection
  322|  4.41k|    if (result && (encoding & DW_EH_PE_indirect))
  ------------------
  |  Branch (322:9): [True: 3.62k, False: 783]
  |  Branch (322:19): [True: 126, False: 3.50k]
  ------------------
  323|    126|        result = *((uintptr_t*)result);
  324|  4.41k|    *data = p;
  325|  4.41k|    return result;
  326|  4.41k|}
cxa_personality.cpp:_ZN10__cxxabiv112_GLOBAL__N_117readPointerHelperIiEEmRPKh:
  163|    126|uintptr_t readPointerHelper(const uint8_t*& p) {
  164|    126|    AsType value;
  165|    126|    memcpy(&value, p, sizeof(AsType));
  166|    126|    p += sizeof(AsType);
  167|    126|    return static_cast<uintptr_t>(value);
  168|    126|}
cxa_personality.cpp:_ZN10__cxxabiv1L11readULEB128EPPKh:
  208|  6.21k|{
  209|  6.21k|    uintptr_t result = 0;
  210|  6.21k|    uintptr_t shift = 0;
  211|  6.21k|    unsigned char byte;
  212|  6.21k|    const uint8_t *p = *data;
  213|  6.21k|    do
  214|  8.69k|    {
  215|  8.69k|        byte = *p++;
  216|  8.69k|        result |= static_cast<uintptr_t>(byte & 0x7F) << shift;
  217|  8.69k|        shift += 7;
  218|  8.69k|    } while (byte & 0x80);
  ------------------
  |  Branch (218:14): [True: 2.47k, False: 6.21k]
  ------------------
  219|  6.21k|    *data = p;
  220|  6.21k|    return result;
  221|  6.21k|}

_ZN10__cxxabiv130__aligned_malloc_with_fallbackEm:
  258|    126|void* __aligned_malloc_with_fallback(size_t size) {
  259|       |#if defined(_WIN32)
  260|       |  if (void* dest = std::__libcpp_aligned_alloc(alignof(__aligned_type), size))
  261|       |    return dest;
  262|       |#elif defined(_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION)
  263|       |  if (void* dest = ::malloc(size))
  264|       |    return dest;
  265|       |#else
  266|    126|  if (size == 0)
  ------------------
  |  Branch (266:7): [True: 0, False: 126]
  ------------------
  267|      0|    size = 1;
  268|    126|  if (void* dest = std::__libcpp_aligned_alloc(__alignof(__aligned_type), size))
  ------------------
  |  Branch (268:13): [True: 126, False: 0]
  ------------------
  269|    126|    return dest;
  270|      0|#endif
  271|      0|  return fallback_malloc(size);
  272|    126|}
_ZN10__cxxabiv122__calloc_with_fallbackEmm:
  274|      1|void* __calloc_with_fallback(size_t count, size_t size) {
  275|      1|  void* ptr = ::calloc(count, size);
  276|      1|  if (NULL != ptr)
  ------------------
  |  Branch (276:7): [True: 1, False: 0]
  ------------------
  277|      1|    return ptr;
  278|       |  // if calloc fails, fall back to emergency stash
  279|      0|  ptr = fallback_malloc(size * count);
  280|      0|  if (NULL != ptr)
  ------------------
  |  Branch (280:7): [True: 0, False: 0]
  ------------------
  281|      0|    ::memset(ptr, 0, size * count);
  282|      0|  return ptr;
  283|      1|}
_ZN10__cxxabiv128__aligned_free_with_fallbackEPv:
  285|    126|void __aligned_free_with_fallback(void* ptr) {
  286|    126|  if (is_fallback_ptr(ptr))
  ------------------
  |  Branch (286:7): [True: 0, False: 126]
  ------------------
  287|      0|    fallback_free(ptr);
  288|    126|  else {
  289|       |#if defined(_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION)
  290|       |    ::free(ptr);
  291|       |#else
  292|    126|    std::__libcpp_aligned_free(ptr);
  293|    126|#endif
  294|    126|  }
  295|    126|}
fallback_malloc.cpp:_ZN12_GLOBAL__N_115is_fallback_ptrEPv:
  128|    126|bool is_fallback_ptr(void* ptr) {
  129|    126|  return ptr >= heap && ptr < (heap + HEAP_SIZE);
  ------------------
  |  Branch (129:10): [True: 126, False: 0]
  |  Branch (129:25): [True: 0, False: 126]
  ------------------
  130|    126|}

_ZNK10__cxxabiv117__class_type_info9can_catchEPKNS_16__shim_type_infoERPv:
  464|    126|{
  465|       |    // bullet 1
  466|    126|    if (is_equal(this, thrown_type, false))
  ------------------
  |  Branch (466:9): [True: 3, False: 123]
  ------------------
  467|      3|        return true;
  468|    123|    const __class_type_info* thrown_class_type =
  469|    123|        dynamic_cast<const __class_type_info*>(thrown_type);
  470|    123|    if (thrown_class_type == 0)
  ------------------
  |  Branch (470:9): [True: 0, False: 123]
  ------------------
  471|      0|        return false;
  472|       |    // bullet 2
  473|    123|    assert(adjustedPtr && "catching a class without an object?");
  ------------------
  |  Branch (473:5): [True: 123, False: 0]
  |  Branch (473:5): [True: 123, Folded]
  |  Branch (473:5): [True: 123, False: 0]
  ------------------
  474|    123|    __dynamic_cast_info info = {thrown_class_type, 0, this, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, true, nullptr};
  475|    123|    info.number_of_dst_type = 1;
  476|    123|    thrown_class_type->has_unambiguous_public_base(&info, adjustedPtr, public_path);
  477|    123|    if (info.path_dst_ptr_to_static_ptr == public_path)
  ------------------
  |  Branch (477:9): [True: 123, False: 0]
  ------------------
  478|    123|    {
  479|    123|        adjustedPtr = const_cast<void*>(info.dst_ptr_leading_to_static_ptr);
  480|    123|        return true;
  481|    123|    }
  482|      0|    return false;
  483|    123|}
_ZNK10__cxxabiv117__class_type_info24process_found_base_classEPNS_19__dynamic_cast_infoEPvi:
  509|    123|{
  510|    123|  if (info->number_to_static_ptr == 0) {
  ------------------
  |  Branch (510:7): [True: 123, False: 0]
  ------------------
  511|       |    // First time we found this base
  512|    123|    info->dst_ptr_leading_to_static_ptr = adjustedPtr;
  513|    123|    info->path_dst_ptr_to_static_ptr = path_below;
  514|       |    // stash the virtual base cookie.
  515|    123|    info->dst_ptr_not_leading_to_static_ptr = info->vbase_cookie;
  516|    123|    info->number_to_static_ptr = 1;
  517|    123|  } else if (info->dst_ptr_not_leading_to_static_ptr == info->vbase_cookie &&
  ------------------
  |  Branch (517:14): [True: 0, False: 0]
  ------------------
  518|      0|             info->dst_ptr_leading_to_static_ptr == adjustedPtr) {
  ------------------
  |  Branch (518:14): [True: 0, False: 0]
  ------------------
  519|       |    // We've been here before.  Update path to "most public"
  520|      0|    if (info->path_dst_ptr_to_static_ptr == not_public_path)
  ------------------
  |  Branch (520:9): [True: 0, False: 0]
  ------------------
  521|      0|      info->path_dst_ptr_to_static_ptr = path_below;
  522|      0|  } else {
  523|       |    // We've detected an ambiguous cast from (thrown_class_type, adjustedPtr)
  524|       |    // to a static_type.
  525|      0|    info->number_to_static_ptr += 1;
  526|      0|    info->path_dst_ptr_to_static_ptr = not_public_path;
  527|      0|    info->search_done = true;
  528|      0|  }
  529|    123|}
_ZNK10__cxxabiv120__si_class_type_info27has_unambiguous_public_baseEPNS_19__dynamic_cast_infoEPvi:
  544|    246|{
  545|    246|    if (is_equal(this, info->static_type, false))
  ------------------
  |  Branch (545:9): [True: 123, False: 123]
  ------------------
  546|    123|        process_found_base_class(info, adjustedPtr, path_below);
  547|    123|    else
  548|    123|        __base_type->has_unambiguous_public_base(info, adjustedPtr, path_below);
  549|    246|}
__dynamic_cast:
  899|    123|               std::ptrdiff_t src2dst_offset) {
  900|       |    // Get (dynamic_ptr, dynamic_type) from static_ptr
  901|    123|    derived_object_info derived_info;
  902|    123|    dyn_cast_get_derived_info(&derived_info, static_ptr);
  903|       |
  904|       |    // Initialize answer to nullptr.  This will be changed from the search
  905|       |    //    results if a non-null answer is found.  Regardless, this is what will
  906|       |    //    be returned.
  907|    123|    const void* dst_ptr = 0;
  908|       |
  909|       |    // Find out if we can use a giant short cut in the search
  910|    123|    if (is_equal(derived_info.dynamic_type, dst_type, false))
  ------------------
  |  Branch (910:9): [True: 0, False: 123]
  ------------------
  911|      0|    {
  912|      0|        dst_ptr = dyn_cast_to_derived(static_ptr,
  913|      0|                                      derived_info.dynamic_ptr,
  914|      0|                                      static_type,
  915|      0|                                      dst_type,
  916|      0|                                      derived_info.offset_to_derived,
  917|      0|                                      src2dst_offset);
  918|      0|    }
  919|    123|    else
  920|    123|    {
  921|       |        // Optimize toward downcasting: let's first try to do a downcast before
  922|       |        //   falling back to the slow path.
  923|    123|        dst_ptr = dyn_cast_try_downcast(static_ptr,
  924|    123|                                        derived_info.dynamic_ptr,
  925|    123|                                        dst_type,
  926|    123|                                        derived_info.dynamic_type,
  927|    123|                                        src2dst_offset);
  928|       |
  929|    123|        if (!dst_ptr)
  ------------------
  |  Branch (929:13): [True: 0, False: 123]
  ------------------
  930|      0|        {
  931|      0|            dst_ptr = dyn_cast_slow(static_ptr,
  932|      0|                                    derived_info.dynamic_ptr,
  933|      0|                                    static_type,
  934|      0|                                    dst_type,
  935|      0|                                    derived_info.dynamic_type,
  936|      0|                                    src2dst_offset);
  937|      0|        }
  938|    123|    }
  939|       |
  940|    123|    return const_cast<void*>(dst_ptr);
  941|    123|}
_ZNK10__cxxabiv117__class_type_info29process_static_type_above_dstEPNS_19__dynamic_cast_infoEPKvS4_i:
  961|    123|{
  962|       |    // Record that we found a static_type
  963|    123|    info->found_any_static_type = true;
  964|    123|    if (current_ptr == info->static_ptr)
  ------------------
  |  Branch (964:9): [True: 123, False: 0]
  ------------------
  965|    123|    {
  966|       |        // Record that we found (static_ptr, static_type)
  967|    123|        info->found_our_static_ptr = true;
  968|    123|        if (info->dst_ptr_leading_to_static_ptr == 0)
  ------------------
  |  Branch (968:13): [True: 123, False: 0]
  ------------------
  969|    123|        {
  970|       |            // First time here
  971|    123|            info->dst_ptr_leading_to_static_ptr = dst_ptr;
  972|    123|            info->path_dst_ptr_to_static_ptr = path_below;
  973|    123|            info->number_to_static_ptr = 1;
  974|       |            // If there is only one dst_type in the entire tree and the path from
  975|       |            //    there to here is public then we are done!
  976|    123|            if (info->number_of_dst_type == 1 && info->path_dst_ptr_to_static_ptr == public_path)
  ------------------
  |  Branch (976:17): [True: 123, False: 0]
  |  Branch (976:50): [True: 123, False: 0]
  ------------------
  977|    123|                info->search_done = true;
  978|    123|        }
  979|      0|        else if (info->dst_ptr_leading_to_static_ptr == dst_ptr)
  ------------------
  |  Branch (979:18): [True: 0, False: 0]
  ------------------
  980|      0|        {
  981|       |            // We've been here before.  Update path to "most public"
  982|      0|            if (info->path_dst_ptr_to_static_ptr == not_public_path)
  ------------------
  |  Branch (982:17): [True: 0, False: 0]
  ------------------
  983|      0|                info->path_dst_ptr_to_static_ptr = path_below;
  984|       |            // If there is only one dst_type in the entire tree and the path from
  985|       |            //    there to here is public then we are done!
  986|      0|            if (info->number_of_dst_type == 1 && info->path_dst_ptr_to_static_ptr == public_path)
  ------------------
  |  Branch (986:17): [True: 0, False: 0]
  |  Branch (986:50): [True: 0, False: 0]
  ------------------
  987|      0|                info->search_done = true;
  988|      0|        }
  989|      0|        else
  990|      0|        {
  991|       |            // We've detected an ambiguous cast from (static_ptr, static_type)
  992|       |            //   to a dst_type
  993|      0|            info->number_to_static_ptr += 1;
  994|      0|            info->search_done = true;
  995|      0|        }
  996|    123|    }
  997|    123|}
_ZNK10__cxxabiv120__si_class_type_info16search_above_dstEPNS_19__dynamic_cast_infoEPKvS4_ib:
 1469|    246|{
 1470|    246|    if (is_equal(this, info->static_type, use_strcmp))
  ------------------
  |  Branch (1470:9): [True: 123, False: 123]
  ------------------
 1471|    123|        process_static_type_above_dst(info, dst_ptr, current_ptr, path_below);
 1472|    123|    else
 1473|    123|        __base_type->search_above_dst(info, dst_ptr, current_ptr, path_below, use_strcmp);
 1474|    246|}
private_typeinfo.cpp:_ZL8is_equalPKSt9type_infoS1_b:
   57|    741|{
   58|       |    // Use std::type_info's default comparison unless we've explicitly asked
   59|       |    // for strcmp.
   60|    741|    if (!use_strcmp)
  ------------------
  |  Branch (60:9): [True: 741, False: 0]
  ------------------
   61|    741|        return *x == *y;
   62|       |    // Still allow pointer equality to short circut.
   63|      0|    return x == y || strcmp(x->name(), y->name()) == 0;
  ------------------
  |  Branch (63:12): [True: 0, False: 0]
  |  Branch (63:22): [True: 0, False: 0]
  ------------------
   64|    741|}
private_typeinfo.cpp:_ZN10__cxxabiv112_GLOBAL__N_125dyn_cast_get_derived_infoEPNS0_19derived_object_infoEPKv:
   89|    123|{
   90|       |#if __has_feature(cxx_abi_relative_vtable)
   91|       |    // The vtable address will point to the first virtual function, which is 8
   92|       |    // bytes after the start of the vtable (4 for the offset from top + 4 for
   93|       |    // the typeinfo component).
   94|       |    const int32_t* vtable =
   95|       |        *reinterpret_cast<const int32_t* const*>(static_ptr);
   96|       |    info->offset_to_derived = static_cast<std::ptrdiff_t>(vtable[-2]);
   97|       |    info->dynamic_ptr = static_cast<const char*>(static_ptr) + info->offset_to_derived;
   98|       |
   99|       |    // The typeinfo component is now a relative offset to a proxy.
  100|       |    int32_t offset_to_ti_proxy = vtable[-1];
  101|       |    const uint8_t* ptr_to_ti_proxy =
  102|       |        reinterpret_cast<const uint8_t*>(vtable) + offset_to_ti_proxy;
  103|       |    info->dynamic_type = *(reinterpret_cast<const __class_type_info* const*>(ptr_to_ti_proxy));
  104|       |#else
  105|    123|    void **vtable = *static_cast<void ** const *>(static_ptr);
  106|    123|    info->offset_to_derived = reinterpret_cast<ptrdiff_t>(vtable[-2]);
  107|    123|    info->dynamic_ptr = static_cast<const char*>(static_ptr) + info->offset_to_derived;
  108|    123|    info->dynamic_type = static_cast<const __class_type_info*>(vtable[-1]);
  109|    123|#endif
  110|    123|}
private_typeinfo.cpp:_ZN10__cxxabiv112_GLOBAL__N_121dyn_cast_try_downcastEPKvS2_PKNS_17__class_type_infoES5_l:
  205|    123|{
  206|    123|    if (src2dst_offset < 0)
  ------------------
  |  Branch (206:9): [True: 0, False: 123]
  ------------------
  207|      0|    {
  208|       |        // We can only optimize the case if the static type is a unique public
  209|       |        //   base of dst_type. Give up.
  210|      0|        return nullptr;
  211|      0|    }
  212|       |
  213|       |    // Pretend there is a dst_type object that leads to static_ptr. Later we
  214|       |    //   will check whether this imagined dst_type object exists. If it exists
  215|       |    //   then it will be the casting result.
  216|    123|    const void* dst_ptr_to_static = reinterpret_cast<const char*>(static_ptr) - src2dst_offset;
  217|       |
  218|    123|    if (reinterpret_cast<std::intptr_t>(dst_ptr_to_static) < reinterpret_cast<std::intptr_t>(dynamic_ptr))
  ------------------
  |  Branch (218:9): [True: 0, False: 123]
  ------------------
  219|      0|    {
  220|       |        // The imagined dst_type object does not exist. Bail-out quickly.
  221|      0|        return nullptr;
  222|      0|    }
  223|       |
  224|       |    // Try to search a path from dynamic_type to dst_type.
  225|    123|    __dynamic_cast_info dynamic_to_dst_info = {dynamic_type,
  226|    123|                                               dst_ptr_to_static,
  227|    123|                                               dst_type,
  228|    123|                                               src2dst_offset,
  229|    123|                                               0,
  230|    123|                                               0,
  231|    123|                                               0,
  232|    123|                                               0,
  233|    123|                                               0,
  234|    123|                                               0,
  235|    123|                                               0,
  236|    123|                                               0,
  237|    123|                                               1, // number_of_dst_type
  238|    123|                                               false,
  239|    123|                                               false,
  240|    123|                                               false,
  241|    123|                                               true,
  242|    123|                                               nullptr};
  243|    123|    dynamic_type->search_above_dst(&dynamic_to_dst_info, dynamic_ptr, dynamic_ptr, public_path, false);
  244|    123|    if (dynamic_to_dst_info.path_dst_ptr_to_static_ptr != unknown) {
  ------------------
  |  Branch (244:9): [True: 123, False: 0]
  ------------------
  245|       |        // We have found at least one path from dynamic_ptr to dst_ptr. The
  246|       |        //   downcast can succeed.
  247|    123|        return dst_ptr_to_static;
  248|    123|    }
  249|       |
  250|      0|    return nullptr;
  251|    123|}

_ZNSt9exceptionD2Ev:
   18|    126|{
   19|    126|}

_Znwm:
   66|  8.13k|_LIBCPP_MAKE_OVERRIDABLE_FUNCTION_DETECTABLE _LIBCPP_WEAK void* operator new(std::size_t size) _THROW_BAD_ALLOC {
   67|  8.13k|  void* p = operator_new_impl(size);
   68|  8.13k|  if (p == nullptr)
  ------------------
  |  Branch (68:7): [True: 0, False: 8.13k]
  ------------------
   69|      0|    __throw_bad_alloc_shim();
   70|  8.13k|  return p;
   71|  8.13k|}
_ZdlPv:
  125|  8.13k|_LIBCPP_WEAK void operator delete(void* ptr) noexcept { std::free(ptr); }
_ZdlPvm:
  129|  8.01k|_LIBCPP_WEAK void operator delete(void* ptr, size_t) noexcept { ::operator delete(ptr); }
stdlib_new_delete.cpp:_ZL17operator_new_implm:
   50|  8.13k|static void* operator_new_impl(std::size_t size) {
   51|  8.13k|  if (size == 0)
  ------------------
  |  Branch (51:7): [True: 0, False: 8.13k]
  ------------------
   52|      0|    size = 1;
   53|  8.13k|  void* p;
   54|  8.13k|  while ((p = std::malloc(size)) == nullptr) {
  ------------------
  |  Branch (54:10): [True: 0, False: 8.13k]
  ------------------
   55|       |    // If malloc fails and there is a new_handler,
   56|       |    // call it to try free up memory.
   57|      0|    std::new_handler nh = std::get_new_handler();
   58|      0|    if (nh)
  ------------------
  |  Branch (58:9): [True: 0, False: 0]
  ------------------
   59|      0|      nh();
   60|      0|    else
   61|      0|      break;
   62|      0|  }
   63|  8.13k|  return p;
   64|  8.13k|}

_ZNSt13runtime_errorD2Ev:
   30|    126|runtime_error::~runtime_error() noexcept {}

